1 //===-- HexagonRegisterInfo.td - Hexagon Register defs -----*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
11 // Declarations that describe the Hexagon register file.
12 //===----------------------------------------------------------------------===//
14 let Namespace = "Hexagon" in {
16 class HexagonReg<bits<5> num, string n, list<string> alt = [],
17 list<Register> alias = []> : Register<n, alt> {
20 let HWEncoding{4-0} = num;
23 class HexagonDoubleReg<bits<5> num, string n, list<Register> subregs,
24 list<string> alt = []> :
25 RegisterWithSubRegs<n, subregs> {
29 let HWEncoding{4-0} = num;
32 // Registers are identified with 5-bit ID numbers.
33 // Ri - 32-bit integer registers.
34 class Ri<bits<5> num, string n, list<string> alt = []> :
35 HexagonReg<num, n, alt> {
39 // Rf - 32-bit floating-point registers.
40 class Rf<bits<5> num, string n> : HexagonReg<num, n> {
45 // Rd - 64-bit registers.
46 class Rd<bits<5> num, string n, list<Register> subregs,
47 list<string> alt = []> :
48 HexagonDoubleReg<num, n, subregs, alt> {
50 let SubRegs = subregs;
53 // Rp - predicate registers
54 class Rp<bits<5> num, string n> : HexagonReg<num, n> {
59 // Rq - vector predicate registers
60 class Rq<bits<3> num, string n> : Register<n, []> {
61 let HWEncoding{2-0} = num;
64 // Rc - control registers
65 class Rc<bits<5> num, string n,
66 list<string> alt = [], list<Register> alias = []> :
67 HexagonReg<num, n, alt, alias> {
71 // Rcc - 64-bit control registers.
72 class Rcc<bits<5> num, string n, list<Register> subregs,
73 list<string> alt = []> :
74 HexagonDoubleReg<num, n, subregs, alt> {
76 let SubRegs = subregs;
79 // Mx - address modifier registers
80 class Mx<bits<1> num, string n> : HexagonReg<{0b0000, num}, n> {
81 let Num = !cast<bits<5>>(num);
84 def subreg_loreg : SubRegIndex<32>;
85 def subreg_hireg : SubRegIndex<32, 32>;
86 def subreg_overflow : SubRegIndex<1, 0>;
90 def R#i : Ri<i, "r"#i>, DwarfRegNum<[i]>;
93 def R29 : Ri<29, "r29", ["sp"]>, DwarfRegNum<[29]>;
94 def R30 : Ri<30, "r30", ["fp"]>, DwarfRegNum<[30]>;
95 def R31 : Ri<31, "r31", ["lr"]>, DwarfRegNum<[31]>;
97 // Aliases of the R* registers used to hold 64-bit int values (doubles).
98 let SubRegIndices = [subreg_loreg, subreg_hireg], CoveredBySubRegs = 1 in {
99 def D0 : Rd< 0, "r1:0", [R0, R1]>, DwarfRegNum<[32]>;
100 def D1 : Rd< 2, "r3:2", [R2, R3]>, DwarfRegNum<[34]>;
101 def D2 : Rd< 4, "r5:4", [R4, R5]>, DwarfRegNum<[36]>;
102 def D3 : Rd< 6, "r7:6", [R6, R7]>, DwarfRegNum<[38]>;
103 def D4 : Rd< 8, "r9:8", [R8, R9]>, DwarfRegNum<[40]>;
104 def D5 : Rd<10, "r11:10", [R10, R11]>, DwarfRegNum<[42]>;
105 def D6 : Rd<12, "r13:12", [R12, R13]>, DwarfRegNum<[44]>;
106 def D7 : Rd<14, "r15:14", [R14, R15]>, DwarfRegNum<[46]>;
107 def D8 : Rd<16, "r17:16", [R16, R17]>, DwarfRegNum<[48]>;
108 def D9 : Rd<18, "r19:18", [R18, R19]>, DwarfRegNum<[50]>;
109 def D10 : Rd<20, "r21:20", [R20, R21]>, DwarfRegNum<[52]>;
110 def D11 : Rd<22, "r23:22", [R22, R23]>, DwarfRegNum<[54]>;
111 def D12 : Rd<24, "r25:24", [R24, R25]>, DwarfRegNum<[56]>;
112 def D13 : Rd<26, "r27:26", [R26, R27]>, DwarfRegNum<[58]>;
113 def D14 : Rd<28, "r29:28", [R28, R29]>, DwarfRegNum<[60]>;
114 def D15 : Rd<30, "r31:30", [R30, R31], ["lr:fp"]>, DwarfRegNum<[62]>;
117 // Predicate registers.
118 def P0 : Rp<0, "p0">, DwarfRegNum<[63]>;
119 def P1 : Rp<1, "p1">, DwarfRegNum<[64]>;
120 def P2 : Rp<2, "p2">, DwarfRegNum<[65]>;
121 def P3 : Rp<3, "p3">, DwarfRegNum<[66]>;
123 // Modifier registers.
124 // C6 and C7 can also be M0 and M1, but register names must be unique, even
125 // if belonging to different register classes.
126 def M0 : Mx<0, "m0">, DwarfRegNum<[72]>;
127 def M1 : Mx<1, "m1">, DwarfRegNum<[73]>;
129 // Fake register to represent USR.OVF bit. Artihmetic/saturating instruc-
130 // tions modify this bit, and multiple such instructions are allowed in the
131 // same packet. We need to ignore output dependencies on this bit, but not
132 // on the entire USR.
133 def USR_OVF : Rc<?, "usr.ovf">;
135 def USR : Rc<8, "usr", ["c8"]>, DwarfRegNum<[75]> {
136 let SubRegIndices = [subreg_overflow];
137 let SubRegs = [USR_OVF];
140 // Control registers.
141 def SA0 : Rc<0, "sa0", ["c0"]>, DwarfRegNum<[67]>;
142 def LC0 : Rc<1, "lc0", ["c1"]>, DwarfRegNum<[68]>;
143 def SA1 : Rc<2, "sa1", ["c2"]>, DwarfRegNum<[69]>;
144 def LC1 : Rc<3, "lc1", ["c3"]>, DwarfRegNum<[70]>;
145 def P3_0 : Rc<4, "p3:0", ["c4"], [P0, P1, P2, P3]>,
147 def C5 : Rc<5, "c5", ["c5"]>, DwarfRegNum<[72]>; // future use
148 def C6 : Rc<6, "c6", [], [M0]>, DwarfRegNum<[73]>;
149 def C7 : Rc<7, "c7", [], [M1]>, DwarfRegNum<[74]>;
150 // Define C8 separately and make it aliased with USR.
151 // The problem is that USR has subregisters (e.g. overflow). If USR was
152 // specified as a subregister of C9_8, it would imply that subreg_overflow
153 // and subreg_loreg can be composed, which leads to all kinds of issues
155 def C8 : Rc<8, "c8", [], [USR]>, DwarfRegNum<[75]>;
156 def PC : Rc<9, "pc">, DwarfRegNum<[76]>;
157 def UGP : Rc<10, "ugp", ["c10"]>, DwarfRegNum<[77]>;
158 def GP : Rc<11, "gp">, DwarfRegNum<[78]>;
159 def CS0 : Rc<12, "cs0", ["c12"]>, DwarfRegNum<[79]>;
160 def CS1 : Rc<13, "cs1", ["c13"]>, DwarfRegNum<[80]>;
161 def UPCL : Rc<14, "upcyclelo", ["c14"]>, DwarfRegNum<[81]>;
162 def UPCH : Rc<15, "upcyclehi", ["c15"]>, DwarfRegNum<[82]>;
165 // Control registers pairs.
166 let SubRegIndices = [subreg_loreg, subreg_hireg], CoveredBySubRegs = 1 in {
167 def C1_0 : Rcc<0, "c1:0", [SA0, LC0], ["lc0:sa0"]>, DwarfRegNum<[67]>;
168 def C3_2 : Rcc<2, "c3:2", [SA1, LC1], ["lc1:sa1"]>, DwarfRegNum<[69]>;
169 def C7_6 : Rcc<6, "c7:6", [C6, C7], ["m1:0"]>, DwarfRegNum<[72]>;
170 // Use C8 instead of USR as a subregister of C9_8.
171 def C9_8 : Rcc<8, "c9:8", [C8, PC]>, DwarfRegNum<[74]>;
172 def C11_10 : Rcc<10, "c11:10", [UGP, GP]>, DwarfRegNum<[76]>;
173 def CS : Rcc<12, "c13:12", [CS0, CS1], ["cs1:0"]>, DwarfRegNum<[78]>;
174 def UPC : Rcc<14, "c15:14", [UPCL, UPCH]>, DwarfRegNum<[80]>;
177 foreach i = 0-31 in {
178 def V#i : Ri<i, "v"#i>, DwarfRegNum<[!add(i, 99)]>;
181 // Aliases of the V* registers used to hold double vec values.
182 let SubRegIndices = [subreg_loreg, subreg_hireg], CoveredBySubRegs = 1 in {
183 def W0 : Rd< 0, "v1:0", [V0, V1]>, DwarfRegNum<[99]>;
184 def W1 : Rd< 2, "v3:2", [V2, V3]>, DwarfRegNum<[101]>;
185 def W2 : Rd< 4, "v5:4", [V4, V5]>, DwarfRegNum<[103]>;
186 def W3 : Rd< 6, "v7:6", [V6, V7]>, DwarfRegNum<[105]>;
187 def W4 : Rd< 8, "v9:8", [V8, V9]>, DwarfRegNum<[107]>;
188 def W5 : Rd<10, "v11:10", [V10, V11]>, DwarfRegNum<[109]>;
189 def W6 : Rd<12, "v13:12", [V12, V13]>, DwarfRegNum<[111]>;
190 def W7 : Rd<14, "v15:14", [V14, V15]>, DwarfRegNum<[113]>;
191 def W8 : Rd<16, "v17:16", [V16, V17]>, DwarfRegNum<[115]>;
192 def W9 : Rd<18, "v19:18", [V18, V19]>, DwarfRegNum<[117]>;
193 def W10 : Rd<20, "v21:20", [V20, V21]>, DwarfRegNum<[119]>;
194 def W11 : Rd<22, "v23:22", [V22, V23]>, DwarfRegNum<[121]>;
195 def W12 : Rd<24, "v25:24", [V24, V25]>, DwarfRegNum<[123]>;
196 def W13 : Rd<26, "v27:26", [V26, V27]>, DwarfRegNum<[125]>;
197 def W14 : Rd<28, "v29:28", [V28, V29]>, DwarfRegNum<[127]>;
198 def W15 : Rd<30, "v31:30", [V30, V31]>, DwarfRegNum<[129]>;
201 // Vector Predicate registers.
202 def Q0 : Rq<0, "q0">, DwarfRegNum<[131]>;
203 def Q1 : Rq<1, "q1">, DwarfRegNum<[132]>;
204 def Q2 : Rq<2, "q2">, DwarfRegNum<[133]>;
205 def Q3 : Rq<3, "q3">, DwarfRegNum<[134]>;
209 // FIXME: the register order should be defined in terms of the preferred
210 // allocation order...
212 def IntRegs : RegisterClass<"Hexagon", [i32, f32, v4i8, v2i16], 32,
213 (add (sequence "R%u", 0, 9),
214 (sequence "R%u", 12, 28),
215 R10, R11, R29, R30, R31)> {
218 // Registers are listed in reverse order for allocation preference reasons.
219 def IntRegsLow8 : RegisterClass<"Hexagon", [i32], 32,
220 (add R7, R6, R5, R4, R3, R2, R1, R0)> ;
222 def DoubleRegs : RegisterClass<"Hexagon", [i64, f64, v8i8, v4i16, v2i32], 64,
223 (add (sequence "D%u", 0, 4),
224 (sequence "D%u", 6, 13), D5, D14, D15)>;
226 def VectorRegs : RegisterClass<"Hexagon", [v64i8, v32i16, v16i32, v8i64], 512,
227 (add (sequence "V%u", 0, 31))>;
229 def VecDblRegs : RegisterClass<"Hexagon",
230 [v128i8, v64i16, v32i32, v16i64], 1024,
231 (add (sequence "W%u", 0, 15))>;
233 def VectorRegs128B : RegisterClass<"Hexagon",
234 [v128i8, v64i16, v32i32, v16i64], 1024,
235 (add (sequence "V%u", 0, 31))>;
237 def VecDblRegs128B : RegisterClass<"Hexagon",
238 [v256i8,v128i16,v64i32,v32i64], 2048,
239 (add (sequence "W%u", 0, 15))>;
241 def VecPredRegs : RegisterClass<"Hexagon", [v512i1], 512,
242 (add (sequence "Q%u", 0, 3))>;
244 def VecPredRegs128B : RegisterClass<"Hexagon", [v1024i1], 1024,
245 (add (sequence "Q%u", 0, 3))>;
247 def PredRegs : RegisterClass<"Hexagon",
248 [i1, v2i1, v4i1, v8i1, v4i8, v2i16, i32], 32,
249 (add (sequence "P%u", 0, 3))>
255 def ModRegs : RegisterClass<"Hexagon", [i32], 32, (add M0, M1)>;
257 let Size = 32, isAllocatable = 0 in
258 def CtrRegs : RegisterClass<"Hexagon", [i32], 32,
259 (add LC0, SA0, LC1, SA1,
261 M0, M1, C6, C7, CS0, CS1, UPCL, UPCH,
262 USR, USR_OVF, UGP, GP, PC)>;
264 let Size = 64, isAllocatable = 0 in
265 def CtrRegs64 : RegisterClass<"Hexagon", [i64], 64,
266 (add C1_0, C3_2, C7_6, C9_8, C11_10, CS, UPC)>;
269 list<Register> Regs = [D0, D1, D2, D3, D4, D5, D6, D7,
273 LC0, LC1, SA0, SA1, USR, USR_OVF, CS0, CS1,
274 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11,
275 V12, V13, V14, V15, V16, V17, V18, V19, V20, V21,
276 V22, V23, V24, V25, V26, V27, V28, V29, V30, V31,
277 W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11,
282 def PositiveHalfWord : PatLeaf<(i32 IntRegs:$a),
284 return isPositiveHalfWord(N);