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 |