AArch64RegisterInfo.td revision 263508
1239281Sgonzo//===- AArch64RegisterInfo.td - ARM Register defs ----------*- tablegen -*-===// 2239281Sgonzo// 3239281Sgonzo// The LLVM Compiler Infrastructure 4239281Sgonzo// 5239281Sgonzo// This file is distributed under the University of Illinois Open Source 6239281Sgonzo// License. See LICENSE.TXT for details. 7239281Sgonzo// 8239281Sgonzo//===----------------------------------------------------------------------===// 9239281Sgonzo// 10239281Sgonzo// This file contains declarations that describe the AArch64 register file 11239281Sgonzo// 12239281Sgonzo//===----------------------------------------------------------------------===// 13239281Sgonzo 14239281Sgonzolet Namespace = "AArch64" in { 15239281Sgonzodef sub_128 : SubRegIndex<128>; 16239281Sgonzodef sub_64 : SubRegIndex<64>; 17239281Sgonzodef sub_32 : SubRegIndex<32>; 18239281Sgonzodef sub_16 : SubRegIndex<16>; 19239281Sgonzodef sub_8 : SubRegIndex<8>; 20239281Sgonzo 21239281Sgonzo// Note: Code depends on these having consecutive numbers. 22239281Sgonzodef qqsub : SubRegIndex<256, 256>; 23239281Sgonzo 24239281Sgonzodef qsub_0 : SubRegIndex<128>; 25239281Sgonzodef qsub_1 : SubRegIndex<128, 128>; 26239281Sgonzodef qsub_2 : ComposedSubRegIndex<qqsub, qsub_0>; 27239281Sgonzodef qsub_3 : ComposedSubRegIndex<qqsub, qsub_1>; 28239281Sgonzo 29239281Sgonzodef dsub_0 : SubRegIndex<64>; 30239281Sgonzodef dsub_1 : SubRegIndex<64, 64>; 31239281Sgonzodef dsub_2 : ComposedSubRegIndex<qsub_1, dsub_0>; 32239281Sgonzodef dsub_3 : ComposedSubRegIndex<qsub_1, dsub_1>; 33239281Sgonzodef dsub_4 : ComposedSubRegIndex<qsub_2, dsub_0>; 34278079Sloos} 35239281Sgonzo 36239281Sgonzo// Registers are identified with 5-bit ID numbers. 37239281Sgonzoclass AArch64Reg<bits<16> enc, string n> : Register<n> { 38239281Sgonzo let HWEncoding = enc; 39239281Sgonzo let Namespace = "AArch64"; 40278079Sloos} 41239281Sgonzo 42239281Sgonzoclass AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [], 43239281Sgonzo list<SubRegIndex> inds = []> 44239281Sgonzo : AArch64Reg<enc, n> { 45239281Sgonzo let SubRegs = subregs; 46239281Sgonzo let SubRegIndices = inds; 47239281Sgonzo} 48239281Sgonzo 49239281Sgonzo//===----------------------------------------------------------------------===// 50239281Sgonzo// Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp 51278079Sloos//===----------------------------------------------------------------------===// 52278079Sloos 53239281Sgonzoforeach Index = 0-30 in { 54239281Sgonzo def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>; 55239281Sgonzo} 56239281Sgonzo 57253025Sgonzodef WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>; 58253025Sgonzodef WZR : AArch64Reg<31, "wzr">; 59239281Sgonzo 60239281Sgonzo// Could be combined with previous loop, but this way leaves w and x registers 61239281Sgonzo// consecutive as LLVM register numbers, which makes for easier debugging. 62239281Sgonzoforeach Index = 0-30 in { 63278079Sloos def X#Index : AArch64RegWithSubs<Index, "x"#Index, 64278079Sloos [!cast<Register>("W"#Index)], [sub_32]>, 65278079Sloos DwarfRegNum<[Index]>; 66278079Sloos} 67239281Sgonzo 68239281Sgonzodef XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>; 69239281Sgonzodef XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>; 70239281Sgonzo 71239281Sgonzo// Most instructions treat register 31 as zero for reads and a black-hole for 72239281Sgonzo// writes. 73239281Sgonzo 74239281Sgonzo// Note that the order of registers is important for the Disassembler here: 75239281Sgonzo// tablegen uses it to form MCRegisterClass::getRegister, which we assume can 76239281Sgonzo// take an encoding value. 77278079Sloosdef GPR32 : RegisterClass<"AArch64", [i32], 32, 78278079Sloos (add (sequence "W%u", 0, 30), WZR)> { 79239281Sgonzo} 80239281Sgonzo 81239281Sgonzodef GPR64 : RegisterClass<"AArch64", [i64], 64, 82239281Sgonzo (add (sequence "X%u", 0, 30), XZR)> { 83239281Sgonzo} 84239281Sgonzo 85239281Sgonzodef GPR32nowzr : RegisterClass<"AArch64", [i32], 32, 86239281Sgonzo (sequence "W%u", 0, 30)> { 87239281Sgonzo} 88239281Sgonzo 89239281Sgonzodef GPR64noxzr : RegisterClass<"AArch64", [i64], 64, 90239281Sgonzo (sequence "X%u", 0, 30)> { 91239281Sgonzo} 92239281Sgonzo 93239281Sgonzo// For tail calls, we can't use callee-saved registers or the structure-return 94239281Sgonzo// register, as they are supposed to be live across function calls and may be 95239281Sgonzo// clobbered by the epilogue. 96239281Sgonzodef tcGPR64 : RegisterClass<"AArch64", [i64], 64, 97239281Sgonzo (add (sequence "X%u", 0, 7), 98239281Sgonzo (sequence "X%u", 9, 18))> { 99239281Sgonzo} 100239281Sgonzo 101239281Sgonzo 102239281Sgonzo// Certain addressing-useful instructions accept sp directly. Again the order of 103239281Sgonzo// registers is important to the Disassembler. 104239281Sgonzodef GPR32wsp : RegisterClass<"AArch64", [i32], 32, 105239281Sgonzo (add (sequence "W%u", 0, 30), WSP)> { 106239281Sgonzo} 107239281Sgonzo 108239281Sgonzodef GPR64xsp : RegisterClass<"AArch64", [i64], 64, 109239281Sgonzo (add (sequence "X%u", 0, 30), XSP)> { 110239281Sgonzo} 111239281Sgonzo 112239281Sgonzo// Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and 113239281Sgonzo// non-SP variants). We can't use a bare register in those patterns because 114239281Sgonzo// TableGen doesn't like it, so we need a class containing just stack registers 115239281Sgonzodef Rxsp : RegisterClass<"AArch64", [i64], 64, 116239281Sgonzo (add XSP)> { 117239281Sgonzo} 118239281Sgonzo 119239281Sgonzodef Rwsp : RegisterClass<"AArch64", [i32], 32, 120239281Sgonzo (add WSP)> { 121239281Sgonzo} 122239281Sgonzo 123239281Sgonzo//===----------------------------------------------------------------------===// 124239281Sgonzo// Scalar registers in the vector unit: 125239281Sgonzo// b0-b31, h0-h31, s0-s31, d0-d31, q0-q31 126239281Sgonzo//===----------------------------------------------------------------------===// 127239281Sgonzo 128239281Sgonzoforeach Index = 0-31 in { 129239281Sgonzo def B # Index : AArch64Reg< Index, "b" # Index>, 130239281Sgonzo DwarfRegNum<[!add(Index, 64)]>; 131239281Sgonzo 132239281Sgonzo def H # Index : AArch64RegWithSubs<Index, "h" # Index, 133239281Sgonzo [!cast<Register>("B" # Index)], [sub_8]>, 134239281Sgonzo DwarfRegNum<[!add(Index, 64)]>; 135239281Sgonzo 136239281Sgonzo def S # Index : AArch64RegWithSubs<Index, "s" # Index, 137239281Sgonzo [!cast<Register>("H" # Index)], [sub_16]>, 138239281Sgonzo DwarfRegNum<[!add(Index, 64)]>; 139239281Sgonzo 140239281Sgonzo def D # Index : AArch64RegWithSubs<Index, "d" # Index, 141239281Sgonzo [!cast<Register>("S" # Index)], [sub_32]>, 142239281Sgonzo DwarfRegNum<[!add(Index, 64)]>; 143239281Sgonzo 144253025Sgonzo def Q # Index : AArch64RegWithSubs<Index, "q" # Index, 145253025Sgonzo [!cast<Register>("D" # Index)], [sub_64]>, 146253025Sgonzo DwarfRegNum<[!add(Index, 64)]>; 147253025Sgonzo} 148253025Sgonzo 149253025Sgonzo 150239281Sgonzodef FPR8 : RegisterClass<"AArch64", [i8, v1i8], 8, 151239281Sgonzo (sequence "B%u", 0, 31)> { 152239281Sgonzo} 153239281Sgonzo 154239281Sgonzodef FPR16 : RegisterClass<"AArch64", [f16, v1i16], 16, 155239281Sgonzo (sequence "H%u", 0, 31)> { 156239281Sgonzo} 157278079Sloos 158278079Sloosdef FPR32 : RegisterClass<"AArch64", [f32, v1i32, v1f32], 32, 159278079Sloos (sequence "S%u", 0, 31)> { 160239281Sgonzo} 161239281Sgonzo 162239281Sgonzodef FPR64 : RegisterClass<"AArch64", 163239281Sgonzo [f64, v2f32, v2i32, v4i16, v8i8, v1i64, v1f64], 164239281Sgonzo 64, (sequence "D%u", 0, 31)>; 165239281Sgonzo 166239281Sgonzodef FPR128 : RegisterClass<"AArch64", 167239281Sgonzo [f128, v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 168239281Sgonzo 128, (sequence "Q%u", 0, 31)>; 169239281Sgonzo 170239281Sgonzodef FPR64Lo : RegisterClass<"AArch64", 171239281Sgonzo [f64, v2f32, v2i32, v4i16, v8i8, v1i64, v1f64], 172239281Sgonzo 64, (sequence "D%u", 0, 15)>; 173239281Sgonzo 174239281Sgonzodef FPR128Lo : RegisterClass<"AArch64", 175239281Sgonzo [f128, v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 176239281Sgonzo 128, (sequence "Q%u", 0, 15)>; 177239281Sgonzo 178239281Sgonzo//===----------------------------------------------------------------------===// 179278079Sloos// Vector registers: 180278079Sloos//===----------------------------------------------------------------------===// 181278079Sloos 182278079Sloosdef VPR64AsmOperand : AsmOperandClass { 183278079Sloos let Name = "VPR"; 184278079Sloos let PredicateMethod = "isReg"; 185278079Sloos let RenderMethod = "addRegOperands"; 186278079Sloos} 187278079Sloos 188278079Sloosdef VPR64 : RegisterOperand<FPR64, "printVPRRegister">; 189278079Sloos 190278079Sloosdef VPR128 : RegisterOperand<FPR128, "printVPRRegister">; 191278079Sloos 192278079Sloosdef VPR64Lo : RegisterOperand<FPR64Lo, "printVPRRegister">; 193278079Sloos 194278079Sloosdef VPR128Lo : RegisterOperand<FPR128Lo, "printVPRRegister">; 195239281Sgonzo 196239281Sgonzo// Flags register 197239281Sgonzodef NZCV : Register<"nzcv"> { 198239281Sgonzo let Namespace = "AArch64"; 199239281Sgonzo} 200239281Sgonzo 201239281Sgonzodef FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> { 202239281Sgonzo let CopyCost = -1; 203239281Sgonzo let isAllocatable = 0; 204239281Sgonzo} 205239281Sgonzo 206239281Sgonzo//===----------------------------------------------------------------------===// 207239281Sgonzo// Consecutive vector registers 208239281Sgonzo//===----------------------------------------------------------------------===// 209239281Sgonzo// 2 Consecutive 64-bit registers: D0_D1, D1_D2, ..., D30_D31 210239281Sgonzodef Tuples2D : RegisterTuples<[dsub_0, dsub_1], 211239281Sgonzo [(rotl FPR64, 0), (rotl FPR64, 1)]>; 212 213// 3 Consecutive 64-bit registers: D0_D1_D2, ..., D31_D0_D1 214def Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2], 215 [(rotl FPR64, 0), (rotl FPR64, 1), 216 (rotl FPR64, 2)]>; 217 218// 4 Consecutive 64-bit registers: D0_D1_D2_D3, ..., D31_D0_D1_D2 219def Tuples4D : RegisterTuples<[dsub_0, dsub_1, dsub_2, dsub_3], 220 [(rotl FPR64, 0), (rotl FPR64, 1), 221 (rotl FPR64, 2), (rotl FPR64, 3)]>; 222 223// 2 Consecutive 128-bit registers: Q0_Q1, Q1_Q2, ..., Q30_Q31 224def Tuples2Q : RegisterTuples<[qsub_0, qsub_1], 225 [(rotl FPR128, 0), (rotl FPR128, 1)]>; 226 227// 3 Consecutive 128-bit registers: Q0_Q1_Q2, ..., Q31_Q0_Q1 228def Tuples3Q : RegisterTuples<[qsub_0, qsub_1, qsub_2], 229 [(rotl FPR128, 0), (rotl FPR128, 1), 230 (rotl FPR128, 2)]>; 231 232// 4 Consecutive 128-bit registers: Q0_Q1_Q2_Q3, ..., Q31_Q0_Q1_Q2 233def Tuples4Q : RegisterTuples<[qsub_0, qsub_1, qsub_2, qsub_3], 234 [(rotl FPR128, 0), (rotl FPR128, 1), 235 (rotl FPR128, 2), (rotl FPR128, 3)]>; 236 237// The followings are super register classes to model 2/3/4 consecutive 238// 64-bit/128-bit registers. 239 240def DPair : RegisterClass<"AArch64", [v2i64], 64, (add Tuples2D)>; 241 242def DTriple : RegisterClass<"AArch64", [untyped], 64, (add Tuples3D)> { 243 let Size = 192; // 3 x 64 bits, we have no predefined type of that size. 244} 245 246def DQuad : RegisterClass<"AArch64", [v4i64], 64, (add Tuples4D)>; 247 248def QPair : RegisterClass<"AArch64", [v4i64], 128, (add Tuples2Q)>; 249 250def QTriple : RegisterClass<"AArch64", [untyped], 128, (add Tuples3Q)> { 251 let Size = 384; // 3 x 128 bits, we have no predefined type of that size. 252} 253 254def QQuad : RegisterClass<"AArch64", [v8i64], 128, (add Tuples4Q)>; 255 256 257// The followings are vector list operands 258multiclass VectorList_operands<string PREFIX, string LAYOUT, int Count, 259 RegisterClass RegList> { 260 def _asmoperand : AsmOperandClass { 261 let Name = PREFIX # LAYOUT # Count; 262 let RenderMethod = "addVectorListOperands"; 263 let PredicateMethod = 264 "isVectorList<A64Layout::VL_" # LAYOUT # ", " # Count # ">"; 265 let ParserMethod = "ParseVectorList"; 266 } 267 268 def _operand : RegisterOperand<RegList, 269 "printVectorList<A64Layout::VL_" # LAYOUT # ", " # Count # ">"> { 270 let ParserMatchClass = 271 !cast<AsmOperandClass>(PREFIX # LAYOUT # "_asmoperand"); 272 } 273} 274 275multiclass VectorList_BHSD<string PREFIX, int Count, RegisterClass DRegList, 276 RegisterClass QRegList> { 277 defm 8B : VectorList_operands<PREFIX, "8B", Count, DRegList>; 278 defm 4H : VectorList_operands<PREFIX, "4H", Count, DRegList>; 279 defm 2S : VectorList_operands<PREFIX, "2S", Count, DRegList>; 280 defm 1D : VectorList_operands<PREFIX, "1D", Count, DRegList>; 281 defm 16B : VectorList_operands<PREFIX, "16B", Count, QRegList>; 282 defm 8H : VectorList_operands<PREFIX, "8H", Count, QRegList>; 283 defm 4S : VectorList_operands<PREFIX, "4S", Count, QRegList>; 284 defm 2D : VectorList_operands<PREFIX, "2D", Count, QRegList>; 285} 286 287// Vector list operand with 1/2/3/4 registers: VOne8B_operand,..., VQuad2D_operand 288defm VOne : VectorList_BHSD<"VOne", 1, FPR64, FPR128>; 289defm VPair : VectorList_BHSD<"VPair", 2, DPair, QPair>; 290defm VTriple : VectorList_BHSD<"VTriple", 3, DTriple, QTriple>; 291defm VQuad : VectorList_BHSD<"VQuad", 4, DQuad, QQuad>;