X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMRegisterInfo.td;h=7c0319a01ee71d58aadbc82ff618a78f26751e23;hb=ea139f1c91d257c41e0d118e9fbbd694e67361d3;hp=ed8ac1aff7a71dd6adda325373a2c2cba239338a;hpb=eb1641d54a7eda7717304bc4d55d059208d8ebed;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index ed8ac1aff7a..7c0319a01ee 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -27,28 +27,31 @@ class ARMFReg Enc, string n> : Register { // Subregister indices. let Namespace = "ARM" in { -def qqsub_0 : SubRegIndex; -def qqsub_1 : SubRegIndex; +def qqsub_0 : SubRegIndex<256>; +def qqsub_1 : SubRegIndex<256, 256>; // Note: Code depends on these having consecutive numbers. -def qsub_0 : SubRegIndex; -def qsub_1 : SubRegIndex; -def qsub_2 : SubRegIndex<[qqsub_1, qsub_0]>; -def qsub_3 : SubRegIndex<[qqsub_1, qsub_1]>; - -def dsub_0 : SubRegIndex; -def dsub_1 : SubRegIndex; -def dsub_2 : SubRegIndex<[qsub_1, dsub_0]>; -def dsub_3 : SubRegIndex<[qsub_1, dsub_1]>; -def dsub_4 : SubRegIndex<[qsub_2, dsub_0]>; -def dsub_5 : SubRegIndex<[qsub_2, dsub_1]>; -def dsub_6 : SubRegIndex<[qsub_3, dsub_0]>; -def dsub_7 : SubRegIndex<[qsub_3, dsub_1]>; - -def ssub_0 : SubRegIndex; -def ssub_1 : SubRegIndex; -def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>; -def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>; +def qsub_0 : SubRegIndex<128>; +def qsub_1 : SubRegIndex<128, 128>; +def qsub_2 : ComposedSubRegIndex; +def qsub_3 : ComposedSubRegIndex; + +def dsub_0 : SubRegIndex<64>; +def dsub_1 : SubRegIndex<64, 64>; +def dsub_2 : ComposedSubRegIndex; +def dsub_3 : ComposedSubRegIndex; +def dsub_4 : ComposedSubRegIndex; +def dsub_5 : ComposedSubRegIndex; +def dsub_6 : ComposedSubRegIndex; +def dsub_7 : ComposedSubRegIndex; + +def ssub_0 : SubRegIndex<32>; +def ssub_1 : SubRegIndex<32, 32>; +def ssub_2 : ComposedSubRegIndex; +def ssub_3 : ComposedSubRegIndex; + +def gsub_0 : SubRegIndex<32>; +def gsub_1 : SubRegIndex<32, 32>; // Let TableGen synthesize the remaining 12 ssub_* indices. // We don't need to name them. } @@ -113,13 +116,13 @@ def D15 : ARMReg<15, "d15", [S30, S31]>, DwarfRegNum<[271]>; } // VFP3 defines 16 additional double registers -def D16 : ARMFReg<16, "d16">, DwarfRegNum<[272]>; +def D16 : ARMFReg<16, "d16">, DwarfRegNum<[272]>; def D17 : ARMFReg<17, "d17">, DwarfRegNum<[273]>; def D18 : ARMFReg<18, "d18">, DwarfRegNum<[274]>; def D19 : ARMFReg<19, "d19">, DwarfRegNum<[275]>; def D20 : ARMFReg<20, "d20">, DwarfRegNum<[276]>; def D21 : ARMFReg<21, "d21">, DwarfRegNum<[277]>; -def D22 : ARMFReg<22, "d22">, DwarfRegNum<[278]>; +def D22 : ARMFReg<22, "d22">, DwarfRegNum<[278]>; def D23 : ARMFReg<23, "d23">, DwarfRegNum<[279]>; def D24 : ARMFReg<24, "d24">, DwarfRegNum<[280]>; def D25 : ARMFReg<25, "d25">, DwarfRegNum<[281]>; @@ -154,21 +157,27 @@ def Q15 : ARMReg<15, "q15", [D30, D31]>; // Current Program Status Register. // We model fpscr with two registers: FPSCR models the control bits and will be -// reserved. FPSCR_NZCV models the flag bits and will be unreserved. -def CPSR : ARMReg<0, "cpsr">; -def APSR : ARMReg<1, "apsr">; -def SPSR : ARMReg<2, "spsr">; -def FPSCR : ARMReg<3, "fpscr">; -def FPSCR_NZCV : ARMReg<3, "fpscr_nzcv"> { +// reserved. FPSCR_NZCV models the flag bits and will be unreserved. APSR_NZCV +// models the APSR when it's accessed by some special instructions. In such cases +// it has the same encoding as PC. +def CPSR : ARMReg<0, "cpsr">; +def APSR : ARMReg<1, "apsr">; +def APSR_NZCV : ARMReg<15, "apsr_nzcv">; +def SPSR : ARMReg<2, "spsr">; +def FPSCR : ARMReg<3, "fpscr">; +def FPSCR_NZCV : ARMReg<3, "fpscr_nzcv"> { let Aliases = [FPSCR]; } def ITSTATE : ARMReg<4, "itstate">; // Special Registers - only available in privileged mode. -def FPSID : ARMReg<0, "fpsid">; -def MVFR1 : ARMReg<6, "mvfr1">; -def MVFR0 : ARMReg<7, "mvfr0">; -def FPEXC : ARMReg<8, "fpexc">; +def FPSID : ARMReg<0, "fpsid">; +def MVFR2 : ARMReg<5, "mvfr2">; +def MVFR1 : ARMReg<6, "mvfr1">; +def MVFR0 : ARMReg<7, "mvfr0">; +def FPEXC : ARMReg<8, "fpexc">; +def FPINST : ARMReg<9, "fpinst">; +def FPINST2 : ARMReg<10, "fpinst2">; // Register classes. // @@ -190,7 +199,7 @@ def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), // Thumb1 instructions that know how to use hi regs. let AltOrders = [(add LR, GPR), (trunc GPR, 8)]; let AltOrderSelect = [{ - return 1 + MF.getTarget().getSubtarget().isThumb1Only(); + return 1 + MF.getSubtarget().isThumb1Only(); }]; } @@ -200,7 +209,17 @@ def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), def GPRnopc : RegisterClass<"ARM", [i32], 32, (sub GPR, PC)> { let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8)]; let AltOrderSelect = [{ - return 1 + MF.getTarget().getSubtarget().isThumb1Only(); + return 1 + MF.getSubtarget().isThumb1Only(); + }]; +} + +// GPRs without the PC but with APSR. Some instructions allow accessing the +// APSR, while actually encoding PC in the register field. This is useful +// for assembly and disassembly only. +def GPRwithAPSR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), APSR_NZCV)> { + let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8)]; + let AltOrderSelect = [{ + return 1 + MF.getSubtarget().isThumb1Only(); }]; } @@ -218,7 +237,7 @@ def GPRsp : RegisterClass<"ARM", [i32], 32, (add SP)>; def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> { let AltOrders = [(add LR, rGPR), (trunc rGPR, 8)]; let AltOrderSelect = [{ - return 1 + MF.getTarget().getSubtarget().isThumb1Only(); + return 1 + MF.getSubtarget().isThumb1Only(); }]; } @@ -233,10 +252,10 @@ def hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)>; // to the saved value before the tail call, which would clobber a call address. // Note, getMinimalPhysRegClass(R0) returns tGPR because of the names of // this class and the preceding one(!) This is what we want. -def tcGPR : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3, R9, R12)> { +def tcGPR : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3, R12)> { let AltOrders = [(and tcGPR, tGPR)]; let AltOrderSelect = [{ - return MF.getTarget().getSubtarget().isThumb1Only(); + return MF.getSubtarget().isThumb1Only(); }]; } @@ -247,12 +266,19 @@ def CCR : RegisterClass<"ARM", [i32], 32, (add CPSR)> { } // Scalar single precision floating point register class.. -// FIXME: Allocation order changed to s0, s2, s4, ... as a quick hack to -// avoid partial-write dependencies on D registers (S registers are -// renamed as portions of D registers). -def SPR : RegisterClass<"ARM", [f32], 32, (add (decimate - (sequence "S%u", 0, 31), 2), - (sequence "S%u", 0, 31))>; +// FIXME: Allocation order changed to s0, s2, ... or s0, s4, ... as a quick hack +// to avoid partial-write dependencies on D or Q (depending on platform) +// registers (S registers are renamed as portions of D/Q registers). +def SPR : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 31)> { + let AltOrders = [(add (decimate SPR, 2), SPR), + (add (decimate SPR, 4), + (decimate SPR, 2), + (decimate (rotl SPR, 1), 4), + (decimate (rotl SPR, 1), 2))]; + let AltOrderSelect = [{ + return 1 + MF.getSubtarget().useStride4VFPs(MF); + }]; +} // Subset of SPR which can be used as a source of NEON scalars for 16-bit // operations @@ -264,9 +290,13 @@ def SPR_8 : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 15)>; // is double-word alignment though. def DPR : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, (sequence "D%u", 0, 31)> { - // Allocate non-VFP2 registers D16-D31 first. - let AltOrders = [(rotl DPR, 16)]; - let AltOrderSelect = [{ return 1; }]; + // Allocate non-VFP2 registers D16-D31 first, and prefer even registers on + // Darwin platforms. + let AltOrders = [(rotl DPR, 16), + (add (decimate (rotl DPR, 16), 2), (rotl DPR, 16))]; + let AltOrderSelect = [{ + return 1 + MF.getSubtarget().useStride4VFPs(MF); + }]; } // Subset of DPR that are accessible with VFP2 (and so that also have @@ -313,6 +343,17 @@ def DPair : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], let AltOrderSelect = [{ return 1; }]; } +// Pseudo-registers representing even-odd pairs of GPRs from R1 to R13/SP. +// These are needed by instructions (e.g. ldrexd/strexd) requiring even-odd GPRs. +def Tuples2R : RegisterTuples<[gsub_0, gsub_1], + [(add R0, R2, R4, R6, R8, R10, R12), + (add R1, R3, R5, R7, R9, R11, SP)]>; + +// Register class representing a pair of even-odd GPRs. +def GPRPair : RegisterClass<"ARM", [untyped], 64, (add Tuples2R)> { + let Size = 64; // 2 x 32 bits, we have no predefined type of that size. +} + // Pseudo-registers representing 3 consecutive D registers. def Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2], [(shl DPR, 0),