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