| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 // to a few constants). If this is a problem, we could change the code | 90 // to a few constants). If this is a problem, we could change the code |
| 91 // such that we use an enum in optimized mode, and the struct in debug | 91 // such that we use an enum in optimized mode, and the struct in debug |
| 92 // mode. This way we get the compile-time error checking in debug mode | 92 // mode. This way we get the compile-time error checking in debug mode |
| 93 // and best performance in optimized code. | 93 // and best performance in optimized code. |
| 94 | 94 |
| 95 | 95 |
| 96 // ----------------------------------------------------------------------------- | 96 // ----------------------------------------------------------------------------- |
| 97 // Implementation of Register and FPURegister. | 97 // Implementation of Register and FPURegister. |
| 98 | 98 |
| 99 struct Register { | 99 struct Register { |
| 100 static const int kCpRegister = 23; // cp (s7) is the 23rd register. | 100 static constexpr int kCpRegister = 23; // cp (s7) is the 23rd register. |
| 101 | 101 |
| 102 #if defined(V8_TARGET_LITTLE_ENDIAN) | 102 #if defined(V8_TARGET_LITTLE_ENDIAN) |
| 103 static const int kMantissaOffset = 0; | 103 static constexpr int kMantissaOffset = 0; |
| 104 static const int kExponentOffset = 4; | 104 static constexpr int kExponentOffset = 4; |
| 105 #elif defined(V8_TARGET_BIG_ENDIAN) | 105 #elif defined(V8_TARGET_BIG_ENDIAN) |
| 106 static const int kMantissaOffset = 4; | 106 static constexpr int kMantissaOffset = 4; |
| 107 static const int kExponentOffset = 0; | 107 static constexpr int kExponentOffset = 0; |
| 108 #else | 108 #else |
| 109 #error Unknown endianness | 109 #error Unknown endianness |
| 110 #endif | 110 #endif |
| 111 | 111 |
| 112 enum Code { | 112 enum Code { |
| 113 #define REGISTER_CODE(R) kCode_##R, | 113 #define REGISTER_CODE(R) kCode_##R, |
| 114 GENERAL_REGISTERS(REGISTER_CODE) | 114 GENERAL_REGISTERS(REGISTER_CODE) |
| 115 #undef REGISTER_CODE | 115 #undef REGISTER_CODE |
| 116 kAfterLast, | 116 kAfterLast, |
| 117 kCode_no_reg = -1 | 117 kCode_no_reg = -1 |
| 118 }; | 118 }; |
| 119 | 119 |
| 120 static const int kNumRegisters = Code::kAfterLast; | 120 static constexpr int kNumRegisters = Code::kAfterLast; |
| 121 | 121 |
| 122 static Register from_code(int code) { | 122 static Register from_code(int code) { |
| 123 DCHECK(code >= 0); | 123 DCHECK(code >= 0); |
| 124 DCHECK(code < kNumRegisters); | 124 DCHECK(code < kNumRegisters); |
| 125 Register r = { code }; | 125 Register r = { code }; |
| 126 return r; | 126 return r; |
| 127 } | 127 } |
| 128 | 128 |
| 129 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } | 129 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } |
| 130 bool is(Register reg) const { return reg_code == reg.reg_code; } | 130 bool is(Register reg) const { return reg_code == reg.reg_code; } |
| 131 int code() const { | 131 int code() const { |
| 132 DCHECK(is_valid()); | 132 DCHECK(is_valid()); |
| 133 return reg_code; | 133 return reg_code; |
| 134 } | 134 } |
| 135 int bit() const { | 135 constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; } |
| 136 DCHECK(is_valid()); | |
| 137 return 1 << reg_code; | |
| 138 } | |
| 139 | 136 |
| 140 // Unfortunately we can't make this private in a struct. | 137 // Unfortunately we can't make this private in a struct. |
| 141 int reg_code; | 138 int reg_code; |
| 142 }; | 139 }; |
| 143 | 140 |
| 144 // s7: context register | 141 // s7: context register |
| 145 // s3: lithium scratch | 142 // s3: lithium scratch |
| 146 // s4: lithium scratch2 | 143 // s4: lithium scratch2 |
| 147 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; | 144 #define DECLARE_REGISTER(R) constexpr Register R = {Register::kCode_##R}; |
| 148 GENERAL_REGISTERS(DECLARE_REGISTER) | 145 GENERAL_REGISTERS(DECLARE_REGISTER) |
| 149 #undef DECLARE_REGISTER | 146 #undef DECLARE_REGISTER |
| 150 const Register no_reg = {Register::kCode_no_reg}; | 147 constexpr Register no_reg = {Register::kCode_no_reg}; |
| 151 | |
| 152 | 148 |
| 153 int ToNumber(Register reg); | 149 int ToNumber(Register reg); |
| 154 | 150 |
| 155 Register ToRegister(int num); | 151 Register ToRegister(int num); |
| 156 | 152 |
| 157 static const bool kSimpleFPAliasing = true; | 153 constexpr bool kSimpleFPAliasing = true; |
| 158 static const bool kSimdMaskRegisters = false; | 154 constexpr bool kSimdMaskRegisters = false; |
| 159 | 155 |
| 160 // Coprocessor register. | 156 // Coprocessor register. |
| 161 struct FPURegister { | 157 struct FPURegister { |
| 162 enum Code { | 158 enum Code { |
| 163 #define REGISTER_CODE(R) kCode_##R, | 159 #define REGISTER_CODE(R) kCode_##R, |
| 164 DOUBLE_REGISTERS(REGISTER_CODE) | 160 DOUBLE_REGISTERS(REGISTER_CODE) |
| 165 #undef REGISTER_CODE | 161 #undef REGISTER_CODE |
| 166 kAfterLast, | 162 kAfterLast, |
| 167 kCode_no_reg = -1 | 163 kCode_no_reg = -1 |
| 168 }; | 164 }; |
| 169 | 165 |
| 170 static const int kMaxNumRegisters = Code::kAfterLast; | 166 static constexpr int kMaxNumRegisters = Code::kAfterLast; |
| 171 | 167 |
| 172 inline static int NumRegisters(); | 168 inline static int NumRegisters(); |
| 173 | 169 |
| 174 // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers | 170 // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers |
| 175 // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to | 171 // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to |
| 176 // number of Double regs (64-bit regs, or FPU-reg-pairs). | 172 // number of Double regs (64-bit regs, or FPU-reg-pairs). |
| 177 | 173 |
| 178 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } | 174 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } |
| 179 bool is(FPURegister reg) const { return reg_code == reg.reg_code; } | 175 bool is(FPURegister reg) const { return reg_code == reg.reg_code; } |
| 180 FPURegister low() const { | 176 FPURegister low() const { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 193 FPURegister reg; | 189 FPURegister reg; |
| 194 reg.reg_code = reg_code + 1; | 190 reg.reg_code = reg_code + 1; |
| 195 DCHECK(reg.is_valid()); | 191 DCHECK(reg.is_valid()); |
| 196 return reg; | 192 return reg; |
| 197 } | 193 } |
| 198 | 194 |
| 199 int code() const { | 195 int code() const { |
| 200 DCHECK(is_valid()); | 196 DCHECK(is_valid()); |
| 201 return reg_code; | 197 return reg_code; |
| 202 } | 198 } |
| 203 int bit() const { | 199 constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; } |
| 204 DCHECK(is_valid()); | |
| 205 return 1 << reg_code; | |
| 206 } | |
| 207 | 200 |
| 208 static FPURegister from_code(int code) { | 201 static FPURegister from_code(int code) { |
| 209 FPURegister r = {code}; | 202 FPURegister r = {code}; |
| 210 return r; | 203 return r; |
| 211 } | 204 } |
| 212 void setcode(int f) { | 205 void setcode(int f) { |
| 213 reg_code = f; | 206 reg_code = f; |
| 214 DCHECK(is_valid()); | 207 DCHECK(is_valid()); |
| 215 } | 208 } |
| 216 // Unfortunately we can't make this private in a struct. | 209 // Unfortunately we can't make this private in a struct. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 231 // but it is not in common use. Someday we will want to support this in v8.) | 224 // but it is not in common use. Someday we will want to support this in v8.) |
| 232 | 225 |
| 233 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. | 226 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. |
| 234 typedef FPURegister FloatRegister; | 227 typedef FPURegister FloatRegister; |
| 235 | 228 |
| 236 typedef FPURegister DoubleRegister; | 229 typedef FPURegister DoubleRegister; |
| 237 | 230 |
| 238 // TODO(mips64) Define SIMD registers. | 231 // TODO(mips64) Define SIMD registers. |
| 239 typedef FPURegister Simd128Register; | 232 typedef FPURegister Simd128Register; |
| 240 | 233 |
| 241 const DoubleRegister no_freg = {-1}; | 234 constexpr DoubleRegister no_freg = {-1}; |
| 242 | 235 |
| 243 const DoubleRegister f0 = {0}; // Return value in hard float mode. | 236 constexpr DoubleRegister f0 = {0}; // Return value in hard float mode. |
| 244 const DoubleRegister f1 = {1}; | 237 constexpr DoubleRegister f1 = {1}; |
| 245 const DoubleRegister f2 = {2}; | 238 constexpr DoubleRegister f2 = {2}; |
| 246 const DoubleRegister f3 = {3}; | 239 constexpr DoubleRegister f3 = {3}; |
| 247 const DoubleRegister f4 = {4}; | 240 constexpr DoubleRegister f4 = {4}; |
| 248 const DoubleRegister f5 = {5}; | 241 constexpr DoubleRegister f5 = {5}; |
| 249 const DoubleRegister f6 = {6}; | 242 constexpr DoubleRegister f6 = {6}; |
| 250 const DoubleRegister f7 = {7}; | 243 constexpr DoubleRegister f7 = {7}; |
| 251 const DoubleRegister f8 = {8}; | 244 constexpr DoubleRegister f8 = {8}; |
| 252 const DoubleRegister f9 = {9}; | 245 constexpr DoubleRegister f9 = {9}; |
| 253 const DoubleRegister f10 = {10}; | 246 constexpr DoubleRegister f10 = {10}; |
| 254 const DoubleRegister f11 = {11}; | 247 constexpr DoubleRegister f11 = {11}; |
| 255 const DoubleRegister f12 = {12}; // Arg 0 in hard float mode. | 248 constexpr DoubleRegister f12 = {12}; // Arg 0 in hard float mode. |
| 256 const DoubleRegister f13 = {13}; | 249 constexpr DoubleRegister f13 = {13}; |
| 257 const DoubleRegister f14 = {14}; // Arg 1 in hard float mode. | 250 constexpr DoubleRegister f14 = {14}; // Arg 1 in hard float mode. |
| 258 const DoubleRegister f15 = {15}; | 251 constexpr DoubleRegister f15 = {15}; |
| 259 const DoubleRegister f16 = {16}; | 252 constexpr DoubleRegister f16 = {16}; |
| 260 const DoubleRegister f17 = {17}; | 253 constexpr DoubleRegister f17 = {17}; |
| 261 const DoubleRegister f18 = {18}; | 254 constexpr DoubleRegister f18 = {18}; |
| 262 const DoubleRegister f19 = {19}; | 255 constexpr DoubleRegister f19 = {19}; |
| 263 const DoubleRegister f20 = {20}; | 256 constexpr DoubleRegister f20 = {20}; |
| 264 const DoubleRegister f21 = {21}; | 257 constexpr DoubleRegister f21 = {21}; |
| 265 const DoubleRegister f22 = {22}; | 258 constexpr DoubleRegister f22 = {22}; |
| 266 const DoubleRegister f23 = {23}; | 259 constexpr DoubleRegister f23 = {23}; |
| 267 const DoubleRegister f24 = {24}; | 260 constexpr DoubleRegister f24 = {24}; |
| 268 const DoubleRegister f25 = {25}; | 261 constexpr DoubleRegister f25 = {25}; |
| 269 const DoubleRegister f26 = {26}; | 262 constexpr DoubleRegister f26 = {26}; |
| 270 const DoubleRegister f27 = {27}; | 263 constexpr DoubleRegister f27 = {27}; |
| 271 const DoubleRegister f28 = {28}; | 264 constexpr DoubleRegister f28 = {28}; |
| 272 const DoubleRegister f29 = {29}; | 265 constexpr DoubleRegister f29 = {29}; |
| 273 const DoubleRegister f30 = {30}; | 266 constexpr DoubleRegister f30 = {30}; |
| 274 const DoubleRegister f31 = {31}; | 267 constexpr DoubleRegister f31 = {31}; |
| 275 | 268 |
| 276 // Register aliases. | 269 // Register aliases. |
| 277 // cp is assumed to be a callee saved register. | 270 // cp is assumed to be a callee saved register. |
| 278 // Defined using #define instead of "static const Register&" because Clang | 271 constexpr Register kRootRegister = s6; |
| 279 // complains otherwise when a compilation unit that includes this header | 272 constexpr Register cp = s7; |
| 280 // doesn't use the variables. | 273 constexpr Register kLithiumScratchReg = s3; |
| 281 #define kRootRegister s6 | 274 constexpr Register kLithiumScratchReg2 = s4; |
| 282 #define cp s7 | 275 constexpr DoubleRegister kLithiumScratchDouble = f30; |
| 283 #define kLithiumScratchReg s3 | 276 constexpr DoubleRegister kDoubleRegZero = f28; |
| 284 #define kLithiumScratchReg2 s4 | |
| 285 #define kLithiumScratchDouble f30 | |
| 286 #define kDoubleRegZero f28 | |
| 287 // Used on mips64r6 for compare operations. | 277 // Used on mips64r6 for compare operations. |
| 288 // We use the last non-callee saved odd register for N64 ABI | 278 // We use the last non-callee saved odd register for N64 ABI |
| 289 #define kDoubleCompareReg f23 | 279 constexpr DoubleRegister kDoubleCompareReg = f23; |
| 290 | 280 |
| 291 // FPU (coprocessor 1) control registers. | 281 // FPU (coprocessor 1) control registers. |
| 292 // Currently only FCSR (#31) is implemented. | 282 // Currently only FCSR (#31) is implemented. |
| 293 struct FPUControlRegister { | 283 struct FPUControlRegister { |
| 294 bool is_valid() const { return reg_code == kFCSRRegister; } | 284 bool is_valid() const { return reg_code == kFCSRRegister; } |
| 295 bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; } | 285 bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; } |
| 296 int code() const { | 286 int code() const { |
| 297 DCHECK(is_valid()); | 287 DCHECK(is_valid()); |
| 298 return reg_code; | 288 return reg_code; |
| 299 } | 289 } |
| 300 int bit() const { | 290 constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; } |
| 301 DCHECK(is_valid()); | |
| 302 return 1 << reg_code; | |
| 303 } | |
| 304 void setcode(int f) { | 291 void setcode(int f) { |
| 305 reg_code = f; | 292 reg_code = f; |
| 306 DCHECK(is_valid()); | 293 DCHECK(is_valid()); |
| 307 } | 294 } |
| 308 // Unfortunately we can't make this private in a struct. | 295 // Unfortunately we can't make this private in a struct. |
| 309 int reg_code; | 296 int reg_code; |
| 310 }; | 297 }; |
| 311 | 298 |
| 312 const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; | 299 constexpr FPUControlRegister no_fpucreg = {kInvalidFPUControlRegister}; |
| 313 const FPUControlRegister FCSR = { kFCSRRegister }; | 300 constexpr FPUControlRegister FCSR = {kFCSRRegister}; |
| 314 | 301 |
| 315 // ----------------------------------------------------------------------------- | 302 // ----------------------------------------------------------------------------- |
| 316 // Machine instruction Operands. | 303 // Machine instruction Operands. |
| 317 const int kSmiShift = kSmiTagSize + kSmiShiftSize; | 304 constexpr int kSmiShift = kSmiTagSize + kSmiShiftSize; |
| 318 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; | 305 constexpr uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; |
| 319 // Class Operand represents a shifter operand in data processing instructions. | 306 // Class Operand represents a shifter operand in data processing instructions. |
| 320 class Operand BASE_EMBEDDED { | 307 class Operand BASE_EMBEDDED { |
| 321 public: | 308 public: |
| 322 // Immediate. | 309 // Immediate. |
| 323 INLINE(explicit Operand(int64_t immediate, | 310 INLINE(explicit Operand(int64_t immediate, |
| 324 RelocInfo::Mode rmode = RelocInfo::NONE64)); | 311 RelocInfo::Mode rmode = RelocInfo::NONE64)); |
| 325 INLINE(explicit Operand(const ExternalReference& f)); | 312 INLINE(explicit Operand(const ExternalReference& f)); |
| 326 INLINE(explicit Operand(const char* s)); | 313 INLINE(explicit Operand(const char* s)); |
| 327 INLINE(explicit Operand(Object** opp)); | 314 INLINE(explicit Operand(Object** opp)); |
| 328 INLINE(explicit Operand(Context** cpp)); | 315 INLINE(explicit Operand(Context** cpp)); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 instruction_payload - kInstructionsFor64BitConstant * kInstrSize, code, | 489 instruction_payload - kInstructionsFor64BitConstant * kInstrSize, code, |
| 503 target); | 490 target); |
| 504 } | 491 } |
| 505 | 492 |
| 506 // This sets the internal reference at the pc. | 493 // This sets the internal reference at the pc. |
| 507 inline static void deserialization_set_target_internal_reference_at( | 494 inline static void deserialization_set_target_internal_reference_at( |
| 508 Isolate* isolate, Address pc, Address target, | 495 Isolate* isolate, Address pc, Address target, |
| 509 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); | 496 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); |
| 510 | 497 |
| 511 // Size of an instruction. | 498 // Size of an instruction. |
| 512 static const int kInstrSize = sizeof(Instr); | 499 static constexpr int kInstrSize = sizeof(Instr); |
| 513 | 500 |
| 514 // Difference between address of current opcode and target address offset. | 501 // Difference between address of current opcode and target address offset. |
| 515 static const int kBranchPCOffset = 4; | 502 static constexpr int kBranchPCOffset = 4; |
| 516 | 503 |
| 517 // Here we are patching the address in the LUI/ORI instruction pair. | 504 // Here we are patching the address in the LUI/ORI instruction pair. |
| 518 // These values are used in the serialization process and must be zero for | 505 // These values are used in the serialization process and must be zero for |
| 519 // MIPS platform, as Code, Embedded Object or External-reference pointers | 506 // MIPS platform, as Code, Embedded Object or External-reference pointers |
| 520 // are split across two consecutive instructions and don't exist separately | 507 // are split across two consecutive instructions and don't exist separately |
| 521 // in the code, so the serializer should not step forwards in memory after | 508 // in the code, so the serializer should not step forwards in memory after |
| 522 // a target is resolved and written. | 509 // a target is resolved and written. |
| 523 static const int kSpecialTargetSize = 0; | 510 static constexpr int kSpecialTargetSize = 0; |
| 524 | 511 |
| 525 // Number of consecutive instructions used to store 32bit/64bit constant. | 512 // Number of consecutive instructions used to store 32bit/64bit constant. |
| 526 // This constant was used in RelocInfo::target_address_address() function | 513 // This constant was used in RelocInfo::target_address_address() function |
| 527 // to tell serializer address of the instruction that follows | 514 // to tell serializer address of the instruction that follows |
| 528 // LUI/ORI instruction pair. | 515 // LUI/ORI instruction pair. |
| 529 static const int kInstructionsFor32BitConstant = 2; | 516 static constexpr int kInstructionsFor32BitConstant = 2; |
| 530 static const int kInstructionsFor64BitConstant = 4; | 517 static constexpr int kInstructionsFor64BitConstant = 4; |
| 531 | 518 |
| 532 // Distance between the instruction referring to the address of the call | 519 // Distance between the instruction referring to the address of the call |
| 533 // target and the return address. | 520 // target and the return address. |
| 534 #ifdef _MIPS_ARCH_MIPS64R6 | 521 #ifdef _MIPS_ARCH_MIPS64R6 |
| 535 static const int kCallTargetAddressOffset = 5 * kInstrSize; | 522 static constexpr int kCallTargetAddressOffset = 5 * kInstrSize; |
| 536 #else | 523 #else |
| 537 static const int kCallTargetAddressOffset = 6 * kInstrSize; | 524 static constexpr int kCallTargetAddressOffset = 6 * kInstrSize; |
| 538 #endif | 525 #endif |
| 539 | 526 |
| 540 // Distance between start of patched debug break slot and the emitted address | 527 // Distance between start of patched debug break slot and the emitted address |
| 541 // to jump to. | 528 // to jump to. |
| 542 static const int kPatchDebugBreakSlotAddressOffset = 6 * kInstrSize; | 529 static constexpr int kPatchDebugBreakSlotAddressOffset = 6 * kInstrSize; |
| 543 | 530 |
| 544 // Difference between address of current opcode and value read from pc | 531 // Difference between address of current opcode and value read from pc |
| 545 // register. | 532 // register. |
| 546 static const int kPcLoadDelta = 4; | 533 static constexpr int kPcLoadDelta = 4; |
| 547 | 534 |
| 548 #ifdef _MIPS_ARCH_MIPS64R6 | 535 #ifdef _MIPS_ARCH_MIPS64R6 |
| 549 static const int kDebugBreakSlotInstructions = 5; | 536 static constexpr int kDebugBreakSlotInstructions = 5; |
| 550 #else | 537 #else |
| 551 static const int kDebugBreakSlotInstructions = 6; | 538 static constexpr int kDebugBreakSlotInstructions = 6; |
| 552 #endif | 539 #endif |
| 553 static const int kDebugBreakSlotLength = | 540 static constexpr int kDebugBreakSlotLength = |
| 554 kDebugBreakSlotInstructions * kInstrSize; | 541 kDebugBreakSlotInstructions * kInstrSize; |
| 555 | 542 |
| 556 // Max offset for instructions with 16-bit offset field | 543 // Max offset for instructions with 16-bit offset field |
| 557 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; | 544 static constexpr int kMaxBranchOffset = (1 << (18 - 1)) - 1; |
| 558 | 545 |
| 559 // Max offset for compact branch instructions with 26-bit offset field | 546 // Max offset for compact branch instructions with 26-bit offset field |
| 560 static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1; | 547 static constexpr int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1; |
| 561 | 548 |
| 562 static const int kTrampolineSlotsSize = 2 * kInstrSize; | 549 static constexpr int kTrampolineSlotsSize = 2 * kInstrSize; |
| 563 | 550 |
| 564 // --------------------------------------------------------------------------- | 551 // --------------------------------------------------------------------------- |
| 565 // Code generation. | 552 // Code generation. |
| 566 | 553 |
| 567 // Insert the smallest number of nop instructions | 554 // Insert the smallest number of nop instructions |
| 568 // possible to align the pc offset to a multiple | 555 // possible to align the pc offset to a multiple |
| 569 // of m. m must be a power of 2 (>= 4). | 556 // of m. m must be a power of 2 (>= 4). |
| 570 void Align(int m); | 557 void Align(int m); |
| 571 // Insert the smallest number of zero bytes possible to align the pc offset | 558 // Insert the smallest number of zero bytes possible to align the pc offset |
| 572 // to a mulitple of m. m must be a power of 2 (>= 2). | 559 // to a mulitple of m. m must be a power of 2 (>= 2). |
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 if (IsPrevInstrCompactBranch()) { | 1293 if (IsPrevInstrCompactBranch()) { |
| 1307 nop(); | 1294 nop(); |
| 1308 } | 1295 } |
| 1309 } | 1296 } |
| 1310 | 1297 |
| 1311 inline void CheckTrampolinePoolQuick(int extra_instructions = 0); | 1298 inline void CheckTrampolinePoolQuick(int extra_instructions = 0); |
| 1312 | 1299 |
| 1313 private: | 1300 private: |
| 1314 // Buffer size and constant pool distance are checked together at regular | 1301 // Buffer size and constant pool distance are checked together at regular |
| 1315 // intervals of kBufferCheckInterval emitted bytes. | 1302 // intervals of kBufferCheckInterval emitted bytes. |
| 1316 static const int kBufferCheckInterval = 1*KB/2; | 1303 static constexpr int kBufferCheckInterval = 1 * KB / 2; |
| 1317 | 1304 |
| 1318 // Code generation. | 1305 // Code generation. |
| 1319 // The relocation writer's position is at least kGap bytes below the end of | 1306 // The relocation writer's position is at least kGap bytes below the end of |
| 1320 // the generated instructions. This is so that multi-instruction sequences do | 1307 // the generated instructions. This is so that multi-instruction sequences do |
| 1321 // not have to check for overflow. The same is true for writes of large | 1308 // not have to check for overflow. The same is true for writes of large |
| 1322 // relocation info entries. | 1309 // relocation info entries. |
| 1323 static const int kGap = 32; | 1310 static constexpr int kGap = 32; |
| 1324 | |
| 1325 | 1311 |
| 1326 // Repeated checking whether the trampoline pool should be emitted is rather | 1312 // Repeated checking whether the trampoline pool should be emitted is rather |
| 1327 // expensive. By default we only check again once a number of instructions | 1313 // expensive. By default we only check again once a number of instructions |
| 1328 // has been generated. | 1314 // has been generated. |
| 1329 static const int kCheckConstIntervalInst = 32; | 1315 static constexpr int kCheckConstIntervalInst = 32; |
| 1330 static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; | 1316 static constexpr int kCheckConstInterval = |
| 1317 kCheckConstIntervalInst * kInstrSize; |
| 1331 | 1318 |
| 1332 int next_buffer_check_; // pc offset of next buffer check. | 1319 int next_buffer_check_; // pc offset of next buffer check. |
| 1333 | 1320 |
| 1334 // Emission of the trampoline pool may be blocked in some code sequences. | 1321 // Emission of the trampoline pool may be blocked in some code sequences. |
| 1335 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. | 1322 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. |
| 1336 int no_trampoline_pool_before_; // Block emission before this pc offset. | 1323 int no_trampoline_pool_before_; // Block emission before this pc offset. |
| 1337 | 1324 |
| 1338 // Keep track of the last emitted pool to guarantee a maximal distance. | 1325 // Keep track of the last emitted pool to guarantee a maximal distance. |
| 1339 int last_trampoline_pool_end_; // pc offset of the end of the last pool. | 1326 int last_trampoline_pool_end_; // pc offset of the end of the last pool. |
| 1340 | 1327 |
| 1341 // Automatic growth of the assembly buffer may be blocked for some sequences. | 1328 // Automatic growth of the assembly buffer may be blocked for some sequences. |
| 1342 bool block_buffer_growth_; // Block growth when true. | 1329 bool block_buffer_growth_; // Block growth when true. |
| 1343 | 1330 |
| 1344 // Relocation information generation. | 1331 // Relocation information generation. |
| 1345 // Each relocation is encoded as a variable size value. | 1332 // Each relocation is encoded as a variable size value. |
| 1346 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1333 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
| 1347 RelocInfoWriter reloc_info_writer; | 1334 RelocInfoWriter reloc_info_writer; |
| 1348 | 1335 |
| 1349 // The bound position, before this we cannot do instruction elimination. | 1336 // The bound position, before this we cannot do instruction elimination. |
| 1350 int last_bound_pos_; | 1337 int last_bound_pos_; |
| 1351 | 1338 |
| 1352 // Readable constants for compact branch handling in emit() | 1339 // Readable constants for compact branch handling in emit() |
| 1353 enum class CompactBranchType : bool { NO = false, COMPACT_BRANCH = true }; | 1340 enum class CompactBranchType : bool { NO = false, COMPACT_BRANCH = true }; |
| 1354 | 1341 |
| 1355 // Code emission. | 1342 // Code emission. |
| 1356 inline void CheckBuffer(); | 1343 inline void CheckBuffer(); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 }; | 1477 }; |
| 1491 | 1478 |
| 1492 int32_t get_trampoline_entry(int32_t pos); | 1479 int32_t get_trampoline_entry(int32_t pos); |
| 1493 int unbound_labels_count_; | 1480 int unbound_labels_count_; |
| 1494 // After trampoline is emitted, long branches are used in generated code for | 1481 // After trampoline is emitted, long branches are used in generated code for |
| 1495 // the forward branches whose target offsets could be beyond reach of branch | 1482 // the forward branches whose target offsets could be beyond reach of branch |
| 1496 // instruction. We use this information to trigger different mode of | 1483 // instruction. We use this information to trigger different mode of |
| 1497 // branch instruction generation, where we use jump instructions rather | 1484 // branch instruction generation, where we use jump instructions rather |
| 1498 // than regular branch instructions. | 1485 // than regular branch instructions. |
| 1499 bool trampoline_emitted_; | 1486 bool trampoline_emitted_; |
| 1500 static const int kInvalidSlotPos = -1; | 1487 static constexpr int kInvalidSlotPos = -1; |
| 1501 | 1488 |
| 1502 // Internal reference positions, required for unbounded internal reference | 1489 // Internal reference positions, required for unbounded internal reference |
| 1503 // labels. | 1490 // labels. |
| 1504 std::set<int64_t> internal_reference_positions_; | 1491 std::set<int64_t> internal_reference_positions_; |
| 1505 bool is_internal_reference(Label* L) { | 1492 bool is_internal_reference(Label* L) { |
| 1506 return internal_reference_positions_.find(L->pos()) != | 1493 return internal_reference_positions_.find(L->pos()) != |
| 1507 internal_reference_positions_.end(); | 1494 internal_reference_positions_.end(); |
| 1508 } | 1495 } |
| 1509 | 1496 |
| 1510 void EmittedCompactBranchInstruction() { prev_instr_compact_branch_ = true; } | 1497 void EmittedCompactBranchInstruction() { prev_instr_compact_branch_ = true; } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1526 public: | 1513 public: |
| 1527 explicit EnsureSpace(Assembler* assembler) { | 1514 explicit EnsureSpace(Assembler* assembler) { |
| 1528 assembler->CheckBuffer(); | 1515 assembler->CheckBuffer(); |
| 1529 } | 1516 } |
| 1530 }; | 1517 }; |
| 1531 | 1518 |
| 1532 } // namespace internal | 1519 } // namespace internal |
| 1533 } // namespace v8 | 1520 } // namespace v8 |
| 1534 | 1521 |
| 1535 #endif // V8_ARM_ASSEMBLER_MIPS_H_ | 1522 #endif // V8_ARM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |