brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.8 KiB · 11b7a0a Raw
886 lines · plain
1//===-- RISCVRegisterInfo.td - RISC-V Register defs --------*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9//===----------------------------------------------------------------------===//10//  Declarations that describe the RISC-V register files11//===----------------------------------------------------------------------===//12 13let Namespace = "RISCV" in {14class RISCVReg<bits<5> Enc, string n, list<string> alt = []> : Register<n> {15  let HWEncoding{4-0} = Enc;16  let AltNames = alt;17}18 19class RISCVRegWithSubRegs<bits<5> Enc, string n, list<Register> subregs,20                          list<string> alt = []>21      : RegisterWithSubRegs<n, subregs> {22  let HWEncoding{4-0} = Enc;23  let AltNames = alt;24}25 26class RISCVReg16<bits<5> Enc, string n, list<string> alt = []> : Register<n> {27  let HWEncoding{4-0} = Enc;28  let AltNames = alt;29}30 31def sub_16 : SubRegIndex<16>;32class RISCVReg32<RISCVReg16 subreg>33  : RISCVRegWithSubRegs<subreg.HWEncoding{4-0}, subreg.AsmName, [subreg],34                        subreg.AltNames> {35  let SubRegIndices = [sub_16];36}37 38// Because RISCVReg64 register have AsmName and AltNames that alias with their39// 16/32-bit sub-register, RISCVAsmParser will need to coerce a register number40// from a RISCVReg16/RISCVReg32 to the equivalent RISCVReg64 when appropriate.41def sub_32 : SubRegIndex<32>;42class RISCVReg64<RISCVReg32 subreg>43  : RISCVRegWithSubRegs<subreg.HWEncoding{4-0}, subreg.AsmName, [subreg],44                        subreg.AltNames> {45  let SubRegIndices = [sub_32];46}47 48def sub_64 : SubRegIndex<64>;49class RISCVReg128<RISCVReg64 subreg>50    : RISCVRegWithSubRegs<subreg.HWEncoding{4-0}, subreg.AsmName, [subreg],51                          subreg.AltNames> {52  let SubRegIndices = [sub_64];53}54 55let FallbackRegAltNameIndex = NoRegAltName in56def ABIRegAltName : RegAltNameIndex;57 58def sub_vrm4_0 : SubRegIndex<256>;59def sub_vrm4_1 : SubRegIndex<256, 256>;60def sub_vrm2_0 : SubRegIndex<128>;61def sub_vrm2_1 : SubRegIndex<128, 128>;62def sub_vrm2_2 : ComposedSubRegIndex<sub_vrm4_1, sub_vrm2_0>;63def sub_vrm2_3 : ComposedSubRegIndex<sub_vrm4_1, sub_vrm2_1>;64def sub_vrm1_0 : SubRegIndex<64>;65def sub_vrm1_1 : SubRegIndex<64, 64>;66def sub_vrm1_2 : ComposedSubRegIndex<sub_vrm2_1, sub_vrm1_0>;67def sub_vrm1_3 : ComposedSubRegIndex<sub_vrm2_1, sub_vrm1_1>;68def sub_vrm1_4 : ComposedSubRegIndex<sub_vrm2_2, sub_vrm1_0>;69def sub_vrm1_5 : ComposedSubRegIndex<sub_vrm2_2, sub_vrm1_1>;70def sub_vrm1_6 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_0>;71def sub_vrm1_7 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_1>;72 73// GPR sizes change with HwMode.74def sub_gpr_even : SubRegIndex<32> {75  let SubRegRanges = SubRegRangeByHwMode<[RV32, RV64],76                                         [SubRegRange<32>, SubRegRange<64>]>;77}78def sub_gpr_odd  : SubRegIndex<32, 32> {79  let SubRegRanges = SubRegRangeByHwMode<[RV32, RV64],80                                         [SubRegRange<32, 32>, SubRegRange<64, 64>]>;81}82} // Namespace = "RISCV"83 84//===----------------------------------------------------------------------===//85// General Purpose Registers (aka Integer Registers)86//===----------------------------------------------------------------------===//87 88// CostPerUse is set higher for registers that may not be compressible as they89// are not part of GPRC, the most restrictive register class used by the90// compressed instruction set. This will influence the greedy register91// allocator to reduce the use of registers that can't be encoded in 16 bit92// instructions.93 94let RegAltNameIndices = [ABIRegAltName] in {95  // 16-bit sub-registers for use by Zhinx. Having a 16-bit sub-register reduces96  // the spill size for these operations.97  let isConstant = true in98  def X0_H  : RISCVReg<0, "x0", ["zero"]>;99  let CostPerUse = [0, 1] in {100  def X1_H  : RISCVReg<1, "x1", ["ra"]>;101  def X2_H  : RISCVReg<2, "x2", ["sp"]>;102  def X3_H  : RISCVReg<3, "x3", ["gp"]>;103  def X4_H  : RISCVReg<4, "x4", ["tp"]>;104  def X5_H  : RISCVReg<5, "x5", ["t0"]>;105  def X6_H  : RISCVReg<6, "x6", ["t1"]>;106  def X7_H  : RISCVReg<7, "x7", ["t2"]>;107  }108  def X8_H  : RISCVReg<8, "x8", ["s0", "fp"]>;109  def X9_H  : RISCVReg<9, "x9", ["s1"]>;110  def X10_H : RISCVReg<10,"x10", ["a0"]>;111  def X11_H : RISCVReg<11,"x11", ["a1"]>;112  def X12_H : RISCVReg<12,"x12", ["a2"]>;113  def X13_H : RISCVReg<13,"x13", ["a3"]>;114  def X14_H : RISCVReg<14,"x14", ["a4"]>;115  def X15_H : RISCVReg<15,"x15", ["a5"]>;116  let CostPerUse = [0, 1] in {117  def X16_H : RISCVReg<16,"x16", ["a6"]>;118  def X17_H : RISCVReg<17,"x17", ["a7"]>;119  def X18_H : RISCVReg<18,"x18", ["s2"]>;120  def X19_H : RISCVReg<19,"x19", ["s3"]>;121  def X20_H : RISCVReg<20,"x20", ["s4"]>;122  def X21_H : RISCVReg<21,"x21", ["s5"]>;123  def X22_H : RISCVReg<22,"x22", ["s6"]>;124  def X23_H : RISCVReg<23,"x23", ["s7"]>;125  def X24_H : RISCVReg<24,"x24", ["s8"]>;126  def X25_H : RISCVReg<25,"x25", ["s9"]>;127  def X26_H : RISCVReg<26,"x26", ["s10"]>;128  def X27_H : RISCVReg<27,"x27", ["s11"]>;129  def X28_H : RISCVReg<28,"x28", ["t3"]>;130  def X29_H : RISCVReg<29,"x29", ["t4"]>;131  def X30_H : RISCVReg<30,"x30", ["t5"]>;132  def X31_H : RISCVReg<31,"x31", ["t6"]>;133  }134 135  let SubRegIndices = [sub_16] in {136  let isConstant = true in137  def X0_W  : RISCVRegWithSubRegs<0, "x0", [X0_H], ["zero"]>;138  let CostPerUse = [0, 1] in {139  def X1_W  : RISCVRegWithSubRegs<1, "x1", [X1_H], ["ra"]>;140  def X2_W  : RISCVRegWithSubRegs<2, "x2", [X2_H], ["sp"]>;141  def X3_W  : RISCVRegWithSubRegs<3, "x3", [X3_H], ["gp"]>;142  def X4_W  : RISCVRegWithSubRegs<4, "x4", [X4_H], ["tp"]>;143  def X5_W  : RISCVRegWithSubRegs<5, "x5", [X5_H], ["t0"]>;144  def X6_W  : RISCVRegWithSubRegs<6, "x6", [X6_H], ["t1"]>;145  def X7_W  : RISCVRegWithSubRegs<7, "x7", [X7_H], ["t2"]>;146  }147  def X8_W  : RISCVRegWithSubRegs<8, "x8", [X8_H], ["s0", "fp"]>;148  def X9_W  : RISCVRegWithSubRegs<9, "x9", [X9_H], ["s1"]>;149  def X10_W : RISCVRegWithSubRegs<10,"x10", [X10_H], ["a0"]>;150  def X11_W : RISCVRegWithSubRegs<11,"x11", [X11_H], ["a1"]>;151  def X12_W : RISCVRegWithSubRegs<12,"x12", [X12_H], ["a2"]>;152  def X13_W : RISCVRegWithSubRegs<13,"x13", [X13_H], ["a3"]>;153  def X14_W : RISCVRegWithSubRegs<14,"x14", [X14_H], ["a4"]>;154  def X15_W : RISCVRegWithSubRegs<15,"x15", [X15_H], ["a5"]>;155  let CostPerUse = [0, 1] in {156  def X16_W : RISCVRegWithSubRegs<16,"x16", [X16_H], ["a6"]>;157  def X17_W : RISCVRegWithSubRegs<17,"x17", [X17_H], ["a7"]>;158  def X18_W : RISCVRegWithSubRegs<18,"x18", [X18_H], ["s2"]>;159  def X19_W : RISCVRegWithSubRegs<19,"x19", [X19_H], ["s3"]>;160  def X20_W : RISCVRegWithSubRegs<20,"x20", [X20_H], ["s4"]>;161  def X21_W : RISCVRegWithSubRegs<21,"x21", [X21_H], ["s5"]>;162  def X22_W : RISCVRegWithSubRegs<22,"x22", [X22_H], ["s6"]>;163  def X23_W : RISCVRegWithSubRegs<23,"x23", [X23_H], ["s7"]>;164  def X24_W : RISCVRegWithSubRegs<24,"x24", [X24_H], ["s8"]>;165  def X25_W : RISCVRegWithSubRegs<25,"x25", [X25_H], ["s9"]>;166  def X26_W : RISCVRegWithSubRegs<26,"x26", [X26_H], ["s10"]>;167  def X27_W : RISCVRegWithSubRegs<27,"x27", [X27_H], ["s11"]>;168  def X28_W : RISCVRegWithSubRegs<28,"x28", [X28_H], ["t3"]>;169  def X29_W : RISCVRegWithSubRegs<29,"x29", [X29_H], ["t4"]>;170  def X30_W : RISCVRegWithSubRegs<30,"x30", [X30_H], ["t5"]>;171  def X31_W : RISCVRegWithSubRegs<31,"x31", [X31_H], ["t6"]>;172  }173  }174 175  let SubRegIndices = [sub_32] in {176  let isConstant = true in177  def X0  : RISCVRegWithSubRegs<0, "x0", [X0_W], ["zero"]>, DwarfRegNum<[0]>;178  let CostPerUse = [0, 1] in {179  def X1  : RISCVRegWithSubRegs<1, "x1", [X1_W], ["ra"]>, DwarfRegNum<[1]>;180  def X2  : RISCVRegWithSubRegs<2, "x2", [X2_W], ["sp"]>, DwarfRegNum<[2]>;181  def X3  : RISCVRegWithSubRegs<3, "x3", [X3_W], ["gp"]>, DwarfRegNum<[3]>;182  def X4  : RISCVRegWithSubRegs<4, "x4", [X4_W], ["tp"]>, DwarfRegNum<[4]>;183  def X5  : RISCVRegWithSubRegs<5, "x5", [X5_W], ["t0"]>, DwarfRegNum<[5]>;184  def X6  : RISCVRegWithSubRegs<6, "x6", [X6_W], ["t1"]>, DwarfRegNum<[6]>;185  def X7  : RISCVRegWithSubRegs<7, "x7", [X7_W], ["t2"]>, DwarfRegNum<[7]>;186  }187  def X8  : RISCVRegWithSubRegs<8, "x8", [X8_W], ["s0", "fp"]>, DwarfRegNum<[8]>;188  def X9  : RISCVRegWithSubRegs<9, "x9", [X9_W], ["s1"]>, DwarfRegNum<[9]>;189  def X10 : RISCVRegWithSubRegs<10,"x10", [X10_W], ["a0"]>, DwarfRegNum<[10]>;190  def X11 : RISCVRegWithSubRegs<11,"x11", [X11_W], ["a1"]>, DwarfRegNum<[11]>;191  def X12 : RISCVRegWithSubRegs<12,"x12", [X12_W], ["a2"]>, DwarfRegNum<[12]>;192  def X13 : RISCVRegWithSubRegs<13,"x13", [X13_W], ["a3"]>, DwarfRegNum<[13]>;193  def X14 : RISCVRegWithSubRegs<14,"x14", [X14_W], ["a4"]>, DwarfRegNum<[14]>;194  def X15 : RISCVRegWithSubRegs<15,"x15", [X15_W], ["a5"]>, DwarfRegNum<[15]>;195  let CostPerUse = [0, 1] in {196  def X16 : RISCVRegWithSubRegs<16,"x16", [X16_W], ["a6"]>, DwarfRegNum<[16]>;197  def X17 : RISCVRegWithSubRegs<17,"x17", [X17_W], ["a7"]>, DwarfRegNum<[17]>;198  def X18 : RISCVRegWithSubRegs<18,"x18", [X18_W], ["s2"]>, DwarfRegNum<[18]>;199  def X19 : RISCVRegWithSubRegs<19,"x19", [X19_W], ["s3"]>, DwarfRegNum<[19]>;200  def X20 : RISCVRegWithSubRegs<20,"x20", [X20_W], ["s4"]>, DwarfRegNum<[20]>;201  def X21 : RISCVRegWithSubRegs<21,"x21", [X21_W], ["s5"]>, DwarfRegNum<[21]>;202  def X22 : RISCVRegWithSubRegs<22,"x22", [X22_W], ["s6"]>, DwarfRegNum<[22]>;203  def X23 : RISCVRegWithSubRegs<23,"x23", [X23_W], ["s7"]>, DwarfRegNum<[23]>;204  def X24 : RISCVRegWithSubRegs<24,"x24", [X24_W], ["s8"]>, DwarfRegNum<[24]>;205  def X25 : RISCVRegWithSubRegs<25,"x25", [X25_W], ["s9"]>, DwarfRegNum<[25]>;206  def X26 : RISCVRegWithSubRegs<26,"x26", [X26_W], ["s10"]>, DwarfRegNum<[26]>;207  def X27 : RISCVRegWithSubRegs<27,"x27", [X27_W], ["s11"]>, DwarfRegNum<[27]>;208  def X28 : RISCVRegWithSubRegs<28,"x28", [X28_W], ["t3"]>, DwarfRegNum<[28]>;209  def X29 : RISCVRegWithSubRegs<29,"x29", [X29_W], ["t4"]>, DwarfRegNum<[29]>;210  def X30 : RISCVRegWithSubRegs<30,"x30", [X30_W], ["t5"]>, DwarfRegNum<[30]>;211  def X31 : RISCVRegWithSubRegs<31,"x31", [X31_W], ["t6"]>, DwarfRegNum<[31]>;212  }213  }214}215 216def XLenVT : ValueTypeByHwMode<[RV32, RV64],217                               [i32,  i64]>;218defvar XLenPairVT = untyped;219 220// Allow f64 in GPR for ZDINX on RV64.221def XLenFVT : ValueTypeByHwMode<[RV64],222                                [f64]>;223def XLenPairFVT : ValueTypeByHwMode<[RV32],224                                    [f64]>;225 226// P extension227def XLenVecI8VT : ValueTypeByHwMode<[RV32, RV64],228                                    [v4i8, v8i8]>;229def XLenVecI16VT : ValueTypeByHwMode<[RV32,  RV64],230                                     [v2i16, v4i16]>;231def XLenVecI32VT : ValueTypeByHwMode<[RV64],232                                     [v2i32]>;233def XLenRI : RegInfoByHwMode<234      [RV32,              RV64],235      [RegInfo<32,32,32>, RegInfo<64,64,64>]>;236 237class RISCVRegisterClass<list<ValueType> regTypes, int align, dag regList>238    : RegisterClass<"RISCV", regTypes, align, regList> {239  bit IsVRegClass = 0;240  int VLMul = 1;241  int NF = 1;242 243  let TSFlags{0} = IsVRegClass;244  let TSFlags{2-1} = !logtwo(VLMul);245  let TSFlags{5-3} = !sub(NF, 1);246}247 248class GPRRegisterClass<dag regList>249    : RISCVRegisterClass<[XLenVT, XLenFVT,250                          // P extension packed vector types:251                          XLenVecI8VT, XLenVecI16VT, XLenVecI32VT], 32, regList> {252  let RegInfos = XLenRI;253}254 255// The order of registers represents the preferred allocation sequence.256// Registers are listed in the order caller-save, callee-save, specials.257def GPR : GPRRegisterClass<(add (sequence "X%u", 10, 17),258                                (sequence "X%u", 5, 7),259                                (sequence "X%u", 28, 31),260                                (sequence "X%u", 8, 9),261                                (sequence "X%u", 18, 27),262                                (sequence "X%u", 0, 4))>;263 264def GPRX0 : GPRRegisterClass<(add X0)>;265 266def GPRX1 : GPRRegisterClass<(add X1)> {267  let DiagnosticType = "InvalidRegClassGPRX1";268  let DiagnosticString = "register must be ra (x1)";269}270 271def GPRX5 : GPRRegisterClass<(add X5)> {272  let DiagnosticType = "InvalidRegClassGPRX5";273  let DiagnosticString = "register must be t0 (x5)";274}275 276def GPRNoX0 : GPRRegisterClass<(sub GPR, X0)> {277  let DiagnosticType = "InvalidRegClassGPRNoX0";278  let DiagnosticString = "register must be a GPR excluding zero (x0)";279}280 281def GPRNoX2 : GPRRegisterClass<(sub GPR, X2)> {282  let DiagnosticType = "InvalidRegClassGPRNoX2";283  let DiagnosticString = "register must be a GPR excluding sp (x2)";284}285 286def GPRNoX0X2 : GPRRegisterClass<(sub GPR, X0, X2)> {287  let DiagnosticType = "InvalidRegClassGPRNoX0X2";288  let DiagnosticString = "register must be a GPR excluding zero (x0) and sp (x2)";289}290 291def GPRX7 : GPRRegisterClass<(add X7)>;292 293// Don't use X1 or X5 for JALR since that is a hint to pop the return address294// stack on some microarchitectures. Also remove the reserved registers X0, X2,295// X3, and X4 as it reduces the number of register classes that get synthesized296// by tablegen.297def GPRJALR : GPRRegisterClass<(sub GPR, (sequence "X%u", 0, 5))>;298 299def GPRJALRNonX7 : GPRRegisterClass<(sub GPRJALR, X7)>;300 301def GPRC : GPRRegisterClass<(add (sequence "X%u", 10, 15),302                                 (sequence "X%u", 8, 9))>;303 304// For indirect tail calls, we can't use callee-saved registers, as they are305// restored to the saved value before the tail call, which would clobber a call306// address. We shouldn't use x5 since that is a hint for to pop the return307// address stack on some microarchitectures.308def GPRTC : GPRRegisterClass<(add (sequence "X%u", 6, 7),309                                  (sequence "X%u", 10, 17),310                                  (sequence "X%u", 28, 31))>;311def GPRTCNonX7 : GPRRegisterClass<(sub GPRTC, X7)>;312 313def SP : GPRRegisterClass<(add X2)> {314  let DiagnosticType = "InvalidRegClassSP";315  let DiagnosticString = "register must be sp (x2)";316}317 318// Saved Registers from s0 to s7, for C.MVA01S07 instruction in Zcmp extension319def SR07 : GPRRegisterClass<(add (sequence "X%u", 8, 9),320                                 (sequence "X%u", 18, 23))>;321 322def GPRX1X5 :  GPRRegisterClass<(add X1, X5)> {323  let DiagnosticType = "InvalidRegClassGPRX1X5";324  let DiagnosticString = "register must be ra or t0 (x1 or x5)";325}326 327def GPRNoX31 : GPRRegisterClass<(sub GPR, X31)> {328  let DiagnosticType = "InvalidRegClassGPRX31";329  let DiagnosticString = "register must be a GPR excluding t6 (x31)";330}331 332//===----------------------------------------------------------------------===//333// Even-Odd GPR Pairs334//===----------------------------------------------------------------------===//335 336def XLenPairRI : RegInfoByHwMode<337      [RV32,                RV64],338      [RegInfo<64, 64, 32>, RegInfo<128, 128, 64>]>;339 340// Dummy zero register for use in the register pair containing X0 (as X1 is341// not read to or written when the X0 register pair is used).342def DUMMY_REG_PAIR_WITH_X0 : RISCVReg<0, "0">;343 344// Must add DUMMY_REG_PAIR_WITH_X0 to a separate register class to prevent the345// register's existence from changing codegen (due to the regPressureSetLimit346// for the GPR register class being altered).347def GPRAll : GPRRegisterClass<(add GPR, DUMMY_REG_PAIR_WITH_X0)>;348 349let RegAltNameIndices = [ABIRegAltName] in {350  def X0_Pair : RISCVRegWithSubRegs<0, X0.AsmName,351                                    [X0, DUMMY_REG_PAIR_WITH_X0],352                                    X0.AltNames> {353    let SubRegIndices = [sub_gpr_even, sub_gpr_odd];354    let CoveredBySubRegs = 1;355  }356  foreach I = 1-15 in {357    defvar Index = !shl(I, 1);358    defvar IndexP1 = !add(Index, 1);359    defvar Reg = !cast<Register>("X"#Index);360    defvar RegP1 = !cast<Register>("X"#IndexP1);361    def "X" # Index #"_X" # IndexP1 : RISCVRegWithSubRegs<Index,362                                                          Reg.AsmName,363                                                          [Reg, RegP1],364                                                          Reg.AltNames> {365      let SubRegIndices = [sub_gpr_even, sub_gpr_odd];366      let CoveredBySubRegs = 1;367    }368  }369}370 371let RegInfos = XLenPairRI, CopyCost = 2 in {372def GPRPair : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (add373    X10_X11, X12_X13, X14_X15, X16_X17,374    X6_X7,375    X28_X29, X30_X31,376    X8_X9,377    X18_X19, X20_X21, X22_X23, X24_X25, X26_X27,378    X0_Pair, X2_X3, X4_X5379)>;380 381def GPRPairNoX0 : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (sub GPRPair, X0_Pair)>;382 383def GPRPairC : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (add384  X10_X11, X12_X13, X14_X15, X8_X9385)>;386} // let RegInfos = XLenPairRI, CopyCost = 2387 388//===----------------------------------------------------------------------===//389// Floating Point registers390//===----------------------------------------------------------------------===//391 392let RegAltNameIndices = [ABIRegAltName] in {393  def F0_H  : RISCVReg16<0, "f0", ["ft0"]>, DwarfRegNum<[32]>;394  def F1_H  : RISCVReg16<1, "f1", ["ft1"]>, DwarfRegNum<[33]>;395  def F2_H  : RISCVReg16<2, "f2", ["ft2"]>, DwarfRegNum<[34]>;396  def F3_H  : RISCVReg16<3, "f3", ["ft3"]>, DwarfRegNum<[35]>;397  def F4_H  : RISCVReg16<4, "f4", ["ft4"]>, DwarfRegNum<[36]>;398  def F5_H  : RISCVReg16<5, "f5", ["ft5"]>, DwarfRegNum<[37]>;399  def F6_H  : RISCVReg16<6, "f6", ["ft6"]>, DwarfRegNum<[38]>;400  def F7_H  : RISCVReg16<7, "f7", ["ft7"]>, DwarfRegNum<[39]>;401  def F8_H  : RISCVReg16<8, "f8", ["fs0"]>, DwarfRegNum<[40]>;402  def F9_H  : RISCVReg16<9, "f9", ["fs1"]>, DwarfRegNum<[41]>;403  def F10_H : RISCVReg16<10,"f10", ["fa0"]>, DwarfRegNum<[42]>;404  def F11_H : RISCVReg16<11,"f11", ["fa1"]>, DwarfRegNum<[43]>;405  def F12_H : RISCVReg16<12,"f12", ["fa2"]>, DwarfRegNum<[44]>;406  def F13_H : RISCVReg16<13,"f13", ["fa3"]>, DwarfRegNum<[45]>;407  def F14_H : RISCVReg16<14,"f14", ["fa4"]>, DwarfRegNum<[46]>;408  def F15_H : RISCVReg16<15,"f15", ["fa5"]>, DwarfRegNum<[47]>;409  def F16_H : RISCVReg16<16,"f16", ["fa6"]>, DwarfRegNum<[48]>;410  def F17_H : RISCVReg16<17,"f17", ["fa7"]>, DwarfRegNum<[49]>;411  def F18_H : RISCVReg16<18,"f18", ["fs2"]>, DwarfRegNum<[50]>;412  def F19_H : RISCVReg16<19,"f19", ["fs3"]>, DwarfRegNum<[51]>;413  def F20_H : RISCVReg16<20,"f20", ["fs4"]>, DwarfRegNum<[52]>;414  def F21_H : RISCVReg16<21,"f21", ["fs5"]>, DwarfRegNum<[53]>;415  def F22_H : RISCVReg16<22,"f22", ["fs6"]>, DwarfRegNum<[54]>;416  def F23_H : RISCVReg16<23,"f23", ["fs7"]>, DwarfRegNum<[55]>;417  def F24_H : RISCVReg16<24,"f24", ["fs8"]>, DwarfRegNum<[56]>;418  def F25_H : RISCVReg16<25,"f25", ["fs9"]>, DwarfRegNum<[57]>;419  def F26_H : RISCVReg16<26,"f26", ["fs10"]>, DwarfRegNum<[58]>;420  def F27_H : RISCVReg16<27,"f27", ["fs11"]>, DwarfRegNum<[59]>;421  def F28_H : RISCVReg16<28,"f28", ["ft8"]>, DwarfRegNum<[60]>;422  def F29_H : RISCVReg16<29,"f29", ["ft9"]>, DwarfRegNum<[61]>;423  def F30_H : RISCVReg16<30,"f30", ["ft10"]>, DwarfRegNum<[62]>;424  def F31_H : RISCVReg16<31,"f31", ["ft11"]>, DwarfRegNum<[63]>;425 426  foreach Index = 0-31 in {427    def F#Index#_F : RISCVReg32<!cast<RISCVReg16>("F"#Index#"_H")>,428      DwarfRegAlias<!cast<Register>("F"#Index#"_H")>;429  }430 431  foreach Index = 0-31 in {432    def F#Index#_D : RISCVReg64<!cast<RISCVReg32>("F"#Index#"_F")>,433      DwarfRegAlias<!cast<Register>("F"#Index#"_H")>;434  }435 436  foreach Index = 0-31 in {437    def F#Index#_Q : RISCVReg128<!cast<RISCVReg64>("F"#Index#"_D")>,438      DwarfRegAlias<!cast<Register>("F"#Index#"_H")>;439  }440}441 442// The order of registers represents the preferred allocation sequence,443// meaning caller-save regs are listed before callee-save.444// We start by allocating argument registers in reverse order since they are445// compressible.446def FPR16 : RISCVRegisterClass<[f16, bf16], 16, (add447    (sequence "F%u_H", 15, 10), // fa5-fa0448    (sequence "F%u_H", 0, 7),   // ft0-f7449    (sequence "F%u_H", 16, 17), // fa6-fa7450    (sequence "F%u_H", 28, 31), // ft8-ft11451    (sequence "F%u_H", 8, 9),   // fs0-fs1452    (sequence "F%u_H", 18, 27)  // fs2-fs11453)>;454 455def FPR16C : RISCVRegisterClass<[f16, bf16], 16, (add456    (sequence "F%u_H", 15, 10),457    (sequence "F%u_H", 8, 9)458)>;459 460def FPR32 : RISCVRegisterClass<[f32], 32, (add461    (sequence "F%u_F", 15, 10),462    (sequence "F%u_F", 0, 7),463    (sequence "F%u_F", 16, 17),464    (sequence "F%u_F", 28, 31),465    (sequence "F%u_F", 8, 9),466    (sequence "F%u_F", 18, 27)467)>;468 469def FPR32C : RISCVRegisterClass<[f32], 32, (add470  (sequence "F%u_F", 15, 10),471  (sequence "F%u_F", 8, 9)472)>;473 474// The order of registers represents the preferred allocation sequence,475// meaning caller-save regs are listed before callee-save.476def FPR64 : RISCVRegisterClass<[f64], 64, (add477    (sequence "F%u_D", 15, 10),478    (sequence "F%u_D", 0, 7),479    (sequence "F%u_D", 16, 17),480    (sequence "F%u_D", 28, 31),481    (sequence "F%u_D", 8, 9),482    (sequence "F%u_D", 18, 27)483)>;484 485def FPR64C : RISCVRegisterClass<[f64], 64, (add486  (sequence "F%u_D", 15, 10),487  (sequence "F%u_D", 8, 9)488)>;489 490def FPR128 : RISCVRegisterClass<[f128], 128, (add491    (sequence "F%u_Q", 15, 10),492    (sequence "F%u_Q", 0, 7),493    (sequence "F%u_Q", 16, 17),494    (sequence "F%u_Q", 28, 31),495    (sequence "F%u_Q", 8, 9),496    (sequence "F%u_Q", 18, 27)497)>;498 499//===----------------------------------------------------------------------===//500// GPR Classes for "H/F/D in X"501//===----------------------------------------------------------------------===//502 503// 16-bit GPR sub-register class used by Zhinx instructions.504def GPRF16 : RISCVRegisterClass<[f16], 16, (add (sequence "X%u_H", 10, 17),505                                                (sequence "X%u_H", 5, 7),506                                                (sequence "X%u_H", 28, 31),507                                                (sequence "X%u_H", 8, 9),508                                                (sequence "X%u_H", 18, 27),509                                                (sequence "X%u_H", 0, 4))>;510def GPRF16C : RISCVRegisterClass<[f16], 16, (add (sequence "X%u_H", 10, 15),511                                                 (sequence "X%u_H", 8, 9))>;512def GPRF16NoX0 : RISCVRegisterClass<[f16], 16, (sub GPRF16, X0_H)>;513 514def GPRF32 : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 17),515                                                (sequence "X%u_W", 5, 7),516                                                (sequence "X%u_W", 28, 31),517                                                (sequence "X%u_W", 8, 9),518                                                (sequence "X%u_W", 18, 27),519                                                (sequence "X%u_W", 0, 4))>;520def GPRF32C : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 15),521                                                 (sequence "X%u_W", 8, 9))>;522def GPRF32NoX0 : RISCVRegisterClass<[f32], 32, (sub GPRF32, X0_W)>;523 524//===----------------------------------------------------------------------===//525// Vector type mapping to LLVM types.526//===----------------------------------------------------------------------===//527 528// The V vector extension requires that VLEN >= 128 and <= 65536.529// Additionally, the only supported ELEN values are 32 and 64,530// thus `vscale` can be defined as VLEN/64,531// allowing the same types with either ELEN value.532//533//         MF8    MF4     MF2     M1      M2      M4       M8534// i64*    N/A    N/A     N/A     nxv1i64 nxv2i64 nxv4i64  nxv8i64535// i32     N/A    N/A     nxv1i32 nxv2i32 nxv4i32 nxv8i32  nxv16i32536// i16     N/A    nxv1i16 nxv2i16 nxv4i16 nxv8i16 nxv16i16 nxv32i16537// i8      nxv1i8 nxv2i8  nxv4i8  nxv8i8  nxv16i8 nxv32i8  nxv64i8538// double* N/A    N/A     N/A     nxv1f64 nxv2f64 nxv4f64  nxv8f64539// float   N/A    N/A     nxv1f32 nxv2f32 nxv4f32 nxv8f32  nxv16f32540// half    N/A    nxv1f16 nxv2f16 nxv4f16 nxv8f16 nxv16f16 nxv32f16541// * ELEN=64542 543defvar vint8mf8_t = nxv1i8;544defvar vint8mf4_t = nxv2i8;545defvar vint8mf2_t = nxv4i8;546defvar vint8m1_t = nxv8i8;547defvar vint8m2_t = nxv16i8;548defvar vint8m4_t = nxv32i8;549defvar vint8m8_t = nxv64i8;550 551defvar vint16mf4_t = nxv1i16;552defvar vint16mf2_t = nxv2i16;553defvar vint16m1_t  = nxv4i16;554defvar vint16m2_t  = nxv8i16;555defvar vint16m4_t  = nxv16i16;556defvar vint16m8_t  = nxv32i16;557 558defvar vint32mf2_t = nxv1i32;559defvar vint32m1_t  = nxv2i32;560defvar vint32m2_t  = nxv4i32;561defvar vint32m4_t  = nxv8i32;562defvar vint32m8_t  = nxv16i32;563 564defvar vint64m1_t = nxv1i64;565defvar vint64m2_t = nxv2i64;566defvar vint64m4_t = nxv4i64;567defvar vint64m8_t = nxv8i64;568 569defvar vfloat16mf4_t = nxv1f16;570defvar vfloat16mf2_t = nxv2f16;571defvar vfloat16m1_t  = nxv4f16;572defvar vfloat16m2_t  = nxv8f16;573defvar vfloat16m4_t  = nxv16f16;574defvar vfloat16m8_t  = nxv32f16;575 576defvar vbfloat16mf4_t = nxv1bf16;577defvar vbfloat16mf2_t = nxv2bf16;578defvar vbfloat16m1_t  = nxv4bf16;579defvar vbfloat16m2_t  = nxv8bf16;580defvar vbfloat16m4_t  = nxv16bf16;581defvar vbfloat16m8_t  = nxv32bf16;582 583defvar vfloat32mf2_t = nxv1f32;584defvar vfloat32m1_t  = nxv2f32;585defvar vfloat32m2_t  = nxv4f32;586defvar vfloat32m4_t  = nxv8f32;587defvar vfloat32m8_t  = nxv16f32;588 589defvar vfloat64m1_t = nxv1f64;590defvar vfloat64m2_t = nxv2f64;591defvar vfloat64m4_t = nxv4f64;592defvar vfloat64m8_t = nxv8f64;593 594defvar vbool1_t  = nxv64i1;595defvar vbool2_t  = nxv32i1;596defvar vbool4_t  = nxv16i1;597defvar vbool8_t  = nxv8i1;598defvar vbool16_t = nxv4i1;599defvar vbool32_t = nxv2i1;600defvar vbool64_t = nxv1i1;601 602// There is no need to define register classes for fractional LMUL.603defvar LMULList = [1, 2, 4, 8];604 605//===----------------------------------------------------------------------===//606// Utility classes for segment load/store.607//===----------------------------------------------------------------------===//608// The set of legal NF for LMUL = lmul.609// LMUL <= 1, NF = 2, 3, 4, 5, 6, 7, 8610// LMUL == 2, NF = 2, 3, 4611// LMUL == 4, NF = 2612// LMUL == 8, no legal NF613class NFList<int lmul> {614  list<int> L = !cond(!eq(lmul, 8): [],615                      !eq(lmul, 4): [2],616                      !eq(lmul, 2): [2, 3, 4],617                      true: [2, 3, 4, 5, 6, 7, 8]);618}619 620// Generate [start, end) SubRegIndex list.621class SubRegSet<int nf, int lmul> {622  list<SubRegIndex> L = !foldl([]<SubRegIndex>,623                               !range(0, 8),624                               AccList, i,625                               !listconcat(AccList,626                                 !if(!lt(i, nf),627                                   [!cast<SubRegIndex>("sub_vrm" # lmul # "_" # i)],628                                   [])));629}630 631// Collect the valid indexes into 'R' under NF and LMUL values from TUPLE_INDEX.632// When NF = 2, the valid TUPLE_INDEX is 0 and 1.633// For example, when LMUL = 4, the potential valid indexes is634// [8, 12, 16, 20, 24, 28, 4]. However, not all these indexes are valid under635// NF = 2. For example, 28 is not valid under LMUL = 4, NF = 2 and TUPLE_INDEX = 0.636// The filter is637//   (tuple_index + i) x lmul <= (tuple_index x lmul) + 32 - (nf x lmul)638//639// Use START = 0, LMUL = 4 and NF = 2 as the example,640//   i x 4 <= 24641// The class will return [8, 12, 16, 20, 24, 4].642// Use START = 1, LMUL = 4 and NF = 2 as the example,643//   (1 + i) x 4 <= 28644// The class will return [12, 16, 20, 24, 28, 8].645//646class IndexSet<int tuple_index, int nf, int lmul, bit isV0 = false> {647  list<int> R =648    !foldl([]<int>,649              !if(isV0, [0],650                !cond(651                  !eq(lmul, 1): !listconcat(!range(8, 32), !range(1, 8)),652                  !eq(lmul, 2): !listconcat(!range(4, 16), !range(1, 4)),653                  !eq(lmul, 4): !listconcat(!range(2, 8), !range(1, 2)))),654              L, i,655              !listconcat(L,656                          !if(!le(!mul(!add(i, tuple_index), lmul),657                                  !sub(!add(32, !mul(tuple_index, lmul)), !mul(nf, lmul))),658                              [!mul(!add(i, tuple_index), lmul)], [])));659}660 661// This class returns a list of vector register collections.662// For example, for NF = 2 and LMUL = 4,663// L would be:664//   ([ V8M4, V12M4, V16M4, V20M4, V24M4, V4M4],665//    [V12M4, V16M4, V20M4, V24M4, V28M4, V8M4])666// Names are the starting register of each register list,667// in this example:668//   ["v8", "v12", "v16", "v20", "v24", "v4"]669class VRegList<list<dag> LIn, int start, int nf, int lmul, bit isV0> {670  list<dag> L =671    !if(!ge(start, nf),672        LIn,673        !listconcat(674          [!dag(add,675                !foreach(i, IndexSet<start, nf, lmul, isV0>.R,676                  !cast<Register>("V" # i # !cond(!eq(lmul, 2): "M2",677                                                  !eq(lmul, 4): "M4",678                                                  true: ""))),679                !listsplat("",680                  !size(IndexSet<start, nf, lmul, isV0>.R)))],681          VRegList<LIn, !add(start, 1), nf, lmul, isV0>.L));682  list<string> Names =683    !if(!ge(start, nf), [],684        !foreach(i, IndexSet<start, nf, lmul, isV0>.R, "v" # i));685}686 687//===----------------------------------------------------------------------===//688// Vector registers689//===----------------------------------------------------------------------===//690 691foreach Index = !range(0, 32, 1) in {692  def V#Index : RISCVReg<Index, "v"#Index>, DwarfRegNum<[!add(Index, 96)]>;693}694 695foreach Index = !range(0, 32, 2) in {696  def V#Index#M2 : RISCVRegWithSubRegs<Index, "v"#Index,697                     [!cast<Register>("V"#Index),698                      !cast<Register>("V"#!add(Index, 1))]>,699                   DwarfRegAlias<!cast<Register>("V"#Index)> {700    let SubRegIndices = [sub_vrm1_0, sub_vrm1_1];701  }702}703 704foreach Index = !range(0, 32, 4) in {705  def V#Index#M4 : RISCVRegWithSubRegs<Index, "v"#Index,706                     [!cast<Register>("V"#Index#"M2"),707                      !cast<Register>("V"#!add(Index, 2)#"M2")]>,708                   DwarfRegAlias<!cast<Register>("V"#Index)> {709    let SubRegIndices = [sub_vrm2_0, sub_vrm2_1];710  }711}712 713foreach Index = !range(0, 32, 8) in {714  def V#Index#M8 : RISCVRegWithSubRegs<Index, "v"#Index,715                     [!cast<Register>("V"#Index#"M4"),716                      !cast<Register>("V"#!add(Index, 4)#"M4")]>,717                   DwarfRegAlias<!cast<Register>("V"#Index)> {718    let SubRegIndices = [sub_vrm4_0, sub_vrm4_1];719  }720}721 722def VTYPE  : RISCVReg<0, "vtype">;723def VL     : RISCVReg<0, "vl">;724def VXSAT  : RISCVReg<0, "vxsat">;725def VXRM   : RISCVReg<0, "vxrm">;726let isConstant = true in727def VLENB  : RISCVReg<0, "vlenb">,728             DwarfRegNum<[!add(4096, SysRegVLENB.Encoding)]>;729 730def VCSR : RISCVRegisterClass<[XLenVT], 32,731                              (add VTYPE, VL, VLENB)> {732  let RegInfos = XLenRI;733  let isAllocatable = 0;734}735 736 737foreach m = [1, 2, 4] in {738  foreach n = NFList<m>.L in {739    defvar RegListWOV0 = VRegList<[], 0, n, m, false>;740    defvar RegListWV0 = VRegList<[], 0, n, m, true>;741    def "VN" # n # "M" # m # "NoV0": RegisterTuples<742                                       SubRegSet<n, m>.L,743                                       RegListWOV0.L,744                                       RegListWOV0.Names>;745    def "VN" # n # "M" # m # "V0" : RegisterTuples<746                                       SubRegSet<n, m>.L,747                                       RegListWV0.L,748                                       RegListWV0.Names>;749  }750}751 752class VReg<list<ValueType> regTypes, dag regList, int Vlmul, int nf = 1>753    : RISCVRegisterClass<regTypes,754                         64, // The maximum supported ELEN is 64.755                         regList> {756  let IsVRegClass = 1;757  let VLMul = Vlmul;758  let NF = nf;759 760  let Size = !mul(VLMul, NF, 64);761  let CopyCost = !mul(VLMul, NF);762  // Prefer to allocate high LMUL registers first.763  let AllocationPriority = !if(!gt(Vlmul, 1), Vlmul, 0);764}765 766defvar VMaskVTs = [vbool1_t, vbool2_t, vbool4_t, vbool8_t, vbool16_t,767                   vbool32_t, vbool64_t];768 769defvar VM1VTs = [vint8m1_t, vint16m1_t, vint32m1_t, vint64m1_t,770                 vbfloat16m1_t, vfloat16m1_t, vfloat32m1_t,771                 vfloat64m1_t, vint8mf2_t, vint8mf4_t, vint8mf8_t,772                 vint16mf2_t, vint16mf4_t, vint32mf2_t,773                 vfloat16mf4_t, vfloat16mf2_t, vbfloat16mf4_t,774                 vbfloat16mf2_t, vfloat32mf2_t];775 776defvar VM2VTs = [vint8m2_t, vint16m2_t, vint32m2_t, vint64m2_t,777                 vfloat16m2_t, vbfloat16m2_t,778                 vfloat32m2_t, vfloat64m2_t];779 780defvar VM4VTs = [vint8m4_t, vint16m4_t, vint32m4_t, vint64m4_t,781                 vfloat16m4_t, vbfloat16m4_t,782                 vfloat32m4_t, vfloat64m4_t];783 784defvar VM8VTs = [vint8m8_t, vint16m8_t, vint32m8_t, vint64m8_t,785                 vfloat16m8_t, vbfloat16m8_t,786                 vfloat32m8_t, vfloat64m8_t];787 788// We reverse the order of last 8 registers so that we don't needlessly prevent789// allocation of higher lmul register groups while still putting v0 last in the790// allocation order.791 792def VR : VReg<!listconcat(VM1VTs, VMaskVTs),793              (add (sequence "V%u", 8, 31),794                   (sequence "V%u", 7, 0)), 1>;795 796def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;797 798def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),799                             (sequence "V%uM2", 6, 0, 2)), 2>;800 801def VRM2NoV0 : VReg<VM2VTs, (sub VRM2, V0M2), 2>;802 803def VRM4 : VReg<VM4VTs, (add V8M4, V12M4, V16M4, V20M4,804                             V24M4, V28M4, V4M4, V0M4), 4>;805 806def VRM4NoV0 : VReg<VM4VTs, (sub VRM4, V0M4), 4>;807 808def VRM8 : VReg<VM8VTs, (add V8M8, V16M8, V24M8, V0M8), 8>;809 810def VRM8NoV0 : VReg<VM8VTs, (sub VRM8, V0M8), 8>;811 812def VMV0 : VReg<VMaskVTs, (add V0), 1>;813 814// The register class is added for inline assembly for vector mask types.815def VM : VReg<VMaskVTs, (add VR), 1>;816 817defvar VTupM1N2VTs = [riscv_nxv8i8x2, riscv_nxv4i8x2, riscv_nxv2i8x2, riscv_nxv1i8x2];818defvar VTupM1N3VTs = [riscv_nxv8i8x3, riscv_nxv4i8x3, riscv_nxv2i8x3, riscv_nxv1i8x3];819defvar VTupM1N4VTs = [riscv_nxv8i8x4, riscv_nxv4i8x4, riscv_nxv2i8x4, riscv_nxv1i8x4];820defvar VTupM1N5VTs = [riscv_nxv8i8x5, riscv_nxv4i8x5, riscv_nxv2i8x5, riscv_nxv1i8x5];821defvar VTupM1N6VTs = [riscv_nxv8i8x6, riscv_nxv4i8x6, riscv_nxv2i8x6, riscv_nxv1i8x6];822defvar VTupM1N7VTs = [riscv_nxv8i8x7, riscv_nxv4i8x7, riscv_nxv2i8x7, riscv_nxv1i8x7];823defvar VTupM1N8VTs = [riscv_nxv8i8x8, riscv_nxv4i8x8, riscv_nxv2i8x8, riscv_nxv1i8x8];824defvar VTupM2N2VTs = [riscv_nxv16i8x2];825defvar VTupM2N3VTs = [riscv_nxv16i8x3];826defvar VTupM2N4VTs = [riscv_nxv16i8x4];827defvar VTupM4N2VTs = [riscv_nxv32i8x2];828class VTupRegList<int LMUL, int NF> {829  list<ValueType> L = !cond(!and(!eq(LMUL, 1), !eq(NF, 2)): VTupM1N2VTs,830                            !and(!eq(LMUL, 1), !eq(NF, 3)): VTupM1N3VTs,831                            !and(!eq(LMUL, 1), !eq(NF, 4)): VTupM1N4VTs,832                            !and(!eq(LMUL, 1), !eq(NF, 5)): VTupM1N5VTs,833                            !and(!eq(LMUL, 1), !eq(NF, 6)): VTupM1N6VTs,834                            !and(!eq(LMUL, 1), !eq(NF, 7)): VTupM1N7VTs,835                            !and(!eq(LMUL, 1), !eq(NF, 8)): VTupM1N8VTs,836                            !and(!eq(LMUL, 2), !eq(NF, 2)): VTupM2N2VTs,837                            !and(!eq(LMUL, 2), !eq(NF, 3)): VTupM2N3VTs,838                            !and(!eq(LMUL, 2), !eq(NF, 4)): VTupM2N4VTs,839                            !and(!eq(LMUL, 4), !eq(NF, 2)): VTupM4N2VTs);840}841 842foreach m = LMULList in {843  foreach nf = NFList<m>.L in {844    def "VRN" # nf # "M" # m # "NoV0"845      : VReg<VTupRegList<m, nf>.L,846             (add !cast<RegisterTuples>("VN" # nf # "M" # m # "NoV0")),847             m, nf>;848    def "VRN" # nf # "M" # m849      : VReg<VTupRegList<m, nf>.L,850             (add !cast<RegisterTuples>("VN" # nf # "M" # m # "NoV0"),851                  !cast<RegisterTuples>("VN" # nf # "M" # m # "V0")),852             m, nf>;853  }854}855 856//===----------------------------------------------------------------------===//857// Special registers858//===----------------------------------------------------------------------===//859 860def FFLAGS : RISCVReg<0, "fflags">;861def FRM    : RISCVReg<0, "frm">;862def FCSR   : RISCVReg<0, "fcsr">;863 864// Shadow Stack register865def SSP    : RISCVReg<0, "ssp">;866 867// Dummy SiFive VCIX state register868def SF_VCIX_STATE : RISCVReg<0, "sf.vcix_state">;869def : RISCVRegisterClass<[XLenVT], 32, (add SF_VCIX_STATE)> {870  let RegInfos = XLenRI;871  let isAllocatable = 0;872}873 874//===----------------------------------------------------------------------===//875// XSfmmbase tiles876//===----------------------------------------------------------------------===//877foreach Index = 0-15 in878  def T#Index : RISCVReg<Index, "mt"#Index, []>,879                DwarfRegNum<[!add(Index, 3072)]>;880 881let RegInfos = XLenRI in {882  def TR   : RISCVRegisterClass<[untyped], 32, (add (sequence "T%u", 0, 15))>;883  def TRM2 : RISCVRegisterClass<[untyped], 32, (add (decimate TR, 2))>;884  def TRM4 : RISCVRegisterClass<[untyped], 32, (add (decimate TR, 4))>;885}886