Forgot to add: When I was writing the x86_64 ABI code for gollvm, I spent some time creating an ABI test harness to find problems in my code. You can find it at:
https://github.com/thanm/cabi-testgen The overall idea is that it randomly generates a lot of parameter-passing code, then you can build half of the code with a "known good" compiler (in this case gccgo would be the logical choice) and then the other half with the compiler you are developing. This may be useful once you get a bit farther along. Cheers, Than On Tue, Aug 20, 2019 at 9:33 AM Than McIntosh <th...@google.com> wrote: > Hi Eric, > > Thanks for the note. Your question about the code in > CABIOracle::canPassDirectly, e.g . > > if (regsInt + regsSSE == 1) > return true; > > is a good one. I'll see about adding some comments to the code there. > > By way of explanation, the Gollvm code is modeled after the approach used > in clang, which does something similar in this case. For example, consider > the following small C program: > > typedef unsigned long long u; > extern u bar(u p1, u p2, u p3, u p4, u p5, u p6, u p7, u p8, u p9, u p10); > u foo(u p) { > return bar(1,2,3,4,5,6,7,8,9,p); > } > > Let's say you compile this code with clang for x86_64 and look at the > emitted LLVM IR and emitted assembly, e.g. > > clang -c -S file.c -O > clang -c -S file.c -O -emit-llvm > > In the *.ll file you'll see this LLVM IR for 'foo': > > define i64 @foo(i64) local_unnamed_addr #0 { > %2 = tail call i64 @bar(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 > %0) #2 > ret i64 %2 > } > > What is interesting here is that the function being called, "bar", has 7 > arguments. Under the rules of the C/C++ ABI for x86_64, not all of the > parameters can be passed in registers -- some of them have to go in memory. > However looking at the signature, there are no memory arguments, everything > is being passed by value. Now let's look at the assembly: > > foo: > pushq %rax > *movq %rdi, (%rsp)* > movl $1, %edi > movl $2, %esi > movl $3, %edx > movl $4, %ecx > movl $5, %r8d > movl $6, %r9d > callq bar > popq %rcx > retq > > > As you can see, the back end knows about the rules of the C/C++ ABI for > x86_64, and it has put the right things in registers and in memory so that > the ABI is honored. > > So essentially what's happening is that the front end (clang) is playing a > little game with the back end -- for the more complicated cases involving > aggregates and things bigger than a single register, the front end makes > the LLVM IR explicit with regard to what gets passed in memory via by > value. For small parameters (things that will fit into a single register) > it just leaves them by value and counts on having the back end sort it out. > Doing things this way has advantages from a performance perspective. > > For your second question, yes, your approach seems reasonable -- > making CABIOracle into a base class and then adding virtual methods seems > like the right way to go. I don't have any very specific advice on classes > like CABIParamInfo and EightByteInfo -- I would say the former seems a bit > more abstract and reusable whereas the notion of an "EightByte" seems > pretty specific to the language in the x86_64 abi description. I would just > take your best shot and see how things go. > > Hope this helps, let me know if you have other questions... > > Thanks, Than > > > > > On Tue, Aug 20, 2019 at 8:42 AM eric fang <eric.f...@arm.com> wrote: > >> Hi Than, >> >> I'm trying to implement the abi part for arm64, and got two questions for >> you: >> >> 1, function CABIOracle::canPassDirectly in >> gollvm/bridge/go-llvm-cabi-oracle.cpp, I'm not quite understand the first >> if statement: >> if (regsInt + regsSSE == 1) >> return true; >> Why not consider whether there are enough available registers here? >> >> 2, I plan to abstract the CABIOracle class into a base class, and each >> architecture implements an inheritance class based on this class. But there >> are some auxiliary classes and structures (like class CABIParamInfo and >> EightByteInfo etc.) in this file that are also x86 specific. I haven't >> figured out how to handle these yet, maybe some of them are also reusable. >> Do you think this design is reasonable? Any suggestions? I should submit a >> prototype patch, which would be more convenient to discuss, but I have not >> implemented it yet. . . >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/702e3129-b72a-411d-80fe-70e9daae207d%40googlegroups.com >> <https://groups.google.com/d/msgid/golang-nuts/702e3129-b72a-411d-80fe-70e9daae207d%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CA%2BUr55Hm%3DOWBbFkZQuiaNzPjqV_1DaqxzvTRGu%3DLf4Kd8VU%2BTQ%40mail.gmail.com.