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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 // Implementation of Operand and MemOperand | 157 // Implementation of Operand and MemOperand |
158 // See assembler-arm-inl.h for inlined constructors | 158 // See assembler-arm-inl.h for inlined constructors |
159 | 159 |
160 Operand::Operand(Handle<Object> handle) { | 160 Operand::Operand(Handle<Object> handle) { |
161 rm_ = no_reg; | 161 rm_ = no_reg; |
162 // Verify all Objects referred by code are NOT in new space. | 162 // Verify all Objects referred by code are NOT in new space. |
163 Object* obj = *handle; | 163 Object* obj = *handle; |
164 ASSERT(!Heap::InNewSpace(obj)); | 164 ASSERT(!Heap::InNewSpace(obj)); |
165 if (obj->IsHeapObject()) { | 165 if (obj->IsHeapObject()) { |
166 imm32_ = reinterpret_cast<intptr_t>(handle.location()); | 166 imm32_ = reinterpret_cast<intptr_t>(handle.location()); |
167 rmode_ = embedded_object; | 167 rmode_ = RelocInfo::EMBEDDED_OBJECT; |
168 } else { | 168 } else { |
169 // no relocation needed | 169 // no relocation needed |
170 imm32_ = reinterpret_cast<intptr_t>(obj); | 170 imm32_ = reinterpret_cast<intptr_t>(obj); |
171 rmode_ = no_reloc; | 171 rmode_ = RelocInfo::NONE; |
172 } | 172 } |
173 } | 173 } |
174 | 174 |
175 | 175 |
176 Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) { | 176 Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) { |
177 ASSERT(is_uint5(shift_imm)); | 177 ASSERT(is_uint5(shift_imm)); |
178 ASSERT(shift_op != ROR || shift_imm != 0); // use RRX if you mean it | 178 ASSERT(shift_op != ROR || shift_imm != 0); // use RRX if you mean it |
179 rm_ = rm; | 179 rm_ = rm; |
180 rs_ = no_reg; | 180 rs_ = no_reg; |
181 shift_op_ = shift_op; | 181 shift_op_ = shift_op; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 313 |
314 // setup buffer pointers | 314 // setup buffer pointers |
315 ASSERT(buffer_ != NULL); | 315 ASSERT(buffer_ != NULL); |
316 pc_ = buffer_; | 316 pc_ = buffer_; |
317 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); | 317 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); |
318 num_prinfo_ = 0; | 318 num_prinfo_ = 0; |
319 next_buffer_check_ = 0; | 319 next_buffer_check_ = 0; |
320 no_const_pool_before_ = 0; | 320 no_const_pool_before_ = 0; |
321 last_const_pool_end_ = 0; | 321 last_const_pool_end_ = 0; |
322 last_bound_pos_ = 0; | 322 last_bound_pos_ = 0; |
323 last_position_ = kNoPosition; | 323 last_position_ = RelocInfo::kNoPosition; |
324 last_position_is_statement_ = false; | 324 last_position_is_statement_ = false; |
325 } | 325 } |
326 | 326 |
327 | 327 |
328 Assembler::~Assembler() { | 328 Assembler::~Assembler() { |
329 if (own_buffer_) { | 329 if (own_buffer_) { |
330 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { | 330 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { |
331 spare_buffer_ = buffer_; | 331 spare_buffer_ = buffer_; |
332 } else { | 332 } else { |
333 DeleteArray(buffer_); | 333 DeleteArray(buffer_); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 void Assembler::addrmod1(Instr instr, | 581 void Assembler::addrmod1(Instr instr, |
582 Register rn, | 582 Register rn, |
583 Register rd, | 583 Register rd, |
584 const Operand& x) { | 584 const Operand& x) { |
585 CheckBuffer(); | 585 CheckBuffer(); |
586 ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0); | 586 ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0); |
587 if (!x.rm_.is_valid()) { | 587 if (!x.rm_.is_valid()) { |
588 // immediate | 588 // immediate |
589 uint32_t rotate_imm; | 589 uint32_t rotate_imm; |
590 uint32_t immed_8; | 590 uint32_t immed_8; |
591 if ((x.rmode_ != no_reloc && x.rmode_ != external_reference) || | 591 if ((x.rmode_ != RelocInfo::NONE && |
| 592 x.rmode_ != RelocInfo::EXTERNAL_REFERENCE) || |
592 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { | 593 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { |
593 // The immediate operand cannot be encoded as a shifter operand, so load | 594 // The immediate operand cannot be encoded as a shifter operand, so load |
594 // it first to register ip and change the original instruction to use ip. | 595 // it first to register ip and change the original instruction to use ip. |
595 // However, if the original instruction is a 'mov rd, x' (not setting the | 596 // However, if the original instruction is a 'mov rd, x' (not setting the |
596 // condition code), then replace it with a 'ldr rd, [pc]' | 597 // condition code), then replace it with a 'ldr rd, [pc]' |
597 RecordRelocInfo(x.rmode_, x.imm32_); | 598 RecordRelocInfo(x.rmode_, x.imm32_); |
598 ASSERT(!rn.is(ip)); // rn should never be ip, or will be trashed | 599 ASSERT(!rn.is(ip)); // rn should never be ip, or will be trashed |
599 Condition cond = static_cast<Condition>(instr & CondMask); | 600 Condition cond = static_cast<Condition>(instr & CondMask); |
600 if ((instr & ~CondMask) == 13*B21) { // mov, S not set | 601 if ((instr & ~CondMask) == 13*B21) { // mov, S not set |
601 ldr(rd, MemOperand(pc, 0), cond); | 602 ldr(rd, MemOperand(pc, 0), cond); |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 | 1000 |
1000 | 1001 |
1001 void Assembler::msr(SRegisterFieldMask fields, const Operand& src, | 1002 void Assembler::msr(SRegisterFieldMask fields, const Operand& src, |
1002 Condition cond) { | 1003 Condition cond) { |
1003 ASSERT(fields >= B16 && fields < B20); // at least one field set | 1004 ASSERT(fields >= B16 && fields < B20); // at least one field set |
1004 Instr instr; | 1005 Instr instr; |
1005 if (!src.rm_.is_valid()) { | 1006 if (!src.rm_.is_valid()) { |
1006 // immediate | 1007 // immediate |
1007 uint32_t rotate_imm; | 1008 uint32_t rotate_imm; |
1008 uint32_t immed_8; | 1009 uint32_t immed_8; |
1009 if ((src.rmode_ != no_reloc && src.rmode_ != external_reference)|| | 1010 if ((src.rmode_ != RelocInfo::NONE && |
| 1011 src.rmode_ != RelocInfo::EXTERNAL_REFERENCE)|| |
1010 !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { | 1012 !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { |
1011 // immediate operand cannot be encoded, load it first to register ip | 1013 // immediate operand cannot be encoded, load it first to register ip |
1012 RecordRelocInfo(src.rmode_, src.imm32_); | 1014 RecordRelocInfo(src.rmode_, src.imm32_); |
1013 ldr(ip, MemOperand(pc, 0), cond); | 1015 ldr(ip, MemOperand(pc, 0), cond); |
1014 msr(fields, Operand(ip), cond); | 1016 msr(fields, Operand(ip), cond); |
1015 return; | 1017 return; |
1016 } | 1018 } |
1017 instr = I | rotate_imm*B8 | immed_8; | 1019 instr = I | rotate_imm*B8 | immed_8; |
1018 } else { | 1020 } else { |
1019 ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0); // only rm allowed | 1021 ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0); // only rm allowed |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1346 else | 1348 else |
1347 add(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond); | 1349 add(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond); |
1348 } | 1350 } |
1349 } | 1351 } |
1350 | 1352 |
1351 | 1353 |
1352 // Debugging | 1354 // Debugging |
1353 void Assembler::RecordComment(const char* msg) { | 1355 void Assembler::RecordComment(const char* msg) { |
1354 if (FLAG_debug_code) { | 1356 if (FLAG_debug_code) { |
1355 CheckBuffer(); | 1357 CheckBuffer(); |
1356 RecordRelocInfo(comment, reinterpret_cast<intptr_t>(msg)); | 1358 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); |
1357 } | 1359 } |
1358 } | 1360 } |
1359 | 1361 |
1360 | 1362 |
1361 void Assembler::RecordPosition(int pos) { | 1363 void Assembler::RecordPosition(int pos) { |
1362 if (pos == kNoPosition) return; | 1364 if (pos == RelocInfo::kNoPosition) return; |
1363 ASSERT(position >= 0); | 1365 ASSERT(pos >= 0); |
1364 if (pos == last_position_) return; | 1366 if (pos == last_position_) return; |
1365 CheckBuffer(); | 1367 CheckBuffer(); |
1366 RecordRelocInfo(position, pos); | 1368 RecordRelocInfo(RelocInfo::POSITION, pos); |
1367 last_position_ = pos; | 1369 last_position_ = pos; |
1368 last_position_is_statement_ = false; | 1370 last_position_is_statement_ = false; |
1369 } | 1371 } |
1370 | 1372 |
1371 | 1373 |
1372 void Assembler::RecordStatementPosition(int pos) { | 1374 void Assembler::RecordStatementPosition(int pos) { |
1373 if (pos == last_position_) return; | 1375 if (pos == last_position_) return; |
1374 CheckBuffer(); | 1376 CheckBuffer(); |
1375 RecordRelocInfo(statement_position, pos); | 1377 RecordRelocInfo(RelocInfo::STATEMENT_POSITION, pos); |
1376 last_position_ = pos; | 1378 last_position_ = pos; |
1377 last_position_is_statement_ = true; | 1379 last_position_is_statement_ = true; |
1378 } | 1380 } |
1379 | 1381 |
1380 | 1382 |
1381 void Assembler::GrowBuffer() { | 1383 void Assembler::GrowBuffer() { |
1382 if (!own_buffer_) FATAL("external code buffer is too small"); | 1384 if (!own_buffer_) FATAL("external code buffer is too small"); |
1383 | 1385 |
1384 // compute new buffer size | 1386 // compute new buffer size |
1385 CodeDesc desc; // the new buffer | 1387 CodeDesc desc; // the new buffer |
(...skipping 27 matching lines...) Expand all Loading... |
1413 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, | 1415 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, |
1414 reloc_info_writer.last_pc() + pc_delta); | 1416 reloc_info_writer.last_pc() + pc_delta); |
1415 | 1417 |
1416 // none of our relocation types are pc relative pointing outside the code | 1418 // none of our relocation types are pc relative pointing outside the code |
1417 // buffer nor pc absolute pointing inside the code buffer, so there is no need | 1419 // buffer nor pc absolute pointing inside the code buffer, so there is no need |
1418 // to relocate any emitted relocation entries | 1420 // to relocate any emitted relocation entries |
1419 | 1421 |
1420 // relocate pending relocation entries | 1422 // relocate pending relocation entries |
1421 for (int i = 0; i < num_prinfo_; i++) { | 1423 for (int i = 0; i < num_prinfo_; i++) { |
1422 RelocInfo& rinfo = prinfo_[i]; | 1424 RelocInfo& rinfo = prinfo_[i]; |
1423 ASSERT(rinfo.rmode() != comment && rinfo.rmode() != position); | 1425 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && |
| 1426 rinfo.rmode() != RelocInfo::POSITION); |
1424 rinfo.set_pc(rinfo.pc() + pc_delta); | 1427 rinfo.set_pc(rinfo.pc() + pc_delta); |
1425 } | 1428 } |
1426 } | 1429 } |
1427 | 1430 |
1428 | 1431 |
1429 void Assembler::RecordRelocInfo(RelocMode rmode, intptr_t data) { | 1432 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
1430 RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants | 1433 RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants |
1431 if (rmode >= comment && rmode <= statement_position) { | 1434 if (rmode >= RelocInfo::COMMENT && rmode <= RelocInfo::STATEMENT_POSITION) { |
1432 // adjust code for new modes | 1435 // adjust code for new modes |
1433 ASSERT(is_comment(rmode) || is_position(rmode)); | 1436 ASSERT(RelocInfo::IsComment(rmode) || RelocInfo::IsPosition(rmode)); |
1434 // these modes do not need an entry in the constant pool | 1437 // these modes do not need an entry in the constant pool |
1435 } else { | 1438 } else { |
1436 ASSERT(num_prinfo_ < kMaxNumPRInfo); | 1439 ASSERT(num_prinfo_ < kMaxNumPRInfo); |
1437 prinfo_[num_prinfo_++] = rinfo; | 1440 prinfo_[num_prinfo_++] = rinfo; |
1438 // Make sure the constant pool is not emitted in place of the next | 1441 // Make sure the constant pool is not emitted in place of the next |
1439 // instruction for which we just recorded relocation info | 1442 // instruction for which we just recorded relocation info |
1440 BlockConstPoolBefore(pc_offset() + kInstrSize); | 1443 BlockConstPoolBefore(pc_offset() + kInstrSize); |
1441 } | 1444 } |
1442 if (rinfo.rmode() != no_reloc) { | 1445 if (rinfo.rmode() != RelocInfo::NONE) { |
1443 // Don't record external references unless the heap will be serialized. | 1446 // Don't record external references unless the heap will be serialized. |
1444 if (rmode == external_reference && | 1447 if (rmode == RelocInfo::EXTERNAL_REFERENCE && |
1445 !Serializer::enabled() && | 1448 !Serializer::enabled() && |
1446 !FLAG_debug_code) { | 1449 !FLAG_debug_code) { |
1447 return; | 1450 return; |
1448 } | 1451 } |
1449 ASSERT(buffer_space() >= kMaxRelocSize); // too late to grow buffer here | 1452 ASSERT(buffer_space() >= kMaxRelocSize); // too late to grow buffer here |
1450 reloc_info_writer.Write(&rinfo); | 1453 reloc_info_writer.Write(&rinfo); |
1451 } | 1454 } |
1452 } | 1455 } |
1453 | 1456 |
1454 | 1457 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 | 1516 |
1514 RecordComment("[ Constant Pool"); | 1517 RecordComment("[ Constant Pool"); |
1515 | 1518 |
1516 // Put down constant pool marker | 1519 // Put down constant pool marker |
1517 // "Undefined instruction" as specified by A3.1 Instruction set encoding | 1520 // "Undefined instruction" as specified by A3.1 Instruction set encoding |
1518 emit(0x03000000 | num_prinfo_); | 1521 emit(0x03000000 | num_prinfo_); |
1519 | 1522 |
1520 // Emit constant pool entries | 1523 // Emit constant pool entries |
1521 for (int i = 0; i < num_prinfo_; i++) { | 1524 for (int i = 0; i < num_prinfo_; i++) { |
1522 RelocInfo& rinfo = prinfo_[i]; | 1525 RelocInfo& rinfo = prinfo_[i]; |
1523 ASSERT(rinfo.rmode() != comment && rinfo.rmode() != position && | 1526 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && |
1524 rinfo.rmode() != statement_position); | 1527 rinfo.rmode() != RelocInfo::POSITION && |
| 1528 rinfo.rmode() != RelocInfo::STATEMENT_POSITION); |
1525 Instr instr = instr_at(rinfo.pc()); | 1529 Instr instr = instr_at(rinfo.pc()); |
1526 // Instruction to patch must be a ldr/str [pc, #offset] | 1530 // Instruction to patch must be a ldr/str [pc, #offset] |
1527 // P and U set, B and W clear, Rn == pc, offset12 still 0 | 1531 // P and U set, B and W clear, Rn == pc, offset12 still 0 |
1528 ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) == | 1532 ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) == |
1529 (2*B25 | P | U | pc.code()*B16)); | 1533 (2*B25 | P | U | pc.code()*B16)); |
1530 int delta = pc_ - rinfo.pc() - 8; | 1534 int delta = pc_ - rinfo.pc() - 8; |
1531 ASSERT(delta >= -4); // instr could be ldr pc, [pc, #-4] followed by targ32 | 1535 ASSERT(delta >= -4); // instr could be ldr pc, [pc, #-4] followed by targ32 |
1532 if (delta < 0) { | 1536 if (delta < 0) { |
1533 instr &= ~U; | 1537 instr &= ~U; |
1534 delta = -delta; | 1538 delta = -delta; |
(...skipping 11 matching lines...) Expand all Loading... |
1546 bind(&after_pool); | 1550 bind(&after_pool); |
1547 } | 1551 } |
1548 | 1552 |
1549 // Since a constant pool was just emitted, move the check offset forward by | 1553 // Since a constant pool was just emitted, move the check offset forward by |
1550 // the standard interval. | 1554 // the standard interval. |
1551 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 1555 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
1552 } | 1556 } |
1553 | 1557 |
1554 | 1558 |
1555 } } // namespace v8::internal | 1559 } } // namespace v8::internal |
OLD | NEW |