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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); | 511 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); |
512 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); | 512 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); |
513 } | 513 } |
514 | 514 |
515 // rm <shift_op> rs | 515 // rm <shift_op> rs |
516 explicit Operand(Register rm, ShiftOp shift_op, Register rs); | 516 explicit Operand(Register rm, ShiftOp shift_op, Register rs); |
517 | 517 |
518 // Return true if this is a register operand. | 518 // Return true if this is a register operand. |
519 INLINE(bool is_reg() const); | 519 INLINE(bool is_reg() const); |
520 | 520 |
521 // Return true if this operand fits in one instruction so that no | 521 // Return the number of actual instructions required to implement the given |
522 // 2-instruction solution with a load into the ip register is necessary. If | 522 // instruction for this particular operand. This can be a single instruction, |
| 523 // if no load into the ip register is necessary, or anything between 2 and 4 |
| 524 // instructions when we need to load from the constant pool (depending upon |
| 525 // whether the constant pool entry is in the small or extended section). If |
523 // 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 |
524 // actual instruction to use is required for this calculation. For other | 527 // actual instruction to use is required for this calculation. For other |
525 // instructions instr is ignored. | 528 // instructions instr is ignored. |
526 bool is_single_instruction(const Assembler* assembler, | 529 // |
527 Instr instr = 0) const; | 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. |
| 532 int instructions_required(const Assembler* assembler, Instr instr = 0) const; |
528 bool must_output_reloc_info(const Assembler* assembler) const; | 533 bool must_output_reloc_info(const Assembler* assembler) const; |
529 | 534 |
530 inline int32_t immediate() const { | 535 inline int32_t immediate() const { |
531 ASSERT(!rm_.is_valid()); | 536 ASSERT(!rm_.is_valid()); |
532 return imm32_; | 537 return imm32_; |
533 } | 538 } |
534 | 539 |
535 Register rm() const { return rm_; } | 540 Register rm() const { return rm_; } |
536 Register rs() const { return rs_; } | 541 Register rs() const { return rs_; } |
537 ShiftOp shift_op() const { return shift_op_; } | 542 ShiftOp shift_op() const { return shift_op_; } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 private: | 643 private: |
639 DoubleRegister base_; | 644 DoubleRegister base_; |
640 NeonListType type_; | 645 NeonListType type_; |
641 }; | 646 }; |
642 | 647 |
643 | 648 |
644 // Class used to build a constant pool. | 649 // Class used to build a constant pool. |
645 class ConstantPoolBuilder BASE_EMBEDDED { | 650 class ConstantPoolBuilder BASE_EMBEDDED { |
646 public: | 651 public: |
647 explicit ConstantPoolBuilder(); | 652 explicit ConstantPoolBuilder(); |
648 void AddEntry(Assembler* assm, const RelocInfo& rinfo); | 653 ConstantPoolArray::LayoutSection AddEntry(Assembler* assm, |
| 654 const RelocInfo& rinfo); |
649 void Relocate(int pc_delta); | 655 void Relocate(int pc_delta); |
650 bool IsEmpty(); | 656 bool IsEmpty(); |
651 Handle<ConstantPoolArray> New(Isolate* isolate); | 657 Handle<ConstantPoolArray> New(Isolate* isolate); |
652 void Populate(Assembler* assm, ConstantPoolArray* constant_pool); | 658 void Populate(Assembler* assm, ConstantPoolArray* constant_pool); |
653 | 659 |
654 inline int count_of_64bit() const { return count_of_64bit_; } | 660 inline ConstantPoolArray::LayoutSection current_section() const { |
655 inline int count_of_code_ptr() const { return count_of_code_ptr_; } | 661 return current_section_; |
656 inline int count_of_heap_ptr() const { return count_of_heap_ptr_; } | 662 } |
657 inline int count_of_32bit() const { return count_of_32bit_; } | 663 |
| 664 inline ConstantPoolArray::NumberOfEntries* number_of_entries( |
| 665 ConstantPoolArray::LayoutSection section) { |
| 666 return &number_of_entries_[section]; |
| 667 } |
| 668 |
| 669 inline ConstantPoolArray::NumberOfEntries* small_entries() { |
| 670 return number_of_entries(ConstantPoolArray::SMALL_SECTION); |
| 671 } |
| 672 |
| 673 inline ConstantPoolArray::NumberOfEntries* extended_entries() { |
| 674 return number_of_entries(ConstantPoolArray::EXTENDED_SECTION); |
| 675 } |
658 | 676 |
659 private: | 677 private: |
660 bool Is64BitEntry(RelocInfo::Mode rmode); | 678 struct ConstantPoolEntry { |
661 bool Is32BitEntry(RelocInfo::Mode rmode); | 679 ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section, |
662 bool IsCodePtrEntry(RelocInfo::Mode rmode); | 680 int merged_index) |
663 bool IsHeapPtrEntry(RelocInfo::Mode rmode); | 681 : rinfo_(rinfo), section_(section), merged_index_(merged_index) {} |
664 | 682 |
665 // TODO(rmcilroy): This should ideally be a ZoneList, however that would mean | 683 RelocInfo rinfo_; |
666 // RelocInfo would need to subclass ZoneObject which it currently doesn't. | 684 ConstantPoolArray::LayoutSection section_; |
667 std::vector<RelocInfo> entries_; | 685 int merged_index_; |
668 std::vector<int> merged_indexes_; | 686 }; |
669 int count_of_64bit_; | 687 |
670 int count_of_code_ptr_; | 688 ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode); |
671 int count_of_heap_ptr_; | 689 |
672 int count_of_32bit_; | 690 std::vector<ConstantPoolEntry> entries_; |
| 691 ConstantPoolArray::LayoutSection current_section_; |
| 692 ConstantPoolArray::NumberOfEntries number_of_entries_[2]; |
673 }; | 693 }; |
674 | 694 |
675 struct VmovIndex { | 695 struct VmovIndex { |
676 unsigned char index; | 696 unsigned char index; |
677 }; | 697 }; |
678 const VmovIndex VmovIndexLo = { 0 }; | 698 const VmovIndex VmovIndexLo = { 0 }; |
679 const VmovIndex VmovIndexHi = { 1 }; | 699 const VmovIndex VmovIndexHi = { 1 }; |
680 | 700 |
681 class Assembler : public AssemblerBase { | 701 class Assembler : public AssemblerBase { |
682 public: | 702 public: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 // Note: The same Label can be used for forward and backward branches | 736 // Note: The same Label can be used for forward and backward branches |
717 // but it may be bound only once. | 737 // but it may be bound only once. |
718 | 738 |
719 void bind(Label* L); // binds an unbound label L to the current code position | 739 void bind(Label* L); // binds an unbound label L to the current code position |
720 | 740 |
721 // Returns the branch offset to the given label from the current code position | 741 // Returns the branch offset to the given label from the current code position |
722 // Links the label to the current position if it is still unbound | 742 // Links the label to the current position if it is still unbound |
723 // Manages the jump elimination optimization if the second parameter is true. | 743 // Manages the jump elimination optimization if the second parameter is true. |
724 int branch_offset(Label* L, bool jump_elimination_allowed); | 744 int branch_offset(Label* L, bool jump_elimination_allowed); |
725 | 745 |
| 746 // Returns true if the given pc address is the start of a constant pool load |
| 747 // instruction sequence. |
| 748 INLINE(static bool is_constant_pool_load(Address pc)); |
| 749 |
726 // Return the address in the constant pool of the code target address used by | 750 // Return the address in the constant pool of the code target address used by |
727 // the branch/call instruction at pc, or the object in a mov. | 751 // the branch/call instruction at pc, or the object in a mov. |
728 INLINE(static Address constant_pool_entry_address( | 752 INLINE(static Address constant_pool_entry_address( |
729 Address pc, ConstantPoolArray* constant_pool)); | 753 Address pc, ConstantPoolArray* constant_pool)); |
730 | 754 |
731 // Read/Modify the code target address in the branch/call instruction at pc. | 755 // Read/Modify the code target address in the branch/call instruction at pc. |
732 INLINE(static Address target_address_at(Address pc, | 756 INLINE(static Address target_address_at(Address pc, |
733 ConstantPoolArray* constant_pool)); | 757 ConstantPoolArray* constant_pool)); |
734 INLINE(static void set_target_address_at(Address pc, | 758 INLINE(static void set_target_address_at(Address pc, |
735 ConstantPoolArray* constant_pool, | 759 ConstantPoolArray* constant_pool, |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } | 1376 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } |
1353 static void instr_at_put(byte* pc, Instr instr) { | 1377 static void instr_at_put(byte* pc, Instr instr) { |
1354 *reinterpret_cast<Instr*>(pc) = instr; | 1378 *reinterpret_cast<Instr*>(pc) = instr; |
1355 } | 1379 } |
1356 static Condition GetCondition(Instr instr); | 1380 static Condition GetCondition(Instr instr); |
1357 static bool IsBranch(Instr instr); | 1381 static bool IsBranch(Instr instr); |
1358 static int GetBranchOffset(Instr instr); | 1382 static int GetBranchOffset(Instr instr); |
1359 static bool IsLdrRegisterImmediate(Instr instr); | 1383 static bool IsLdrRegisterImmediate(Instr instr); |
1360 static bool IsVldrDRegisterImmediate(Instr instr); | 1384 static bool IsVldrDRegisterImmediate(Instr instr); |
1361 static Instr GetConsantPoolLoadPattern(); | 1385 static Instr GetConsantPoolLoadPattern(); |
| 1386 static Instr GetConsantPoolLoadMask(); |
| 1387 static bool IsLdrPpRegOffset(Instr instr); |
| 1388 static Instr GetLdrPpRegOffsetPattern(); |
1362 static bool IsLdrPpImmediateOffset(Instr instr); | 1389 static bool IsLdrPpImmediateOffset(Instr instr); |
1363 static bool IsVldrDPpImmediateOffset(Instr instr); | 1390 static bool IsVldrDPpImmediateOffset(Instr instr); |
1364 static int GetLdrRegisterImmediateOffset(Instr instr); | 1391 static int GetLdrRegisterImmediateOffset(Instr instr); |
1365 static int GetVldrDRegisterImmediateOffset(Instr instr); | 1392 static int GetVldrDRegisterImmediateOffset(Instr instr); |
1366 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); | 1393 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); |
1367 static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset); | 1394 static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset); |
1368 static bool IsStrRegisterImmediate(Instr instr); | 1395 static bool IsStrRegisterImmediate(Instr instr); |
1369 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); | 1396 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); |
1370 static bool IsAddRegisterImmediate(Instr instr); | 1397 static bool IsAddRegisterImmediate(Instr instr); |
1371 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); | 1398 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); |
(...skipping 10 matching lines...) Expand all Loading... |
1382 static bool IsVldrDPcImmediateOffset(Instr instr); | 1409 static bool IsVldrDPcImmediateOffset(Instr instr); |
1383 static bool IsBlxReg(Instr instr); | 1410 static bool IsBlxReg(Instr instr); |
1384 static bool IsBlxIp(Instr instr); | 1411 static bool IsBlxIp(Instr instr); |
1385 static bool IsTstImmediate(Instr instr); | 1412 static bool IsTstImmediate(Instr instr); |
1386 static bool IsCmpRegister(Instr instr); | 1413 static bool IsCmpRegister(Instr instr); |
1387 static bool IsCmpImmediate(Instr instr); | 1414 static bool IsCmpImmediate(Instr instr); |
1388 static Register GetCmpImmediateRegister(Instr instr); | 1415 static Register GetCmpImmediateRegister(Instr instr); |
1389 static int GetCmpImmediateRawImmediate(Instr instr); | 1416 static int GetCmpImmediateRawImmediate(Instr instr); |
1390 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1417 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
1391 static bool IsMovT(Instr instr); | 1418 static bool IsMovT(Instr instr); |
| 1419 static Instr GetMovTPattern(); |
1392 static bool IsMovW(Instr instr); | 1420 static bool IsMovW(Instr instr); |
| 1421 static Instr GetMovWPattern(); |
| 1422 static Instr EncodeMovwImmediate(uint32_t immediate); |
| 1423 static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate); |
1393 | 1424 |
1394 // Constants in pools are accessed via pc relative addressing, which can | 1425 // Constants in pools are accessed via pc relative addressing, which can |
1395 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point | 1426 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point |
1396 // PC-relative loads, thereby defining a maximum distance between the | 1427 // PC-relative loads, thereby defining a maximum distance between the |
1397 // instruction and the accessed constant. | 1428 // instruction and the accessed constant. |
1398 static const int kMaxDistToIntPool = 4*KB; | 1429 static const int kMaxDistToIntPool = 4*KB; |
1399 static const int kMaxDistToFPPool = 1*KB; | 1430 static const int kMaxDistToFPPool = 1*KB; |
1400 // All relocations could be integer, it therefore acts as the limit. | 1431 // All relocations could be integer, it therefore acts as the limit. |
1401 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; | 1432 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; |
1402 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; | 1433 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; |
1403 | 1434 |
1404 // Postpone the generation of the constant pool for the specified number of | 1435 // Postpone the generation of the constant pool for the specified number of |
1405 // instructions. | 1436 // instructions. |
1406 void BlockConstPoolFor(int instructions); | 1437 void BlockConstPoolFor(int instructions); |
1407 | 1438 |
1408 // Check if is time to emit a constant pool. | 1439 // Check if is time to emit a constant pool. |
1409 void CheckConstPool(bool force_emit, bool require_jump); | 1440 void CheckConstPool(bool force_emit, bool require_jump); |
1410 | 1441 |
1411 // Allocate a constant pool of the correct size for the generated code. | 1442 // Allocate a constant pool of the correct size for the generated code. |
1412 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); | 1443 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); |
1413 | 1444 |
1414 // Generate the constant pool for the generated code. | 1445 // Generate the constant pool for the generated code. |
1415 void PopulateConstantPool(ConstantPoolArray* constant_pool); | 1446 void PopulateConstantPool(ConstantPoolArray* constant_pool); |
1416 | 1447 |
1417 bool can_use_constant_pool() const { | 1448 bool is_constant_pool_available() const { return constant_pool_available_; } |
1418 return is_constant_pool_available() && !constant_pool_full_; | 1449 |
| 1450 bool use_extended_constant_pool() const { |
| 1451 return constant_pool_builder_.current_section() == |
| 1452 ConstantPoolArray::EXTENDED_SECTION; |
1419 } | 1453 } |
1420 | 1454 |
1421 void set_constant_pool_full() { | |
1422 constant_pool_full_ = true; | |
1423 } | |
1424 | 1455 |
1425 protected: | 1456 protected: |
1426 // Relocation for a type-recording IC has the AST id added to it. This | 1457 // Relocation for a type-recording IC has the AST id added to it. This |
1427 // member variable is a way to pass the information from the call site to | 1458 // member variable is a way to pass the information from the call site to |
1428 // the relocation info. | 1459 // the relocation info. |
1429 TypeFeedbackId recorded_ast_id_; | 1460 TypeFeedbackId recorded_ast_id_; |
1430 | 1461 |
1431 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1462 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
1432 | 1463 |
1433 // Decode branch instruction at pos and return branch target pos | 1464 // Decode branch instruction at pos and return branch target pos |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1468 // trigger a check. | 1499 // trigger a check. |
1469 next_buffer_check_ = no_const_pool_before_; | 1500 next_buffer_check_ = no_const_pool_before_; |
1470 } | 1501 } |
1471 } | 1502 } |
1472 | 1503 |
1473 bool is_const_pool_blocked() const { | 1504 bool is_const_pool_blocked() const { |
1474 return (const_pool_blocked_nesting_ > 0) || | 1505 return (const_pool_blocked_nesting_ > 0) || |
1475 (pc_offset() < no_const_pool_before_); | 1506 (pc_offset() < no_const_pool_before_); |
1476 } | 1507 } |
1477 | 1508 |
1478 bool is_constant_pool_available() const { | |
1479 return constant_pool_available_; | |
1480 } | |
1481 | |
1482 void set_constant_pool_available(bool available) { | 1509 void set_constant_pool_available(bool available) { |
1483 constant_pool_available_ = available; | 1510 constant_pool_available_ = available; |
1484 } | 1511 } |
1485 | 1512 |
1486 private: | 1513 private: |
1487 int next_buffer_check_; // pc offset of next buffer check | 1514 int next_buffer_check_; // pc offset of next buffer check |
1488 | 1515 |
1489 // Code generation | 1516 // Code generation |
1490 // The relocation writer's position is at least kGap bytes below the end of | 1517 // The relocation writer's position is at least kGap bytes below the end of |
1491 // the generated instructions. This is so that multi-instruction sequences do | 1518 // the generated instructions. This is so that multi-instruction sequences do |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 int num_pending_64_bit_reloc_info_; | 1568 int num_pending_64_bit_reloc_info_; |
1542 | 1569 |
1543 ConstantPoolBuilder constant_pool_builder_; | 1570 ConstantPoolBuilder constant_pool_builder_; |
1544 | 1571 |
1545 // The bound position, before this we cannot do instruction elimination. | 1572 // The bound position, before this we cannot do instruction elimination. |
1546 int last_bound_pos_; | 1573 int last_bound_pos_; |
1547 | 1574 |
1548 // Indicates whether the constant pool can be accessed, which is only possible | 1575 // Indicates whether the constant pool can be accessed, which is only possible |
1549 // if the pp register points to the current code object's constant pool. | 1576 // if the pp register points to the current code object's constant pool. |
1550 bool constant_pool_available_; | 1577 bool constant_pool_available_; |
1551 // Indicates whether the constant pool is too full to accept new entries due | |
1552 // to the ldr instruction's limitted immediate offset range. | |
1553 bool constant_pool_full_; | |
1554 | 1578 |
1555 // Code emission | 1579 // Code emission |
1556 inline void CheckBuffer(); | 1580 inline void CheckBuffer(); |
1557 void GrowBuffer(); | 1581 void GrowBuffer(); |
1558 inline void emit(Instr x); | 1582 inline void emit(Instr x); |
1559 | 1583 |
1560 // 32-bit immediate values | 1584 // 32-bit immediate values |
1561 void move_32_bit_immediate(Register rd, | 1585 void move_32_bit_immediate(Register rd, |
1562 const Operand& x, | 1586 const Operand& x, |
1563 Condition cond = al); | 1587 Condition cond = al); |
(...skipping 11 matching lines...) Expand all Loading... |
1575 void next(Label* L); | 1599 void next(Label* L); |
1576 | 1600 |
1577 enum UseConstantPoolMode { | 1601 enum UseConstantPoolMode { |
1578 USE_CONSTANT_POOL, | 1602 USE_CONSTANT_POOL, |
1579 DONT_USE_CONSTANT_POOL | 1603 DONT_USE_CONSTANT_POOL |
1580 }; | 1604 }; |
1581 | 1605 |
1582 // Record reloc info for current pc_ | 1606 // Record reloc info for current pc_ |
1583 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1607 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
1584 void RecordRelocInfo(const RelocInfo& rinfo); | 1608 void RecordRelocInfo(const RelocInfo& rinfo); |
1585 void ConstantPoolAddEntry(const RelocInfo& rinfo); | 1609 ConstantPoolArray::LayoutSection ConstantPoolAddEntry(const RelocInfo& rinfo); |
1586 | 1610 |
1587 friend class RelocInfo; | 1611 friend class RelocInfo; |
1588 friend class CodePatcher; | 1612 friend class CodePatcher; |
1589 friend class BlockConstPoolScope; | 1613 friend class BlockConstPoolScope; |
1590 friend class FrameAndConstantPoolScope; | 1614 friend class FrameAndConstantPoolScope; |
1591 friend class ConstantPoolUnavailableScope; | 1615 friend class ConstantPoolUnavailableScope; |
1592 | 1616 |
1593 PositionsRecorder positions_recorder_; | 1617 PositionsRecorder positions_recorder_; |
1594 friend class PositionsRecorder; | 1618 friend class PositionsRecorder; |
1595 friend class EnsureSpace; | 1619 friend class EnsureSpace; |
1596 }; | 1620 }; |
1597 | 1621 |
1598 | 1622 |
1599 class EnsureSpace BASE_EMBEDDED { | 1623 class EnsureSpace BASE_EMBEDDED { |
1600 public: | 1624 public: |
1601 explicit EnsureSpace(Assembler* assembler) { | 1625 explicit EnsureSpace(Assembler* assembler) { |
1602 assembler->CheckBuffer(); | 1626 assembler->CheckBuffer(); |
1603 } | 1627 } |
1604 }; | 1628 }; |
1605 | 1629 |
1606 | 1630 |
1607 } } // namespace v8::internal | 1631 } } // namespace v8::internal |
1608 | 1632 |
1609 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1633 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |