181ad6265SDimitry Andric//===-- LoongArchRegisterInfo.td - LoongArch Register defs -*- tablegen -*-===// 281ad6265SDimitry Andric// 381ad6265SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric// 781ad6265SDimitry Andric//===----------------------------------------------------------------------===// 881ad6265SDimitry Andric 981ad6265SDimitry Andric//===----------------------------------------------------------------------===// 1081ad6265SDimitry Andric// Declarations that describe the LoongArch register files 1181ad6265SDimitry Andric//===----------------------------------------------------------------------===// 1281ad6265SDimitry Andric 1381ad6265SDimitry Andriclet Namespace = "LoongArch" in { 1481ad6265SDimitry Andricclass LoongArchReg<bits<16> Enc, string n, list<string> alt = []> 1581ad6265SDimitry Andric : Register<n> { 1681ad6265SDimitry Andric let HWEncoding = Enc; 1781ad6265SDimitry Andric let AltNames = alt; 1881ad6265SDimitry Andric} 1981ad6265SDimitry Andric 20*06c3fb27SDimitry Andricclass LoongArchRegWithSubRegs<bits<16> Enc, string n, list<Register> subregs, 21*06c3fb27SDimitry Andric list<string> alt = []> 22*06c3fb27SDimitry Andric : RegisterWithSubRegs<n, subregs> { 23*06c3fb27SDimitry Andric let HWEncoding = Enc; 24*06c3fb27SDimitry Andric let AltNames = alt; 25*06c3fb27SDimitry Andric} 26*06c3fb27SDimitry Andric 2781ad6265SDimitry Andricclass LoongArchReg32<bits<16> Enc, string n, list<string> alt = []> 2881ad6265SDimitry Andric : Register<n> { 2981ad6265SDimitry Andric let HWEncoding = Enc; 3081ad6265SDimitry Andric let AltNames = alt; 3181ad6265SDimitry Andric} 3281ad6265SDimitry Andric 3381ad6265SDimitry Andricdef sub_32 : SubRegIndex<32>; 3481ad6265SDimitry Andricclass LoongArchReg64<LoongArchReg32 subreg> 35*06c3fb27SDimitry Andric : LoongArchRegWithSubRegs<subreg.HWEncoding, subreg.AsmName, [subreg], 36*06c3fb27SDimitry Andric subreg.AltNames> { 3781ad6265SDimitry Andric let SubRegIndices = [sub_32]; 38*06c3fb27SDimitry Andric} 39*06c3fb27SDimitry Andric 40*06c3fb27SDimitry Andricdef sub_64 : SubRegIndex<64>; 41*06c3fb27SDimitry Andricclass LoongArchReg128<LoongArchReg64 subreg, string n> 42*06c3fb27SDimitry Andric : LoongArchRegWithSubRegs<subreg.HWEncoding, n, [subreg]> { 43*06c3fb27SDimitry Andric let SubRegIndices = [sub_64]; 44*06c3fb27SDimitry Andric} 45*06c3fb27SDimitry Andric 46*06c3fb27SDimitry Andricdef sub_128 : SubRegIndex<128>; 47*06c3fb27SDimitry Andricclass LoongArchReg256<LoongArchReg128 subreg, string n> 48*06c3fb27SDimitry Andric : LoongArchRegWithSubRegs<subreg.HWEncoding, n, [subreg]> { 49*06c3fb27SDimitry Andric let SubRegIndices = [sub_128]; 5081ad6265SDimitry Andric} 5181ad6265SDimitry Andric 5281ad6265SDimitry Andriclet FallbackRegAltNameIndex = NoRegAltName in 5381ad6265SDimitry Andricdef RegAliasName : RegAltNameIndex; 5481ad6265SDimitry Andric} // Namespace = "LoongArch" 5581ad6265SDimitry Andric 5681ad6265SDimitry Andric// Integer registers 5781ad6265SDimitry Andric 5881ad6265SDimitry Andriclet RegAltNameIndices = [RegAliasName] in { 59bdd1243dSDimitry Andric let isConstant = true in 6081ad6265SDimitry Andric def R0 : LoongArchReg<0, "r0", ["zero"]>, DwarfRegNum<[0]>; 6181ad6265SDimitry Andric def R1 : LoongArchReg<1, "r1", ["ra"]>, DwarfRegNum<[1]>; 6281ad6265SDimitry Andric def R2 : LoongArchReg<2, "r2", ["tp"]>, DwarfRegNum<[2]>; 6381ad6265SDimitry Andric def R3 : LoongArchReg<3, "r3", ["sp"]>, DwarfRegNum<[3]>; 6481ad6265SDimitry Andric def R4 : LoongArchReg<4, "r4", ["a0"]>, DwarfRegNum<[4]>; 6581ad6265SDimitry Andric def R5 : LoongArchReg<5, "r5", ["a1"]>, DwarfRegNum<[5]>; 6681ad6265SDimitry Andric def R6 : LoongArchReg<6, "r6", ["a2"]>, DwarfRegNum<[6]>; 6781ad6265SDimitry Andric def R7 : LoongArchReg<7, "r7", ["a3"]>, DwarfRegNum<[7]>; 6881ad6265SDimitry Andric def R8 : LoongArchReg<8, "r8", ["a4"]>, DwarfRegNum<[8]>; 6981ad6265SDimitry Andric def R9 : LoongArchReg<9, "r9", ["a5"]>, DwarfRegNum<[9]>; 7081ad6265SDimitry Andric def R10 : LoongArchReg<10, "r10", ["a6"]>, DwarfRegNum<[10]>; 7181ad6265SDimitry Andric def R11 : LoongArchReg<11, "r11", ["a7"]>, DwarfRegNum<[11]>; 7281ad6265SDimitry Andric def R12 : LoongArchReg<12, "r12", ["t0"]>, DwarfRegNum<[12]>; 7381ad6265SDimitry Andric def R13 : LoongArchReg<13, "r13", ["t1"]>, DwarfRegNum<[13]>; 7481ad6265SDimitry Andric def R14 : LoongArchReg<14, "r14", ["t2"]>, DwarfRegNum<[14]>; 7581ad6265SDimitry Andric def R15 : LoongArchReg<15, "r15", ["t3"]>, DwarfRegNum<[15]>; 7681ad6265SDimitry Andric def R16 : LoongArchReg<16, "r16", ["t4"]>, DwarfRegNum<[16]>; 7781ad6265SDimitry Andric def R17 : LoongArchReg<17, "r17", ["t5"]>, DwarfRegNum<[17]>; 7881ad6265SDimitry Andric def R18 : LoongArchReg<18, "r18", ["t6"]>, DwarfRegNum<[18]>; 7981ad6265SDimitry Andric def R19 : LoongArchReg<19, "r19", ["t7"]>, DwarfRegNum<[19]>; 8081ad6265SDimitry Andric def R20 : LoongArchReg<20, "r20", ["t8"]>, DwarfRegNum<[20]>; 8181ad6265SDimitry Andric def R21 : LoongArchReg<21, "r21", [""]>, DwarfRegNum<[21]>; 8281ad6265SDimitry Andric def R22 : LoongArchReg<22, "r22", ["fp", "s9"]>, DwarfRegNum<[22]>; 8381ad6265SDimitry Andric def R23 : LoongArchReg<23, "r23", ["s0"]>, DwarfRegNum<[23]>; 8481ad6265SDimitry Andric def R24 : LoongArchReg<24, "r24", ["s1"]>, DwarfRegNum<[24]>; 8581ad6265SDimitry Andric def R25 : LoongArchReg<25, "r25", ["s2"]>, DwarfRegNum<[25]>; 8681ad6265SDimitry Andric def R26 : LoongArchReg<26, "r26", ["s3"]>, DwarfRegNum<[26]>; 8781ad6265SDimitry Andric def R27 : LoongArchReg<27, "r27", ["s4"]>, DwarfRegNum<[27]>; 8881ad6265SDimitry Andric def R28 : LoongArchReg<28, "r28", ["s5"]>, DwarfRegNum<[28]>; 8981ad6265SDimitry Andric def R29 : LoongArchReg<29, "r29", ["s6"]>, DwarfRegNum<[29]>; 9081ad6265SDimitry Andric def R30 : LoongArchReg<30, "r30", ["s7"]>, DwarfRegNum<[30]>; 9181ad6265SDimitry Andric def R31 : LoongArchReg<31, "r31", ["s8"]>, DwarfRegNum<[31]>; 9281ad6265SDimitry Andric} // RegAltNameIndices = [RegAliasName] 9381ad6265SDimitry Andric 9481ad6265SDimitry Andricdef GRLenVT : ValueTypeByHwMode<[LA32, LA64], 9581ad6265SDimitry Andric [i32, i64]>; 9681ad6265SDimitry Andricdef GRLenRI : RegInfoByHwMode< 9781ad6265SDimitry Andric [LA32, LA64], 9881ad6265SDimitry Andric [RegInfo<32,32,32>, RegInfo<64,64,64>]>; 9981ad6265SDimitry Andric 10081ad6265SDimitry Andric// The order of registers represents the preferred allocation sequence. 10181ad6265SDimitry Andric// Registers are listed in the order caller-save, callee-save, specials. 10281ad6265SDimitry Andricdef GPR : RegisterClass<"LoongArch", [GRLenVT], 32, (add 10381ad6265SDimitry Andric // Argument registers (a0...a7) 10481ad6265SDimitry Andric (sequence "R%u", 4, 11), 10581ad6265SDimitry Andric // Temporary registers (t0...t8) 10681ad6265SDimitry Andric (sequence "R%u", 12, 20), 10781ad6265SDimitry Andric // Static register (s9/fp, s0...s8) 10881ad6265SDimitry Andric (sequence "R%u", 22, 31), 10981ad6265SDimitry Andric // Specials (r0, ra, tp, sp) 11081ad6265SDimitry Andric (sequence "R%u", 0, 3), 11181ad6265SDimitry Andric // Reserved (Non-allocatable) 11281ad6265SDimitry Andric R21 11381ad6265SDimitry Andric )> { 11481ad6265SDimitry Andric let RegInfos = GRLenRI; 11581ad6265SDimitry Andric} 11681ad6265SDimitry Andric 117bdd1243dSDimitry Andric// GPR for indirect tail calls. We can't use callee-saved registers, as they are 118bdd1243dSDimitry Andric// restored to the saved value before the tail call, which would clobber a call 119bdd1243dSDimitry Andric// address. 120bdd1243dSDimitry Andricdef GPRT : RegisterClass<"LoongArch", [GRLenVT], 32, (add 121bdd1243dSDimitry Andric // a0...a7, t0...t8 122bdd1243dSDimitry Andric (sequence "R%u", 4, 20) 123bdd1243dSDimitry Andric )> { 124bdd1243dSDimitry Andric let RegInfos = GRLenRI; 125bdd1243dSDimitry Andric} 126bdd1243dSDimitry Andric 12781ad6265SDimitry Andric// Floating point registers 12881ad6265SDimitry Andric 12981ad6265SDimitry Andriclet RegAltNameIndices = [RegAliasName] in { 13081ad6265SDimitry Andric def F0 : LoongArchReg32<0, "f0", ["fa0"]>, DwarfRegNum<[32]>; 13181ad6265SDimitry Andric def F1 : LoongArchReg32<1, "f1", ["fa1"]>, DwarfRegNum<[33]>; 13281ad6265SDimitry Andric def F2 : LoongArchReg32<2, "f2", ["fa2"]>, DwarfRegNum<[34]>; 13381ad6265SDimitry Andric def F3 : LoongArchReg32<3, "f3", ["fa3"]>, DwarfRegNum<[35]>; 13481ad6265SDimitry Andric def F4 : LoongArchReg32<4, "f4", ["fa4"]>, DwarfRegNum<[36]>; 13581ad6265SDimitry Andric def F5 : LoongArchReg32<5, "f5", ["fa5"]>, DwarfRegNum<[37]>; 13681ad6265SDimitry Andric def F6 : LoongArchReg32<6, "f6", ["fa6"]>, DwarfRegNum<[38]>; 13781ad6265SDimitry Andric def F7 : LoongArchReg32<7, "f7", ["fa7"]>, DwarfRegNum<[39]>; 13881ad6265SDimitry Andric def F8 : LoongArchReg32<8, "f8", ["ft0"]>, DwarfRegNum<[40]>; 13981ad6265SDimitry Andric def F9 : LoongArchReg32<9, "f9", ["ft1"]>, DwarfRegNum<[41]>; 14081ad6265SDimitry Andric def F10 : LoongArchReg32<10,"f10", ["ft2"]>, DwarfRegNum<[42]>; 14181ad6265SDimitry Andric def F11 : LoongArchReg32<11,"f11", ["ft3"]>, DwarfRegNum<[43]>; 14281ad6265SDimitry Andric def F12 : LoongArchReg32<12,"f12", ["ft4"]>, DwarfRegNum<[44]>; 14381ad6265SDimitry Andric def F13 : LoongArchReg32<13,"f13", ["ft5"]>, DwarfRegNum<[45]>; 14481ad6265SDimitry Andric def F14 : LoongArchReg32<14,"f14", ["ft6"]>, DwarfRegNum<[46]>; 14581ad6265SDimitry Andric def F15 : LoongArchReg32<15,"f15", ["ft7"]>, DwarfRegNum<[47]>; 14681ad6265SDimitry Andric def F16 : LoongArchReg32<16,"f16", ["ft8"]>, DwarfRegNum<[48]>; 14781ad6265SDimitry Andric def F17 : LoongArchReg32<17,"f17", ["ft9"]>, DwarfRegNum<[49]>; 14881ad6265SDimitry Andric def F18 : LoongArchReg32<18,"f18", ["ft10"]>, DwarfRegNum<[50]>; 14981ad6265SDimitry Andric def F19 : LoongArchReg32<19,"f19", ["ft11"]>, DwarfRegNum<[51]>; 15081ad6265SDimitry Andric def F20 : LoongArchReg32<20,"f20", ["ft12"]>, DwarfRegNum<[52]>; 15181ad6265SDimitry Andric def F21 : LoongArchReg32<21,"f21", ["ft13"]>, DwarfRegNum<[53]>; 15281ad6265SDimitry Andric def F22 : LoongArchReg32<22,"f22", ["ft14"]>, DwarfRegNum<[54]>; 15381ad6265SDimitry Andric def F23 : LoongArchReg32<23,"f23", ["ft15"]>, DwarfRegNum<[55]>; 15481ad6265SDimitry Andric def F24 : LoongArchReg32<24,"f24", ["fs0"]>, DwarfRegNum<[56]>; 15581ad6265SDimitry Andric def F25 : LoongArchReg32<25,"f25", ["fs1"]>, DwarfRegNum<[57]>; 15681ad6265SDimitry Andric def F26 : LoongArchReg32<26,"f26", ["fs2"]>, DwarfRegNum<[58]>; 15781ad6265SDimitry Andric def F27 : LoongArchReg32<27,"f27", ["fs3"]>, DwarfRegNum<[59]>; 15881ad6265SDimitry Andric def F28 : LoongArchReg32<28,"f28", ["fs4"]>, DwarfRegNum<[60]>; 15981ad6265SDimitry Andric def F29 : LoongArchReg32<29,"f29", ["fs5"]>, DwarfRegNum<[61]>; 16081ad6265SDimitry Andric def F30 : LoongArchReg32<30,"f30", ["fs6"]>, DwarfRegNum<[62]>; 16181ad6265SDimitry Andric def F31 : LoongArchReg32<31,"f31", ["fs7"]>, DwarfRegNum<[63]>; 16281ad6265SDimitry Andric 16381ad6265SDimitry Andric foreach I = 0-31 in { 16481ad6265SDimitry Andric def F#I#_64 : LoongArchReg64<!cast<LoongArchReg32>("F"#I)>, 16581ad6265SDimitry Andric DwarfRegNum<[!add(I, 32)]>; 16681ad6265SDimitry Andric } 16781ad6265SDimitry Andric} 16881ad6265SDimitry Andric 16981ad6265SDimitry Andric// The order of registers represents the preferred allocation sequence. 17081ad6265SDimitry Andricdef FPR32 : RegisterClass<"LoongArch", [f32], 32, (sequence "F%u", 0, 31)>; 17181ad6265SDimitry Andricdef FPR64 : RegisterClass<"LoongArch", [f64], 64, (sequence "F%u_64", 0, 31)>; 17281ad6265SDimitry Andric 17381ad6265SDimitry Andric// Condition flag registers 17481ad6265SDimitry Andric 17581ad6265SDimitry Andricforeach I = 0-7 in 17681ad6265SDimitry Andricdef FCC#I : LoongArchReg<I, "fcc"#I>; 17781ad6265SDimitry Andric 17881ad6265SDimitry Andricdef CFR : RegisterClass<"LoongArch", [GRLenVT], 32, (sequence "FCC%u", 0, 7)> { 17981ad6265SDimitry Andric let RegInfos = GRLenRI; 18081ad6265SDimitry Andric} 18181ad6265SDimitry Andric 18281ad6265SDimitry Andric// Control and status registers 18381ad6265SDimitry Andric 18481ad6265SDimitry Andricforeach I = 0-3 in 18581ad6265SDimitry Andricdef FCSR#I : LoongArchReg<I, "fcsr"#I>; 18681ad6265SDimitry Andric 18781ad6265SDimitry Andriclet isAllocatable = false in 18881ad6265SDimitry Andricdef FCSR : RegisterClass<"LoongArch", [i32], 32, (sequence "FCSR%u", 0, 3)>; 189*06c3fb27SDimitry Andric 190*06c3fb27SDimitry Andric// LSX registers 191*06c3fb27SDimitry Andric 192*06c3fb27SDimitry Andricforeach I = 0-31 in 193*06c3fb27SDimitry Andricdef VR#I : LoongArchReg128<!cast<LoongArchReg64>("F"#I#"_64"), "vr"#I>, 194*06c3fb27SDimitry Andric DwarfRegAlias<!cast<LoongArchReg64>("F"#I#"_64")>; 195*06c3fb27SDimitry Andric 196*06c3fb27SDimitry Andricdef LSX128 : RegisterClass<"LoongArch", 197*06c3fb27SDimitry Andric [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], 198*06c3fb27SDimitry Andric 128, (sequence "VR%u", 0, 31)>; 199*06c3fb27SDimitry Andric 200*06c3fb27SDimitry Andric// LASX registers 201*06c3fb27SDimitry Andric 202*06c3fb27SDimitry Andricforeach I = 0-31 in 203*06c3fb27SDimitry Andricdef XR#I : LoongArchReg256<!cast<LoongArchReg128>("VR"#I), "xr"#I>, 204*06c3fb27SDimitry Andric DwarfRegAlias<!cast<LoongArchReg128>("VR"#I)>; 205*06c3fb27SDimitry Andric 206*06c3fb27SDimitry Andricdef LASX256 : RegisterClass<"LoongArch", 207*06c3fb27SDimitry Andric [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], 208*06c3fb27SDimitry Andric 256, (sequence "XR%u", 0, 31)>; 209*06c3fb27SDimitry Andric 210*06c3fb27SDimitry Andric// Scratchpad registers 211*06c3fb27SDimitry Andric 212*06c3fb27SDimitry Andricforeach I = 0-3 in 213*06c3fb27SDimitry Andricdef SCR#I : LoongArchReg<I, "scr"#I>; 214*06c3fb27SDimitry Andric 215*06c3fb27SDimitry Andriclet isAllocatable = false, RegInfos = GRLenRI in 216*06c3fb27SDimitry Andricdef SCR : RegisterClass<"LoongArch", [GRLenVT], 32, (sequence "SCR%u", 0, 3)>; 217