xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceRegistersX8632.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceRegistersX8632.h - Register information ---*- C++ -*-===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Declares the registers and their encodings for x86-32.
12*03ce13f7SAndroid Build Coastguard Worker ///
13*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICEREGISTERSX8632_H
16*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICEREGISTERSX8632_H
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "IceBitVector.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceInstX8632.def"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLoweringX86RegClass.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h"
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker #include <initializer_list>
26*03ce13f7SAndroid Build Coastguard Worker 
27*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
28*03ce13f7SAndroid Build Coastguard Worker using namespace ::Ice::X86;
29*03ce13f7SAndroid Build Coastguard Worker 
30*03ce13f7SAndroid Build Coastguard Worker class RegX8632 {
31*03ce13f7SAndroid Build Coastguard Worker public:
32*03ce13f7SAndroid Build Coastguard Worker   /// An enum of every register. The enum value may not match the encoding used
33*03ce13f7SAndroid Build Coastguard Worker   /// to binary encode register operands in instructions.
34*03ce13f7SAndroid Build Coastguard Worker   enum AllRegisters {
35*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
36*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
37*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
38*03ce13f7SAndroid Build Coastguard Worker   val,
39*03ce13f7SAndroid Build Coastguard Worker     REGX8632_TABLE
40*03ce13f7SAndroid Build Coastguard Worker #undef X
41*03ce13f7SAndroid Build Coastguard Worker         Reg_NUM
42*03ce13f7SAndroid Build Coastguard Worker   };
43*03ce13f7SAndroid Build Coastguard Worker 
44*03ce13f7SAndroid Build Coastguard Worker   /// An enum of GPR Registers. The enum value does match the encoding used to
45*03ce13f7SAndroid Build Coastguard Worker   /// binary encode register operands in instructions.
46*03ce13f7SAndroid Build Coastguard Worker   enum GPRRegister {
47*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
48*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
49*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
50*03ce13f7SAndroid Build Coastguard Worker   Encoded_##val = encode,
51*03ce13f7SAndroid Build Coastguard Worker     REGX8632_GPR_TABLE
52*03ce13f7SAndroid Build Coastguard Worker #undef X
53*03ce13f7SAndroid Build Coastguard Worker         Encoded_Not_GPR = -1
54*03ce13f7SAndroid Build Coastguard Worker   };
55*03ce13f7SAndroid Build Coastguard Worker 
56*03ce13f7SAndroid Build Coastguard Worker   /// An enum of XMM Registers. The enum value does match the encoding used to
57*03ce13f7SAndroid Build Coastguard Worker   /// binary encode register operands in instructions.
58*03ce13f7SAndroid Build Coastguard Worker   enum XmmRegister {
59*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
60*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
61*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
62*03ce13f7SAndroid Build Coastguard Worker   Encoded_##val = encode,
63*03ce13f7SAndroid Build Coastguard Worker     REGX8632_XMM_TABLE
64*03ce13f7SAndroid Build Coastguard Worker #undef X
65*03ce13f7SAndroid Build Coastguard Worker         Encoded_Not_Xmm = -1
66*03ce13f7SAndroid Build Coastguard Worker   };
67*03ce13f7SAndroid Build Coastguard Worker 
68*03ce13f7SAndroid Build Coastguard Worker   /// An enum of Byte Registers. The enum value does match the encoding used to
69*03ce13f7SAndroid Build Coastguard Worker   /// binary encode register operands in instructions.
70*03ce13f7SAndroid Build Coastguard Worker   enum ByteRegister {
71*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
72*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
73*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
74*03ce13f7SAndroid Build Coastguard Worker   Encoded_8_##val = encode,
75*03ce13f7SAndroid Build Coastguard Worker     REGX8632_BYTEREG_TABLE
76*03ce13f7SAndroid Build Coastguard Worker #undef X
77*03ce13f7SAndroid Build Coastguard Worker         Encoded_Not_ByteReg = -1
78*03ce13f7SAndroid Build Coastguard Worker   };
79*03ce13f7SAndroid Build Coastguard Worker 
80*03ce13f7SAndroid Build Coastguard Worker   /// An enum of X87 Stack Registers. The enum value does match the encoding
81*03ce13f7SAndroid Build Coastguard Worker   /// used to binary encode register operands in instructions.
82*03ce13f7SAndroid Build Coastguard Worker   enum X87STRegister {
83*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name) Encoded_##val = encode,
84*03ce13f7SAndroid Build Coastguard Worker     X87ST_REGX8632_TABLE
85*03ce13f7SAndroid Build Coastguard Worker #undef X
86*03ce13f7SAndroid Build Coastguard Worker         Encoded_Not_X87STReg = -1
87*03ce13f7SAndroid Build Coastguard Worker   };
88*03ce13f7SAndroid Build Coastguard Worker 
getEncodedSTReg(uint32_t X87RegNum)89*03ce13f7SAndroid Build Coastguard Worker   static inline X87STRegister getEncodedSTReg(uint32_t X87RegNum) {
90*03ce13f7SAndroid Build Coastguard Worker     assert(int(Encoded_X87ST_First) <= int(X87RegNum));
91*03ce13f7SAndroid Build Coastguard Worker     assert(X87RegNum <= Encoded_X87ST_Last);
92*03ce13f7SAndroid Build Coastguard Worker     return X87STRegister(X87RegNum);
93*03ce13f7SAndroid Build Coastguard Worker   }
94*03ce13f7SAndroid Build Coastguard Worker 
getRegName(RegNumT RegNum)95*03ce13f7SAndroid Build Coastguard Worker   static inline const char *getRegName(RegNumT RegNum) {
96*03ce13f7SAndroid Build Coastguard Worker     static const char *const RegNames[Reg_NUM] = {
97*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
98*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
99*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
100*03ce13f7SAndroid Build Coastguard Worker   name,
101*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
102*03ce13f7SAndroid Build Coastguard Worker #undef X
103*03ce13f7SAndroid Build Coastguard Worker     };
104*03ce13f7SAndroid Build Coastguard Worker     RegNum.assertIsValid();
105*03ce13f7SAndroid Build Coastguard Worker     return RegNames[RegNum];
106*03ce13f7SAndroid Build Coastguard Worker   }
107*03ce13f7SAndroid Build Coastguard Worker 
getEncodedGPR(RegNumT RegNum)108*03ce13f7SAndroid Build Coastguard Worker   static inline GPRRegister getEncodedGPR(RegNumT RegNum) {
109*03ce13f7SAndroid Build Coastguard Worker     static const GPRRegister GPRRegs[Reg_NUM] = {
110*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
111*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
112*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
113*03ce13f7SAndroid Build Coastguard Worker   GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR),
114*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
115*03ce13f7SAndroid Build Coastguard Worker #undef X
116*03ce13f7SAndroid Build Coastguard Worker     };
117*03ce13f7SAndroid Build Coastguard Worker     RegNum.assertIsValid();
118*03ce13f7SAndroid Build Coastguard Worker     assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR);
119*03ce13f7SAndroid Build Coastguard Worker     return GPRRegs[RegNum];
120*03ce13f7SAndroid Build Coastguard Worker   }
121*03ce13f7SAndroid Build Coastguard Worker 
getEncodedByteReg(RegNumT RegNum)122*03ce13f7SAndroid Build Coastguard Worker   static inline ByteRegister getEncodedByteReg(RegNumT RegNum) {
123*03ce13f7SAndroid Build Coastguard Worker     static const ByteRegister ByteRegs[Reg_NUM] = {
124*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
125*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
126*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
127*03ce13f7SAndroid Build Coastguard Worker   ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg),
128*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
129*03ce13f7SAndroid Build Coastguard Worker #undef X
130*03ce13f7SAndroid Build Coastguard Worker     };
131*03ce13f7SAndroid Build Coastguard Worker     RegNum.assertIsValid();
132*03ce13f7SAndroid Build Coastguard Worker     assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg);
133*03ce13f7SAndroid Build Coastguard Worker     return ByteRegs[RegNum];
134*03ce13f7SAndroid Build Coastguard Worker   }
135*03ce13f7SAndroid Build Coastguard Worker 
isXmm(RegNumT RegNum)136*03ce13f7SAndroid Build Coastguard Worker   static inline bool isXmm(RegNumT RegNum) {
137*03ce13f7SAndroid Build Coastguard Worker     static const bool IsXmm[Reg_NUM] = {
138*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
139*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
140*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
141*03ce13f7SAndroid Build Coastguard Worker   isXmm,
142*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
143*03ce13f7SAndroid Build Coastguard Worker #undef X
144*03ce13f7SAndroid Build Coastguard Worker     };
145*03ce13f7SAndroid Build Coastguard Worker     return IsXmm[RegNum];
146*03ce13f7SAndroid Build Coastguard Worker   }
147*03ce13f7SAndroid Build Coastguard Worker 
getEncodedXmm(RegNumT RegNum)148*03ce13f7SAndroid Build Coastguard Worker   static inline XmmRegister getEncodedXmm(RegNumT RegNum) {
149*03ce13f7SAndroid Build Coastguard Worker     static const XmmRegister XmmRegs[Reg_NUM] = {
150*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
151*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
152*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
153*03ce13f7SAndroid Build Coastguard Worker   XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm),
154*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
155*03ce13f7SAndroid Build Coastguard Worker #undef X
156*03ce13f7SAndroid Build Coastguard Worker     };
157*03ce13f7SAndroid Build Coastguard Worker     RegNum.assertIsValid();
158*03ce13f7SAndroid Build Coastguard Worker     assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm);
159*03ce13f7SAndroid Build Coastguard Worker     return XmmRegs[RegNum];
160*03ce13f7SAndroid Build Coastguard Worker   }
161*03ce13f7SAndroid Build Coastguard Worker 
getEncoding(RegNumT RegNum)162*03ce13f7SAndroid Build Coastguard Worker   static inline uint32_t getEncoding(RegNumT RegNum) {
163*03ce13f7SAndroid Build Coastguard Worker     static const uint32_t Encoding[Reg_NUM] = {
164*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
165*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
166*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
167*03ce13f7SAndroid Build Coastguard Worker   encode,
168*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
169*03ce13f7SAndroid Build Coastguard Worker #undef X
170*03ce13f7SAndroid Build Coastguard Worker     };
171*03ce13f7SAndroid Build Coastguard Worker     RegNum.assertIsValid();
172*03ce13f7SAndroid Build Coastguard Worker     return Encoding[RegNum];
173*03ce13f7SAndroid Build Coastguard Worker   }
174*03ce13f7SAndroid Build Coastguard Worker 
getBaseReg(RegNumT RegNum)175*03ce13f7SAndroid Build Coastguard Worker   static inline RegNumT getBaseReg(RegNumT RegNum) {
176*03ce13f7SAndroid Build Coastguard Worker     static const RegNumT BaseRegs[Reg_NUM] = {
177*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
178*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
179*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
180*03ce13f7SAndroid Build Coastguard Worker   base,
181*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
182*03ce13f7SAndroid Build Coastguard Worker #undef X
183*03ce13f7SAndroid Build Coastguard Worker     };
184*03ce13f7SAndroid Build Coastguard Worker     RegNum.assertIsValid();
185*03ce13f7SAndroid Build Coastguard Worker     return BaseRegs[RegNum];
186*03ce13f7SAndroid Build Coastguard Worker   }
187*03ce13f7SAndroid Build Coastguard Worker 
188*03ce13f7SAndroid Build Coastguard Worker private:
getFirstGprForType(Type Ty)189*03ce13f7SAndroid Build Coastguard Worker   static inline AllRegisters getFirstGprForType(Type Ty) {
190*03ce13f7SAndroid Build Coastguard Worker     switch (Ty) {
191*03ce13f7SAndroid Build Coastguard Worker     default:
192*03ce13f7SAndroid Build Coastguard Worker       llvm_unreachable("Invalid type for GPR.");
193*03ce13f7SAndroid Build Coastguard Worker     case IceType_i1:
194*03ce13f7SAndroid Build Coastguard Worker     case IceType_i8:
195*03ce13f7SAndroid Build Coastguard Worker       return Reg_al;
196*03ce13f7SAndroid Build Coastguard Worker     case IceType_i16:
197*03ce13f7SAndroid Build Coastguard Worker       return Reg_ax;
198*03ce13f7SAndroid Build Coastguard Worker     case IceType_i32:
199*03ce13f7SAndroid Build Coastguard Worker       return Reg_eax;
200*03ce13f7SAndroid Build Coastguard Worker     }
201*03ce13f7SAndroid Build Coastguard Worker   }
202*03ce13f7SAndroid Build Coastguard Worker 
203*03ce13f7SAndroid Build Coastguard Worker public:
204*03ce13f7SAndroid Build Coastguard Worker   // Return a register in RegNum's alias set that is suitable for Ty.
getGprForType(Type Ty,RegNumT RegNum)205*03ce13f7SAndroid Build Coastguard Worker   static inline RegNumT getGprForType(Type Ty, RegNumT RegNum) {
206*03ce13f7SAndroid Build Coastguard Worker     assert(RegNum.hasValue());
207*03ce13f7SAndroid Build Coastguard Worker 
208*03ce13f7SAndroid Build Coastguard Worker     if (!isScalarIntegerType(Ty)) {
209*03ce13f7SAndroid Build Coastguard Worker       return RegNum;
210*03ce13f7SAndroid Build Coastguard Worker     }
211*03ce13f7SAndroid Build Coastguard Worker 
212*03ce13f7SAndroid Build Coastguard Worker     // [abcd]h registers are not convertible to their ?l, ?x, and e?x versions.
213*03ce13f7SAndroid Build Coastguard Worker     switch (RegNum) {
214*03ce13f7SAndroid Build Coastguard Worker     default:
215*03ce13f7SAndroid Build Coastguard Worker       break;
216*03ce13f7SAndroid Build Coastguard Worker     case Reg_ah:
217*03ce13f7SAndroid Build Coastguard Worker     case Reg_bh:
218*03ce13f7SAndroid Build Coastguard Worker     case Reg_ch:
219*03ce13f7SAndroid Build Coastguard Worker     case Reg_dh:
220*03ce13f7SAndroid Build Coastguard Worker       assert(isByteSizedType(Ty));
221*03ce13f7SAndroid Build Coastguard Worker       return RegNum;
222*03ce13f7SAndroid Build Coastguard Worker     }
223*03ce13f7SAndroid Build Coastguard Worker 
224*03ce13f7SAndroid Build Coastguard Worker     const AllRegisters FirstGprForType = getFirstGprForType(Ty);
225*03ce13f7SAndroid Build Coastguard Worker 
226*03ce13f7SAndroid Build Coastguard Worker     switch (RegNum) {
227*03ce13f7SAndroid Build Coastguard Worker     default:
228*03ce13f7SAndroid Build Coastguard Worker       llvm::report_fatal_error("Unknown register.");
229*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
230*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
231*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
232*03ce13f7SAndroid Build Coastguard Worker   case val: {                                                                  \
233*03ce13f7SAndroid Build Coastguard Worker     if (!isGPR)                                                                \
234*03ce13f7SAndroid Build Coastguard Worker       return val;                                                              \
235*03ce13f7SAndroid Build Coastguard Worker     assert((is32) || (is16) || (is8) || getBaseReg(val) == Reg_esp);           \
236*03ce13f7SAndroid Build Coastguard Worker     constexpr AllRegisters FirstGprWithRegNumSize =                            \
237*03ce13f7SAndroid Build Coastguard Worker         (((is32) || val == Reg_esp)                                            \
238*03ce13f7SAndroid Build Coastguard Worker              ? Reg_eax                                                         \
239*03ce13f7SAndroid Build Coastguard Worker              : (((is16) || val == Reg_sp) ? Reg_ax : Reg_al));                 \
240*03ce13f7SAndroid Build Coastguard Worker     const RegNumT NewRegNum =                                                  \
241*03ce13f7SAndroid Build Coastguard Worker         RegNumT::fixme(RegNum - FirstGprWithRegNumSize + FirstGprForType);     \
242*03ce13f7SAndroid Build Coastguard Worker     assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) &&                      \
243*03ce13f7SAndroid Build Coastguard Worker            "Error involving " #val);                                           \
244*03ce13f7SAndroid Build Coastguard Worker     return NewRegNum;                                                          \
245*03ce13f7SAndroid Build Coastguard Worker   }
246*03ce13f7SAndroid Build Coastguard Worker       REGX8632_TABLE
247*03ce13f7SAndroid Build Coastguard Worker #undef X
248*03ce13f7SAndroid Build Coastguard Worker     }
249*03ce13f7SAndroid Build Coastguard Worker   }
250*03ce13f7SAndroid Build Coastguard Worker 
251*03ce13f7SAndroid Build Coastguard Worker public:
252*03ce13f7SAndroid Build Coastguard Worker   static inline void
initRegisterSet(const::Ice::ClFlags &,std::array<SmallBitVector,RCX86_NUM> * TypeToRegisterSet,std::array<SmallBitVector,Reg_NUM> * RegisterAliases)253*03ce13f7SAndroid Build Coastguard Worker   initRegisterSet(const ::Ice::ClFlags & /*Flags*/,
254*03ce13f7SAndroid Build Coastguard Worker                   std::array<SmallBitVector, RCX86_NUM> *TypeToRegisterSet,
255*03ce13f7SAndroid Build Coastguard Worker                   std::array<SmallBitVector, Reg_NUM> *RegisterAliases) {
256*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector IntegerRegistersI32(Reg_NUM);
257*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector IntegerRegistersI16(Reg_NUM);
258*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector IntegerRegistersI8(Reg_NUM);
259*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector FloatRegisters(Reg_NUM);
260*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector VectorRegisters(Reg_NUM);
261*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector Trunc64To8Registers(Reg_NUM);
262*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector Trunc32To8Registers(Reg_NUM);
263*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector Trunc16To8Registers(Reg_NUM);
264*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector Trunc8RcvrRegisters(Reg_NUM);
265*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector AhRcvrRegisters(Reg_NUM);
266*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector InvalidRegisters(Reg_NUM);
267*03ce13f7SAndroid Build Coastguard Worker 
268*03ce13f7SAndroid Build Coastguard Worker     static constexpr struct {
269*03ce13f7SAndroid Build Coastguard Worker       uint16_t Val;
270*03ce13f7SAndroid Build Coastguard Worker       unsigned Is64 : 1;
271*03ce13f7SAndroid Build Coastguard Worker       unsigned Is32 : 1;
272*03ce13f7SAndroid Build Coastguard Worker       unsigned Is16 : 1;
273*03ce13f7SAndroid Build Coastguard Worker       unsigned Is8 : 1;
274*03ce13f7SAndroid Build Coastguard Worker       unsigned IsXmm : 1;
275*03ce13f7SAndroid Build Coastguard Worker       unsigned Is64To8 : 1;
276*03ce13f7SAndroid Build Coastguard Worker       unsigned Is32To8 : 1;
277*03ce13f7SAndroid Build Coastguard Worker       unsigned Is16To8 : 1;
278*03ce13f7SAndroid Build Coastguard Worker       unsigned IsTrunc8Rcvr : 1;
279*03ce13f7SAndroid Build Coastguard Worker       unsigned IsAhRcvr : 1;
280*03ce13f7SAndroid Build Coastguard Worker #define NUM_ALIASES_BITS 2
281*03ce13f7SAndroid Build Coastguard Worker       SizeT NumAliases : (NUM_ALIASES_BITS + 1);
282*03ce13f7SAndroid Build Coastguard Worker       uint16_t Aliases[1 << NUM_ALIASES_BITS];
283*03ce13f7SAndroid Build Coastguard Worker #undef NUM_ALIASES_BITS
284*03ce13f7SAndroid Build Coastguard Worker     } X8632RegTable[Reg_NUM] = {
285*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,      \
286*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,       \
287*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                      \
288*03ce13f7SAndroid Build Coastguard Worker   {                                                                             \
289*03ce13f7SAndroid Build Coastguard Worker       val,          is64,     is32,                                             \
290*03ce13f7SAndroid Build Coastguard Worker       is16,         is8,      isXmm,                                            \
291*03ce13f7SAndroid Build Coastguard Worker       is64To8,      is32To8,  is16To8,                                          \
292*03ce13f7SAndroid Build Coastguard Worker       isTrunc8Rcvr, isAhRcvr, (std::initializer_list<uint16_t> aliases).size(), \
293*03ce13f7SAndroid Build Coastguard Worker       aliases,                                                                  \
294*03ce13f7SAndroid Build Coastguard Worker   },
295*03ce13f7SAndroid Build Coastguard Worker         REGX8632_TABLE
296*03ce13f7SAndroid Build Coastguard Worker #undef X
297*03ce13f7SAndroid Build Coastguard Worker     };
298*03ce13f7SAndroid Build Coastguard Worker 
299*03ce13f7SAndroid Build Coastguard Worker     for (SizeT ii = 0; ii < llvm::array_lengthof(X8632RegTable); ++ii) {
300*03ce13f7SAndroid Build Coastguard Worker       const auto &Entry = X8632RegTable[ii];
301*03ce13f7SAndroid Build Coastguard Worker       (IntegerRegistersI32)[Entry.Val] = Entry.Is32;
302*03ce13f7SAndroid Build Coastguard Worker       (IntegerRegistersI16)[Entry.Val] = Entry.Is16;
303*03ce13f7SAndroid Build Coastguard Worker       (IntegerRegistersI8)[Entry.Val] = Entry.Is8;
304*03ce13f7SAndroid Build Coastguard Worker       (FloatRegisters)[Entry.Val] = Entry.IsXmm;
305*03ce13f7SAndroid Build Coastguard Worker       (VectorRegisters)[Entry.Val] = Entry.IsXmm;
306*03ce13f7SAndroid Build Coastguard Worker       (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8;
307*03ce13f7SAndroid Build Coastguard Worker       (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8;
308*03ce13f7SAndroid Build Coastguard Worker       (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8;
309*03ce13f7SAndroid Build Coastguard Worker       (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr;
310*03ce13f7SAndroid Build Coastguard Worker       (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr;
311*03ce13f7SAndroid Build Coastguard Worker       (*RegisterAliases)[Entry.Val].resize(Reg_NUM);
312*03ce13f7SAndroid Build Coastguard Worker       for (SizeT J = 0; J < Entry.NumAliases; J++) {
313*03ce13f7SAndroid Build Coastguard Worker         SizeT Alias = Entry.Aliases[J];
314*03ce13f7SAndroid Build Coastguard Worker         assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias");
315*03ce13f7SAndroid Build Coastguard Worker         (*RegisterAliases)[Entry.Val].set(Alias);
316*03ce13f7SAndroid Build Coastguard Worker       }
317*03ce13f7SAndroid Build Coastguard Worker       (*RegisterAliases)[Entry.Val].set(Entry.Val);
318*03ce13f7SAndroid Build Coastguard Worker     }
319*03ce13f7SAndroid Build Coastguard Worker 
320*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_void] = InvalidRegisters;
321*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8;
322*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8;
323*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16;
324*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32;
325*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_i64] = InvalidRegisters;
326*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_f32] = FloatRegisters;
327*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_f64] = FloatRegisters;
328*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters;
329*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_v8i1] = VectorRegisters;
330*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_v16i1] = VectorRegisters;
331*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_v16i8] = VectorRegisters;
332*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_v8i16] = VectorRegisters;
333*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_v4i32] = VectorRegisters;
334*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RC_v4f32] = VectorRegisters;
335*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RCX86_Is64To8] = Trunc64To8Registers;
336*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RCX86_Is32To8] = Trunc32To8Registers;
337*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RCX86_Is16To8] = Trunc16To8Registers;
338*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RCX86_IsTrunc8Rcvr] = Trunc8RcvrRegisters;
339*03ce13f7SAndroid Build Coastguard Worker     (*TypeToRegisterSet)[RCX86_IsAhRcvr] = AhRcvrRegisters;
340*03ce13f7SAndroid Build Coastguard Worker   }
341*03ce13f7SAndroid Build Coastguard Worker 
342*03ce13f7SAndroid Build Coastguard Worker   static inline SmallBitVector
getRegisterSet(const::Ice::ClFlags &,TargetLowering::RegSetMask Include,TargetLowering::RegSetMask Exclude)343*03ce13f7SAndroid Build Coastguard Worker   getRegisterSet(const ::Ice::ClFlags & /*Flags*/,
344*03ce13f7SAndroid Build Coastguard Worker                  TargetLowering::RegSetMask Include,
345*03ce13f7SAndroid Build Coastguard Worker                  TargetLowering::RegSetMask Exclude) {
346*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector Registers(Reg_NUM);
347*03ce13f7SAndroid Build Coastguard Worker 
348*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,     \
349*03ce13f7SAndroid Build Coastguard Worker           isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,      \
350*03ce13f7SAndroid Build Coastguard Worker           isTrunc8Rcvr, isAhRcvr, aliases)                                     \
351*03ce13f7SAndroid Build Coastguard Worker   if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave))         \
352*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = true;                                                     \
353*03ce13f7SAndroid Build Coastguard Worker   if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave))       \
354*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = true;                                                     \
355*03ce13f7SAndroid Build Coastguard Worker   if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer))      \
356*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = true;                                                     \
357*03ce13f7SAndroid Build Coastguard Worker   if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer))      \
358*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = true;                                                     \
359*03ce13f7SAndroid Build Coastguard Worker   if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave))         \
360*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = false;                                                    \
361*03ce13f7SAndroid Build Coastguard Worker   if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave))       \
362*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = false;                                                    \
363*03ce13f7SAndroid Build Coastguard Worker   if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer))      \
364*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = false;                                                    \
365*03ce13f7SAndroid Build Coastguard Worker   if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer))      \
366*03ce13f7SAndroid Build Coastguard Worker     Registers[val] = false;
367*03ce13f7SAndroid Build Coastguard Worker 
368*03ce13f7SAndroid Build Coastguard Worker     REGX8632_TABLE
369*03ce13f7SAndroid Build Coastguard Worker 
370*03ce13f7SAndroid Build Coastguard Worker #undef X
371*03ce13f7SAndroid Build Coastguard Worker 
372*03ce13f7SAndroid Build Coastguard Worker     return Registers;
373*03ce13f7SAndroid Build Coastguard Worker   }
374*03ce13f7SAndroid Build Coastguard Worker 
375*03ce13f7SAndroid Build Coastguard Worker   // x86-32 calling convention:
376*03ce13f7SAndroid Build Coastguard Worker   //
377*03ce13f7SAndroid Build Coastguard Worker   // * The first four arguments of vector type, regardless of their position
378*03ce13f7SAndroid Build Coastguard Worker   // relative to the other arguments in the argument list, are placed in
379*03ce13f7SAndroid Build Coastguard Worker   // registers xmm0 - xmm3.
380*03ce13f7SAndroid Build Coastguard Worker   //
381*03ce13f7SAndroid Build Coastguard Worker   // This intends to match the section "IA-32 Function Calling Convention" of
382*03ce13f7SAndroid Build Coastguard Worker   // the document "OS X ABI Function Call Guide" by Apple.
383*03ce13f7SAndroid Build Coastguard Worker 
384*03ce13f7SAndroid Build Coastguard Worker   /// The maximum number of arguments to pass in XMM registers
385*03ce13f7SAndroid Build Coastguard Worker   static constexpr uint32_t X86_MAX_XMM_ARGS = 4;
386*03ce13f7SAndroid Build Coastguard Worker   /// The maximum number of arguments to pass in GPR registers
387*03ce13f7SAndroid Build Coastguard Worker   static constexpr uint32_t X86_MAX_GPR_ARGS = 0;
388*03ce13f7SAndroid Build Coastguard Worker   /// Get the register for a given argument slot in the XMM registers.
getRegisterForXmmArgNum(uint32_t ArgNum)389*03ce13f7SAndroid Build Coastguard Worker   static inline RegNumT getRegisterForXmmArgNum(uint32_t ArgNum) {
390*03ce13f7SAndroid Build Coastguard Worker     // TODO(sehr): Change to use the CCArg technique used in ARM32.
391*03ce13f7SAndroid Build Coastguard Worker     static_assert(Reg_xmm0 + 1 == Reg_xmm1,
392*03ce13f7SAndroid Build Coastguard Worker                   "Inconsistency between XMM register numbers and ordinals");
393*03ce13f7SAndroid Build Coastguard Worker     if (ArgNum >= X86_MAX_XMM_ARGS) {
394*03ce13f7SAndroid Build Coastguard Worker       return RegNumT();
395*03ce13f7SAndroid Build Coastguard Worker     }
396*03ce13f7SAndroid Build Coastguard Worker     return RegNumT::fixme(Reg_xmm0 + ArgNum);
397*03ce13f7SAndroid Build Coastguard Worker   }
398*03ce13f7SAndroid Build Coastguard Worker   /// Get the register for a given argument slot in the GPRs.
getRegisterForGprArgNum(Type Ty,uint32_t ArgNum)399*03ce13f7SAndroid Build Coastguard Worker   static inline RegNumT getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) {
400*03ce13f7SAndroid Build Coastguard Worker     assert(Ty == IceType_i64 || Ty == IceType_i32);
401*03ce13f7SAndroid Build Coastguard Worker     (void)Ty;
402*03ce13f7SAndroid Build Coastguard Worker     (void)ArgNum;
403*03ce13f7SAndroid Build Coastguard Worker     return RegNumT();
404*03ce13f7SAndroid Build Coastguard Worker   }
405*03ce13f7SAndroid Build Coastguard Worker   // Given the absolute argument position and argument position by type, return
406*03ce13f7SAndroid Build Coastguard Worker   // the register index to assign it to.
getArgIndex(SizeT argPos,SizeT argPosByType)407*03ce13f7SAndroid Build Coastguard Worker   static inline SizeT getArgIndex(SizeT argPos, SizeT argPosByType) {
408*03ce13f7SAndroid Build Coastguard Worker     (void)argPos;
409*03ce13f7SAndroid Build Coastguard Worker     return argPosByType;
410*03ce13f7SAndroid Build Coastguard Worker   };
411*03ce13f7SAndroid Build Coastguard Worker };
412*03ce13f7SAndroid Build Coastguard Worker 
413*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
414*03ce13f7SAndroid Build Coastguard Worker 
415*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICEREGISTERSX8632_H
416