1 //===- AArch64RegisterInfo.td - ARM Register defs ----------*- tablegen -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains declarations that describe the AArch64 register file 11 // 12 //===----------------------------------------------------------------------===// 13 14 let Namespace = "AArch64" in { 15 def sub_128 : SubRegIndex; 16 def sub_64 : SubRegIndex; 17 def sub_32 : SubRegIndex; 18 def sub_16 : SubRegIndex; 19 def sub_8 : SubRegIndex; 20 21 // The VPR registers are handled as sub-registers of FPR equivalents, but 22 // they're really the same thing. We give this concept a special index. 23 def sub_alias : SubRegIndex; 24 } 25 26 // Registers are identified with 5-bit ID numbers. 27 class AArch64Reg<bits<16> enc, string n> : Register<n> { 28 let HWEncoding = enc; 29 let Namespace = "AArch64"; 30 } 31 32 class AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [], 33 list<SubRegIndex> inds = []> 34 : AArch64Reg<enc, n> { 35 let SubRegs = subregs; 36 let SubRegIndices = inds; 37 } 38 39 //===----------------------------------------------------------------------===// 40 // Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp 41 //===----------------------------------------------------------------------===// 42 43 foreach Index = 0-30 in { 44 def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>; 45 } 46 47 def WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>; 48 def WZR : AArch64Reg<31, "wzr">; 49 50 // Could be combined with previous loop, but this way leaves w and x registers 51 // consecutive as LLVM register numbers, which makes for easier debugging. 52 foreach Index = 0-30 in { 53 def X#Index : AArch64RegWithSubs<Index, "x"#Index, 54 [!cast<Register>("W"#Index)], [sub_32]>, 55 DwarfRegNum<[Index]>; 56 } 57 58 def XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>; 59 def XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>; 60 61 // Most instructions treat register 31 as zero for reads and a black-hole for 62 // writes. 63 64 // Note that the order of registers is important for the Disassembler here: 65 // tablegen uses it to form MCRegisterClass::getRegister, which we assume can 66 // take an encoding value. 67 def GPR32 : RegisterClass<"AArch64", [i32], 32, 68 (add (sequence "W%u", 0, 30), WZR)> { 69 } 70 71 def GPR64 : RegisterClass<"AArch64", [i64], 64, 72 (add (sequence "X%u", 0, 30), XZR)> { 73 } 74 75 def GPR32nowzr : RegisterClass<"AArch64", [i32], 32, 76 (sequence "W%u", 0, 30)> { 77 } 78 79 def GPR64noxzr : RegisterClass<"AArch64", [i64], 64, 80 (sequence "X%u", 0, 30)> { 81 } 82 83 // For tail calls, we can't use callee-saved registers or the structure-return 84 // register, as they are supposed to be live across function calls and may be 85 // clobbered by the epilogue. 86 def tcGPR64 : RegisterClass<"AArch64", [i64], 64, 87 (add (sequence "X%u", 0, 7), 88 (sequence "X%u", 9, 18))> { 89 } 90 91 92 // Certain addressing-useful instructions accept sp directly. Again the order of 93 // registers is important to the Disassembler. 94 def GPR32wsp : RegisterClass<"AArch64", [i32], 32, 95 (add (sequence "W%u", 0, 30), WSP)> { 96 } 97 98 def GPR64xsp : RegisterClass<"AArch64", [i64], 64, 99 (add (sequence "X%u", 0, 30), XSP)> { 100 } 101 102 // Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and 103 // non-SP variants). We can't use a bare register in those patterns because 104 // TableGen doesn't like it, so we need a class containing just stack registers 105 def Rxsp : RegisterClass<"AArch64", [i64], 64, 106 (add XSP)> { 107 } 108 109 def Rwsp : RegisterClass<"AArch64", [i32], 32, 110 (add WSP)> { 111 } 112 113 //===----------------------------------------------------------------------===// 114 // Scalar registers in the vector unit: 115 // b0-b31, h0-h31, s0-s31, d0-d31, q0-q31 116 //===----------------------------------------------------------------------===// 117 118 foreach Index = 0-31 in { 119 def B # Index : AArch64Reg< Index, "b" # Index>, 120 DwarfRegNum<[!add(Index, 64)]>; 121 122 def H # Index : AArch64RegWithSubs<Index, "h" # Index, 123 [!cast<Register>("B" # Index)], [sub_8]>, 124 DwarfRegNum<[!add(Index, 64)]>; 125 126 def S # Index : AArch64RegWithSubs<Index, "s" # Index, 127 [!cast<Register>("H" # Index)], [sub_16]>, 128 DwarfRegNum<[!add(Index, 64)]>; 129 130 def D # Index : AArch64RegWithSubs<Index, "d" # Index, 131 [!cast<Register>("S" # Index)], [sub_32]>, 132 DwarfRegNum<[!add(Index, 64)]>; 133 134 def Q # Index : AArch64RegWithSubs<Index, "q" # Index, 135 [!cast<Register>("D" # Index)], [sub_64]>, 136 DwarfRegNum<[!add(Index, 64)]>; 137 } 138 139 140 def FPR8 : RegisterClass<"AArch64", [i8], 8, 141 (sequence "B%u", 0, 31)> { 142 } 143 144 def FPR16 : RegisterClass<"AArch64", [f16], 16, 145 (sequence "H%u", 0, 31)> { 146 } 147 148 def FPR32 : RegisterClass<"AArch64", [f32], 32, 149 (sequence "S%u", 0, 31)> { 150 } 151 152 def FPR64 : RegisterClass<"AArch64", [f64], 64, 153 (sequence "D%u", 0, 31)> { 154 } 155 156 def FPR128 : RegisterClass<"AArch64", [f128], 128, 157 (sequence "Q%u", 0, 31)> { 158 } 159 160 161 //===----------------------------------------------------------------------===// 162 // Vector registers: 163 //===----------------------------------------------------------------------===// 164 165 // NEON registers simply specify the overall vector, and it's expected that 166 // Instructions will individually specify the acceptable data layout. In 167 // principle this leaves two approaches open: 168 // + An operand, giving a single ADDvvv instruction (for example). This turns 169 // out to be unworkable in the assembly parser (without every Instruction 170 // having a "cvt" function, at least) because the constraints can't be 171 // properly enforced. It also complicates specifying patterns since each 172 // instruction will accept many types. 173 // + A bare token (e.g. ".2d"). This means the AsmParser has to know specific 174 // details about NEON registers, but simplifies most other details. 175 // 176 // The second approach was taken. 177 178 foreach Index = 0-31 in { 179 def V # Index : AArch64RegWithSubs<Index, "v" # Index, 180 [!cast<Register>("Q" # Index)], 181 [sub_alias]>, 182 DwarfRegNum<[!add(Index, 64)]>; 183 } 184 185 // These two classes contain the same registers, which should be reasonably 186 // sensible for MC and allocation purposes, but allows them to be treated 187 // separately for things like stack spilling. 188 def VPR64 : RegisterClass<"AArch64", [v2f32, v2i32, v4i16, v8i8], 64, 189 (sequence "V%u", 0, 31)>; 190 191 def VPR128 : RegisterClass<"AArch64", 192 [v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 128, 193 (sequence "V%u", 0, 31)>; 194 195 // Flags register 196 def NZCV : Register<"nzcv"> { 197 let Namespace = "AArch64"; 198 } 199 200 def FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> { 201 let CopyCost = -1; 202 let isAllocatable = 0; 203 } 204