1249259Sdim//===- AArch64RegisterInfo.td - ARM Register defs ----------*- tablegen -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file contains declarations that describe the AArch64 register file 11249259Sdim// 12249259Sdim//===----------------------------------------------------------------------===// 13249259Sdim 14249259Sdimlet Namespace = "AArch64" in { 15263508Sdimdef sub_128 : SubRegIndex<128>; 16263508Sdimdef sub_64 : SubRegIndex<64>; 17263508Sdimdef sub_32 : SubRegIndex<32>; 18263508Sdimdef sub_16 : SubRegIndex<16>; 19263508Sdimdef sub_8 : SubRegIndex<8>; 20249259Sdim 21263508Sdim// Note: Code depends on these having consecutive numbers. 22263508Sdimdef qqsub : SubRegIndex<256, 256>; 23263508Sdim 24263508Sdimdef qsub_0 : SubRegIndex<128>; 25263508Sdimdef qsub_1 : SubRegIndex<128, 128>; 26263508Sdimdef qsub_2 : ComposedSubRegIndex<qqsub, qsub_0>; 27263508Sdimdef qsub_3 : ComposedSubRegIndex<qqsub, qsub_1>; 28263508Sdim 29263508Sdimdef dsub_0 : SubRegIndex<64>; 30263508Sdimdef dsub_1 : SubRegIndex<64, 64>; 31263508Sdimdef dsub_2 : ComposedSubRegIndex<qsub_1, dsub_0>; 32263508Sdimdef dsub_3 : ComposedSubRegIndex<qsub_1, dsub_1>; 33263508Sdimdef dsub_4 : ComposedSubRegIndex<qsub_2, dsub_0>; 34249259Sdim} 35249259Sdim 36249259Sdim// Registers are identified with 5-bit ID numbers. 37249259Sdimclass AArch64Reg<bits<16> enc, string n> : Register<n> { 38249259Sdim let HWEncoding = enc; 39249259Sdim let Namespace = "AArch64"; 40249259Sdim} 41249259Sdim 42249259Sdimclass AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [], 43249259Sdim list<SubRegIndex> inds = []> 44249259Sdim : AArch64Reg<enc, n> { 45249259Sdim let SubRegs = subregs; 46249259Sdim let SubRegIndices = inds; 47249259Sdim} 48249259Sdim 49249259Sdim//===----------------------------------------------------------------------===// 50249259Sdim// Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp 51249259Sdim//===----------------------------------------------------------------------===// 52249259Sdim 53249259Sdimforeach Index = 0-30 in { 54249259Sdim def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>; 55249259Sdim} 56249259Sdim 57249259Sdimdef WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>; 58249259Sdimdef WZR : AArch64Reg<31, "wzr">; 59249259Sdim 60249259Sdim// Could be combined with previous loop, but this way leaves w and x registers 61249259Sdim// consecutive as LLVM register numbers, which makes for easier debugging. 62249259Sdimforeach Index = 0-30 in { 63249259Sdim def X#Index : AArch64RegWithSubs<Index, "x"#Index, 64249259Sdim [!cast<Register>("W"#Index)], [sub_32]>, 65249259Sdim DwarfRegNum<[Index]>; 66249259Sdim} 67249259Sdim 68249259Sdimdef XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>; 69249259Sdimdef XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>; 70249259Sdim 71249259Sdim// Most instructions treat register 31 as zero for reads and a black-hole for 72249259Sdim// writes. 73249259Sdim 74249259Sdim// Note that the order of registers is important for the Disassembler here: 75249259Sdim// tablegen uses it to form MCRegisterClass::getRegister, which we assume can 76249259Sdim// take an encoding value. 77249259Sdimdef GPR32 : RegisterClass<"AArch64", [i32], 32, 78249259Sdim (add (sequence "W%u", 0, 30), WZR)> { 79249259Sdim} 80249259Sdim 81249259Sdimdef GPR64 : RegisterClass<"AArch64", [i64], 64, 82249259Sdim (add (sequence "X%u", 0, 30), XZR)> { 83249259Sdim} 84249259Sdim 85249259Sdimdef GPR32nowzr : RegisterClass<"AArch64", [i32], 32, 86249259Sdim (sequence "W%u", 0, 30)> { 87249259Sdim} 88249259Sdim 89249259Sdimdef GPR64noxzr : RegisterClass<"AArch64", [i64], 64, 90249259Sdim (sequence "X%u", 0, 30)> { 91249259Sdim} 92249259Sdim 93249259Sdim// For tail calls, we can't use callee-saved registers or the structure-return 94249259Sdim// register, as they are supposed to be live across function calls and may be 95249259Sdim// clobbered by the epilogue. 96249259Sdimdef tcGPR64 : RegisterClass<"AArch64", [i64], 64, 97249259Sdim (add (sequence "X%u", 0, 7), 98249259Sdim (sequence "X%u", 9, 18))> { 99249259Sdim} 100249259Sdim 101249259Sdim 102249259Sdim// Certain addressing-useful instructions accept sp directly. Again the order of 103249259Sdim// registers is important to the Disassembler. 104249259Sdimdef GPR32wsp : RegisterClass<"AArch64", [i32], 32, 105249259Sdim (add (sequence "W%u", 0, 30), WSP)> { 106249259Sdim} 107249259Sdim 108249259Sdimdef GPR64xsp : RegisterClass<"AArch64", [i64], 64, 109249259Sdim (add (sequence "X%u", 0, 30), XSP)> { 110249259Sdim} 111249259Sdim 112249259Sdim// Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and 113249259Sdim// non-SP variants). We can't use a bare register in those patterns because 114249259Sdim// TableGen doesn't like it, so we need a class containing just stack registers 115249259Sdimdef Rxsp : RegisterClass<"AArch64", [i64], 64, 116249259Sdim (add XSP)> { 117249259Sdim} 118249259Sdim 119249259Sdimdef Rwsp : RegisterClass<"AArch64", [i32], 32, 120249259Sdim (add WSP)> { 121249259Sdim} 122249259Sdim 123249259Sdim//===----------------------------------------------------------------------===// 124249259Sdim// Scalar registers in the vector unit: 125249259Sdim// b0-b31, h0-h31, s0-s31, d0-d31, q0-q31 126249259Sdim//===----------------------------------------------------------------------===// 127249259Sdim 128249259Sdimforeach Index = 0-31 in { 129249259Sdim def B # Index : AArch64Reg< Index, "b" # Index>, 130249259Sdim DwarfRegNum<[!add(Index, 64)]>; 131249259Sdim 132249259Sdim def H # Index : AArch64RegWithSubs<Index, "h" # Index, 133249259Sdim [!cast<Register>("B" # Index)], [sub_8]>, 134249259Sdim DwarfRegNum<[!add(Index, 64)]>; 135249259Sdim 136249259Sdim def S # Index : AArch64RegWithSubs<Index, "s" # Index, 137249259Sdim [!cast<Register>("H" # Index)], [sub_16]>, 138249259Sdim DwarfRegNum<[!add(Index, 64)]>; 139249259Sdim 140249259Sdim def D # Index : AArch64RegWithSubs<Index, "d" # Index, 141249259Sdim [!cast<Register>("S" # Index)], [sub_32]>, 142249259Sdim DwarfRegNum<[!add(Index, 64)]>; 143249259Sdim 144249259Sdim def Q # Index : AArch64RegWithSubs<Index, "q" # Index, 145249259Sdim [!cast<Register>("D" # Index)], [sub_64]>, 146249259Sdim DwarfRegNum<[!add(Index, 64)]>; 147249259Sdim} 148249259Sdim 149249259Sdim 150263508Sdimdef FPR8 : RegisterClass<"AArch64", [i8, v1i8], 8, 151249259Sdim (sequence "B%u", 0, 31)> { 152249259Sdim} 153249259Sdim 154263508Sdimdef FPR16 : RegisterClass<"AArch64", [f16, v1i16], 16, 155249259Sdim (sequence "H%u", 0, 31)> { 156249259Sdim} 157249259Sdim 158263508Sdimdef FPR32 : RegisterClass<"AArch64", [f32, v1i32, v1f32], 32, 159249259Sdim (sequence "S%u", 0, 31)> { 160249259Sdim} 161249259Sdim 162263508Sdimdef FPR64 : RegisterClass<"AArch64", 163263508Sdim [f64, v2f32, v2i32, v4i16, v8i8, v1i64, v1f64], 164263508Sdim 64, (sequence "D%u", 0, 31)>; 165249259Sdim 166263508Sdimdef FPR128 : RegisterClass<"AArch64", 167263508Sdim [f128, v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 168263508Sdim 128, (sequence "Q%u", 0, 31)>; 169249259Sdim 170263508Sdimdef FPR64Lo : RegisterClass<"AArch64", 171263508Sdim [f64, v2f32, v2i32, v4i16, v8i8, v1i64, v1f64], 172263508Sdim 64, (sequence "D%u", 0, 15)>; 173249259Sdim 174263508Sdimdef FPR128Lo : RegisterClass<"AArch64", 175263508Sdim [f128, v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 176263508Sdim 128, (sequence "Q%u", 0, 15)>; 177263508Sdim 178249259Sdim//===----------------------------------------------------------------------===// 179249259Sdim// Vector registers: 180249259Sdim//===----------------------------------------------------------------------===// 181249259Sdim 182263508Sdimdef VPR64AsmOperand : AsmOperandClass { 183263508Sdim let Name = "VPR"; 184263508Sdim let PredicateMethod = "isReg"; 185263508Sdim let RenderMethod = "addRegOperands"; 186249259Sdim} 187249259Sdim 188263508Sdimdef VPR64 : RegisterOperand<FPR64, "printVPRRegister">; 189249259Sdim 190263508Sdimdef VPR128 : RegisterOperand<FPR128, "printVPRRegister">; 191249259Sdim 192263508Sdimdef VPR64Lo : RegisterOperand<FPR64Lo, "printVPRRegister">; 193263508Sdim 194263508Sdimdef VPR128Lo : RegisterOperand<FPR128Lo, "printVPRRegister">; 195263508Sdim 196249259Sdim// Flags register 197249259Sdimdef NZCV : Register<"nzcv"> { 198249259Sdim let Namespace = "AArch64"; 199249259Sdim} 200249259Sdim 201249259Sdimdef FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> { 202249259Sdim let CopyCost = -1; 203249259Sdim let isAllocatable = 0; 204249259Sdim} 205263508Sdim 206263508Sdim//===----------------------------------------------------------------------===// 207263508Sdim// Consecutive vector registers 208263508Sdim//===----------------------------------------------------------------------===// 209263508Sdim// 2 Consecutive 64-bit registers: D0_D1, D1_D2, ..., D30_D31 210263508Sdimdef Tuples2D : RegisterTuples<[dsub_0, dsub_1], 211263508Sdim [(rotl FPR64, 0), (rotl FPR64, 1)]>; 212263508Sdim 213263508Sdim// 3 Consecutive 64-bit registers: D0_D1_D2, ..., D31_D0_D1 214263508Sdimdef Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2], 215263508Sdim [(rotl FPR64, 0), (rotl FPR64, 1), 216263508Sdim (rotl FPR64, 2)]>; 217263508Sdim 218263508Sdim// 4 Consecutive 64-bit registers: D0_D1_D2_D3, ..., D31_D0_D1_D2 219263508Sdimdef Tuples4D : RegisterTuples<[dsub_0, dsub_1, dsub_2, dsub_3], 220263508Sdim [(rotl FPR64, 0), (rotl FPR64, 1), 221263508Sdim (rotl FPR64, 2), (rotl FPR64, 3)]>; 222263508Sdim 223263508Sdim// 2 Consecutive 128-bit registers: Q0_Q1, Q1_Q2, ..., Q30_Q31 224263508Sdimdef Tuples2Q : RegisterTuples<[qsub_0, qsub_1], 225263508Sdim [(rotl FPR128, 0), (rotl FPR128, 1)]>; 226263508Sdim 227263508Sdim// 3 Consecutive 128-bit registers: Q0_Q1_Q2, ..., Q31_Q0_Q1 228263508Sdimdef Tuples3Q : RegisterTuples<[qsub_0, qsub_1, qsub_2], 229263508Sdim [(rotl FPR128, 0), (rotl FPR128, 1), 230263508Sdim (rotl FPR128, 2)]>; 231263508Sdim 232263508Sdim// 4 Consecutive 128-bit registers: Q0_Q1_Q2_Q3, ..., Q31_Q0_Q1_Q2 233263508Sdimdef Tuples4Q : RegisterTuples<[qsub_0, qsub_1, qsub_2, qsub_3], 234263508Sdim [(rotl FPR128, 0), (rotl FPR128, 1), 235263508Sdim (rotl FPR128, 2), (rotl FPR128, 3)]>; 236263508Sdim 237263508Sdim// The followings are super register classes to model 2/3/4 consecutive 238263508Sdim// 64-bit/128-bit registers. 239263508Sdim 240263508Sdimdef DPair : RegisterClass<"AArch64", [v2i64], 64, (add Tuples2D)>; 241263508Sdim 242263508Sdimdef DTriple : RegisterClass<"AArch64", [untyped], 64, (add Tuples3D)> { 243263508Sdim let Size = 192; // 3 x 64 bits, we have no predefined type of that size. 244263508Sdim} 245263508Sdim 246263508Sdimdef DQuad : RegisterClass<"AArch64", [v4i64], 64, (add Tuples4D)>; 247263508Sdim 248263508Sdimdef QPair : RegisterClass<"AArch64", [v4i64], 128, (add Tuples2Q)>; 249263508Sdim 250263508Sdimdef QTriple : RegisterClass<"AArch64", [untyped], 128, (add Tuples3Q)> { 251263508Sdim let Size = 384; // 3 x 128 bits, we have no predefined type of that size. 252263508Sdim} 253263508Sdim 254263508Sdimdef QQuad : RegisterClass<"AArch64", [v8i64], 128, (add Tuples4Q)>; 255263508Sdim 256263508Sdim 257263508Sdim// The followings are vector list operands 258263508Sdimmulticlass VectorList_operands<string PREFIX, string LAYOUT, int Count, 259263508Sdim RegisterClass RegList> { 260263508Sdim def _asmoperand : AsmOperandClass { 261263508Sdim let Name = PREFIX # LAYOUT # Count; 262263508Sdim let RenderMethod = "addVectorListOperands"; 263263508Sdim let PredicateMethod = 264263508Sdim "isVectorList<A64Layout::VL_" # LAYOUT # ", " # Count # ">"; 265263508Sdim let ParserMethod = "ParseVectorList"; 266263508Sdim } 267263508Sdim 268263508Sdim def _operand : RegisterOperand<RegList, 269263508Sdim "printVectorList<A64Layout::VL_" # LAYOUT # ", " # Count # ">"> { 270263508Sdim let ParserMatchClass = 271263508Sdim !cast<AsmOperandClass>(PREFIX # LAYOUT # "_asmoperand"); 272263508Sdim } 273263508Sdim} 274263508Sdim 275263508Sdimmulticlass VectorList_BHSD<string PREFIX, int Count, RegisterClass DRegList, 276263508Sdim RegisterClass QRegList> { 277263508Sdim defm 8B : VectorList_operands<PREFIX, "8B", Count, DRegList>; 278263508Sdim defm 4H : VectorList_operands<PREFIX, "4H", Count, DRegList>; 279263508Sdim defm 2S : VectorList_operands<PREFIX, "2S", Count, DRegList>; 280263508Sdim defm 1D : VectorList_operands<PREFIX, "1D", Count, DRegList>; 281263508Sdim defm 16B : VectorList_operands<PREFIX, "16B", Count, QRegList>; 282263508Sdim defm 8H : VectorList_operands<PREFIX, "8H", Count, QRegList>; 283263508Sdim defm 4S : VectorList_operands<PREFIX, "4S", Count, QRegList>; 284263508Sdim defm 2D : VectorList_operands<PREFIX, "2D", Count, QRegList>; 285263508Sdim} 286263508Sdim 287263508Sdim// Vector list operand with 1/2/3/4 registers: VOne8B_operand,..., VQuad2D_operand 288263508Sdimdefm VOne : VectorList_BHSD<"VOne", 1, FPR64, FPR128>; 289263508Sdimdefm VPair : VectorList_BHSD<"VPair", 2, DPair, QPair>; 290263508Sdimdefm VTriple : VectorList_BHSD<"VTriple", 3, DTriple, QTriple>; 291263508Sdimdefm VQuad : VectorList_BHSD<"VQuad", 4, DQuad, QQuad>;