X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsCallingConv.td;h=0b4b7785af670bd7aff9b2f52084f681a0f286d7;hb=72f9544cc033e9e7316691f0f210672c9639cb14;hp=4d64da2b3e166d12ad2467ce385c46379c210e7a;hpb=b4b823941cb12bc50a07c9e6f0c648a72cfa9683;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index 4d64da2b3e1..0b4b7785af6 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -20,6 +20,29 @@ class CCIfSubtarget // The inverse of CCIfSubtarget class CCIfSubtargetNot : CCIfSubtarget; +/// Match if the original argument (before lowering) was a float. +/// For example, this is true for i32's that were lowered from soft-float. +class CCIfOrigArgWasNotFloat + : CCIf<"!static_cast(&State)->WasOriginalArgFloat(ValNo)", + A>; + +/// Match if the original argument (before lowering) was a 128-bit float (i.e. +/// long double). +class CCIfOrigArgWasF128 + : CCIf<"static_cast(&State)->WasOriginalArgF128(ValNo)", A>; + +/// Match if this specific argument is a vararg. +/// This is slightly different fro CCIfIsVarArg which matches if any argument is +/// a vararg. +class CCIfArgIsVarArg + : CCIf<"!static_cast(&State)->IsCallOperandFixed(ValNo)", A>; + + +/// Match if the special calling conv is the specified value. +class CCIfSpecialCallingConv + : CCIf<"static_cast(&State)->getSpecialCallingConv() == " + "MipsCCState::" # CC, A>; + // For soft-float, f128 values are returned in A0_64 rather than V1_64. def RetCC_F128SoftFloat : CallingConv<[ CCAssignToReg<[V0_64, A0_64]> @@ -41,9 +64,9 @@ def RetCC_F128HardFloat : CallingConv<[ // Handle F128 specially since we can't identify the original type during the // tablegen-erated code. def RetCC_F128 : CallingConv<[ - CCIfSubtarget<"abiUsesSoftFloat()", + CCIfSubtarget<"useSoftFloat()", CCIfType<[i64], CCDelegateTo>>, - CCIfSubtargetNot<"abiUsesSoftFloat()", + CCIfSubtargetNot<"useSoftFloat()", CCIfType<[i64], CCDelegateTo>> ]>; @@ -51,9 +74,25 @@ def RetCC_F128 : CallingConv<[ // Mips O32 Calling Convention //===----------------------------------------------------------------------===// +def CC_MipsO32 : CallingConv<[ + // Promote i8/i16 arguments to i32. + CCIfType<[i1, i8, i16], CCPromoteToType>, + + // Integer values get stored in stack slots that are 4 bytes in + // size and 4-byte aligned. + CCIfType<[i32, f32], CCAssignToStack<4, 4>>, + + // Integer values get stored in stack slots that are 8 bytes in + // size and 8-byte aligned. + CCIfType<[f64], CCAssignToStack<8, 8>> +]>; + // Only the return rules are defined here for O32. The rules for argument // passing are defined in MipsISelLowering.cpp. def RetCC_MipsO32 : CallingConv<[ + // Promote i1/i8/i16 return values to i32. + CCIfType<[i1, i8, i16], CCPromoteToType>, + // i32 are returned in registers V0, V1, A0, A1 CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>>, @@ -78,16 +117,26 @@ def CC_MipsO32_FP : CallingConv<[ // Mips N32/64 Calling Convention //===----------------------------------------------------------------------===// +def CC_MipsN_SoftFloat : CallingConv<[ + CCAssignToRegWithShadow<[A0, A1, A2, A3, + T0, T1, T2, T3], + [D12_64, D13_64, D14_64, D15_64, + D16_64, D17_64, D18_64, D19_64]>, + CCAssignToStack<4, 8> +]>; + def CC_MipsN : CallingConv<[ - // Promote i8/i16 arguments to i32. - CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i8, i16, i32, i64], + CCIfSubtargetNot<"isLittle()", + CCIfInReg>>>, - // Integer arguments are passed in integer registers. - CCIfType<[i32], CCAssignToRegWithShadow<[A0, A1, A2, A3, - T0, T1, T2, T3], - [F12, F13, F14, F15, - F16, F17, F18, F19]>>, + // All integers (except soft-float integers) are promoted to 64-bit. + CCIfType<[i8, i16, i32], CCIfOrigArgWasNotFloat>>, + // The only i32's we have left are soft-float arguments. + CCIfSubtarget<"useSoftFloat()", CCIfType<[i32], CCDelegateTo>>, + + // Integer arguments are passed in integer registers. CCIfType<[i64], CCAssignToRegWithShadow<[A0_64, A1_64, A2_64, A3_64, T0_64, T1_64, T2_64, T3_64], [D12_64, D13_64, D14_64, D15_64, @@ -106,23 +155,27 @@ def CC_MipsN : CallingConv<[ T0_64, T1_64, T2_64, T3_64]>>, // All stack parameter slots become 64-bit doublewords and are 8-byte aligned. - CCIfType<[i32, f32], CCAssignToStack<4, 8>>, + CCIfType<[f32], CCAssignToStack<4, 8>>, CCIfType<[i64, f64], CCAssignToStack<8, 8>> ]>; // N32/64 variable arguments. // All arguments are passed in integer registers. def CC_MipsN_VarArg : CallingConv<[ - // Promote i8/i16 arguments to i32. - CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i8, i16, i32, i64], + CCIfSubtargetNot<"isLittle()", + CCIfInReg>>>, + + // All integers are promoted to 64-bit. + CCIfType<[i8, i16, i32], CCPromoteToType>, - CCIfType<[i32, f32], CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3]>>, + CCIfType<[f32], CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3]>>, CCIfType<[i64, f64], CCAssignToReg<[A0_64, A1_64, A2_64, A3_64, T0_64, T1_64, T2_64, T3_64]>>, // All stack parameter slots become 64-bit doublewords and are 8-byte aligned. - CCIfType<[i32, f32], CCAssignToStack<4, 8>>, + CCIfType<[f32], CCAssignToStack<4, 8>>, CCIfType<[i64, f64], CCAssignToStack<8, 8>> ]>; @@ -137,9 +190,7 @@ def RetCC_MipsN : CallingConv<[ // // f128 should only occur for the N64 ABI where long double is 128-bit. On // N32, long double is equivalent to double. - CCIfType<[i64], - CCIf<"static_cast(&State)->WasOriginalArgF128(ValNo)", - CCDelegateTo>>, + CCIfType<[i64], CCIfOrigArgWasF128>>, // Aggregate returns are positioned at the lowest address in the slot for // both little and big-endian targets. When passing in registers, this @@ -305,8 +356,7 @@ def CC_Mips16RetHelper : CallingConv<[ def CC_Mips_FixedArg : CallingConv<[ // Mips16 needs special handling on some functions. CCIf<"State.getCallingConv() != CallingConv::Fast", - CCIf<"static_cast(&State)->getSpecialCallingConv() == " - "MipsCCState::Mips16RetHelperConv", + CCIfSpecialCallingConv<"Mips16RetHelperConv", CCDelegateTo>>, CCIfByVal>, @@ -322,9 +372,8 @@ def CC_Mips_FixedArg : CallingConv<[ // f128 should only occur for the N64 ABI where long double is 128-bit. On // N32, long double is equivalent to double. CCIfType<[i64], - CCIfSubtargetNot<"abiUsesSoftFloat()", - CCIf<"static_cast(&State)->WasOriginalArgF128(ValNo)", - CCBitConvertToType>>>, + CCIfSubtargetNot<"useSoftFloat()", + CCIfOrigArgWasF128>>>, CCIfCC<"CallingConv::Fast", CCDelegateTo>, @@ -344,9 +393,7 @@ def CC_Mips_VarArg : CallingConv<[ ]>; def CC_Mips : CallingConv<[ - CCIfVarArg< - CCIf<"!static_cast(&State)->IsCallOperandFixed(ValNo)", - CCDelegateTo>>, + CCIfVarArg>>, CCDelegateTo ]>; @@ -380,3 +427,28 @@ def CSR_Mips16RetHelper : CalleeSavedRegs<(add V0, V1, FP, (sequence "A%u", 3, 0), (sequence "S%u", 7, 0), (sequence "D%u", 15, 10))>; + +def CSR_Interrupt_32R6 : CalleeSavedRegs<(add (sequence "A%u", 3, 0), + (sequence "S%u", 7, 0), + (sequence "V%u", 1, 0), + (sequence "T%u", 9, 0), + RA, FP, GP, AT)>; + +def CSR_Interrupt_32 : CalleeSavedRegs<(add (sequence "A%u", 3, 0), + (sequence "S%u", 7, 0), + (sequence "V%u", 1, 0), + (sequence "T%u", 9, 0), + RA, FP, GP, AT, LO0, HI0)>; + +def CSR_Interrupt_64R6 : CalleeSavedRegs<(add (sequence "A%u_64", 3, 0), + (sequence "V%u_64", 1, 0), + (sequence "S%u_64", 7, 0), + (sequence "T%u_64", 9, 0), + RA_64, FP_64, GP_64, AT_64)>; + +def CSR_Interrupt_64 : CalleeSavedRegs<(add (sequence "A%u_64", 3, 0), + (sequence "S%u_64", 7, 0), + (sequence "T%u_64", 9, 0), + (sequence "V%u_64", 1, 0), + RA_64, FP_64, GP_64, AT_64, + LO0_64, HI0_64)>;