| //=- SystemZCallingConv.td - Calling conventions for SystemZ -*- tablegen -*-=// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // This describes the calling conventions for the SystemZ ABI. |
| //===----------------------------------------------------------------------===// |
| |
| class CCIfExtend<CCAction A> |
| : CCIf<"ArgFlags.isSExt() || ArgFlags.isZExt()", A>; |
| |
| //===----------------------------------------------------------------------===// |
| // SVR4 return value calling convention |
| //===----------------------------------------------------------------------===// |
| def RetCC_SystemZ : CallingConv<[ |
| // Promote i32 to i64 if it has an explicit extension type. |
| CCIfType<[i32], CCIfExtend<CCPromoteToType<i64>>>, |
| |
| // ABI-compliant code returns 64-bit integers in R2. Make the other |
| // call-clobbered argument registers available for code that doesn't |
| // care about the ABI. (R6 is an argument register too, but is |
| // call-saved and therefore not suitable for return values.) |
| CCIfType<[i32], CCAssignToReg<[R2W, R3W, R4W, R5W]>>, |
| CCIfType<[i64], CCAssignToReg<[R2D, R3D, R4D, R5D]>>, |
| |
| // ABI-complaint code returns float and double in F0. Make the |
| // other floating-point argument registers available for code that |
| // doesn't care about the ABI. All floating-point argument registers |
| // are call-clobbered, so we can use all of them here. |
| CCIfType<[f32], CCAssignToReg<[F0S, F2S, F4S, F6S]>>, |
| CCIfType<[f64], CCAssignToReg<[F0D, F2D, F4D, F6D]>> |
| |
| // ABI-compliant code returns long double by reference, but that conversion |
| // is left to higher-level code. Perhaps we could add an f128 definition |
| // here for code that doesn't care about the ABI? |
| ]>; |
| |
| //===----------------------------------------------------------------------===// |
| // SVR4 argument calling conventions |
| //===----------------------------------------------------------------------===// |
| def CC_SystemZ : CallingConv<[ |
| // Promote i32 to i64 if it has an explicit extension type. |
| // The convention is that true integer arguments that are smaller |
| // than 64 bits should be marked as extended, but structures that |
| // are smaller than 64 bits shouldn't. |
| CCIfType<[i32], CCIfExtend<CCPromoteToType<i64>>>, |
| |
| // Force long double values to the stack and pass i64 pointers to them. |
| CCIfType<[f128], CCPassIndirect<i64>>, |
| |
| // The first 5 integer arguments are passed in R2-R6. Note that R6 |
| // is call-saved. |
| CCIfType<[i32], CCAssignToReg<[R2W, R3W, R4W, R5W, R6W]>>, |
| CCIfType<[i64], CCAssignToReg<[R2D, R3D, R4D, R5D, R6D]>>, |
| |
| // The first 4 float and double arguments are passed in even registers F0-F6. |
| CCIfType<[f32], CCAssignToReg<[F0S, F2S, F4S, F6S]>>, |
| CCIfType<[f64], CCAssignToReg<[F0D, F2D, F4D, F6D]>>, |
| |
| // Other arguments are passed in 8-byte-aligned 8-byte stack slots. |
| CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>> |
| ]>; |