Home | History | Annotate | Download | only in AArch64
      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<128>;
     16 def sub_64 : SubRegIndex<64>;
     17 def sub_32 : SubRegIndex<32>;
     18 def sub_16 : SubRegIndex<16>;
     19 def sub_8  : SubRegIndex<8>;
     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<128>;
     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, v1i64], 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