diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVRegisterInfo.td')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 148 |
1 files changed, 88 insertions, 60 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index e1a11fd9389f..fde75206889c 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -51,20 +51,20 @@ class RISCVRegWithSubRegs<bits<5> Enc, string n, list<Register> subregs, def ABIRegAltName : RegAltNameIndex; -def sub_vrm1_0 : SubRegIndex<64, -1>; -def sub_vrm1_1 : SubRegIndex<64, -1>; -def sub_vrm1_2 : SubRegIndex<64, -1>; -def sub_vrm1_3 : SubRegIndex<64, -1>; -def sub_vrm1_4 : SubRegIndex<64, -1>; -def sub_vrm1_5 : SubRegIndex<64, -1>; -def sub_vrm1_6 : SubRegIndex<64, -1>; -def sub_vrm1_7 : SubRegIndex<64, -1>; -def sub_vrm2_0 : SubRegIndex<128, -1>; -def sub_vrm2_1 : SubRegIndex<128, -1>; -def sub_vrm2_2 : SubRegIndex<128, -1>; -def sub_vrm2_3 : SubRegIndex<128, -1>; -def sub_vrm4_0 : SubRegIndex<256, -1>; -def sub_vrm4_1 : SubRegIndex<256, -1>; +def sub_vrm4_0 : SubRegIndex<256>; +def sub_vrm4_1 : SubRegIndex<256, 256>; +def sub_vrm2_0 : SubRegIndex<128>; +def sub_vrm2_1 : SubRegIndex<128, 128>; +def sub_vrm2_2 : ComposedSubRegIndex<sub_vrm4_1, sub_vrm2_0>; +def sub_vrm2_3 : ComposedSubRegIndex<sub_vrm4_1, sub_vrm2_1>; +def sub_vrm1_0 : SubRegIndex<64>; +def sub_vrm1_1 : SubRegIndex<64, 64>; +def sub_vrm1_2 : ComposedSubRegIndex<sub_vrm2_1, sub_vrm1_0>; +def sub_vrm1_3 : ComposedSubRegIndex<sub_vrm2_1, sub_vrm1_1>; +def sub_vrm1_4 : ComposedSubRegIndex<sub_vrm2_2, sub_vrm1_0>; +def sub_vrm1_5 : ComposedSubRegIndex<sub_vrm2_2, sub_vrm1_1>; +def sub_vrm1_6 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_0>; +def sub_vrm1_7 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_1>; } // Namespace = "RISCV" @@ -78,7 +78,7 @@ def sub_vrm4_1 : SubRegIndex<256, -1>; let RegAltNameIndices = [ABIRegAltName] in { def X0 : RISCVReg<0, "x0", ["zero"]>, DwarfRegNum<[0]>; - let CostPerUse = 1 in { + let CostPerUse = [1] in { def X1 : RISCVReg<1, "x1", ["ra"]>, DwarfRegNum<[1]>; def X2 : RISCVReg<2, "x2", ["sp"]>, DwarfRegNum<[2]>; def X3 : RISCVReg<3, "x3", ["gp"]>, DwarfRegNum<[3]>; @@ -95,7 +95,7 @@ let RegAltNameIndices = [ABIRegAltName] in { def X13 : RISCVReg<13,"x13", ["a3"]>, DwarfRegNum<[13]>; def X14 : RISCVReg<14,"x14", ["a4"]>, DwarfRegNum<[14]>; def X15 : RISCVReg<15,"x15", ["a5"]>, DwarfRegNum<[15]>; - let CostPerUse = 1 in { + let CostPerUse = [1] in { def X16 : RISCVReg<16,"x16", ["a6"]>, DwarfRegNum<[16]>; def X17 : RISCVReg<17,"x17", ["a7"]>, DwarfRegNum<[17]>; def X18 : RISCVReg<18,"x18", ["s2"]>, DwarfRegNum<[18]>; @@ -117,6 +117,9 @@ let RegAltNameIndices = [ABIRegAltName] in { def XLenVT : ValueTypeByHwMode<[RV32, RV64], [i32, i64]>; +def XLenRI : RegInfoByHwMode< + [RV32, RV64], + [RegInfo<32,32,32>, RegInfo<64,64,64>]>; // The order of registers represents the preferred allocation sequence. // Registers are listed in the order caller-save, callee-save, specials. @@ -128,15 +131,11 @@ def GPR : RegisterClass<"RISCV", [XLenVT], 32, (add (sequence "X%u", 18, 27), (sequence "X%u", 0, 4) )> { - let RegInfos = RegInfoByHwMode< - [RV32, RV64], - [RegInfo<32,32,32>, RegInfo<64,64,64>]>; + let RegInfos = XLenRI; } def GPRX0 : RegisterClass<"RISCV", [XLenVT], 32, (add X0)> { - let RegInfos = RegInfoByHwMode< - [RV32, RV64], - [RegInfo<32,32,32>, RegInfo<64,64,64>]>; + let RegInfos = XLenRI; } // The order of registers represents the preferred allocation sequence. @@ -149,9 +148,7 @@ def GPRNoX0 : RegisterClass<"RISCV", [XLenVT], 32, (add (sequence "X%u", 18, 27), (sequence "X%u", 1, 4) )> { - let RegInfos = RegInfoByHwMode< - [RV32, RV64], - [RegInfo<32,32,32>, RegInfo<64,64,64>]>; + let RegInfos = XLenRI; } def GPRNoX0X2 : RegisterClass<"RISCV", [XLenVT], 32, (add @@ -162,37 +159,44 @@ def GPRNoX0X2 : RegisterClass<"RISCV", [XLenVT], 32, (add (sequence "X%u", 18, 27), X1, X3, X4 )> { - let RegInfos = RegInfoByHwMode< - [RV32, RV64], - [RegInfo<32,32,32>, RegInfo<64,64,64>]>; + let RegInfos = XLenRI; +} + +// Don't use X1 or X5 for JALR since that is a hint to pop the return address +// stack on some microarchitectures. Also remove the reserved registers X0, X2, +// X3, and X4 as it reduces the number of register classes that get synthesized +// by tablegen. +def GPRJALR : RegisterClass<"RISCV", [XLenVT], 32, (add + (sequence "X%u", 10, 17), + (sequence "X%u", 6, 7), + (sequence "X%u", 28, 31), + (sequence "X%u", 8, 9), + (sequence "X%u", 18, 27) + )> { + let RegInfos = XLenRI; } def GPRC : RegisterClass<"RISCV", [XLenVT], 32, (add (sequence "X%u", 10, 15), (sequence "X%u", 8, 9) )> { - let RegInfos = RegInfoByHwMode< - [RV32, RV64], - [RegInfo<32,32,32>, RegInfo<64,64,64>]>; + let RegInfos = XLenRI; } // For indirect tail calls, we can't use callee-saved registers, as they are // restored to the saved value before the tail call, which would clobber a call -// address. +// address. We shouldn't use x5 since that is a hint for to pop the return +// address stack on some microarchitectures. def GPRTC : RegisterClass<"RISCV", [XLenVT], 32, (add - (sequence "X%u", 5, 7), + (sequence "X%u", 6, 7), (sequence "X%u", 10, 17), (sequence "X%u", 28, 31) )> { - let RegInfos = RegInfoByHwMode< - [RV32, RV64], - [RegInfo<32,32,32>, RegInfo<64,64,64>]>; + let RegInfos = XLenRI; } def SP : RegisterClass<"RISCV", [XLenVT], 32, (add X2)> { - let RegInfos = RegInfoByHwMode< - [RV32, RV64], - [RegInfo<32,32,32>, RegInfo<64,64,64>]>; + let RegInfos = XLenRI; } // Floating point registers @@ -281,8 +285,7 @@ def FPR64C : RegisterClass<"RISCV", [f64], 64, (add // Vector type mapping to LLVM types. // -// Though the V extension allows that VLEN be as small as 8, -// this approach assumes that VLEN>=64. +// The V vector extension requires that VLEN >= 128 and <= 65536. // Additionally, the only supported ELEN values are 32 and 64, // thus `vscale` can be defined as VLEN/64, // allowing the same types with either ELEN value. @@ -394,18 +397,24 @@ class IndexSet<int index, int nf, int lmul> { ), [!mul(i, lmul)], []))); } -class VRegList<list<dag> LIn, int start, int nf, int lmul> { +class VRegList<list<dag> LIn, int start, int nf, int lmul, bit NoV0> { list<dag> L = !if(!ge(start, nf), LIn, !listconcat( [!dag(add, - !foreach(i, IndexSet<start, nf, lmul>.R, - !cast<Register>("V" # i # !cond(!eq(lmul, 2): "M2", - !eq(lmul, 4): "M4", - true: ""))), - !listsplat("", !size(IndexSet<start, nf, lmul>.R)))], - VRegList<LIn, !add(start, 1), nf, lmul>.L)); + !foreach(i, + !if(NoV0, + !tail(IndexSet<start, nf, lmul>.R), + [!head(IndexSet<start, nf, lmul>.R)]), + !cast<Register>("V" # i # !cond(!eq(lmul, 2): "M2", + !eq(lmul, 4): "M4", + true: ""))), + !listsplat("", + !if(NoV0, + !size(!tail(IndexSet<start, nf, lmul>.R)), + !size([!head(IndexSet<start, nf, lmul>.R)]))))], + VRegList<LIn, !add(start, 1), nf, lmul, NoV0>.L)); } // Vector registers @@ -453,8 +462,12 @@ let RegAltNameIndices = [ABIRegAltName] in { foreach m = [1, 2, 4] in { foreach n = NFList<m>.L in { - def "VN" # n # "M" # m: RegisterTuples<SubRegSet<[], 0, n, m>.L, - VRegList<[], 0, n, m>.L>; + def "VN" # n # "M" # m # "NoV0": RegisterTuples< + SubRegSet<[], 0, n, m>.L, + VRegList<[], 0, n, m, 1>.L>; + def "VN" # n # "M" # m # "V0" : RegisterTuples< + SubRegSet<[], 0, n, m>.L, + VRegList<[], 0, n, m, 0>.L>; } } @@ -467,22 +480,22 @@ class VReg<list<ValueType> regTypes, dag regList, int Vlmul> int Size = !mul(Vlmul, 64); } -def VR : VReg<[vint8mf2_t, vint8mf4_t, vint8mf8_t, +def VR : VReg<[vint8m1_t, vint16m1_t, vint32m1_t, vint64m1_t, + vfloat16m1_t, vfloat32m1_t, vfloat64m1_t, + vint8mf2_t, vint8mf4_t, vint8mf8_t, vint16mf2_t, vint16mf4_t, vint32mf2_t, - vint8m1_t, vint16m1_t, vint32m1_t, vint64m1_t, - vfloat16mf4_t, vfloat16mf2_t, vfloat16m1_t, - vfloat32mf2_t, vfloat32m1_t, vfloat64m1_t, + vfloat16mf4_t, vfloat16mf2_t, vfloat32mf2_t, vbool64_t, vbool32_t, vbool16_t, vbool8_t, vbool4_t, vbool2_t, vbool1_t], (add (sequence "V%u", 25, 31), (sequence "V%u", 8, 24), (sequence "V%u", 0, 7)), 1>; -def VRNoV0 : VReg<[vint8mf2_t, vint8mf4_t, vint8mf8_t, +def VRNoV0 : VReg<[vint8m1_t, vint16m1_t, vint32m1_t, vint64m1_t, + vfloat16m1_t, vfloat32m1_t, vfloat64m1_t, + vint8mf2_t, vint8mf4_t, vint8mf8_t, vint16mf2_t, vint16mf4_t, vint32mf2_t, - vint8m1_t, vint16m1_t, vint32m1_t, vint64m1_t, - vfloat16mf4_t, vfloat16mf2_t, vfloat16m1_t, - vfloat32mf2_t, vfloat32m1_t, vfloat64m1_t, + vfloat16mf4_t, vfloat16mf2_t, vfloat32mf2_t, vbool64_t, vbool32_t, vbool16_t, vbool8_t, vbool4_t, vbool2_t, vbool1_t], (add (sequence "V%u", 25, 31), @@ -522,10 +535,25 @@ def VMV0 : RegisterClass<"RISCV", VMaskVTs, 64, (add V0)> { let Size = 64; } +// The register class is added for inline assembly for vector mask types. +def VM : VReg<[vbool1_t, vbool2_t, vbool4_t, vbool8_t, vbool16_t, + vbool32_t, vbool64_t], + (add (sequence "V%u", 25, 31), + (sequence "V%u", 8, 24), + (sequence "V%u", 0, 7)), 1>; + foreach m = LMULList.m in { foreach nf = NFList<m>.L in { - def "VRN" # nf # "M" # m : VReg<[untyped], - (add !cast<RegisterTuples>("VN" # nf # "M" # m)), + def "VRN" # nf # "M" # m: VReg<[untyped], + (add !cast<RegisterTuples>("VN" # nf # "M" # m # "V0"), !cast<RegisterTuples>("VN" # nf # "M" # m # "NoV0")), + !mul(nf, m)>; + def "VRN" # nf # "M" # m # "NoV0": VReg<[untyped], + (add !cast<RegisterTuples>("VN" # nf # "M" # m # "NoV0")), !mul(nf, m)>; } } + +// Special registers +def FFLAGS : RISCVReg<0, "fflags">; +def FRM : RISCVReg<0, "frm">; +def FCSR : RISCVReg<0, "fcsr">; |