| 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 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 int32_t dist = pos - fixup_pos; | 842 int32_t dist = pos - fixup_pos; |
| 843 is_internal = internal_reference_positions_.find(fixup_pos) != | 843 is_internal = internal_reference_positions_.find(fixup_pos) != |
| 844 internal_reference_positions_.end(); | 844 internal_reference_positions_.end(); |
| 845 next(L, is_internal); // Call next before overwriting link with target at | 845 next(L, is_internal); // Call next before overwriting link with target at |
| 846 // fixup_pos. | 846 // fixup_pos. |
| 847 Instr instr = instr_at(fixup_pos); | 847 Instr instr = instr_at(fixup_pos); |
| 848 if (is_internal) { | 848 if (is_internal) { |
| 849 target_at_put(fixup_pos, pos, is_internal); | 849 target_at_put(fixup_pos, pos, is_internal); |
| 850 } else { | 850 } else { |
| 851 if (IsBranch(instr)) { | 851 if (IsBranch(instr)) { |
| 852 if (dist > kMaxBranchOffset) { | 852 int branch_offset = BranchOffset(instr); |
| 853 if (dist > branch_offset) { |
| 853 if (trampoline_pos == kInvalidSlotPos) { | 854 if (trampoline_pos == kInvalidSlotPos) { |
| 854 trampoline_pos = get_trampoline_entry(fixup_pos); | 855 trampoline_pos = get_trampoline_entry(fixup_pos); |
| 855 CHECK(trampoline_pos != kInvalidSlotPos); | 856 CHECK(trampoline_pos != kInvalidSlotPos); |
| 856 } | 857 } |
| 857 CHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset); | 858 CHECK((trampoline_pos - fixup_pos) <= branch_offset); |
| 858 target_at_put(fixup_pos, trampoline_pos, false); | 859 target_at_put(fixup_pos, trampoline_pos, false); |
| 859 fixup_pos = trampoline_pos; | 860 fixup_pos = trampoline_pos; |
| 860 dist = pos - fixup_pos; | 861 dist = pos - fixup_pos; |
| 861 } | 862 } |
| 862 target_at_put(fixup_pos, pos, false); | 863 target_at_put(fixup_pos, pos, false); |
| 863 } else { | 864 } else { |
| 864 target_at_put(fixup_pos, pos, false); | 865 target_at_put(fixup_pos, pos, false); |
| 865 } | 866 } |
| 866 } | 867 } |
| 867 } | 868 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 887 L->Unuse(); | 888 L->Unuse(); |
| 888 } else { | 889 } else { |
| 889 DCHECK(link >= 0); | 890 DCHECK(link >= 0); |
| 890 L->link_to(link); | 891 L->link_to(link); |
| 891 } | 892 } |
| 892 } | 893 } |
| 893 | 894 |
| 894 | 895 |
| 895 bool Assembler::is_near(Label* L) { | 896 bool Assembler::is_near(Label* L) { |
| 896 DCHECK(L->is_bound()); | 897 DCHECK(L->is_bound()); |
| 897 return ((pc_offset() - L->pos()) < kMaxBranchOffset - 4 * kInstrSize); | 898 return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize; |
| 898 } | 899 } |
| 899 | 900 |
| 900 | 901 |
| 901 bool Assembler::is_near(Label* L, OffsetSize bits) { | 902 bool Assembler::is_near(Label* L, OffsetSize bits) { |
| 902 if (L == nullptr || !L->is_bound()) return true; | 903 if (L == nullptr || !L->is_bound()) return true; |
| 903 return ((pc_offset() - L->pos()) < | 904 return pc_offset() - L->pos() < (1 << (bits + 2 - 1)) - 1 - 5 * kInstrSize; |
| 904 (1 << (bits + 2 - 1)) - 1 - 5 * kInstrSize); | |
| 905 } | 905 } |
| 906 | 906 |
| 907 | 907 |
| 908 bool Assembler::is_near_branch(Label* L) { | 908 bool Assembler::is_near_branch(Label* L) { |
| 909 DCHECK(L->is_bound()); | 909 DCHECK(L->is_bound()); |
| 910 int max_offset = | 910 return IsMipsArchVariant(kMips32r6) ? is_near_r6(L) : is_near_pre_r6(L); |
| 911 IsMipsArchVariant(kMips32r6) ? kMaxCompactBranchOffset : kMaxBranchOffset; | |
| 912 return pc_offset() - L->pos() < max_offset - 4 * kInstrSize; | |
| 913 } | 911 } |
| 914 | 912 |
| 915 | 913 |
| 914 int Assembler::BranchOffset(Instr instr) { |
| 915 // At pre-R6 and for other R6 branches the offset is 16 bits. |
| 916 int bits = OffsetSize::kOffset16; |
| 917 |
| 918 if (IsMipsArchVariant(kMips32r6)) { |
| 919 uint32_t opcode = GetOpcodeField(instr); |
| 920 switch (opcode) { |
| 921 // Checks BC or BALC. |
| 922 case BC: |
| 923 case BALC: |
| 924 bits = OffsetSize::kOffset26; |
| 925 break; |
| 926 |
| 927 // Checks BEQZC or BNEZC. |
| 928 case POP66: |
| 929 case POP76: |
| 930 if (GetRsField(instr) != 0) bits = OffsetSize::kOffset21; |
| 931 break; |
| 932 default: |
| 933 break; |
| 934 } |
| 935 } |
| 936 |
| 937 return (1 << (bits + 2 - 1)) - 1; |
| 938 } |
| 939 |
| 940 |
| 916 // We have to use a temporary register for things that can be relocated even | 941 // We have to use a temporary register for things that can be relocated even |
| 917 // if they can be encoded in the MIPS's 16 bits of immediate-offset instruction | 942 // if they can be encoded in the MIPS's 16 bits of immediate-offset instruction |
| 918 // space. There is no guarantee that the relocated location can be similarly | 943 // space. There is no guarantee that the relocated location can be similarly |
| 919 // encoded. | 944 // encoded. |
| 920 bool Assembler::MustUseReg(RelocInfo::Mode rmode) { | 945 bool Assembler::MustUseReg(RelocInfo::Mode rmode) { |
| 921 return !RelocInfo::IsNone(rmode); | 946 return !RelocInfo::IsNone(rmode); |
| 922 } | 947 } |
| 923 | 948 |
| 924 void Assembler::GenInstrRegister(Opcode opcode, | 949 void Assembler::GenInstrRegister(Opcode opcode, |
| 925 Register rs, | 950 Register rs, |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1391 GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); | 1416 GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); |
| 1392 } else { | 1417 } else { |
| 1393 GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); | 1418 GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); |
| 1394 } | 1419 } |
| 1395 } | 1420 } |
| 1396 | 1421 |
| 1397 | 1422 |
| 1398 void Assembler::beqzc(Register rs, int32_t offset) { | 1423 void Assembler::beqzc(Register rs, int32_t offset) { |
| 1399 DCHECK(IsMipsArchVariant(kMips32r6)); | 1424 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1400 DCHECK(!(rs.is(zero_reg))); | 1425 DCHECK(!(rs.is(zero_reg))); |
| 1426 DCHECK(is_int21(offset)); |
| 1401 GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH); | 1427 GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH); |
| 1402 } | 1428 } |
| 1403 | 1429 |
| 1404 | 1430 |
| 1405 void Assembler::bnec(Register rs, Register rt, int16_t offset) { | 1431 void Assembler::bnec(Register rs, Register rt, int16_t offset) { |
| 1406 DCHECK(IsMipsArchVariant(kMips32r6)); | 1432 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1407 DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0); | 1433 DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0); |
| 1408 if (rs.code() < rt.code()) { | 1434 if (rs.code() < rt.code()) { |
| 1409 GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); | 1435 GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); |
| 1410 } else { | 1436 } else { |
| 1411 GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); | 1437 GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); |
| 1412 } | 1438 } |
| 1413 } | 1439 } |
| 1414 | 1440 |
| 1415 | 1441 |
| 1416 void Assembler::bnezc(Register rs, int32_t offset) { | 1442 void Assembler::bnezc(Register rs, int32_t offset) { |
| 1417 DCHECK(IsMipsArchVariant(kMips32r6)); | 1443 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1418 DCHECK(!(rs.is(zero_reg))); | 1444 DCHECK(!(rs.is(zero_reg))); |
| 1445 DCHECK(is_int21(offset)); |
| 1419 GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH); | 1446 GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH); |
| 1420 } | 1447 } |
| 1421 | 1448 |
| 1422 | 1449 |
| 1423 void Assembler::j(int32_t target) { | 1450 void Assembler::j(int32_t target) { |
| 1424 #if DEBUG | 1451 #if DEBUG |
| 1425 // Get pc of delay slot. | 1452 // Get pc of delay slot. |
| 1426 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1453 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
| 1427 bool in_range = ((ipc ^ static_cast<uint32_t>(target)) >> | 1454 bool in_range = ((ipc ^ static_cast<uint32_t>(target)) >> |
| 1428 (kImm26Bits + kImmFieldShift)) == 0; | 1455 (kImm26Bits + kImmFieldShift)) == 0; |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1811 void Assembler::lwpc(Register rs, int32_t offset19) { | 1838 void Assembler::lwpc(Register rs, int32_t offset19) { |
| 1812 DCHECK(IsMipsArchVariant(kMips32r6)); | 1839 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1813 DCHECK(rs.is_valid() && is_int19(offset19)); | 1840 DCHECK(rs.is_valid() && is_int19(offset19)); |
| 1814 uint32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask); | 1841 uint32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask); |
| 1815 GenInstrImmediate(PCREL, rs, imm21); | 1842 GenInstrImmediate(PCREL, rs, imm21); |
| 1816 } | 1843 } |
| 1817 | 1844 |
| 1818 | 1845 |
| 1819 void Assembler::auipc(Register rs, int16_t imm16) { | 1846 void Assembler::auipc(Register rs, int16_t imm16) { |
| 1820 DCHECK(IsMipsArchVariant(kMips32r6)); | 1847 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1821 DCHECK(rs.is_valid() && is_int16(imm16)); | 1848 DCHECK(rs.is_valid()); |
| 1822 uint32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask); | 1849 uint32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask); |
| 1823 GenInstrImmediate(PCREL, rs, imm21); | 1850 GenInstrImmediate(PCREL, rs, imm21); |
| 1824 } | 1851 } |
| 1825 | 1852 |
| 1826 | 1853 |
| 1827 void Assembler::aluipc(Register rs, int16_t imm16) { | 1854 void Assembler::aluipc(Register rs, int16_t imm16) { |
| 1828 DCHECK(IsMipsArchVariant(kMips32r6)); | 1855 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1829 DCHECK(rs.is_valid() && is_int16(imm16)); | 1856 DCHECK(rs.is_valid()); |
| 1830 uint32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask); | 1857 uint32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask); |
| 1831 GenInstrImmediate(PCREL, rs, imm21); | 1858 GenInstrImmediate(PCREL, rs, imm21); |
| 1832 } | 1859 } |
| 1833 | 1860 |
| 1834 | 1861 |
| 1835 // -------------Misc-instructions-------------- | 1862 // -------------Misc-instructions-------------- |
| 1836 | 1863 |
| 1837 // Break / Trap instructions. | 1864 // Break / Trap instructions. |
| 1838 void Assembler::break_(uint32_t code, bool break_as_stop) { | 1865 void Assembler::break_(uint32_t code, bool break_as_stop) { |
| 1839 DCHECK((code & ~0xfffff) == 0); | 1866 DCHECK((code & ~0xfffff) == 0); |
| (...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 if (patched) { | 3145 if (patched) { |
| 3119 CpuFeatures::FlushICache(pc + 2, sizeof(Address)); | 3146 CpuFeatures::FlushICache(pc + 2, sizeof(Address)); |
| 3120 } | 3147 } |
| 3121 } | 3148 } |
| 3122 | 3149 |
| 3123 | 3150 |
| 3124 } // namespace internal | 3151 } // namespace internal |
| 3125 } // namespace v8 | 3152 } // namespace v8 |
| 3126 | 3153 |
| 3127 #endif // V8_TARGET_ARCH_MIPS | 3154 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |