| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_MIPS_CONSTANTS_H_ | 28 #ifndef V8_MIPS_CONSTANTS_H_ |
| 29 #define V8_MIPS_CONSTANTS_H_ | 29 #define V8_MIPS_CONSTANTS_H_ |
| 30 | 30 |
| 31 #include "checks.h" | |
| 32 | |
| 33 // UNIMPLEMENTED_ macro for MIPS. | 31 // UNIMPLEMENTED_ macro for MIPS. |
| 32 #ifdef DEBUG |
| 34 #define UNIMPLEMENTED_MIPS() \ | 33 #define UNIMPLEMENTED_MIPS() \ |
| 35 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ | 34 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ |
| 36 __FILE__, __LINE__, __func__) | 35 __FILE__, __LINE__, __func__) |
| 36 #else |
| 37 #define UNIMPLEMENTED_MIPS() |
| 38 #endif |
| 39 |
| 37 #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") | 40 #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") |
| 38 | 41 |
| 39 | 42 |
| 43 #ifdef _MIPS_ARCH_MIPS32R2 |
| 44 #define mips32r2 1 |
| 45 #else |
| 46 #define mips32r2 0 |
| 47 #endif |
| 48 |
| 49 |
| 40 // Defines constants and accessor classes to assemble, disassemble and | 50 // Defines constants and accessor classes to assemble, disassemble and |
| 41 // simulate MIPS32 instructions. | 51 // simulate MIPS32 instructions. |
| 42 // | 52 // |
| 43 // See: MIPS32 Architecture For Programmers | 53 // See: MIPS32 Architecture For Programmers |
| 44 // Volume II: The MIPS32 Instruction Set | 54 // Volume II: The MIPS32 Instruction Set |
| 45 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. | 55 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. |
| 46 | 56 |
| 47 namespace assembler { | 57 namespace v8 { |
| 48 namespace mips { | 58 namespace internal { |
| 49 | 59 |
| 50 // ----------------------------------------------------------------------------- | 60 // ----------------------------------------------------------------------------- |
| 51 // Registers and FPURegister. | 61 // Registers and FPURegister. |
| 52 | 62 |
| 53 // Number of general purpose registers. | 63 // Number of general purpose registers. |
| 54 static const int kNumRegisters = 32; | 64 static const int kNumRegisters = 32; |
| 55 static const int kInvalidRegister = -1; | 65 static const int kInvalidRegister = -1; |
| 56 | 66 |
| 57 // Number of registers with HI, LO, and pc. | 67 // Number of registers with HI, LO, and pc. |
| 58 static const int kNumSimuRegisters = 35; | 68 static const int kNumSimuRegisters = 35; |
| 59 | 69 |
| 60 // In the simulator, the PC register is simulated as the 34th register. | 70 // In the simulator, the PC register is simulated as the 34th register. |
| 61 static const int kPCRegister = 34; | 71 static const int kPCRegister = 34; |
| 62 | 72 |
| 63 // Number coprocessor registers. | 73 // Number coprocessor registers. |
| 64 static const int kNumFPURegister = 32; | 74 static const int kNumFPURegisters = 32; |
| 65 static const int kInvalidFPURegister = -1; | 75 static const int kInvalidFPURegister = -1; |
| 66 | 76 |
| 77 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented. |
| 78 static const int kFCSRRegister = 31; |
| 79 static const int kInvalidFPUControlRegister = -1; |
| 80 static const uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1; |
| 81 |
| 82 // FCSR constants. |
| 83 static const uint32_t kFCSRFlagMask = (1 << 6) - 1; |
| 84 static const uint32_t kFCSRFlagShift = 2; |
| 85 |
| 67 // Helper functions for converting between register numbers and names. | 86 // Helper functions for converting between register numbers and names. |
| 68 class Registers { | 87 class Registers { |
| 69 public: | 88 public: |
| 70 // Return the name of the register. | 89 // Return the name of the register. |
| 71 static const char* Name(int reg); | 90 static const char* Name(int reg); |
| 72 | 91 |
| 73 // Lookup the register number for the name provided. | 92 // Lookup the register number for the name provided. |
| 74 static int Number(const char* name); | 93 static int Number(const char* name); |
| 75 | 94 |
| 76 struct RegisterAlias { | 95 struct RegisterAlias { |
| 77 int reg; | 96 int reg; |
| 78 const char *name; | 97 const char *name; |
| 79 }; | 98 }; |
| 80 | 99 |
| 81 static const int32_t kMaxValue = 0x7fffffff; | 100 static const int32_t kMaxValue = 0x7fffffff; |
| 82 static const int32_t kMinValue = 0x80000000; | 101 static const int32_t kMinValue = 0x80000000; |
| 83 | 102 |
| 84 private: | 103 private: |
| 85 | 104 |
| 86 static const char* names_[kNumSimuRegisters]; | 105 static const char* names_[kNumSimuRegisters]; |
| 87 static const RegisterAlias aliases_[]; | 106 static const RegisterAlias aliases_[]; |
| 88 }; | 107 }; |
| 89 | 108 |
| 90 // Helper functions for converting between register numbers and names. | 109 // Helper functions for converting between register numbers and names. |
| 91 class FPURegister { | 110 class FPURegisters { |
| 92 public: | 111 public: |
| 93 // Return the name of the register. | 112 // Return the name of the register. |
| 94 static const char* Name(int reg); | 113 static const char* Name(int reg); |
| 95 | 114 |
| 96 // Lookup the register number for the name provided. | 115 // Lookup the register number for the name provided. |
| 97 static int Number(const char* name); | 116 static int Number(const char* name); |
| 98 | 117 |
| 99 struct RegisterAlias { | 118 struct RegisterAlias { |
| 100 int creg; | 119 int creg; |
| 101 const char *name; | 120 const char *name; |
| 102 }; | 121 }; |
| 103 | 122 |
| 104 private: | 123 private: |
| 105 | 124 |
| 106 static const char* names_[kNumFPURegister]; | 125 static const char* names_[kNumFPURegisters]; |
| 107 static const RegisterAlias aliases_[]; | 126 static const RegisterAlias aliases_[]; |
| 108 }; | 127 }; |
| 109 | 128 |
| 110 | 129 |
| 111 // ----------------------------------------------------------------------------- | 130 // ----------------------------------------------------------------------------- |
| 112 // Instructions encoding constants. | 131 // Instructions encoding constants. |
| 113 | 132 |
| 114 // On MIPS all instructions are 32 bits. | 133 // On MIPS all instructions are 32 bits. |
| 115 typedef int32_t Instr; | 134 typedef int32_t Instr; |
| 116 | 135 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 129 static const int kRsShift = 21; | 148 static const int kRsShift = 21; |
| 130 static const int kRsBits = 5; | 149 static const int kRsBits = 5; |
| 131 static const int kRtShift = 16; | 150 static const int kRtShift = 16; |
| 132 static const int kRtBits = 5; | 151 static const int kRtBits = 5; |
| 133 static const int kRdShift = 11; | 152 static const int kRdShift = 11; |
| 134 static const int kRdBits = 5; | 153 static const int kRdBits = 5; |
| 135 static const int kSaShift = 6; | 154 static const int kSaShift = 6; |
| 136 static const int kSaBits = 5; | 155 static const int kSaBits = 5; |
| 137 static const int kFunctionShift = 0; | 156 static const int kFunctionShift = 0; |
| 138 static const int kFunctionBits = 6; | 157 static const int kFunctionBits = 6; |
| 158 static const int kLuiShift = 16; |
| 139 | 159 |
| 140 static const int kImm16Shift = 0; | 160 static const int kImm16Shift = 0; |
| 141 static const int kImm16Bits = 16; | 161 static const int kImm16Bits = 16; |
| 142 static const int kImm26Shift = 0; | 162 static const int kImm26Shift = 0; |
| 143 static const int kImm26Bits = 26; | 163 static const int kImm26Bits = 26; |
| 144 | 164 |
| 145 static const int kFsShift = 11; | 165 static const int kFsShift = 11; |
| 146 static const int kFsBits = 5; | 166 static const int kFsBits = 5; |
| 147 static const int kFtShift = 16; | 167 static const int kFtShift = 16; |
| 148 static const int kFtBits = 5; | 168 static const int kFtBits = 5; |
| 169 static const int kFdShift = 6; |
| 170 static const int kFdBits = 5; |
| 171 static const int kFCccShift = 8; |
| 172 static const int kFCccBits = 3; |
| 173 static const int kFBccShift = 18; |
| 174 static const int kFBccBits = 3; |
| 175 static const int kFBtrueShift = 16; |
| 176 static const int kFBtrueBits = 1; |
| 149 | 177 |
| 150 // ----- Miscellianous useful masks. | 178 // ----- Miscellianous useful masks. |
| 151 // Instruction bit masks. | 179 // Instruction bit masks. |
| 152 static const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; | 180 static const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; |
| 153 static const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; | 181 static const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; |
| 154 static const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; | 182 static const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; |
| 155 static const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; | 183 static const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; |
| 156 static const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; | 184 static const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; |
| 157 static const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; | 185 static const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; |
| 158 static const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; | 186 static const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; |
| 159 static const int kFunctionFieldMask = | 187 static const int kFunctionFieldMask = |
| 160 ((1 << kFunctionBits) - 1) << kFunctionShift; | 188 ((1 << kFunctionBits) - 1) << kFunctionShift; |
| 161 // Misc masks. | 189 // Misc masks. |
| 162 static const int HIMask = 0xffff << 16; | 190 static const int kHiMask = 0xffff << 16; |
| 163 static const int LOMask = 0xffff; | 191 static const int kLoMask = 0xffff; |
| 164 static const int signMask = 0x80000000; | 192 static const int kSignMask = 0x80000000; |
| 165 | 193 |
| 166 | 194 |
| 167 // ----- MIPS Opcodes and Function Fields. | 195 // ----- MIPS Opcodes and Function Fields. |
| 168 // We use this presentation to stay close to the table representation in | 196 // We use this presentation to stay close to the table representation in |
| 169 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. | 197 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. |
| 170 enum Opcode { | 198 enum Opcode { |
| 171 SPECIAL = 0 << kOpcodeShift, | 199 SPECIAL = 0 << kOpcodeShift, |
| 172 REGIMM = 1 << kOpcodeShift, | 200 REGIMM = 1 << kOpcodeShift, |
| 173 | 201 |
| 174 J = ((0 << 3) + 2) << kOpcodeShift, | 202 J = ((0 << 3) + 2) << kOpcodeShift, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 187 XORI = ((1 << 3) + 6) << kOpcodeShift, | 215 XORI = ((1 << 3) + 6) << kOpcodeShift, |
| 188 LUI = ((1 << 3) + 7) << kOpcodeShift, | 216 LUI = ((1 << 3) + 7) << kOpcodeShift, |
| 189 | 217 |
| 190 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class | 218 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class |
| 191 BEQL = ((2 << 3) + 4) << kOpcodeShift, | 219 BEQL = ((2 << 3) + 4) << kOpcodeShift, |
| 192 BNEL = ((2 << 3) + 5) << kOpcodeShift, | 220 BNEL = ((2 << 3) + 5) << kOpcodeShift, |
| 193 BLEZL = ((2 << 3) + 6) << kOpcodeShift, | 221 BLEZL = ((2 << 3) + 6) << kOpcodeShift, |
| 194 BGTZL = ((2 << 3) + 7) << kOpcodeShift, | 222 BGTZL = ((2 << 3) + 7) << kOpcodeShift, |
| 195 | 223 |
| 196 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift, | 224 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift, |
| 225 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift, |
| 197 | 226 |
| 198 LB = ((4 << 3) + 0) << kOpcodeShift, | 227 LB = ((4 << 3) + 0) << kOpcodeShift, |
| 228 LH = ((4 << 3) + 1) << kOpcodeShift, |
| 229 LWL = ((4 << 3) + 2) << kOpcodeShift, |
| 199 LW = ((4 << 3) + 3) << kOpcodeShift, | 230 LW = ((4 << 3) + 3) << kOpcodeShift, |
| 200 LBU = ((4 << 3) + 4) << kOpcodeShift, | 231 LBU = ((4 << 3) + 4) << kOpcodeShift, |
| 232 LHU = ((4 << 3) + 5) << kOpcodeShift, |
| 233 LWR = ((4 << 3) + 6) << kOpcodeShift, |
| 201 SB = ((5 << 3) + 0) << kOpcodeShift, | 234 SB = ((5 << 3) + 0) << kOpcodeShift, |
| 235 SH = ((5 << 3) + 1) << kOpcodeShift, |
| 236 SWL = ((5 << 3) + 2) << kOpcodeShift, |
| 202 SW = ((5 << 3) + 3) << kOpcodeShift, | 237 SW = ((5 << 3) + 3) << kOpcodeShift, |
| 238 SWR = ((5 << 3) + 6) << kOpcodeShift, |
| 203 | 239 |
| 204 LWC1 = ((6 << 3) + 1) << kOpcodeShift, | 240 LWC1 = ((6 << 3) + 1) << kOpcodeShift, |
| 205 LDC1 = ((6 << 3) + 5) << kOpcodeShift, | 241 LDC1 = ((6 << 3) + 5) << kOpcodeShift, |
| 206 | 242 |
| 207 SWC1 = ((7 << 3) + 1) << kOpcodeShift, | 243 SWC1 = ((7 << 3) + 1) << kOpcodeShift, |
| 208 SDC1 = ((7 << 3) + 5) << kOpcodeShift | 244 SDC1 = ((7 << 3) + 5) << kOpcodeShift |
| 209 }; | 245 }; |
| 210 | 246 |
| 211 enum SecondaryField { | 247 enum SecondaryField { |
| 212 // SPECIAL Encoding of Function Field. | 248 // SPECIAL Encoding of Function Field. |
| 213 SLL = ((0 << 3) + 0), | 249 SLL = ((0 << 3) + 0), |
| 214 SRL = ((0 << 3) + 2), | 250 SRL = ((0 << 3) + 2), |
| 215 SRA = ((0 << 3) + 3), | 251 SRA = ((0 << 3) + 3), |
| 216 SLLV = ((0 << 3) + 4), | 252 SLLV = ((0 << 3) + 4), |
| 217 SRLV = ((0 << 3) + 6), | 253 SRLV = ((0 << 3) + 6), |
| 218 SRAV = ((0 << 3) + 7), | 254 SRAV = ((0 << 3) + 7), |
| 255 MOVCI = ((0 << 3) + 1), |
| 219 | 256 |
| 220 JR = ((1 << 3) + 0), | 257 JR = ((1 << 3) + 0), |
| 221 JALR = ((1 << 3) + 1), | 258 JALR = ((1 << 3) + 1), |
| 259 MOVZ = ((1 << 3) + 2), |
| 260 MOVN = ((1 << 3) + 3), |
| 222 BREAK = ((1 << 3) + 5), | 261 BREAK = ((1 << 3) + 5), |
| 223 | 262 |
| 224 MFHI = ((2 << 3) + 0), | 263 MFHI = ((2 << 3) + 0), |
| 225 MFLO = ((2 << 3) + 2), | 264 MFLO = ((2 << 3) + 2), |
| 226 | 265 |
| 227 MULT = ((3 << 3) + 0), | 266 MULT = ((3 << 3) + 0), |
| 228 MULTU = ((3 << 3) + 1), | 267 MULTU = ((3 << 3) + 1), |
| 229 DIV = ((3 << 3) + 2), | 268 DIV = ((3 << 3) + 2), |
| 230 DIVU = ((3 << 3) + 3), | 269 DIVU = ((3 << 3) + 3), |
| 231 | 270 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 243 | 282 |
| 244 TGE = ((6 << 3) + 0), | 283 TGE = ((6 << 3) + 0), |
| 245 TGEU = ((6 << 3) + 1), | 284 TGEU = ((6 << 3) + 1), |
| 246 TLT = ((6 << 3) + 2), | 285 TLT = ((6 << 3) + 2), |
| 247 TLTU = ((6 << 3) + 3), | 286 TLTU = ((6 << 3) + 3), |
| 248 TEQ = ((6 << 3) + 4), | 287 TEQ = ((6 << 3) + 4), |
| 249 TNE = ((6 << 3) + 6), | 288 TNE = ((6 << 3) + 6), |
| 250 | 289 |
| 251 // SPECIAL2 Encoding of Function Field. | 290 // SPECIAL2 Encoding of Function Field. |
| 252 MUL = ((0 << 3) + 2), | 291 MUL = ((0 << 3) + 2), |
| 292 CLZ = ((4 << 3) + 0), |
| 293 CLO = ((4 << 3) + 1), |
| 294 |
| 295 // SPECIAL3 Encoding of Function Field. |
| 296 EXT = ((0 << 3) + 0), |
| 297 INS = ((0 << 3) + 4), |
| 253 | 298 |
| 254 // REGIMM encoding of rt Field. | 299 // REGIMM encoding of rt Field. |
| 255 BLTZ = ((0 << 3) + 0) << 16, | 300 BLTZ = ((0 << 3) + 0) << 16, |
| 256 BGEZ = ((0 << 3) + 1) << 16, | 301 BGEZ = ((0 << 3) + 1) << 16, |
| 257 BLTZAL = ((2 << 3) + 0) << 16, | 302 BLTZAL = ((2 << 3) + 0) << 16, |
| 258 BGEZAL = ((2 << 3) + 1) << 16, | 303 BGEZAL = ((2 << 3) + 1) << 16, |
| 259 | 304 |
| 260 // COP1 Encoding of rs Field. | 305 // COP1 Encoding of rs Field. |
| 261 MFC1 = ((0 << 3) + 0) << 21, | 306 MFC1 = ((0 << 3) + 0) << 21, |
| 307 CFC1 = ((0 << 3) + 2) << 21, |
| 262 MFHC1 = ((0 << 3) + 3) << 21, | 308 MFHC1 = ((0 << 3) + 3) << 21, |
| 263 MTC1 = ((0 << 3) + 4) << 21, | 309 MTC1 = ((0 << 3) + 4) << 21, |
| 310 CTC1 = ((0 << 3) + 6) << 21, |
| 264 MTHC1 = ((0 << 3) + 7) << 21, | 311 MTHC1 = ((0 << 3) + 7) << 21, |
| 265 BC1 = ((1 << 3) + 0) << 21, | 312 BC1 = ((1 << 3) + 0) << 21, |
| 266 S = ((2 << 3) + 0) << 21, | 313 S = ((2 << 3) + 0) << 21, |
| 267 D = ((2 << 3) + 1) << 21, | 314 D = ((2 << 3) + 1) << 21, |
| 268 W = ((2 << 3) + 4) << 21, | 315 W = ((2 << 3) + 4) << 21, |
| 269 L = ((2 << 3) + 5) << 21, | 316 L = ((2 << 3) + 5) << 21, |
| 270 PS = ((2 << 3) + 6) << 21, | 317 PS = ((2 << 3) + 6) << 21, |
| 271 // COP1 Encoding of Function Field When rs=S. | 318 // COP1 Encoding of Function Field When rs=S. |
| 319 ROUND_L_S = ((1 << 3) + 0), |
| 320 TRUNC_L_S = ((1 << 3) + 1), |
| 321 CEIL_L_S = ((1 << 3) + 2), |
| 322 FLOOR_L_S = ((1 << 3) + 3), |
| 323 ROUND_W_S = ((1 << 3) + 4), |
| 324 TRUNC_W_S = ((1 << 3) + 5), |
| 325 CEIL_W_S = ((1 << 3) + 6), |
| 326 FLOOR_W_S = ((1 << 3) + 7), |
| 272 CVT_D_S = ((4 << 3) + 1), | 327 CVT_D_S = ((4 << 3) + 1), |
| 273 CVT_W_S = ((4 << 3) + 4), | 328 CVT_W_S = ((4 << 3) + 4), |
| 274 CVT_L_S = ((4 << 3) + 5), | 329 CVT_L_S = ((4 << 3) + 5), |
| 275 CVT_PS_S = ((4 << 3) + 6), | 330 CVT_PS_S = ((4 << 3) + 6), |
| 276 // COP1 Encoding of Function Field When rs=D. | 331 // COP1 Encoding of Function Field When rs=D. |
| 332 ADD_D = ((0 << 3) + 0), |
| 333 SUB_D = ((0 << 3) + 1), |
| 334 MUL_D = ((0 << 3) + 2), |
| 335 DIV_D = ((0 << 3) + 3), |
| 336 SQRT_D = ((0 << 3) + 4), |
| 337 ABS_D = ((0 << 3) + 5), |
| 338 MOV_D = ((0 << 3) + 6), |
| 339 NEG_D = ((0 << 3) + 7), |
| 340 ROUND_L_D = ((1 << 3) + 0), |
| 341 TRUNC_L_D = ((1 << 3) + 1), |
| 342 CEIL_L_D = ((1 << 3) + 2), |
| 343 FLOOR_L_D = ((1 << 3) + 3), |
| 344 ROUND_W_D = ((1 << 3) + 4), |
| 345 TRUNC_W_D = ((1 << 3) + 5), |
| 346 CEIL_W_D = ((1 << 3) + 6), |
| 347 FLOOR_W_D = ((1 << 3) + 7), |
| 277 CVT_S_D = ((4 << 3) + 0), | 348 CVT_S_D = ((4 << 3) + 0), |
| 278 CVT_W_D = ((4 << 3) + 4), | 349 CVT_W_D = ((4 << 3) + 4), |
| 279 CVT_L_D = ((4 << 3) + 5), | 350 CVT_L_D = ((4 << 3) + 5), |
| 351 C_F_D = ((6 << 3) + 0), |
| 352 C_UN_D = ((6 << 3) + 1), |
| 353 C_EQ_D = ((6 << 3) + 2), |
| 354 C_UEQ_D = ((6 << 3) + 3), |
| 355 C_OLT_D = ((6 << 3) + 4), |
| 356 C_ULT_D = ((6 << 3) + 5), |
| 357 C_OLE_D = ((6 << 3) + 6), |
| 358 C_ULE_D = ((6 << 3) + 7), |
| 280 // COP1 Encoding of Function Field When rs=W or L. | 359 // COP1 Encoding of Function Field When rs=W or L. |
| 281 CVT_S_W = ((4 << 3) + 0), | 360 CVT_S_W = ((4 << 3) + 0), |
| 282 CVT_D_W = ((4 << 3) + 1), | 361 CVT_D_W = ((4 << 3) + 1), |
| 283 CVT_S_L = ((4 << 3) + 0), | 362 CVT_S_L = ((4 << 3) + 0), |
| 284 CVT_D_L = ((4 << 3) + 1), | 363 CVT_D_L = ((4 << 3) + 1), |
| 285 // COP1 Encoding of Function Field When rs=PS. | 364 // COP1 Encoding of Function Field When rs=PS. |
| 286 | 365 |
| 287 NULLSF = 0 | 366 NULLSF = 0 |
| 288 }; | 367 }; |
| 289 | 368 |
| 290 | 369 |
| 291 // ----- Emulated conditions. | 370 // ----- Emulated conditions. |
| 292 // On MIPS we use this enum to abstract from conditionnal branch instructions. | 371 // On MIPS we use this enum to abstract from conditionnal branch instructions. |
| 293 // the 'U' prefix is used to specify unsigned comparisons. | 372 // the 'U' prefix is used to specify unsigned comparisons. |
| 294 enum Condition { | 373 enum Condition { |
| 295 // Any value < 0 is considered no_condition. | 374 // Any value < 0 is considered no_condition. |
| 296 no_condition = -1, | 375 kNoCondition = -1, |
| 297 | 376 |
| 298 overflow = 0, | 377 overflow = 0, |
| 299 no_overflow = 1, | 378 no_overflow = 1, |
| 300 Uless = 2, | 379 Uless = 2, |
| 301 Ugreater_equal= 3, | 380 Ugreater_equal= 3, |
| 302 equal = 4, | 381 equal = 4, |
| 303 not_equal = 5, | 382 not_equal = 5, |
| 304 Uless_equal = 6, | 383 Uless_equal = 6, |
| 305 Ugreater = 7, | 384 Ugreater = 7, |
| 306 negative = 8, | 385 negative = 8, |
| 307 positive = 9, | 386 positive = 9, |
| 308 parity_even = 10, | 387 parity_even = 10, |
| 309 parity_odd = 11, | 388 parity_odd = 11, |
| 310 less = 12, | 389 less = 12, |
| 311 greater_equal = 13, | 390 greater_equal = 13, |
| 312 less_equal = 14, | 391 less_equal = 14, |
| 313 greater = 15, | 392 greater = 15, |
| 314 | 393 |
| 315 cc_always = 16, | 394 cc_always = 16, |
| 316 | 395 |
| 317 // aliases | 396 // aliases |
| 318 carry = Uless, | 397 carry = Uless, |
| 319 not_carry = Ugreater_equal, | 398 not_carry = Ugreater_equal, |
| 320 zero = equal, | 399 zero = equal, |
| 321 eq = equal, | 400 eq = equal, |
| 322 not_zero = not_equal, | 401 not_zero = not_equal, |
| 323 ne = not_equal, | 402 ne = not_equal, |
| 403 nz = not_equal, |
| 324 sign = negative, | 404 sign = negative, |
| 325 not_sign = positive, | 405 not_sign = positive, |
| 406 mi = negative, |
| 407 pl = positive, |
| 408 hi = Ugreater, |
| 409 ls = Uless_equal, |
| 410 ge = greater_equal, |
| 411 lt = less, |
| 412 gt = greater, |
| 413 le = less_equal, |
| 414 hs = Ugreater_equal, |
| 415 lo = Uless, |
| 416 al = cc_always, |
| 326 | 417 |
| 327 cc_default = no_condition | 418 cc_default = kNoCondition |
| 328 }; | 419 }; |
| 329 | 420 |
| 421 |
| 422 // Returns the equivalent of !cc. |
| 423 // Negation of the default kNoCondition (-1) results in a non-default |
| 424 // no_condition value (-2). As long as tests for no_condition check |
| 425 // for condition < 0, this will work as expected. |
| 426 inline Condition NegateCondition(Condition cc) { |
| 427 ASSERT(cc != cc_always); |
| 428 return static_cast<Condition>(cc ^ 1); |
| 429 } |
| 430 |
| 431 |
| 432 inline Condition ReverseCondition(Condition cc) { |
| 433 switch (cc) { |
| 434 case Uless: |
| 435 return Ugreater; |
| 436 case Ugreater: |
| 437 return Uless; |
| 438 case Ugreater_equal: |
| 439 return Uless_equal; |
| 440 case Uless_equal: |
| 441 return Ugreater_equal; |
| 442 case less: |
| 443 return greater; |
| 444 case greater: |
| 445 return less; |
| 446 case greater_equal: |
| 447 return less_equal; |
| 448 case less_equal: |
| 449 return greater_equal; |
| 450 default: |
| 451 return cc; |
| 452 }; |
| 453 } |
| 454 |
| 455 |
| 330 // ----- Coprocessor conditions. | 456 // ----- Coprocessor conditions. |
| 331 enum FPUCondition { | 457 enum FPUCondition { |
| 332 F, // False | 458 F, // False |
| 333 UN, // Unordered | 459 UN, // Unordered |
| 334 EQ, // Equal | 460 EQ, // Equal |
| 335 UEQ, // Unordered or Equal | 461 UEQ, // Unordered or Equal |
| 336 OLT, // Ordered or Less Than | 462 OLT, // Ordered or Less Than |
| 337 ULT, // Unordered or Less Than | 463 ULT, // Unordered or Less Than |
| 338 OLE, // Ordered or Less Than or Equal | 464 OLE, // Ordered or Less Than or Equal |
| 339 ULE // Unordered or Less Than or Equal | 465 ULE // Unordered or Less Than or Equal |
| 340 }; | 466 }; |
| 341 | 467 |
| 342 | 468 |
| 469 // ----------------------------------------------------------------------------- |
| 470 // Hints. |
| 471 |
| 472 // Branch hints are not used on the MIPS. They are defined so that they can |
| 473 // appear in shared function signatures, but will be ignored in MIPS |
| 474 // implementations. |
| 475 enum Hint { |
| 476 no_hint = 0 |
| 477 }; |
| 478 |
| 479 |
| 480 inline Hint NegateHint(Hint hint) { |
| 481 return no_hint; |
| 482 } |
| 483 |
| 484 |
| 485 // ----------------------------------------------------------------------------- |
| 486 // Specific instructions, constants, and masks. |
| 487 // These constants are declared in assembler-mips.cc, as they use named |
| 488 // registers and other constants. |
| 489 |
| 490 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) |
| 491 // operations as post-increment of sp. |
| 492 extern const Instr kPopInstruction; |
| 493 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. |
| 494 extern const Instr kPushInstruction; |
| 495 // sw(r, MemOperand(sp, 0)) |
| 496 extern const Instr kPushRegPattern; |
| 497 // lw(r, MemOperand(sp, 0)) |
| 498 extern const Instr kPopRegPattern; |
| 499 extern const Instr kLwRegFpOffsetPattern; |
| 500 extern const Instr kSwRegFpOffsetPattern; |
| 501 extern const Instr kLwRegFpNegOffsetPattern; |
| 502 extern const Instr kSwRegFpNegOffsetPattern; |
| 503 // A mask for the Rt register for push, pop, lw, sw instructions. |
| 504 extern const Instr kRtMask; |
| 505 extern const Instr kLwSwInstrTypeMask; |
| 506 extern const Instr kLwSwInstrArgumentMask; |
| 507 extern const Instr kLwSwOffsetMask; |
| 508 |
| 343 // Break 0xfffff, reserved for redirected real time call. | 509 // Break 0xfffff, reserved for redirected real time call. |
| 344 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; | 510 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; |
| 345 // A nop instruction. (Encoding of sll 0 0 0). | 511 // A nop instruction. (Encoding of sll 0 0 0). |
| 346 const Instr nopInstr = 0; | 512 const Instr nopInstr = 0; |
| 347 | 513 |
| 348 class Instruction { | 514 class Instruction { |
| 349 public: | 515 public: |
| 350 enum { | 516 enum { |
| 351 kInstructionSize = 4, | 517 kInstrSize = 4, |
| 352 kInstructionSizeLog2 = 2, | 518 kInstrSizeLog2 = 2, |
| 353 // On MIPS PC cannot actually be directly accessed. We behave as if PC was | 519 // On MIPS PC cannot actually be directly accessed. We behave as if PC was |
| 354 // always the value of the current instruction being exectued. | 520 // always the value of the current instruction being executed. |
| 355 kPCReadOffset = 0 | 521 kPCReadOffset = 0 |
| 356 }; | 522 }; |
| 357 | 523 |
| 358 // Get the raw instruction bits. | 524 // Get the raw instruction bits. |
| 359 inline Instr InstructionBits() const { | 525 inline Instr InstructionBits() const { |
| 360 return *reinterpret_cast<const Instr*>(this); | 526 return *reinterpret_cast<const Instr*>(this); |
| 361 } | 527 } |
| 362 | 528 |
| 363 // Set the raw instruction bits to value. | 529 // Set the raw instruction bits to value. |
| 364 inline void SetInstructionBits(Instr value) { | 530 inline void SetInstructionBits(Instr value) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 381 kImmediateType, | 547 kImmediateType, |
| 382 kJumpType, | 548 kJumpType, |
| 383 kUnsupported = -1 | 549 kUnsupported = -1 |
| 384 }; | 550 }; |
| 385 | 551 |
| 386 // Get the encoding type of the instruction. | 552 // Get the encoding type of the instruction. |
| 387 Type InstructionType() const; | 553 Type InstructionType() const; |
| 388 | 554 |
| 389 | 555 |
| 390 // Accessors for the different named fields used in the MIPS encoding. | 556 // Accessors for the different named fields used in the MIPS encoding. |
| 391 inline Opcode OpcodeField() const { | 557 inline Opcode OpcodeValue() const { |
| 392 return static_cast<Opcode>( | 558 return static_cast<Opcode>( |
| 393 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); | 559 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); |
| 394 } | 560 } |
| 395 | 561 |
| 396 inline int RsField() const { | 562 inline int RsValue() const { |
| 397 ASSERT(InstructionType() == kRegisterType || | 563 ASSERT(InstructionType() == kRegisterType || |
| 398 InstructionType() == kImmediateType); | 564 InstructionType() == kImmediateType); |
| 399 return Bits(kRsShift + kRsBits - 1, kRsShift); | 565 return Bits(kRsShift + kRsBits - 1, kRsShift); |
| 400 } | 566 } |
| 401 | 567 |
| 402 inline int RtField() const { | 568 inline int RtValue() const { |
| 403 ASSERT(InstructionType() == kRegisterType || | 569 ASSERT(InstructionType() == kRegisterType || |
| 404 InstructionType() == kImmediateType); | 570 InstructionType() == kImmediateType); |
| 405 return Bits(kRtShift + kRtBits - 1, kRtShift); | 571 return Bits(kRtShift + kRtBits - 1, kRtShift); |
| 406 } | 572 } |
| 407 | 573 |
| 408 inline int RdField() const { | 574 inline int RdValue() const { |
| 409 ASSERT(InstructionType() == kRegisterType); | 575 ASSERT(InstructionType() == kRegisterType); |
| 410 return Bits(kRdShift + kRdBits - 1, kRdShift); | 576 return Bits(kRdShift + kRdBits - 1, kRdShift); |
| 411 } | 577 } |
| 412 | 578 |
| 413 inline int SaField() const { | 579 inline int SaValue() const { |
| 414 ASSERT(InstructionType() == kRegisterType); | 580 ASSERT(InstructionType() == kRegisterType); |
| 415 return Bits(kSaShift + kSaBits - 1, kSaShift); | 581 return Bits(kSaShift + kSaBits - 1, kSaShift); |
| 416 } | 582 } |
| 417 | 583 |
| 418 inline int FunctionField() const { | 584 inline int FunctionValue() const { |
| 419 ASSERT(InstructionType() == kRegisterType || | 585 ASSERT(InstructionType() == kRegisterType || |
| 420 InstructionType() == kImmediateType); | 586 InstructionType() == kImmediateType); |
| 421 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); | 587 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); |
| 422 } | 588 } |
| 423 | 589 |
| 424 inline int FsField() const { | 590 inline int FdValue() const { |
| 425 return Bits(kFsShift + kRsBits - 1, kFsShift); | 591 return Bits(kFdShift + kFdBits - 1, kFdShift); |
| 426 } | 592 } |
| 427 | 593 |
| 428 inline int FtField() const { | 594 inline int FsValue() const { |
| 429 return Bits(kFtShift + kRsBits - 1, kFtShift); | 595 return Bits(kFsShift + kFsBits - 1, kFsShift); |
| 596 } |
| 597 |
| 598 inline int FtValue() const { |
| 599 return Bits(kFtShift + kFtBits - 1, kFtShift); |
| 600 } |
| 601 |
| 602 // Float Compare condition code instruction bits. |
| 603 inline int FCccValue() const { |
| 604 return Bits(kFCccShift + kFCccBits - 1, kFCccShift); |
| 605 } |
| 606 |
| 607 // Float Branch condition code instruction bits. |
| 608 inline int FBccValue() const { |
| 609 return Bits(kFBccShift + kFBccBits - 1, kFBccShift); |
| 610 } |
| 611 |
| 612 // Float Branch true/false instruction bit. |
| 613 inline int FBtrueValue() const { |
| 614 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); |
| 430 } | 615 } |
| 431 | 616 |
| 432 // Return the fields at their original place in the instruction encoding. | 617 // Return the fields at their original place in the instruction encoding. |
| 433 inline Opcode OpcodeFieldRaw() const { | 618 inline Opcode OpcodeFieldRaw() const { |
| 434 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); | 619 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); |
| 435 } | 620 } |
| 436 | 621 |
| 437 inline int RsFieldRaw() const { | 622 inline int RsFieldRaw() const { |
| 438 ASSERT(InstructionType() == kRegisterType || | 623 ASSERT(InstructionType() == kRegisterType || |
| 439 InstructionType() == kImmediateType); | 624 InstructionType() == kImmediateType); |
| 440 return InstructionBits() & kRsFieldMask; | 625 return InstructionBits() & kRsFieldMask; |
| 441 } | 626 } |
| 442 | 627 |
| 628 // Same as above function, but safe to call within InstructionType(). |
| 629 inline int RsFieldRawNoAssert() const { |
| 630 return InstructionBits() & kRsFieldMask; |
| 631 } |
| 632 |
| 443 inline int RtFieldRaw() const { | 633 inline int RtFieldRaw() const { |
| 444 ASSERT(InstructionType() == kRegisterType || | 634 ASSERT(InstructionType() == kRegisterType || |
| 445 InstructionType() == kImmediateType); | 635 InstructionType() == kImmediateType); |
| 446 return InstructionBits() & kRtFieldMask; | 636 return InstructionBits() & kRtFieldMask; |
| 447 } | 637 } |
| 448 | 638 |
| 449 inline int RdFieldRaw() const { | 639 inline int RdFieldRaw() const { |
| 450 ASSERT(InstructionType() == kRegisterType); | 640 ASSERT(InstructionType() == kRegisterType); |
| 451 return InstructionBits() & kRdFieldMask; | 641 return InstructionBits() & kRdFieldMask; |
| 452 } | 642 } |
| 453 | 643 |
| 454 inline int SaFieldRaw() const { | 644 inline int SaFieldRaw() const { |
| 455 ASSERT(InstructionType() == kRegisterType); | 645 ASSERT(InstructionType() == kRegisterType); |
| 456 return InstructionBits() & kSaFieldMask; | 646 return InstructionBits() & kSaFieldMask; |
| 457 } | 647 } |
| 458 | 648 |
| 459 inline int FunctionFieldRaw() const { | 649 inline int FunctionFieldRaw() const { |
| 460 return InstructionBits() & kFunctionFieldMask; | 650 return InstructionBits() & kFunctionFieldMask; |
| 461 } | 651 } |
| 462 | 652 |
| 463 // Get the secondary field according to the opcode. | 653 // Get the secondary field according to the opcode. |
| 464 inline int SecondaryField() const { | 654 inline int SecondaryValue() const { |
| 465 Opcode op = OpcodeFieldRaw(); | 655 Opcode op = OpcodeFieldRaw(); |
| 466 switch (op) { | 656 switch (op) { |
| 467 case SPECIAL: | 657 case SPECIAL: |
| 468 case SPECIAL2: | 658 case SPECIAL2: |
| 469 return FunctionField(); | 659 return FunctionValue(); |
| 470 case COP1: | 660 case COP1: |
| 471 return RsField(); | 661 return RsValue(); |
| 472 case REGIMM: | 662 case REGIMM: |
| 473 return RtField(); | 663 return RtValue(); |
| 474 default: | 664 default: |
| 475 return NULLSF; | 665 return NULLSF; |
| 476 } | 666 } |
| 477 } | 667 } |
| 478 | 668 |
| 479 inline int32_t Imm16Field() const { | 669 inline int32_t Imm16Value() const { |
| 480 ASSERT(InstructionType() == kImmediateType); | 670 ASSERT(InstructionType() == kImmediateType); |
| 481 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); | 671 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); |
| 482 } | 672 } |
| 483 | 673 |
| 484 inline int32_t Imm26Field() const { | 674 inline int32_t Imm26Value() const { |
| 485 ASSERT(InstructionType() == kJumpType); | 675 ASSERT(InstructionType() == kJumpType); |
| 486 return Bits(kImm16Shift + kImm26Bits - 1, kImm26Shift); | 676 return Bits(kImm16Shift + kImm26Bits - 1, kImm26Shift); |
| 487 } | 677 } |
| 488 | 678 |
| 489 // Say if the instruction should not be used in a branch delay slot. | 679 // Say if the instruction should not be used in a branch delay slot. |
| 490 bool IsForbiddenInBranchDelay(); | 680 bool IsForbiddenInBranchDelay() const; |
| 491 // Say if the instruction 'links'. eg: jal, bal. | 681 // Say if the instruction 'links'. eg: jal, bal. |
| 492 bool IsLinkingInstruction(); | 682 bool IsLinkingInstruction() const; |
| 493 // Say if the instruction is a break or a trap. | 683 // Say if the instruction is a break or a trap. |
| 494 bool IsTrap(); | 684 bool IsTrap() const; |
| 495 | 685 |
| 496 // Instructions are read of out a code stream. The only way to get a | 686 // Instructions are read of out a code stream. The only way to get a |
| 497 // reference to an instruction is to convert a pointer. There is no way | 687 // reference to an instruction is to convert a pointer. There is no way |
| 498 // to allocate or create instances of class Instruction. | 688 // to allocate or create instances of class Instruction. |
| 499 // Use the At(pc) function to create references to Instruction. | 689 // Use the At(pc) function to create references to Instruction. |
| 500 static Instruction* At(byte_* pc) { | 690 static Instruction* At(byte_* pc) { |
| 501 return reinterpret_cast<Instruction*>(pc); | 691 return reinterpret_cast<Instruction*>(pc); |
| 502 } | 692 } |
| 503 | 693 |
| 504 private: | 694 private: |
| 505 // We need to prevent the creation of instances of class Instruction. | 695 // We need to prevent the creation of instances of class Instruction. |
| 506 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); | 696 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); |
| 507 }; | 697 }; |
| 508 | 698 |
| 509 | 699 |
| 510 // ----------------------------------------------------------------------------- | 700 // ----------------------------------------------------------------------------- |
| 511 // MIPS assembly various constants. | 701 // MIPS assembly various constants. |
| 512 | 702 |
| 513 static const int kArgsSlotsSize = 4 * Instruction::kInstructionSize; | 703 |
| 704 static const int kArgsSlotsSize = 4 * Instruction::kInstrSize; |
| 514 static const int kArgsSlotsNum = 4; | 705 static const int kArgsSlotsNum = 4; |
| 706 // C/C++ argument slots size. |
| 707 static const int kCArgsSlotsSize = 4 * Instruction::kInstrSize; |
| 708 // JS argument slots size. |
| 709 static const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; |
| 710 // Assembly builtins argument slots size. |
| 711 static const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; |
| 515 | 712 |
| 516 static const int kBranchReturnOffset = 2 * Instruction::kInstructionSize; | 713 static const int kBranchReturnOffset = 2 * Instruction::kInstrSize; |
| 517 | 714 |
| 518 static const int kDoubleAlignment = 2 * 8; | 715 static const int kDoubleAlignmentBits = 3; |
| 519 static const int kDoubleAlignmentMask = kDoubleAlignmentMask - 1; | 716 static const int kDoubleAlignment = (1 << kDoubleAlignmentBits); |
| 717 static const int kDoubleAlignmentMask = kDoubleAlignment - 1; |
| 520 | 718 |
| 521 | 719 |
| 522 } } // namespace assembler::mips | 720 } } // namespace v8::internal |
| 523 | 721 |
| 524 #endif // #ifndef V8_MIPS_CONSTANTS_H_ | 722 #endif // #ifndef V8_MIPS_CONSTANTS_H_ |
| 525 | 723 |
| OLD | NEW |