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