| //===- subzero/src/IceRegistersMIPS32.h - Register information --*- C++ -*-===// | |
| // | |
| // The Subzero Code Generator | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /// | |
| /// \file | |
| /// \brief Declares the registers and their encodings for MIPS32. | |
| /// | |
| //===----------------------------------------------------------------------===// | |
| #ifndef SUBZERO_SRC_ICEREGISTERSMIPS32_H | |
| #define SUBZERO_SRC_ICEREGISTERSMIPS32_H | |
| #include "IceDefs.h" | |
| #include "IceInstMIPS32.def" | |
| #include "IceOperand.h" // RC_Target | |
| #include "IceTypes.h" | |
| namespace Ice { | |
| namespace MIPS32 { | |
| namespace RegMIPS32 { | |
| /// An enum of every register. The enum value may not match the encoding used to | |
| /// binary encode register operands in instructions. | |
| enum AllRegisters { | |
| #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ | |
| isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | |
| val, | |
| REGMIPS32_TABLE | |
| #undef X | |
| Reg_NUM, | |
| #define X(val, init) val init, | |
| REGMIPS32_TABLE_BOUNDS | |
| #undef X | |
| }; | |
| /// An enum of GPR Registers. The enum value does match the encoding used to | |
| /// binary encode register operands in instructions. | |
| enum GPRRegister { | |
| #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ | |
| isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | |
| \ | |
| Encoded_##val = encode, | |
| REGMIPS32_GPR_TABLE | |
| #undef X | |
| Encoded_Not_GPR = -1 | |
| }; | |
| /// An enum of FPR Registers. The enum value does match the encoding used to | |
| /// binary encode register operands in instructions. | |
| enum FPRRegister { | |
| #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ | |
| isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | |
| \ | |
| Encoded_##val = encode, | |
| REGMIPS32_FPR_TABLE | |
| #undef X | |
| Encoded_Not_FPR = -1 | |
| }; | |
| // TODO(jvoung): Floating point and vector registers... | |
| // Need to model overlap and difference in encoding too. | |
| static inline GPRRegister getEncodedGPR(RegNumT RegNum) { | |
| assert(int(Reg_GPR_First) <= int(RegNum)); | |
| assert(unsigned(RegNum) <= Reg_GPR_Last); | |
| return GPRRegister(RegNum - Reg_GPR_First); | |
| } | |
| static inline bool isGPRReg(RegNumT RegNum) { | |
| bool IsGPR = ((int(Reg_GPR_First) <= int(RegNum)) && | |
| (unsigned(RegNum) <= Reg_GPR_Last)) || | |
| ((int(Reg_I64PAIR_First) <= int(RegNum)) && | |
| (unsigned(RegNum) <= Reg_I64PAIR_Last)); | |
| return IsGPR; | |
| } | |
| static inline FPRRegister getEncodedFPR(RegNumT RegNum) { | |
| assert(int(Reg_FPR_First) <= int(RegNum)); | |
| assert(unsigned(RegNum) <= Reg_FPR_Last); | |
| return FPRRegister(RegNum - Reg_FPR_First); | |
| } | |
| static inline bool isFPRReg(RegNumT RegNum) { | |
| return ((int(Reg_FPR_First) <= int(RegNum)) && | |
| (unsigned(RegNum) <= Reg_FPR_Last)); | |
| } | |
| static inline FPRRegister getEncodedFPR64(RegNumT RegNum) { | |
| assert(int(Reg_F64PAIR_First) <= int(RegNum)); | |
| assert(unsigned(RegNum) <= Reg_F64PAIR_Last); | |
| return FPRRegister((RegNum - Reg_F64PAIR_First) * 2); | |
| } | |
| static inline bool isFPR64Reg(RegNumT RegNum) { | |
| return (int(Reg_F64PAIR_First) <= int(RegNum)) && | |
| (unsigned(RegNum) <= Reg_F64PAIR_Last); | |
| } | |
| const char *getRegName(RegNumT RegNum); | |
| static inline RegNumT get64PairFirstRegNum(RegNumT RegNum) { | |
| assert(unsigned(RegNum) >= Reg_I64PAIR_First); | |
| assert(unsigned(RegNum) <= Reg_F64PAIR_Last); | |
| if (unsigned(RegNum) >= Reg_F64PAIR_First && | |
| unsigned(RegNum) <= Reg_F64PAIR_Last) | |
| return RegNumT::fixme(((RegNum - Reg_F64PAIR_First) * 2) + | |
| unsigned(Reg_FPR_First)); | |
| if (unsigned(RegNum) >= Reg_I64PAIR_First && unsigned(RegNum) <= Reg_T8T9) | |
| return RegNumT::fixme(((RegNum - Reg_I64PAIR_First) * 2) + | |
| unsigned(Reg_V0)); | |
| return RegMIPS32::Reg_LO; | |
| } | |
| static inline RegNumT get64PairSecondRegNum(RegNumT RegNum) { | |
| assert(unsigned(RegNum) >= Reg_I64PAIR_First); | |
| assert(unsigned(RegNum) <= Reg_F64PAIR_Last); | |
| if (unsigned(RegNum) >= Reg_F64PAIR_First && | |
| unsigned(RegNum) <= Reg_F64PAIR_Last) | |
| return RegNumT::fixme(((RegNum - Reg_F64PAIR_First) * 2) + | |
| unsigned(Reg_FPR_First) + 1); | |
| if (unsigned(RegNum) >= Reg_I64PAIR_First && unsigned(RegNum) <= Reg_T8T9) | |
| return RegNumT::fixme(((RegNum - Reg_I64PAIR_First) * 2) + | |
| unsigned(Reg_V1)); | |
| return RegMIPS32::Reg_HI; | |
| } | |
| } // end of namespace RegMIPS32 | |
| // Extend enum RegClass with MIPS32-specific register classes (if any). | |
| enum RegClassMIPS32 : uint8_t { RCMIPS32_NUM = RC_Target }; | |
| } // end of namespace MIPS32 | |
| } // end of namespace Ice | |
| #endif // SUBZERO_SRC_ICEREGISTERSMIPS32_H |