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.