Job Noorman
2012-Nov-27 15:32 UTC
[LLVMdev] Problem selecting the correct registers for a calling convention
I'm currently working on the MSP430 backend and I have some problems implementing the calling convention. It's a 16-bit architecture which dictates that arguments should be passed in registers R15-R12. Therefore, I have something like this is a .td file: CCIfType<[i16], CCAssignToReg<[R15W, R14W, R13W, R12W]>> 32-bit arguments should be passed in R14:R15 (R12:R13). Since it's a little endian architecture, R14 (R12) should contain the least significant bytes and R15 (R13) the most significant ones. The problem is that before the calling convention is applied, i32's are legalized into two i16's, the first one containing the least significant bytes. This causes R15 to be selected for the least significant bytes, which is not what I want. This issue is basically that I cannot find a way to distinguish two i16 arguments from one i32. Is there a way to do this in LLVM? Preferably using tablegen, of course:-) Kind regards, Job
Tim Northover
2012-Nov-27 15:50 UTC
[LLVMdev] Problem selecting the correct registers for a calling convention
Hi Job,> This issue is basically that I cannot find a way to distinguish two i16 > arguments from one i32. Is there a way to do this in LLVM? Preferably using > tablegen, of course:-)I think the property you want is "isSplit" (or, from the TableGen side CCIfSplit). This gets applied to the first of those i16s that are produced. Unfortunately I can't think of much you can do from TableGen to swap the registers around (CCIfSplit is useful if the i32 would have to start at an even-numbered register, for example). But in the C++ ISelLowering code you can use that flag to deal with the two registers together in a sane way. Tim.
Job Noorman
2013-Jul-02 09:34 UTC
[LLVMdev] Problem selecting the correct registers for a calling convention
Hi Tim, I finally found some time to work on this issue again and I'm currently trying your suggestion: implementing the calling convention in C++. I have the feeling that isSplit is not enough to deal with my problem since there seems to be no way to tell if later arguments belong to the split or not. For example, a call to a function f(i32, i16, i16) will look exactly the same as one to g(i64):> Arg: 0, isSplit: 1 > Arg: 1, isSplit: 0 > Arg: 2, isSplit: 0 > Arg: 3, isSplit: 0The information I need seems to be available in the InputArg class (OrigArgIndex and PartOffset) but unfortunately, only its Flags member is passed to the calling convention implementation. Am I missing something here? Regards, Job On Tuesday 27 November 2012 15:50:38 Tim Northover wrote:> Hi Job, > > > This issue is basically that I cannot find a way to distinguish two i16 > > arguments from one i32. Is there a way to do this in LLVM? Preferably > > using > > tablegen, of course:-) > > I think the property you want is "isSplit" (or, from the TableGen side > CCIfSplit). > > This gets applied to the first of those i16s that are produced. > Unfortunately I can't think of much you can do from TableGen to swap > the registers around (CCIfSplit is useful if the i32 would have to > start at an even-numbered register, for example). But in the C++ > ISelLowering code you can use that flag to deal with the two registers > together in a sane way. > > Tim.
Maybe Matching Threads
- [LLVMdev] Problem selecting the correct registers for a calling convention
- [LLVMdev] Problem selecting the correct registers for a calling convention
- [LLVMdev] [cfe-commits] Fix handling of ARM homogenous aggregates
- [LLVMdev] [cfe-commits] Fix handling of ARM homogenous aggregates
- [LLVMdev] [cfe-commits] Fix handling of ARM homogenous aggregates