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 | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 // Core register | 93 // Core register |
94 struct Register { | 94 struct Register { |
95 static const int kNumRegisters = 16; | 95 static const int kNumRegisters = 16; |
96 static const int kMaxNumAllocatableRegisters = | 96 static const int kMaxNumAllocatableRegisters = |
97 FLAG_enable_ool_constant_pool ? 8 : 9; | 97 FLAG_enable_ool_constant_pool ? 8 : 9; |
98 static const int kSizeInBytes = 4; | 98 static const int kSizeInBytes = 4; |
99 | 99 |
100 inline static int NumAllocatableRegisters(); | 100 inline static int NumAllocatableRegisters(); |
101 | 101 |
102 static int ToAllocationIndex(Register reg) { | 102 static int ToAllocationIndex(Register reg) { |
103 ASSERT(reg.code() < kMaxNumAllocatableRegisters); | 103 DCHECK(reg.code() < kMaxNumAllocatableRegisters); |
104 return reg.code(); | 104 return reg.code(); |
105 } | 105 } |
106 | 106 |
107 static Register FromAllocationIndex(int index) { | 107 static Register FromAllocationIndex(int index) { |
108 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | 108 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); |
109 return from_code(index); | 109 return from_code(index); |
110 } | 110 } |
111 | 111 |
112 static const char* AllocationIndexToString(int index) { | 112 static const char* AllocationIndexToString(int index) { |
113 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | 113 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); |
114 const char* const names[] = { | 114 const char* const names[] = { |
115 "r0", | 115 "r0", |
116 "r1", | 116 "r1", |
117 "r2", | 117 "r2", |
118 "r3", | 118 "r3", |
119 "r4", | 119 "r4", |
120 "r5", | 120 "r5", |
121 "r6", | 121 "r6", |
122 "r7", | 122 "r7", |
123 "r8", | 123 "r8", |
124 }; | 124 }; |
125 if (FLAG_enable_ool_constant_pool && (index >= 7)) { | 125 if (FLAG_enable_ool_constant_pool && (index >= 7)) { |
126 return names[index + 1]; | 126 return names[index + 1]; |
127 } | 127 } |
128 return names[index]; | 128 return names[index]; |
129 } | 129 } |
130 | 130 |
131 static Register from_code(int code) { | 131 static Register from_code(int code) { |
132 Register r = { code }; | 132 Register r = { code }; |
133 return r; | 133 return r; |
134 } | 134 } |
135 | 135 |
136 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 136 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
137 bool is(Register reg) const { return code_ == reg.code_; } | 137 bool is(Register reg) const { return code_ == reg.code_; } |
138 int code() const { | 138 int code() const { |
139 ASSERT(is_valid()); | 139 DCHECK(is_valid()); |
140 return code_; | 140 return code_; |
141 } | 141 } |
142 int bit() const { | 142 int bit() const { |
143 ASSERT(is_valid()); | 143 DCHECK(is_valid()); |
144 return 1 << code_; | 144 return 1 << code_; |
145 } | 145 } |
146 | 146 |
147 void set_code(int code) { | 147 void set_code(int code) { |
148 code_ = code; | 148 code_ = code; |
149 ASSERT(is_valid()); | 149 DCHECK(is_valid()); |
150 } | 150 } |
151 | 151 |
152 // Unfortunately we can't make this private in a struct. | 152 // Unfortunately we can't make this private in a struct. |
153 int code_; | 153 int code_; |
154 }; | 154 }; |
155 | 155 |
156 const Register no_reg = { kRegister_no_reg_Code }; | 156 const Register no_reg = { kRegister_no_reg_Code }; |
157 | 157 |
158 const Register r0 = { kRegister_r0_Code }; | 158 const Register r0 = { kRegister_r0_Code }; |
159 const Register r1 = { kRegister_r1_Code }; | 159 const Register r1 = { kRegister_r1_Code }; |
(...skipping 15 matching lines...) Expand all Loading... |
175 const Register sp = { kRegister_sp_Code }; | 175 const Register sp = { kRegister_sp_Code }; |
176 const Register lr = { kRegister_lr_Code }; | 176 const Register lr = { kRegister_lr_Code }; |
177 const Register pc = { kRegister_pc_Code }; | 177 const Register pc = { kRegister_pc_Code }; |
178 | 178 |
179 // Single word VFP register. | 179 // Single word VFP register. |
180 struct SwVfpRegister { | 180 struct SwVfpRegister { |
181 static const int kSizeInBytes = 4; | 181 static const int kSizeInBytes = 4; |
182 bool is_valid() const { return 0 <= code_ && code_ < 32; } | 182 bool is_valid() const { return 0 <= code_ && code_ < 32; } |
183 bool is(SwVfpRegister reg) const { return code_ == reg.code_; } | 183 bool is(SwVfpRegister reg) const { return code_ == reg.code_; } |
184 int code() const { | 184 int code() const { |
185 ASSERT(is_valid()); | 185 DCHECK(is_valid()); |
186 return code_; | 186 return code_; |
187 } | 187 } |
188 int bit() const { | 188 int bit() const { |
189 ASSERT(is_valid()); | 189 DCHECK(is_valid()); |
190 return 1 << code_; | 190 return 1 << code_; |
191 } | 191 } |
192 void split_code(int* vm, int* m) const { | 192 void split_code(int* vm, int* m) const { |
193 ASSERT(is_valid()); | 193 DCHECK(is_valid()); |
194 *m = code_ & 0x1; | 194 *m = code_ & 0x1; |
195 *vm = code_ >> 1; | 195 *vm = code_ >> 1; |
196 } | 196 } |
197 | 197 |
198 int code_; | 198 int code_; |
199 }; | 199 }; |
200 | 200 |
201 | 201 |
202 // Double word VFP register. | 202 // Double word VFP register. |
203 struct DwVfpRegister { | 203 struct DwVfpRegister { |
(...skipping 21 matching lines...) Expand all Loading... |
225 static DwVfpRegister from_code(int code) { | 225 static DwVfpRegister from_code(int code) { |
226 DwVfpRegister r = { code }; | 226 DwVfpRegister r = { code }; |
227 return r; | 227 return r; |
228 } | 228 } |
229 | 229 |
230 bool is_valid() const { | 230 bool is_valid() const { |
231 return 0 <= code_ && code_ < kMaxNumRegisters; | 231 return 0 <= code_ && code_ < kMaxNumRegisters; |
232 } | 232 } |
233 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } | 233 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } |
234 int code() const { | 234 int code() const { |
235 ASSERT(is_valid()); | 235 DCHECK(is_valid()); |
236 return code_; | 236 return code_; |
237 } | 237 } |
238 int bit() const { | 238 int bit() const { |
239 ASSERT(is_valid()); | 239 DCHECK(is_valid()); |
240 return 1 << code_; | 240 return 1 << code_; |
241 } | 241 } |
242 void split_code(int* vm, int* m) const { | 242 void split_code(int* vm, int* m) const { |
243 ASSERT(is_valid()); | 243 DCHECK(is_valid()); |
244 *m = (code_ & 0x10) >> 4; | 244 *m = (code_ & 0x10) >> 4; |
245 *vm = code_ & 0x0F; | 245 *vm = code_ & 0x0F; |
246 } | 246 } |
247 | 247 |
248 int code_; | 248 int code_; |
249 }; | 249 }; |
250 | 250 |
251 | 251 |
252 typedef DwVfpRegister DoubleRegister; | 252 typedef DwVfpRegister DoubleRegister; |
253 | 253 |
(...skipping 10 matching lines...) Expand all Loading... |
264 LowDwVfpRegister r = { code }; | 264 LowDwVfpRegister r = { code }; |
265 return r; | 265 return r; |
266 } | 266 } |
267 | 267 |
268 bool is_valid() const { | 268 bool is_valid() const { |
269 return 0 <= code_ && code_ < kMaxNumLowRegisters; | 269 return 0 <= code_ && code_ < kMaxNumLowRegisters; |
270 } | 270 } |
271 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } | 271 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } |
272 bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; } | 272 bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; } |
273 int code() const { | 273 int code() const { |
274 ASSERT(is_valid()); | 274 DCHECK(is_valid()); |
275 return code_; | 275 return code_; |
276 } | 276 } |
277 SwVfpRegister low() const { | 277 SwVfpRegister low() const { |
278 SwVfpRegister reg; | 278 SwVfpRegister reg; |
279 reg.code_ = code_ * 2; | 279 reg.code_ = code_ * 2; |
280 | 280 |
281 ASSERT(reg.is_valid()); | 281 DCHECK(reg.is_valid()); |
282 return reg; | 282 return reg; |
283 } | 283 } |
284 SwVfpRegister high() const { | 284 SwVfpRegister high() const { |
285 SwVfpRegister reg; | 285 SwVfpRegister reg; |
286 reg.code_ = (code_ * 2) + 1; | 286 reg.code_ = (code_ * 2) + 1; |
287 | 287 |
288 ASSERT(reg.is_valid()); | 288 DCHECK(reg.is_valid()); |
289 return reg; | 289 return reg; |
290 } | 290 } |
291 | 291 |
292 int code_; | 292 int code_; |
293 }; | 293 }; |
294 | 294 |
295 | 295 |
296 // Quad word NEON register. | 296 // Quad word NEON register. |
297 struct QwNeonRegister { | 297 struct QwNeonRegister { |
298 static const int kMaxNumRegisters = 16; | 298 static const int kMaxNumRegisters = 16; |
299 | 299 |
300 static QwNeonRegister from_code(int code) { | 300 static QwNeonRegister from_code(int code) { |
301 QwNeonRegister r = { code }; | 301 QwNeonRegister r = { code }; |
302 return r; | 302 return r; |
303 } | 303 } |
304 | 304 |
305 bool is_valid() const { | 305 bool is_valid() const { |
306 return (0 <= code_) && (code_ < kMaxNumRegisters); | 306 return (0 <= code_) && (code_ < kMaxNumRegisters); |
307 } | 307 } |
308 bool is(QwNeonRegister reg) const { return code_ == reg.code_; } | 308 bool is(QwNeonRegister reg) const { return code_ == reg.code_; } |
309 int code() const { | 309 int code() const { |
310 ASSERT(is_valid()); | 310 DCHECK(is_valid()); |
311 return code_; | 311 return code_; |
312 } | 312 } |
313 void split_code(int* vm, int* m) const { | 313 void split_code(int* vm, int* m) const { |
314 ASSERT(is_valid()); | 314 DCHECK(is_valid()); |
315 int encoded_code = code_ << 1; | 315 int encoded_code = code_ << 1; |
316 *m = (encoded_code & 0x10) >> 4; | 316 *m = (encoded_code & 0x10) >> 4; |
317 *vm = encoded_code & 0x0F; | 317 *vm = encoded_code & 0x0F; |
318 } | 318 } |
319 | 319 |
320 int code_; | 320 int code_; |
321 }; | 321 }; |
322 | 322 |
323 | 323 |
324 typedef QwNeonRegister QuadRegister; | 324 typedef QwNeonRegister QuadRegister; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 #define kLastCalleeSavedDoubleReg d15 | 418 #define kLastCalleeSavedDoubleReg d15 |
419 #define kDoubleRegZero d14 | 419 #define kDoubleRegZero d14 |
420 #define kScratchDoubleReg d15 | 420 #define kScratchDoubleReg d15 |
421 | 421 |
422 | 422 |
423 // Coprocessor register | 423 // Coprocessor register |
424 struct CRegister { | 424 struct CRegister { |
425 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 425 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
426 bool is(CRegister creg) const { return code_ == creg.code_; } | 426 bool is(CRegister creg) const { return code_ == creg.code_; } |
427 int code() const { | 427 int code() const { |
428 ASSERT(is_valid()); | 428 DCHECK(is_valid()); |
429 return code_; | 429 return code_; |
430 } | 430 } |
431 int bit() const { | 431 int bit() const { |
432 ASSERT(is_valid()); | 432 DCHECK(is_valid()); |
433 return 1 << code_; | 433 return 1 << code_; |
434 } | 434 } |
435 | 435 |
436 // Unfortunately we can't make this private in a struct. | 436 // Unfortunately we can't make this private in a struct. |
437 int code_; | 437 int code_; |
438 }; | 438 }; |
439 | 439 |
440 | 440 |
441 const CRegister no_creg = { -1 }; | 441 const CRegister no_creg = { -1 }; |
442 | 442 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 // the instruction this operand is used for is a MOV or MVN instruction the | 526 // the instruction this operand is used for is a MOV or MVN instruction the |
527 // actual instruction to use is required for this calculation. For other | 527 // actual instruction to use is required for this calculation. For other |
528 // instructions instr is ignored. | 528 // instructions instr is ignored. |
529 // | 529 // |
530 // The value returned is only valid as long as no entries are added to the | 530 // The value returned is only valid as long as no entries are added to the |
531 // constant pool between this call and the actual instruction being emitted. | 531 // constant pool between this call and the actual instruction being emitted. |
532 int instructions_required(const Assembler* assembler, Instr instr = 0) const; | 532 int instructions_required(const Assembler* assembler, Instr instr = 0) const; |
533 bool must_output_reloc_info(const Assembler* assembler) const; | 533 bool must_output_reloc_info(const Assembler* assembler) const; |
534 | 534 |
535 inline int32_t immediate() const { | 535 inline int32_t immediate() const { |
536 ASSERT(!rm_.is_valid()); | 536 DCHECK(!rm_.is_valid()); |
537 return imm32_; | 537 return imm32_; |
538 } | 538 } |
539 | 539 |
540 Register rm() const { return rm_; } | 540 Register rm() const { return rm_; } |
541 Register rs() const { return rs_; } | 541 Register rs() const { return rs_; } |
542 ShiftOp shift_op() const { return shift_op_; } | 542 ShiftOp shift_op() const { return shift_op_; } |
543 | 543 |
544 private: | 544 private: |
545 Register rm_; | 545 Register rm_; |
546 Register rs_; | 546 Register rs_; |
(...skipping 27 matching lines...) Expand all Loading... |
574 explicit MemOperand(Register rn, Register rm, | 574 explicit MemOperand(Register rn, Register rm, |
575 ShiftOp shift_op, int shift_imm, AddrMode am = Offset); | 575 ShiftOp shift_op, int shift_imm, AddrMode am = Offset); |
576 INLINE(static MemOperand PointerAddressFromSmiKey(Register array, | 576 INLINE(static MemOperand PointerAddressFromSmiKey(Register array, |
577 Register key, | 577 Register key, |
578 AddrMode am = Offset)) { | 578 AddrMode am = Offset)) { |
579 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); | 579 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
580 return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am); | 580 return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am); |
581 } | 581 } |
582 | 582 |
583 void set_offset(int32_t offset) { | 583 void set_offset(int32_t offset) { |
584 ASSERT(rm_.is(no_reg)); | 584 DCHECK(rm_.is(no_reg)); |
585 offset_ = offset; | 585 offset_ = offset; |
586 } | 586 } |
587 | 587 |
588 uint32_t offset() const { | 588 uint32_t offset() const { |
589 ASSERT(rm_.is(no_reg)); | 589 DCHECK(rm_.is(no_reg)); |
590 return offset_; | 590 return offset_; |
591 } | 591 } |
592 | 592 |
593 Register rn() const { return rn_; } | 593 Register rn() const { return rn_; } |
594 Register rm() const { return rm_; } | 594 Register rm() const { return rm_; } |
595 AddrMode am() const { return am_; } | 595 AddrMode am() const { return am_; } |
596 | 596 |
597 bool OffsetIsUint12Encodable() const { | 597 bool OffsetIsUint12Encodable() const { |
598 return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_); | 598 return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_); |
599 } | 599 } |
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1346 | 1346 |
1347 // Mark address of the ExitJSFrame code. | 1347 // Mark address of the ExitJSFrame code. |
1348 void RecordJSReturn(); | 1348 void RecordJSReturn(); |
1349 | 1349 |
1350 // Mark address of a debug break slot. | 1350 // Mark address of a debug break slot. |
1351 void RecordDebugBreakSlot(); | 1351 void RecordDebugBreakSlot(); |
1352 | 1352 |
1353 // Record the AST id of the CallIC being compiled, so that it can be placed | 1353 // Record the AST id of the CallIC being compiled, so that it can be placed |
1354 // in the relocation information. | 1354 // in the relocation information. |
1355 void SetRecordedAstId(TypeFeedbackId ast_id) { | 1355 void SetRecordedAstId(TypeFeedbackId ast_id) { |
1356 ASSERT(recorded_ast_id_.IsNone()); | 1356 DCHECK(recorded_ast_id_.IsNone()); |
1357 recorded_ast_id_ = ast_id; | 1357 recorded_ast_id_ = ast_id; |
1358 } | 1358 } |
1359 | 1359 |
1360 TypeFeedbackId RecordedAstId() { | 1360 TypeFeedbackId RecordedAstId() { |
1361 ASSERT(!recorded_ast_id_.IsNone()); | 1361 DCHECK(!recorded_ast_id_.IsNone()); |
1362 return recorded_ast_id_; | 1362 return recorded_ast_id_; |
1363 } | 1363 } |
1364 | 1364 |
1365 void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); } | 1365 void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); } |
1366 | 1366 |
1367 // Record a comment relocation entry that can be used by a disassembler. | 1367 // Record a comment relocation entry that can be used by a disassembler. |
1368 // Use --code-comments to enable. | 1368 // Use --code-comments to enable. |
1369 void RecordComment(const char* msg); | 1369 void RecordComment(const char* msg); |
1370 | 1370 |
1371 // Record the emission of a constant pool. | 1371 // Record the emission of a constant pool. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1510 } | 1510 } |
1511 | 1511 |
1512 // Resume constant pool emission. Need to be called as many time as | 1512 // Resume constant pool emission. Need to be called as many time as |
1513 // StartBlockConstPool to have an effect. | 1513 // StartBlockConstPool to have an effect. |
1514 void EndBlockConstPool() { | 1514 void EndBlockConstPool() { |
1515 if (--const_pool_blocked_nesting_ == 0) { | 1515 if (--const_pool_blocked_nesting_ == 0) { |
1516 #ifdef DEBUG | 1516 #ifdef DEBUG |
1517 // Max pool start (if we need a jump and an alignment). | 1517 // Max pool start (if we need a jump and an alignment). |
1518 int start = pc_offset() + kInstrSize + 2 * kPointerSize; | 1518 int start = pc_offset() + kInstrSize + 2 * kPointerSize; |
1519 // Check the constant pool hasn't been blocked for too long. | 1519 // Check the constant pool hasn't been blocked for too long. |
1520 ASSERT((num_pending_32_bit_reloc_info_ == 0) || | 1520 DCHECK((num_pending_32_bit_reloc_info_ == 0) || |
1521 (start + num_pending_64_bit_reloc_info_ * kDoubleSize < | 1521 (start + num_pending_64_bit_reloc_info_ * kDoubleSize < |
1522 (first_const_pool_32_use_ + kMaxDistToIntPool))); | 1522 (first_const_pool_32_use_ + kMaxDistToIntPool))); |
1523 ASSERT((num_pending_64_bit_reloc_info_ == 0) || | 1523 DCHECK((num_pending_64_bit_reloc_info_ == 0) || |
1524 (start < (first_const_pool_64_use_ + kMaxDistToFPPool))); | 1524 (start < (first_const_pool_64_use_ + kMaxDistToFPPool))); |
1525 #endif | 1525 #endif |
1526 // Two cases: | 1526 // Two cases: |
1527 // * no_const_pool_before_ >= next_buffer_check_ and the emission is | 1527 // * no_const_pool_before_ >= next_buffer_check_ and the emission is |
1528 // still blocked | 1528 // still blocked |
1529 // * no_const_pool_before_ < next_buffer_check_ and the next emit will | 1529 // * no_const_pool_before_ < next_buffer_check_ and the next emit will |
1530 // trigger a check. | 1530 // trigger a check. |
1531 next_buffer_check_ = no_const_pool_before_; | 1531 next_buffer_check_ = no_const_pool_before_; |
1532 } | 1532 } |
1533 } | 1533 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1655 public: | 1655 public: |
1656 explicit EnsureSpace(Assembler* assembler) { | 1656 explicit EnsureSpace(Assembler* assembler) { |
1657 assembler->CheckBuffer(); | 1657 assembler->CheckBuffer(); |
1658 } | 1658 } |
1659 }; | 1659 }; |
1660 | 1660 |
1661 | 1661 |
1662 } } // namespace v8::internal | 1662 } } // namespace v8::internal |
1663 | 1663 |
1664 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1664 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |