1 //===- subzero/src/IceRegistersMIPS32.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 MIPS32.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef SUBZERO_SRC_ICEREGISTERSMIPS32_H
16 #define SUBZERO_SRC_ICEREGISTERSMIPS32_H
17 
18 #include "IceDefs.h"
19 #include "IceInstMIPS32.def"
20 #include "IceOperand.h" // RC_Target
21 #include "IceTypes.h"
22 
23 namespace Ice {
24 namespace MIPS32 {
25 namespace RegMIPS32 {
26 
27 /// An enum of every register. The enum value may not match the encoding used to
28 /// binary encode register operands in instructions.
29 enum AllRegisters {
30 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt,    \
31           isI64Pair, isFP32, isFP64, isVec128, alias_init)                     \
32   val,
33   REGMIPS32_TABLE
34 #undef X
35       Reg_NUM,
36 #define X(val, init) val init,
37   REGMIPS32_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.
43 enum GPRRegister {
44 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt,    \
45           isI64Pair, isFP32, isFP64, isVec128, alias_init)                     \
46                                                                                \
47   Encoded_##val = encode,
48   REGMIPS32_GPR_TABLE
49 #undef X
50       Encoded_Not_GPR = -1
51 };
52 
53 /// An enum of FPR Registers. The enum value does match the encoding used to
54 /// binary encode register operands in instructions.
55 enum FPRRegister {
56 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt,    \
57           isI64Pair, isFP32, isFP64, isVec128, alias_init)                     \
58                                                                                \
59   Encoded_##val = encode,
60   REGMIPS32_FPR_TABLE
61 #undef X
62       Encoded_Not_FPR = -1
63 };
64 
65 // TODO(jvoung): Floating point and vector registers...
66 // Need to model overlap and difference in encoding too.
67 
getEncodedGPR(RegNumT RegNum)68 static inline GPRRegister getEncodedGPR(RegNumT RegNum) {
69   assert(int(Reg_GPR_First) <= int(RegNum));
70   assert(unsigned(RegNum) <= Reg_GPR_Last);
71   return GPRRegister(RegNum - Reg_GPR_First);
72 }
73 
isGPRReg(RegNumT RegNum)74 static inline bool isGPRReg(RegNumT RegNum) {
75   bool IsGPR = ((int(Reg_GPR_First) <= int(RegNum)) &&
76                 (unsigned(RegNum) <= Reg_GPR_Last)) ||
77                ((int(Reg_I64PAIR_First) <= int(RegNum)) &&
78                 (unsigned(RegNum) <= Reg_I64PAIR_Last));
79   return IsGPR;
80 }
81 
getEncodedFPR(RegNumT RegNum)82 static inline FPRRegister getEncodedFPR(RegNumT RegNum) {
83   assert(int(Reg_FPR_First) <= int(RegNum));
84   assert(unsigned(RegNum) <= Reg_FPR_Last);
85   return FPRRegister(RegNum - Reg_FPR_First);
86 }
87 
isFPRReg(RegNumT RegNum)88 static inline bool isFPRReg(RegNumT RegNum) {
89   return ((int(Reg_FPR_First) <= int(RegNum)) &&
90           (unsigned(RegNum) <= Reg_FPR_Last));
91 }
92 
getEncodedFPR64(RegNumT RegNum)93 static inline FPRRegister getEncodedFPR64(RegNumT RegNum) {
94   assert(int(Reg_F64PAIR_First) <= int(RegNum));
95   assert(unsigned(RegNum) <= Reg_F64PAIR_Last);
96   return FPRRegister((RegNum - Reg_F64PAIR_First) * 2);
97 }
98 
isFPR64Reg(RegNumT RegNum)99 static inline bool isFPR64Reg(RegNumT RegNum) {
100   return (int(Reg_F64PAIR_First) <= int(RegNum)) &&
101          (unsigned(RegNum) <= Reg_F64PAIR_Last);
102 }
103 
104 const char *getRegName(RegNumT RegNum);
105 
get64PairFirstRegNum(RegNumT RegNum)106 static inline RegNumT get64PairFirstRegNum(RegNumT RegNum) {
107   assert(unsigned(RegNum) >= Reg_I64PAIR_First);
108   assert(unsigned(RegNum) <= Reg_F64PAIR_Last);
109   if (unsigned(RegNum) >= Reg_F64PAIR_First &&
110       unsigned(RegNum) <= Reg_F64PAIR_Last)
111     return RegNumT::fixme(((RegNum - Reg_F64PAIR_First) * 2) +
112                           unsigned(Reg_FPR_First));
113   if (unsigned(RegNum) >= Reg_I64PAIR_First && unsigned(RegNum) <= Reg_T8T9)
114     return RegNumT::fixme(((RegNum - Reg_I64PAIR_First) * 2) +
115                           unsigned(Reg_V0));
116   return RegMIPS32::Reg_LO;
117 }
118 
get64PairSecondRegNum(RegNumT RegNum)119 static inline RegNumT get64PairSecondRegNum(RegNumT RegNum) {
120   assert(unsigned(RegNum) >= Reg_I64PAIR_First);
121   assert(unsigned(RegNum) <= Reg_F64PAIR_Last);
122   if (unsigned(RegNum) >= Reg_F64PAIR_First &&
123       unsigned(RegNum) <= Reg_F64PAIR_Last)
124     return RegNumT::fixme(((RegNum - Reg_F64PAIR_First) * 2) +
125                           unsigned(Reg_FPR_First) + 1);
126   if (unsigned(RegNum) >= Reg_I64PAIR_First && unsigned(RegNum) <= Reg_T8T9)
127     return RegNumT::fixme(((RegNum - Reg_I64PAIR_First) * 2) +
128                           unsigned(Reg_V1));
129   return RegMIPS32::Reg_HI;
130 }
131 
132 } // end of namespace RegMIPS32
133 
134 // Extend enum RegClass with MIPS32-specific register classes (if any).
135 enum RegClassMIPS32 : uint8_t { RCMIPS32_NUM = RC_Target };
136 
137 } // end of namespace MIPS32
138 } // end of namespace Ice
139 
140 #endif // SUBZERO_SRC_ICEREGISTERSMIPS32_H
141