AArch64RegisterInfo.td revision 249259
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 { 15249259Sdimdef sub_128 : SubRegIndex; 16249259Sdimdef sub_64 : SubRegIndex; 17249259Sdimdef sub_32 : SubRegIndex; 18249259Sdimdef sub_16 : SubRegIndex; 19249259Sdimdef sub_8 : SubRegIndex; 20249259Sdim 21249259Sdim// The VPR registers are handled as sub-registers of FPR equivalents, but 22249259Sdim// they're really the same thing. We give this concept a special index. 23249259Sdimdef sub_alias : SubRegIndex; 24249259Sdim} 25249259Sdim 26249259Sdim// Registers are identified with 5-bit ID numbers. 27249259Sdimclass AArch64Reg<bits<16> enc, string n> : Register<n> { 28249259Sdim let HWEncoding = enc; 29249259Sdim let Namespace = "AArch64"; 30249259Sdim} 31249259Sdim 32249259Sdimclass AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [], 33249259Sdim list<SubRegIndex> inds = []> 34249259Sdim : AArch64Reg<enc, n> { 35249259Sdim let SubRegs = subregs; 36249259Sdim let SubRegIndices = inds; 37249259Sdim} 38249259Sdim 39249259Sdim//===----------------------------------------------------------------------===// 40249259Sdim// Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp 41249259Sdim//===----------------------------------------------------------------------===// 42249259Sdim 43249259Sdimforeach Index = 0-30 in { 44249259Sdim def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>; 45249259Sdim} 46249259Sdim 47249259Sdimdef WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>; 48249259Sdimdef WZR : AArch64Reg<31, "wzr">; 49249259Sdim 50249259Sdim// Could be combined with previous loop, but this way leaves w and x registers 51249259Sdim// consecutive as LLVM register numbers, which makes for easier debugging. 52249259Sdimforeach Index = 0-30 in { 53249259Sdim def X#Index : AArch64RegWithSubs<Index, "x"#Index, 54249259Sdim [!cast<Register>("W"#Index)], [sub_32]>, 55249259Sdim DwarfRegNum<[Index]>; 56249259Sdim} 57249259Sdim 58249259Sdimdef XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>; 59249259Sdimdef XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>; 60249259Sdim 61249259Sdim// Most instructions treat register 31 as zero for reads and a black-hole for 62249259Sdim// writes. 63249259Sdim 64249259Sdim// Note that the order of registers is important for the Disassembler here: 65249259Sdim// tablegen uses it to form MCRegisterClass::getRegister, which we assume can 66249259Sdim// take an encoding value. 67249259Sdimdef GPR32 : RegisterClass<"AArch64", [i32], 32, 68249259Sdim (add (sequence "W%u", 0, 30), WZR)> { 69249259Sdim} 70249259Sdim 71249259Sdimdef GPR64 : RegisterClass<"AArch64", [i64], 64, 72249259Sdim (add (sequence "X%u", 0, 30), XZR)> { 73249259Sdim} 74249259Sdim 75249259Sdimdef GPR32nowzr : RegisterClass<"AArch64", [i32], 32, 76249259Sdim (sequence "W%u", 0, 30)> { 77249259Sdim} 78249259Sdim 79249259Sdimdef GPR64noxzr : RegisterClass<"AArch64", [i64], 64, 80249259Sdim (sequence "X%u", 0, 30)> { 81249259Sdim} 82249259Sdim 83249259Sdim// For tail calls, we can't use callee-saved registers or the structure-return 84249259Sdim// register, as they are supposed to be live across function calls and may be 85249259Sdim// clobbered by the epilogue. 86249259Sdimdef tcGPR64 : RegisterClass<"AArch64", [i64], 64, 87249259Sdim (add (sequence "X%u", 0, 7), 88249259Sdim (sequence "X%u", 9, 18))> { 89249259Sdim} 90249259Sdim 91249259Sdim 92249259Sdim// Certain addressing-useful instructions accept sp directly. Again the order of 93249259Sdim// registers is important to the Disassembler. 94249259Sdimdef GPR32wsp : RegisterClass<"AArch64", [i32], 32, 95249259Sdim (add (sequence "W%u", 0, 30), WSP)> { 96249259Sdim} 97249259Sdim 98249259Sdimdef GPR64xsp : RegisterClass<"AArch64", [i64], 64, 99249259Sdim (add (sequence "X%u", 0, 30), XSP)> { 100249259Sdim} 101249259Sdim 102249259Sdim// Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and 103249259Sdim// non-SP variants). We can't use a bare register in those patterns because 104249259Sdim// TableGen doesn't like it, so we need a class containing just stack registers 105249259Sdimdef Rxsp : RegisterClass<"AArch64", [i64], 64, 106249259Sdim (add XSP)> { 107249259Sdim} 108249259Sdim 109249259Sdimdef Rwsp : RegisterClass<"AArch64", [i32], 32, 110249259Sdim (add WSP)> { 111249259Sdim} 112249259Sdim 113249259Sdim//===----------------------------------------------------------------------===// 114249259Sdim// Scalar registers in the vector unit: 115249259Sdim// b0-b31, h0-h31, s0-s31, d0-d31, q0-q31 116249259Sdim//===----------------------------------------------------------------------===// 117249259Sdim 118249259Sdimforeach Index = 0-31 in { 119249259Sdim def B # Index : AArch64Reg< Index, "b" # Index>, 120249259Sdim DwarfRegNum<[!add(Index, 64)]>; 121249259Sdim 122249259Sdim def H # Index : AArch64RegWithSubs<Index, "h" # Index, 123249259Sdim [!cast<Register>("B" # Index)], [sub_8]>, 124249259Sdim DwarfRegNum<[!add(Index, 64)]>; 125249259Sdim 126249259Sdim def S # Index : AArch64RegWithSubs<Index, "s" # Index, 127249259Sdim [!cast<Register>("H" # Index)], [sub_16]>, 128249259Sdim DwarfRegNum<[!add(Index, 64)]>; 129249259Sdim 130249259Sdim def D # Index : AArch64RegWithSubs<Index, "d" # Index, 131249259Sdim [!cast<Register>("S" # Index)], [sub_32]>, 132249259Sdim DwarfRegNum<[!add(Index, 64)]>; 133249259Sdim 134249259Sdim def Q # Index : AArch64RegWithSubs<Index, "q" # Index, 135249259Sdim [!cast<Register>("D" # Index)], [sub_64]>, 136249259Sdim DwarfRegNum<[!add(Index, 64)]>; 137249259Sdim} 138249259Sdim 139249259Sdim 140249259Sdimdef FPR8 : RegisterClass<"AArch64", [i8], 8, 141249259Sdim (sequence "B%u", 0, 31)> { 142249259Sdim} 143249259Sdim 144249259Sdimdef FPR16 : RegisterClass<"AArch64", [f16], 16, 145249259Sdim (sequence "H%u", 0, 31)> { 146249259Sdim} 147249259Sdim 148249259Sdimdef FPR32 : RegisterClass<"AArch64", [f32], 32, 149249259Sdim (sequence "S%u", 0, 31)> { 150249259Sdim} 151249259Sdim 152249259Sdimdef FPR64 : RegisterClass<"AArch64", [f64], 64, 153249259Sdim (sequence "D%u", 0, 31)> { 154249259Sdim} 155249259Sdim 156249259Sdimdef FPR128 : RegisterClass<"AArch64", [f128], 128, 157249259Sdim (sequence "Q%u", 0, 31)> { 158249259Sdim} 159249259Sdim 160249259Sdim 161249259Sdim//===----------------------------------------------------------------------===// 162249259Sdim// Vector registers: 163249259Sdim//===----------------------------------------------------------------------===// 164249259Sdim 165249259Sdim// NEON registers simply specify the overall vector, and it's expected that 166249259Sdim// Instructions will individually specify the acceptable data layout. In 167249259Sdim// principle this leaves two approaches open: 168249259Sdim// + An operand, giving a single ADDvvv instruction (for example). This turns 169249259Sdim// out to be unworkable in the assembly parser (without every Instruction 170249259Sdim// having a "cvt" function, at least) because the constraints can't be 171249259Sdim// properly enforced. It also complicates specifying patterns since each 172249259Sdim// instruction will accept many types. 173249259Sdim// + A bare token (e.g. ".2d"). This means the AsmParser has to know specific 174249259Sdim// details about NEON registers, but simplifies most other details. 175249259Sdim// 176249259Sdim// The second approach was taken. 177249259Sdim 178249259Sdimforeach Index = 0-31 in { 179249259Sdim def V # Index : AArch64RegWithSubs<Index, "v" # Index, 180249259Sdim [!cast<Register>("Q" # Index)], 181249259Sdim [sub_alias]>, 182249259Sdim DwarfRegNum<[!add(Index, 64)]>; 183249259Sdim} 184249259Sdim 185249259Sdim// These two classes contain the same registers, which should be reasonably 186249259Sdim// sensible for MC and allocation purposes, but allows them to be treated 187249259Sdim// separately for things like stack spilling. 188249259Sdimdef VPR64 : RegisterClass<"AArch64", [v2f32, v2i32, v4i16, v8i8], 64, 189249259Sdim (sequence "V%u", 0, 31)>; 190249259Sdim 191249259Sdimdef VPR128 : RegisterClass<"AArch64", 192249259Sdim [v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 128, 193249259Sdim (sequence "V%u", 0, 31)>; 194249259Sdim 195249259Sdim// Flags register 196249259Sdimdef NZCV : Register<"nzcv"> { 197249259Sdim let Namespace = "AArch64"; 198249259Sdim} 199249259Sdim 200249259Sdimdef FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> { 201249259Sdim let CopyCost = -1; 202249259Sdim let isAllocatable = 0; 203249259Sdim} 204