1//===- subzero/src/IceRegistersARM32.h - Register information ---*- C++ -*-===//
2//
3//                        The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Declares the registers and their encodings for ARM32.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef SUBZERO_SRC_ICEREGISTERSARM32_H
16#define SUBZERO_SRC_ICEREGISTERSARM32_H
17
18#include "IceDefs.h"
19#include "IceInstARM32.def"
20#include "IceOperand.h" // RC_Target
21#include "IceTypes.h"
22
23namespace Ice {
24namespace ARM32 {
25namespace RegARM32 {
26
27/// An enum of every register. The enum value may not match the encoding used
28/// to binary encode register operands in instructions.
29enum AllRegisters {
30#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
31          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
32  val,
33  REGARM32_TABLE
34#undef X
35      Reg_NUM,
36#define X(val, init) val init,
37  REGARM32_TABLE_BOUNDS
38#undef X
39};
40
41/// An enum of GPR Registers. The enum value does match the encoding used to
42/// binary encode register operands in instructions.
43enum GPRRegister {
44#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
45          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
46  Encoded_##val = encode,
47  REGARM32_GPR_TABLE
48#undef X
49      Encoded_Not_GPR = -1
50};
51
52/// An enum of FP32 S-Registers. The enum value does match the encoding used
53/// to binary encode register operands in instructions.
54enum SRegister {
55#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
56          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
57  Encoded_##val = encode,
58  REGARM32_FP32_TABLE
59#undef X
60      Encoded_Not_SReg = -1
61};
62
63/// An enum of FP64 D-Registers. The enum value does match the encoding used
64/// to binary encode register operands in instructions.
65enum DRegister {
66#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
67          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
68  Encoded_##val = encode,
69  REGARM32_FP64_TABLE
70#undef X
71      Encoded_Not_DReg = -1
72};
73
74/// An enum of 128-bit Q-Registers. The enum value does match the encoding
75/// used to binary encode register operands in instructions.
76enum QRegister {
77#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
78          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
79  Encoded_##val = encode,
80  REGARM32_VEC128_TABLE
81#undef X
82      Encoded_Not_QReg = -1
83};
84
85extern struct RegTableType {
86  const char *Name;
87  unsigned Encoding : 10;
88  unsigned CCArg : 6;
89  unsigned Scratch : 1;
90  unsigned Preserved : 1;
91  unsigned StackPtr : 1;
92  unsigned FramePtr : 1;
93  unsigned IsGPR : 1;
94  unsigned IsInt : 1;
95  unsigned IsI64Pair : 1;
96  unsigned IsFP32 : 1;
97  unsigned IsFP64 : 1;
98  unsigned IsVec128 : 1;
99#define NUM_ALIASES_BITS 3
100  SizeT NumAliases : (NUM_ALIASES_BITS + 1);
101  uint16_t Aliases[1 << NUM_ALIASES_BITS];
102#undef NUM_ALIASES_BITS
103} RegTable[Reg_NUM];
104
105static inline void assertValidRegNum(RegNumT RegNum) {
106  (void)RegNum;
107  assert(RegNum.hasValue());
108}
109
110static inline bool isGPRegister(RegNumT RegNum) {
111  RegNum.assertIsValid();
112  return RegTable[RegNum].IsGPR;
113}
114
115static constexpr inline SizeT getNumGPRegs() {
116  return 0
117#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
118          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
119  +(isGPR)
120      REGARM32_TABLE
121#undef X
122      ;
123}
124
125static inline GPRRegister getEncodedGPR(RegNumT RegNum) {
126  RegNum.assertIsValid();
127  return GPRRegister(RegTable[RegNum].Encoding);
128}
129
130static constexpr inline SizeT getNumGPRs() {
131  return 0
132#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
133          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
134  +(isGPR)
135      REGARM32_TABLE
136#undef X
137      ;
138}
139
140static inline bool isGPR(RegNumT RegNum) {
141  RegNum.assertIsValid();
142  return RegTable[RegNum].IsGPR;
143}
144
145static inline GPRRegister getI64PairFirstGPRNum(RegNumT RegNum) {
146  RegNum.assertIsValid();
147  return GPRRegister(RegTable[RegNum].Encoding);
148}
149
150static inline GPRRegister getI64PairSecondGPRNum(RegNumT RegNum) {
151  RegNum.assertIsValid();
152  return GPRRegister(RegTable[RegNum].Encoding + 1);
153}
154
155static inline bool isI64RegisterPair(RegNumT RegNum) {
156  RegNum.assertIsValid();
157  return RegTable[RegNum].IsI64Pair;
158}
159
160static inline bool isEncodedSReg(RegNumT RegNum) {
161  RegNum.assertIsValid();
162  return RegTable[RegNum].IsFP32;
163}
164
165static constexpr inline SizeT getNumSRegs() {
166  return 0
167#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
168          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
169  +(isFP32)
170      REGARM32_TABLE
171#undef X
172      ;
173}
174
175static inline SRegister getEncodedSReg(RegNumT RegNum) {
176  RegNum.assertIsValid();
177  return SRegister(RegTable[RegNum].Encoding);
178}
179
180static inline bool isEncodedDReg(RegNumT RegNum) {
181  RegNum.assertIsValid();
182  return RegTable[RegNum].IsFP64;
183}
184
185static constexpr inline SizeT getNumDRegs() {
186  return 0
187#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,   \
188          isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)       \
189  +(isFP64)
190      REGARM32_TABLE
191#undef X
192      ;
193}
194
195static inline DRegister getEncodedDReg(RegNumT RegNum) {
196  RegNum.assertIsValid();
197  return DRegister(RegTable[RegNum].Encoding);
198}
199
200static inline bool isEncodedQReg(RegNumT RegNum) {
201  RegNum.assertIsValid();
202  return RegTable[RegNum].IsVec128;
203}
204
205static inline QRegister getEncodedQReg(RegNumT RegNum) {
206  assert(isEncodedQReg(RegNum));
207  return QRegister(RegTable[RegNum].Encoding);
208}
209
210static inline const char *getRegName(RegNumT RegNum) {
211  RegNum.assertIsValid();
212  return RegTable[RegNum].Name;
213}
214
215// Extend enum RegClass with ARM32-specific register classes.
216enum RegClassARM32 : uint8_t {
217  RCARM32_QtoS = RC_Target, // Denotes Q registers that are aliased by S
218                            // registers.
219  RCARM32_NUM
220};
221
222} // end of namespace RegARM32
223} // end of namespace ARM32
224} // end of namespace Ice
225
226#endif // SUBZERO_SRC_ICEREGISTERSARM32_H
227