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 |