[LLVMdev] Struct parameter

Bob Wilson bob.wilson at apple.com
Thu Mar 4 09:31:43 PST 2010


On Mar 3, 2010, at 10:40 PM, Hwalin wrote:

> Hi, guys,
> 
> If there is a struct {i8, i8, i32}, and there are several parameter GPRs(32bits), say, r0, r1~r5, I can make this struct to be passed in r0, r1 because LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS is true in DefaultABI, neither it passed by value, nor it passed as FCA.
> 
> But if the first parameter register r0 is occupied by other argument, in DefaultABI, that struct passed as a i64, and i64 requires 8 bytes alignment in my target, therefore, r1 is skipped for this reason, this is not what I want.
> I have tried to pass struct as FCA or byval, but pass as FCA do not pass those 2 i8 elements in one register, and byval does not obey the
> ABI definition of my target, my target wants that struct passes in 2 general registers with 4 bytes alignment, not 8 byte alignment.
> 
> Should I implement another ABI class for my target in llvm-gcc?

I don't completely understand the details of your problem, but it is unlikely that you need a new ABI class.  There are a number of macros in llvm-gcc that control argument passing for aggregates:

LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR
LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS
LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS

There are some confusing aspects llvm-gcc's argument passing, but once you figure out how it works, there is a lot of flexibility.  These macros are currently used in llvm-gcc to implement some very complicated calling conventions, so there is probably a way to do what you want by having your target provide different versions of these and other macros.

I suggest you take a look at what some of the other targets do.  ARM is currently using the "pass aggregate in integer regs" approach, for example.  If you're using llvm 2.6 or earlier, you might want to try svn trunk since there were some problems fixed in this area recently.



More information about the llvm-dev mailing list