| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 const int kRegister_fp_Code = 11; | 87 const int kRegister_fp_Code = 11; |
| 88 const int kRegister_ip_Code = 12; | 88 const int kRegister_ip_Code = 12; |
| 89 const int kRegister_sp_Code = 13; | 89 const int kRegister_sp_Code = 13; |
| 90 const int kRegister_lr_Code = 14; | 90 const int kRegister_lr_Code = 14; |
| 91 const int kRegister_pc_Code = 15; | 91 const int kRegister_pc_Code = 15; |
| 92 | 92 |
| 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_embedded_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 DCHECK(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 DCHECK(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 DCHECK(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_embedded_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 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 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 }; |
| 160 const Register r2 = { kRegister_r2_Code }; | 160 const Register r2 = { kRegister_r2_Code }; |
| 161 const Register r3 = { kRegister_r3_Code }; | 161 const Register r3 = { kRegister_r3_Code }; |
| 162 const Register r4 = { kRegister_r4_Code }; | 162 const Register r4 = { kRegister_r4_Code }; |
| 163 const Register r5 = { kRegister_r5_Code }; | 163 const Register r5 = { kRegister_r5_Code }; |
| 164 const Register r6 = { kRegister_r6_Code }; | 164 const Register r6 = { kRegister_r6_Code }; |
| 165 // Used as context register. | 165 // Used as context register. |
| 166 const Register r7 = {kRegister_r7_Code}; | 166 const Register r7 = {kRegister_r7_Code}; |
| 167 // Used as constant pool pointer register if FLAG_enable_embedded_constant_pool. | 167 // Used as constant pool pointer register if FLAG_enable_ool_constant_pool. |
| 168 const Register r8 = { kRegister_r8_Code }; | 168 const Register r8 = { kRegister_r8_Code }; |
| 169 // Used as lithium codegen scratch register. | 169 // Used as lithium codegen scratch register. |
| 170 const Register r9 = { kRegister_r9_Code }; | 170 const Register r9 = { kRegister_r9_Code }; |
| 171 // Used as roots register. | 171 // Used as roots register. |
| 172 const Register r10 = { kRegister_r10_Code }; | 172 const Register r10 = { kRegister_r10_Code }; |
| 173 const Register fp = { kRegister_fp_Code }; | 173 const Register fp = { kRegister_fp_Code }; |
| 174 const Register ip = { kRegister_ip_Code }; | 174 const Register ip = { kRegister_ip_Code }; |
| 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 }; |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 public: | 644 public: |
| 645 explicit NeonListOperand(DoubleRegister base, int registers_count = 1); | 645 explicit NeonListOperand(DoubleRegister base, int registers_count = 1); |
| 646 DoubleRegister base() const { return base_; } | 646 DoubleRegister base() const { return base_; } |
| 647 NeonListType type() const { return type_; } | 647 NeonListType type() const { return type_; } |
| 648 private: | 648 private: |
| 649 DoubleRegister base_; | 649 DoubleRegister base_; |
| 650 NeonListType type_; | 650 NeonListType type_; |
| 651 }; | 651 }; |
| 652 | 652 |
| 653 | 653 |
| 654 // Class used to build a constant pool. |
| 655 class ConstantPoolBuilder BASE_EMBEDDED { |
| 656 public: |
| 657 ConstantPoolBuilder(); |
| 658 ConstantPoolArray::LayoutSection AddEntry(Assembler* assm, |
| 659 const RelocInfo& rinfo); |
| 660 void Relocate(int pc_delta); |
| 661 bool IsEmpty(); |
| 662 Handle<ConstantPoolArray> New(Isolate* isolate); |
| 663 void Populate(Assembler* assm, ConstantPoolArray* constant_pool); |
| 664 |
| 665 inline ConstantPoolArray::LayoutSection current_section() const { |
| 666 return current_section_; |
| 667 } |
| 668 |
| 669 inline ConstantPoolArray::NumberOfEntries* number_of_entries( |
| 670 ConstantPoolArray::LayoutSection section) { |
| 671 return &number_of_entries_[section]; |
| 672 } |
| 673 |
| 674 inline ConstantPoolArray::NumberOfEntries* small_entries() { |
| 675 return number_of_entries(ConstantPoolArray::SMALL_SECTION); |
| 676 } |
| 677 |
| 678 inline ConstantPoolArray::NumberOfEntries* extended_entries() { |
| 679 return number_of_entries(ConstantPoolArray::EXTENDED_SECTION); |
| 680 } |
| 681 |
| 682 private: |
| 683 struct ConstantPoolEntry { |
| 684 ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section, |
| 685 int merged_index) |
| 686 : rinfo_(rinfo), section_(section), merged_index_(merged_index) {} |
| 687 |
| 688 RelocInfo rinfo_; |
| 689 ConstantPoolArray::LayoutSection section_; |
| 690 int merged_index_; |
| 691 }; |
| 692 |
| 693 ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode); |
| 694 |
| 695 std::vector<ConstantPoolEntry> entries_; |
| 696 ConstantPoolArray::LayoutSection current_section_; |
| 697 ConstantPoolArray::NumberOfEntries number_of_entries_[2]; |
| 698 }; |
| 699 |
| 654 struct VmovIndex { | 700 struct VmovIndex { |
| 655 unsigned char index; | 701 unsigned char index; |
| 656 }; | 702 }; |
| 657 const VmovIndex VmovIndexLo = { 0 }; | 703 const VmovIndex VmovIndexLo = { 0 }; |
| 658 const VmovIndex VmovIndexHi = { 1 }; | 704 const VmovIndex VmovIndexHi = { 1 }; |
| 659 | 705 |
| 660 class Assembler : public AssemblerBase { | 706 class Assembler : public AssemblerBase { |
| 661 public: | 707 public: |
| 662 // Create an assembler. Instructions and relocation information are emitted | 708 // Create an assembler. Instructions and relocation information are emitted |
| 663 // into a buffer, with the instructions starting from the beginning and the | 709 // into a buffer, with the instructions starting from the beginning and the |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 // Links the label to the current position if it is still unbound | 747 // Links the label to the current position if it is still unbound |
| 702 // Manages the jump elimination optimization if the second parameter is true. | 748 // Manages the jump elimination optimization if the second parameter is true. |
| 703 int branch_offset(Label* L, bool jump_elimination_allowed); | 749 int branch_offset(Label* L, bool jump_elimination_allowed); |
| 704 | 750 |
| 705 // Returns true if the given pc address is the start of a constant pool load | 751 // Returns true if the given pc address is the start of a constant pool load |
| 706 // instruction sequence. | 752 // instruction sequence. |
| 707 INLINE(static bool is_constant_pool_load(Address pc)); | 753 INLINE(static bool is_constant_pool_load(Address pc)); |
| 708 | 754 |
| 709 // Return the address in the constant pool of the code target address used by | 755 // Return the address in the constant pool of the code target address used by |
| 710 // the branch/call instruction at pc, or the object in a mov. | 756 // the branch/call instruction at pc, or the object in a mov. |
| 711 INLINE(static Address constant_pool_entry_address(Address pc, | 757 INLINE(static Address constant_pool_entry_address( |
| 712 Address constant_pool)); | 758 Address pc, ConstantPoolArray* constant_pool)); |
| 713 | 759 |
| 714 // Read/Modify the code target address in the branch/call instruction at pc. | 760 // Read/Modify the code target address in the branch/call instruction at pc. |
| 715 INLINE(static Address target_address_at(Address pc, Address constant_pool)); | 761 INLINE(static Address target_address_at(Address pc, |
| 716 INLINE(static void set_target_address_at( | 762 ConstantPoolArray* constant_pool)); |
| 717 Address pc, Address constant_pool, Address target, | 763 INLINE(static void set_target_address_at(Address pc, |
| 718 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); | 764 ConstantPoolArray* constant_pool, |
| 765 Address target, |
| 766 ICacheFlushMode icache_flush_mode = |
| 767 FLUSH_ICACHE_IF_NEEDED)); |
| 719 INLINE(static Address target_address_at(Address pc, Code* code)) { | 768 INLINE(static Address target_address_at(Address pc, Code* code)) { |
| 720 Address constant_pool = code ? code->constant_pool() : NULL; | 769 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; |
| 721 return target_address_at(pc, constant_pool); | 770 return target_address_at(pc, constant_pool); |
| 722 } | 771 } |
| 723 INLINE(static void set_target_address_at(Address pc, | 772 INLINE(static void set_target_address_at(Address pc, |
| 724 Code* code, | 773 Code* code, |
| 725 Address target, | 774 Address target, |
| 726 ICacheFlushMode icache_flush_mode = | 775 ICacheFlushMode icache_flush_mode = |
| 727 FLUSH_ICACHE_IF_NEEDED)) { | 776 FLUSH_ICACHE_IF_NEEDED)) { |
| 728 Address constant_pool = code ? code->constant_pool() : NULL; | 777 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; |
| 729 set_target_address_at(pc, constant_pool, target, icache_flush_mode); | 778 set_target_address_at(pc, constant_pool, target, icache_flush_mode); |
| 730 } | 779 } |
| 731 | 780 |
| 732 // Return the code target address at a call site from the return address | 781 // Return the code target address at a call site from the return address |
| 733 // of that call in the instruction stream. | 782 // of that call in the instruction stream. |
| 734 INLINE(static Address target_address_from_return_address(Address pc)); | 783 INLINE(static Address target_address_from_return_address(Address pc)); |
| 735 | 784 |
| 736 // Given the address of the beginning of a call, return the address | 785 // Given the address of the beginning of a call, return the address |
| 737 // in the instruction stream that the call will return from. | 786 // in the instruction stream that the call will return from. |
| 738 INLINE(static Address return_address_from_call_start(Address pc)); | 787 INLINE(static Address return_address_from_call_start(Address pc)); |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 // have constant pools generated in different places. | 1443 // have constant pools generated in different places. |
| 1395 // Recording the position and size of emitted constant pools allows to | 1444 // Recording the position and size of emitted constant pools allows to |
| 1396 // correctly compute the offset mappings between the different versions of a | 1445 // correctly compute the offset mappings between the different versions of a |
| 1397 // function in all situations. | 1446 // function in all situations. |
| 1398 // | 1447 // |
| 1399 // The parameter indicates the size of the constant pool (in bytes), including | 1448 // The parameter indicates the size of the constant pool (in bytes), including |
| 1400 // the marker and branch over the data. | 1449 // the marker and branch over the data. |
| 1401 void RecordConstPool(int size); | 1450 void RecordConstPool(int size); |
| 1402 | 1451 |
| 1403 // Writes a single byte or word of data in the code stream. Used | 1452 // Writes a single byte or word of data in the code stream. Used |
| 1404 // for inline tables, e.g., jump-tables. CheckConstantPool() should be | 1453 // for inline tables, e.g., jump-tables. The constant pool should be |
| 1405 // called before any use of db/dd/dq/dp to ensure that constant pools | 1454 // emitted before any use of db and dd to ensure that constant pools |
| 1406 // are not emitted as part of the tables generated. | 1455 // are not emitted as part of the tables generated. |
| 1407 void db(uint8_t data); | 1456 void db(uint8_t data); |
| 1408 void dd(uint32_t data); | 1457 void dd(uint32_t data); |
| 1409 void dq(uint64_t data); | |
| 1410 void dp(uintptr_t data) { dd(data); } | |
| 1411 | 1458 |
| 1412 // Emits the address of the code stub's first instruction. | 1459 // Emits the address of the code stub's first instruction. |
| 1413 void emit_code_stub_address(Code* stub); | 1460 void emit_code_stub_address(Code* stub); |
| 1414 | 1461 |
| 1415 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 1462 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
| 1416 | 1463 |
| 1417 // Read/patch instructions | 1464 // Read/patch instructions |
| 1418 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 1465 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
| 1419 void instr_at_put(int pos, Instr instr) { | 1466 void instr_at_put(int pos, Instr instr) { |
| 1420 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; | 1467 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1472 static int DecodeShiftImm(Instr instr); | 1519 static int DecodeShiftImm(Instr instr); |
| 1473 static Instr PatchShiftImm(Instr instr, int immed); | 1520 static Instr PatchShiftImm(Instr instr, int immed); |
| 1474 | 1521 |
| 1475 // Constants in pools are accessed via pc relative addressing, which can | 1522 // Constants in pools are accessed via pc relative addressing, which can |
| 1476 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point | 1523 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point |
| 1477 // PC-relative loads, thereby defining a maximum distance between the | 1524 // PC-relative loads, thereby defining a maximum distance between the |
| 1478 // instruction and the accessed constant. | 1525 // instruction and the accessed constant. |
| 1479 static const int kMaxDistToIntPool = 4*KB; | 1526 static const int kMaxDistToIntPool = 4*KB; |
| 1480 static const int kMaxDistToFPPool = 1*KB; | 1527 static const int kMaxDistToFPPool = 1*KB; |
| 1481 // All relocations could be integer, it therefore acts as the limit. | 1528 // All relocations could be integer, it therefore acts as the limit. |
| 1482 static const int kMaxNumPending32Constants = kMaxDistToIntPool / kInstrSize; | 1529 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; |
| 1483 static const int kMaxNumPending64Constants = kMaxDistToFPPool / kInstrSize; | 1530 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; |
| 1484 | 1531 |
| 1485 // Postpone the generation of the constant pool for the specified number of | 1532 // Postpone the generation of the constant pool for the specified number of |
| 1486 // instructions. | 1533 // instructions. |
| 1487 void BlockConstPoolFor(int instructions); | 1534 void BlockConstPoolFor(int instructions); |
| 1488 | 1535 |
| 1489 // Check if is time to emit a constant pool. | 1536 // Check if is time to emit a constant pool. |
| 1490 void CheckConstPool(bool force_emit, bool require_jump); | 1537 void CheckConstPool(bool force_emit, bool require_jump); |
| 1491 | 1538 |
| 1492 int EmitEmbeddedConstantPool() { | 1539 // Allocate a constant pool of the correct size for the generated code. |
| 1493 DCHECK(FLAG_enable_embedded_constant_pool); | 1540 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); |
| 1494 return constant_pool_builder_.Emit(this); | 1541 |
| 1542 // Generate the constant pool for the generated code. |
| 1543 void PopulateConstantPool(ConstantPoolArray* constant_pool); |
| 1544 |
| 1545 bool use_extended_constant_pool() const { |
| 1546 return constant_pool_builder_.current_section() == |
| 1547 ConstantPoolArray::EXTENDED_SECTION; |
| 1495 } | 1548 } |
| 1496 | 1549 |
| 1497 bool ConstantPoolAccessIsInOverflow() const { | |
| 1498 return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) == | |
| 1499 ConstantPoolEntry::OVERFLOWED; | |
| 1500 } | |
| 1501 | |
| 1502 void PatchConstantPoolAccessInstruction(int pc_offset, int offset, | |
| 1503 ConstantPoolEntry::Access access, | |
| 1504 ConstantPoolEntry::Type type); | |
| 1505 | 1550 |
| 1506 protected: | 1551 protected: |
| 1507 // Relocation for a type-recording IC has the AST id added to it. This | 1552 // Relocation for a type-recording IC has the AST id added to it. This |
| 1508 // member variable is a way to pass the information from the call site to | 1553 // member variable is a way to pass the information from the call site to |
| 1509 // the relocation info. | 1554 // the relocation info. |
| 1510 TypeFeedbackId recorded_ast_id_; | 1555 TypeFeedbackId recorded_ast_id_; |
| 1511 | 1556 |
| 1512 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1557 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
| 1513 | 1558 |
| 1514 // Decode branch instruction at pos and return branch target pos | 1559 // Decode branch instruction at pos and return branch target pos |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1529 } | 1574 } |
| 1530 | 1575 |
| 1531 // Resume constant pool emission. Need to be called as many time as | 1576 // Resume constant pool emission. Need to be called as many time as |
| 1532 // StartBlockConstPool to have an effect. | 1577 // StartBlockConstPool to have an effect. |
| 1533 void EndBlockConstPool() { | 1578 void EndBlockConstPool() { |
| 1534 if (--const_pool_blocked_nesting_ == 0) { | 1579 if (--const_pool_blocked_nesting_ == 0) { |
| 1535 #ifdef DEBUG | 1580 #ifdef DEBUG |
| 1536 // Max pool start (if we need a jump and an alignment). | 1581 // Max pool start (if we need a jump and an alignment). |
| 1537 int start = pc_offset() + kInstrSize + 2 * kPointerSize; | 1582 int start = pc_offset() + kInstrSize + 2 * kPointerSize; |
| 1538 // Check the constant pool hasn't been blocked for too long. | 1583 // Check the constant pool hasn't been blocked for too long. |
| 1539 DCHECK((num_pending_32_bit_constants_ == 0) || | 1584 DCHECK((num_pending_32_bit_reloc_info_ == 0) || |
| 1540 (start + num_pending_64_bit_constants_ * kDoubleSize < | 1585 (start + num_pending_64_bit_reloc_info_ * kDoubleSize < |
| 1541 (first_const_pool_32_use_ + kMaxDistToIntPool))); | 1586 (first_const_pool_32_use_ + kMaxDistToIntPool))); |
| 1542 DCHECK((num_pending_64_bit_constants_ == 0) || | 1587 DCHECK((num_pending_64_bit_reloc_info_ == 0) || |
| 1543 (start < (first_const_pool_64_use_ + kMaxDistToFPPool))); | 1588 (start < (first_const_pool_64_use_ + kMaxDistToFPPool))); |
| 1544 #endif | 1589 #endif |
| 1545 // Two cases: | 1590 // Two cases: |
| 1546 // * no_const_pool_before_ >= next_buffer_check_ and the emission is | 1591 // * no_const_pool_before_ >= next_buffer_check_ and the emission is |
| 1547 // still blocked | 1592 // still blocked |
| 1548 // * no_const_pool_before_ < next_buffer_check_ and the next emit will | 1593 // * no_const_pool_before_ < next_buffer_check_ and the next emit will |
| 1549 // trigger a check. | 1594 // trigger a check. |
| 1550 next_buffer_check_ = no_const_pool_before_; | 1595 next_buffer_check_ = no_const_pool_before_; |
| 1551 } | 1596 } |
| 1552 } | 1597 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 // Keep track of the first instruction requiring a constant pool entry | 1636 // Keep track of the first instruction requiring a constant pool entry |
| 1592 // since the previous constant pool was emitted. | 1637 // since the previous constant pool was emitted. |
| 1593 int first_const_pool_32_use_; | 1638 int first_const_pool_32_use_; |
| 1594 int first_const_pool_64_use_; | 1639 int first_const_pool_64_use_; |
| 1595 | 1640 |
| 1596 // Relocation info generation | 1641 // Relocation info generation |
| 1597 // Each relocation is encoded as a variable size value | 1642 // Each relocation is encoded as a variable size value |
| 1598 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1643 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
| 1599 RelocInfoWriter reloc_info_writer; | 1644 RelocInfoWriter reloc_info_writer; |
| 1600 | 1645 |
| 1601 // ConstantPoolEntry records are used during code generation as temporary | 1646 // Relocation info records are also used during code generation as temporary |
| 1602 // containers for constants and code target addresses until they are emitted | 1647 // containers for constants and code target addresses until they are emitted |
| 1603 // to the constant pool. These records are temporarily stored in a separate | 1648 // to the constant pool. These pending relocation info records are temporarily |
| 1604 // buffer until a constant pool is emitted. | 1649 // stored in a separate buffer until a constant pool is emitted. |
| 1605 // If every instruction in a long sequence is accessing the pool, we need one | 1650 // If every instruction in a long sequence is accessing the pool, we need one |
| 1606 // pending relocation entry per instruction. | 1651 // pending relocation entry per instruction. |
| 1607 | 1652 |
| 1608 // The buffers of pending constant pool entries. | 1653 // The buffers of pending relocation info. |
| 1609 ConstantPoolEntry pending_32_bit_constants_[kMaxNumPending32Constants]; | 1654 RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo]; |
| 1610 ConstantPoolEntry pending_64_bit_constants_[kMaxNumPending64Constants]; | 1655 RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo]; |
| 1611 // Number of pending constant pool entries in the 32 bits buffer. | 1656 // Number of pending reloc info entries in the 32 bits buffer. |
| 1612 int num_pending_32_bit_constants_; | 1657 int num_pending_32_bit_reloc_info_; |
| 1613 // Number of pending constant pool entries in the 64 bits buffer. | 1658 // Number of pending reloc info entries in the 64 bits buffer. |
| 1614 int num_pending_64_bit_constants_; | 1659 int num_pending_64_bit_reloc_info_; |
| 1615 | 1660 |
| 1616 ConstantPoolBuilder constant_pool_builder_; | 1661 ConstantPoolBuilder constant_pool_builder_; |
| 1617 | 1662 |
| 1618 // The bound position, before this we cannot do instruction elimination. | 1663 // The bound position, before this we cannot do instruction elimination. |
| 1619 int last_bound_pos_; | 1664 int last_bound_pos_; |
| 1620 | 1665 |
| 1621 // Code emission | 1666 // Code emission |
| 1622 inline void CheckBuffer(); | 1667 inline void CheckBuffer(); |
| 1623 void GrowBuffer(); | 1668 void GrowBuffer(); |
| 1624 inline void emit(Instr x); | 1669 inline void emit(Instr x); |
| 1625 | 1670 |
| 1626 // 32-bit immediate values | 1671 // 32-bit immediate values |
| 1627 void move_32_bit_immediate(Register rd, | 1672 void move_32_bit_immediate(Register rd, |
| 1628 const Operand& x, | 1673 const Operand& x, |
| 1629 Condition cond = al); | 1674 Condition cond = al); |
| 1630 | 1675 |
| 1631 // Instruction generation | 1676 // Instruction generation |
| 1632 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); | 1677 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); |
| 1633 void addrmod2(Instr instr, Register rd, const MemOperand& x); | 1678 void addrmod2(Instr instr, Register rd, const MemOperand& x); |
| 1634 void addrmod3(Instr instr, Register rd, const MemOperand& x); | 1679 void addrmod3(Instr instr, Register rd, const MemOperand& x); |
| 1635 void addrmod4(Instr instr, Register rn, RegList rl); | 1680 void addrmod4(Instr instr, Register rn, RegList rl); |
| 1636 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); | 1681 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); |
| 1637 | 1682 |
| 1638 // Labels | 1683 // Labels |
| 1639 void print(Label* L); | 1684 void print(Label* L); |
| 1640 void bind_to(Label* L, int pos); | 1685 void bind_to(Label* L, int pos); |
| 1641 void next(Label* L); | 1686 void next(Label* L); |
| 1642 | 1687 |
| 1688 enum UseConstantPoolMode { |
| 1689 USE_CONSTANT_POOL, |
| 1690 DONT_USE_CONSTANT_POOL |
| 1691 }; |
| 1692 |
| 1643 // Record reloc info for current pc_ | 1693 // Record reloc info for current pc_ |
| 1644 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1694 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
| 1645 ConstantPoolEntry::Access ConstantPoolAddEntry(int position, | 1695 void RecordRelocInfo(const RelocInfo& rinfo); |
| 1646 RelocInfo::Mode rmode, | 1696 ConstantPoolArray::LayoutSection ConstantPoolAddEntry(const RelocInfo& rinfo); |
| 1647 intptr_t value); | |
| 1648 ConstantPoolEntry::Access ConstantPoolAddEntry(int position, double value); | |
| 1649 | 1697 |
| 1650 friend class RelocInfo; | 1698 friend class RelocInfo; |
| 1651 friend class CodePatcher; | 1699 friend class CodePatcher; |
| 1652 friend class BlockConstPoolScope; | 1700 friend class BlockConstPoolScope; |
| 1653 PositionsRecorder positions_recorder_; | 1701 PositionsRecorder positions_recorder_; |
| 1654 friend class PositionsRecorder; | 1702 friend class PositionsRecorder; |
| 1655 friend class EnsureSpace; | 1703 friend class EnsureSpace; |
| 1656 }; | 1704 }; |
| 1657 | 1705 |
| 1658 | 1706 |
| 1659 class EnsureSpace BASE_EMBEDDED { | 1707 class EnsureSpace BASE_EMBEDDED { |
| 1660 public: | 1708 public: |
| 1661 explicit EnsureSpace(Assembler* assembler) { | 1709 explicit EnsureSpace(Assembler* assembler) { |
| 1662 assembler->CheckBuffer(); | 1710 assembler->CheckBuffer(); |
| 1663 } | 1711 } |
| 1664 }; | 1712 }; |
| 1665 | 1713 |
| 1666 | 1714 |
| 1667 } } // namespace v8::internal | 1715 } } // namespace v8::internal |
| 1668 | 1716 |
| 1669 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1717 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |