225 lines · plain
1//===-- LoongArchRegisterInfo.td - LoongArch 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 LoongArch register files11//===----------------------------------------------------------------------===//12 13let Namespace = "LoongArch" in {14class LoongArchReg<bits<16> Enc, string n, list<string> alt = []>15 : Register<n> {16 let HWEncoding = Enc;17 let AltNames = alt;18}19 20class LoongArchRegWithSubRegs<bits<16> Enc, string n, list<Register> subregs,21 list<string> alt = []>22 : RegisterWithSubRegs<n, subregs> {23 let HWEncoding = Enc;24 let AltNames = alt;25}26 27class LoongArchReg32<bits<16> Enc, string n, list<string> alt = []>28 : Register<n> {29 let HWEncoding = Enc;30 let AltNames = alt;31}32 33def sub_32 : SubRegIndex<32>;34class LoongArchReg64<LoongArchReg32 subreg>35 : LoongArchRegWithSubRegs<subreg.HWEncoding, subreg.AsmName, [subreg],36 subreg.AltNames> {37 let SubRegIndices = [sub_32];38}39 40def sub_64 : SubRegIndex<64>;41class LoongArchReg128<LoongArchReg64 subreg, string n>42 : LoongArchRegWithSubRegs<subreg.HWEncoding, n, [subreg]> {43 let SubRegIndices = [sub_64];44}45 46def sub_128 : SubRegIndex<128>;47class LoongArchReg256<LoongArchReg128 subreg, string n>48 : LoongArchRegWithSubRegs<subreg.HWEncoding, n, [subreg]> {49 let SubRegIndices = [sub_128];50}51 52let FallbackRegAltNameIndex = NoRegAltName in53def RegAliasName : RegAltNameIndex;54} // Namespace = "LoongArch"55 56// Integer registers57 58let RegAltNameIndices = [RegAliasName] in {59 let isConstant = true in60 def R0 : LoongArchReg<0, "r0", ["zero"]>, DwarfRegNum<[0]>;61 def R1 : LoongArchReg<1, "r1", ["ra"]>, DwarfRegNum<[1]>;62 def R2 : LoongArchReg<2, "r2", ["tp"]>, DwarfRegNum<[2]>;63 def R3 : LoongArchReg<3, "r3", ["sp"]>, DwarfRegNum<[3]>;64 def R4 : LoongArchReg<4, "r4", ["a0"]>, DwarfRegNum<[4]>;65 def R5 : LoongArchReg<5, "r5", ["a1"]>, DwarfRegNum<[5]>;66 def R6 : LoongArchReg<6, "r6", ["a2"]>, DwarfRegNum<[6]>;67 def R7 : LoongArchReg<7, "r7", ["a3"]>, DwarfRegNum<[7]>;68 def R8 : LoongArchReg<8, "r8", ["a4"]>, DwarfRegNum<[8]>;69 def R9 : LoongArchReg<9, "r9", ["a5"]>, DwarfRegNum<[9]>;70 def R10 : LoongArchReg<10, "r10", ["a6"]>, DwarfRegNum<[10]>;71 def R11 : LoongArchReg<11, "r11", ["a7"]>, DwarfRegNum<[11]>;72 def R12 : LoongArchReg<12, "r12", ["t0"]>, DwarfRegNum<[12]>;73 def R13 : LoongArchReg<13, "r13", ["t1"]>, DwarfRegNum<[13]>;74 def R14 : LoongArchReg<14, "r14", ["t2"]>, DwarfRegNum<[14]>;75 def R15 : LoongArchReg<15, "r15", ["t3"]>, DwarfRegNum<[15]>;76 def R16 : LoongArchReg<16, "r16", ["t4"]>, DwarfRegNum<[16]>;77 def R17 : LoongArchReg<17, "r17", ["t5"]>, DwarfRegNum<[17]>;78 def R18 : LoongArchReg<18, "r18", ["t6"]>, DwarfRegNum<[18]>;79 def R19 : LoongArchReg<19, "r19", ["t7"]>, DwarfRegNum<[19]>;80 def R20 : LoongArchReg<20, "r20", ["t8"]>, DwarfRegNum<[20]>;81 def R21 : LoongArchReg<21, "r21", [""]>, DwarfRegNum<[21]>;82 def R22 : LoongArchReg<22, "r22", ["fp", "s9"]>, DwarfRegNum<[22]>;83 def R23 : LoongArchReg<23, "r23", ["s0"]>, DwarfRegNum<[23]>;84 def R24 : LoongArchReg<24, "r24", ["s1"]>, DwarfRegNum<[24]>;85 def R25 : LoongArchReg<25, "r25", ["s2"]>, DwarfRegNum<[25]>;86 def R26 : LoongArchReg<26, "r26", ["s3"]>, DwarfRegNum<[26]>;87 def R27 : LoongArchReg<27, "r27", ["s4"]>, DwarfRegNum<[27]>;88 def R28 : LoongArchReg<28, "r28", ["s5"]>, DwarfRegNum<[28]>;89 def R29 : LoongArchReg<29, "r29", ["s6"]>, DwarfRegNum<[29]>;90 def R30 : LoongArchReg<30, "r30", ["s7"]>, DwarfRegNum<[30]>;91 def R31 : LoongArchReg<31, "r31", ["s8"]>, DwarfRegNum<[31]>;92} // RegAltNameIndices = [RegAliasName]93 94def GRLenVT : ValueTypeByHwMode<[LA32, LA64],95 [i32, i64]>;96def GRLenRI : RegInfoByHwMode<97 [LA32, LA64],98 [RegInfo<32,32,32>, RegInfo<64,64,64>]>;99 100class GPRRegisterClass<dag regList>101 : RegisterClass<"LoongArch", [GRLenVT], 32, regList> {102 let RegInfos = GRLenRI;103}104 105// The order of registers represents the preferred allocation sequence.106// Registers are listed in the order caller-save, callee-save, specials.107def GPR : GPRRegisterClass<(add // Argument registers (a0...a7)108 (sequence "R%u", 4, 11),109 // Temporary registers (t0...t8)110 (sequence "R%u", 12, 20),111 // Static register (s9/fp, s0...s8)112 (sequence "R%u", 22, 31),113 // Specials (r0, ra, tp, sp)114 (sequence "R%u", 0, 3),115 // Reserved (Non-allocatable)116 R21)>;117 118// GPR for indirect tail calls. We can't use callee-saved registers, as they are119// restored to the saved value before the tail call, which would clobber a call120// address.121def GPRT : GPRRegisterClass<(add // a0...a7, t0...t8122 (sequence "R%u", 4, 20))>;123 124// Don't use R1 for JR since that micro-architecture unconditionally treats a125// "jr $ra" as "return from subroutine", hence doing "jr $ra" would interfere126// with both subroutine return prediction and the more general indirect branch127// prediction.128def GPRJR : GPRRegisterClass<(sub GPR, R1)>;129 130// Don't use R0 or R1 for the rj operand of [G]CSRXCHG, because when rj is131// encoded as 0 or 1, the instruction is interpreted as [G]CSRRD or [G]CSRWR,132// respectively, rather than [G]CSRXCHG.133def GPRNoR0R1 : GPRRegisterClass<(sub GPR, R0, R1)>;134 135// Floating point registers136 137let RegAltNameIndices = [RegAliasName] in {138 def F0 : LoongArchReg32<0, "f0", ["fa0"]>, DwarfRegNum<[32]>;139 def F1 : LoongArchReg32<1, "f1", ["fa1"]>, DwarfRegNum<[33]>;140 def F2 : LoongArchReg32<2, "f2", ["fa2"]>, DwarfRegNum<[34]>;141 def F3 : LoongArchReg32<3, "f3", ["fa3"]>, DwarfRegNum<[35]>;142 def F4 : LoongArchReg32<4, "f4", ["fa4"]>, DwarfRegNum<[36]>;143 def F5 : LoongArchReg32<5, "f5", ["fa5"]>, DwarfRegNum<[37]>;144 def F6 : LoongArchReg32<6, "f6", ["fa6"]>, DwarfRegNum<[38]>;145 def F7 : LoongArchReg32<7, "f7", ["fa7"]>, DwarfRegNum<[39]>;146 def F8 : LoongArchReg32<8, "f8", ["ft0"]>, DwarfRegNum<[40]>;147 def F9 : LoongArchReg32<9, "f9", ["ft1"]>, DwarfRegNum<[41]>;148 def F10 : LoongArchReg32<10,"f10", ["ft2"]>, DwarfRegNum<[42]>;149 def F11 : LoongArchReg32<11,"f11", ["ft3"]>, DwarfRegNum<[43]>;150 def F12 : LoongArchReg32<12,"f12", ["ft4"]>, DwarfRegNum<[44]>;151 def F13 : LoongArchReg32<13,"f13", ["ft5"]>, DwarfRegNum<[45]>;152 def F14 : LoongArchReg32<14,"f14", ["ft6"]>, DwarfRegNum<[46]>;153 def F15 : LoongArchReg32<15,"f15", ["ft7"]>, DwarfRegNum<[47]>;154 def F16 : LoongArchReg32<16,"f16", ["ft8"]>, DwarfRegNum<[48]>;155 def F17 : LoongArchReg32<17,"f17", ["ft9"]>, DwarfRegNum<[49]>;156 def F18 : LoongArchReg32<18,"f18", ["ft10"]>, DwarfRegNum<[50]>;157 def F19 : LoongArchReg32<19,"f19", ["ft11"]>, DwarfRegNum<[51]>;158 def F20 : LoongArchReg32<20,"f20", ["ft12"]>, DwarfRegNum<[52]>;159 def F21 : LoongArchReg32<21,"f21", ["ft13"]>, DwarfRegNum<[53]>;160 def F22 : LoongArchReg32<22,"f22", ["ft14"]>, DwarfRegNum<[54]>;161 def F23 : LoongArchReg32<23,"f23", ["ft15"]>, DwarfRegNum<[55]>;162 def F24 : LoongArchReg32<24,"f24", ["fs0"]>, DwarfRegNum<[56]>;163 def F25 : LoongArchReg32<25,"f25", ["fs1"]>, DwarfRegNum<[57]>;164 def F26 : LoongArchReg32<26,"f26", ["fs2"]>, DwarfRegNum<[58]>;165 def F27 : LoongArchReg32<27,"f27", ["fs3"]>, DwarfRegNum<[59]>;166 def F28 : LoongArchReg32<28,"f28", ["fs4"]>, DwarfRegNum<[60]>;167 def F29 : LoongArchReg32<29,"f29", ["fs5"]>, DwarfRegNum<[61]>;168 def F30 : LoongArchReg32<30,"f30", ["fs6"]>, DwarfRegNum<[62]>;169 def F31 : LoongArchReg32<31,"f31", ["fs7"]>, DwarfRegNum<[63]>;170 171 foreach I = 0-31 in {172 def F#I#_64 : LoongArchReg64<!cast<LoongArchReg32>("F"#I)>,173 DwarfRegNum<[!add(I, 32)]>;174 }175}176 177// The order of registers represents the preferred allocation sequence.178def FPR32 : RegisterClass<"LoongArch", [f32], 32, (sequence "F%u", 0, 31)>;179def FPR64 : RegisterClass<"LoongArch", [f64], 64, (sequence "F%u_64", 0, 31)>;180 181// Condition flag registers182 183foreach I = 0-7 in184def FCC#I : LoongArchReg<I, "fcc"#I>;185 186def CFR : RegisterClass<"LoongArch", [GRLenVT], 32, (sequence "FCC%u", 0, 7)> {187 let RegInfos = GRLenRI;188}189 190// Control and status registers191 192foreach I = 0-3 in193def FCSR#I : LoongArchReg<I, "fcsr"#I>;194 195let isAllocatable = false in196def FCSR : RegisterClass<"LoongArch", [i32], 32, (sequence "FCSR%u", 0, 3)>;197 198// LSX registers199 200foreach I = 0-31 in201def VR#I : LoongArchReg128<!cast<LoongArchReg64>("F"#I#"_64"), "vr"#I>,202 DwarfRegAlias<!cast<LoongArchReg64>("F"#I#"_64")>;203 204def LSX128 : RegisterClass<"LoongArch",205 [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64],206 128, (sequence "VR%u", 0, 31)>;207 208// LASX registers209 210foreach I = 0-31 in211def XR#I : LoongArchReg256<!cast<LoongArchReg128>("VR"#I), "xr"#I>,212 DwarfRegAlias<!cast<LoongArchReg128>("VR"#I)>;213 214def LASX256 : RegisterClass<"LoongArch",215 [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64],216 256, (sequence "XR%u", 0, 31)>;217 218// Scratchpad registers219 220foreach I = 0-3 in221def SCR#I : LoongArchReg<I, "scr"#I>;222 223let isAllocatable = false, RegInfos = GRLenRI in224def SCR : RegisterClass<"LoongArch", [GRLenVT], 32, (sequence "SCR%u", 0, 3)>;225