| 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 | (kNegOffset & kImm16Mask); // NOLINT | 275 | (kNegOffset & kImm16Mask); // NOLINT |
| 276 | 276 |
| 277 const Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift) | 277 const Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift) |
| 278 | (kNegOffset & kImm16Mask); // NOLINT | 278 | (kNegOffset & kImm16Mask); // NOLINT |
| 279 // A mask for the Rt register for push, pop, lw, sw instructions. | 279 // A mask for the Rt register for push, pop, lw, sw instructions. |
| 280 const Instr kRtMask = kRtFieldMask; | 280 const Instr kRtMask = kRtFieldMask; |
| 281 const Instr kLwSwInstrTypeMask = 0xffe00000; | 281 const Instr kLwSwInstrTypeMask = 0xffe00000; |
| 282 const Instr kLwSwInstrArgumentMask = ~kLwSwInstrTypeMask; | 282 const Instr kLwSwInstrArgumentMask = ~kLwSwInstrTypeMask; |
| 283 const Instr kLwSwOffsetMask = kImm16Mask; | 283 const Instr kLwSwOffsetMask = kImm16Mask; |
| 284 | 284 |
| 285 | |
| 286 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) | 285 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) |
| 287 : AssemblerBase(isolate, buffer, buffer_size), | 286 : AssemblerBase(isolate, buffer, buffer_size), |
| 288 recorded_ast_id_(TypeFeedbackId::None()), | 287 recorded_ast_id_(TypeFeedbackId::None()), |
| 289 positions_recorder_(this) { | 288 positions_recorder_(this) { |
| 290 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); | 289 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
| 291 | 290 |
| 292 last_trampoline_pool_end_ = 0; | 291 last_trampoline_pool_end_ = 0; |
| 293 no_trampoline_pool_before_ = 0; | 292 no_trampoline_pool_before_ = 0; |
| 294 trampoline_pool_blocked_nesting_ = 0; | 293 trampoline_pool_blocked_nesting_ = 0; |
| 295 // We leave space (16 * kTrampolineSlotsSize) | 294 // We leave space (16 * kTrampolineSlotsSize) |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 Register rs, | 951 Register rs, |
| 953 FPURegister ft, | 952 FPURegister ft, |
| 954 int32_t j) { | 953 int32_t j) { |
| 955 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); | 954 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); |
| 956 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) | 955 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) |
| 957 | (j & kImm16Mask); | 956 | (j & kImm16Mask); |
| 958 emit(instr); | 957 emit(instr); |
| 959 } | 958 } |
| 960 | 959 |
| 961 | 960 |
| 961 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t j) { |
| 962 DCHECK(rs.is_valid() && (is_uint21(j))); |
| 963 Instr instr = |
| 964 opcode | (rs.code() << kRsShift) | static_cast<uint32_t>(j & kImm21Mask); |
| 965 emit(instr); |
| 966 } |
| 967 |
| 968 |
| 962 void Assembler::GenInstrJump(Opcode opcode, | 969 void Assembler::GenInstrJump(Opcode opcode, |
| 963 uint32_t address) { | 970 uint32_t address) { |
| 964 BlockTrampolinePoolScope block_trampoline_pool(this); | 971 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 965 DCHECK(is_uint26(address)); | 972 DCHECK(is_uint26(address)); |
| 966 Instr instr = opcode | address; | 973 Instr instr = opcode | address; |
| 967 emit(instr); | 974 emit(instr); |
| 968 BlockTrampolinePoolFor(1); // For associated delay slot. | 975 BlockTrampolinePoolFor(1); // For associated delay slot. |
| 969 } | 976 } |
| 970 | 977 |
| 971 | 978 |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 void Assembler::beqc(Register rs, Register rt, int16_t offset) { | 1355 void Assembler::beqc(Register rs, Register rt, int16_t offset) { |
| 1349 DCHECK(IsMipsArchVariant(kMips32r6)); | 1356 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1350 DCHECK(rs.code() < rt.code()); | 1357 DCHECK(rs.code() < rt.code()); |
| 1351 GenInstrImmediate(ADDI, rs, rt, offset); | 1358 GenInstrImmediate(ADDI, rs, rt, offset); |
| 1352 } | 1359 } |
| 1353 | 1360 |
| 1354 | 1361 |
| 1355 void Assembler::beqzc(Register rs, int32_t offset) { | 1362 void Assembler::beqzc(Register rs, int32_t offset) { |
| 1356 DCHECK(IsMipsArchVariant(kMips32r6)); | 1363 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1357 DCHECK(!(rs.is(zero_reg))); | 1364 DCHECK(!(rs.is(zero_reg))); |
| 1358 Instr instr = BEQZC | (rs.code() << kRsShift) | offset; | 1365 Instr instr = POP66 | (rs.code() << kRsShift) | |
| 1366 static_cast<uint32_t>(offset & kImm21Mask); |
| 1359 emit(instr); | 1367 emit(instr); |
| 1360 } | 1368 } |
| 1361 | 1369 |
| 1362 | 1370 |
| 1363 void Assembler::bnec(Register rs, Register rt, int16_t offset) { | 1371 void Assembler::bnec(Register rs, Register rt, int16_t offset) { |
| 1364 DCHECK(IsMipsArchVariant(kMips32r6)); | 1372 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1365 DCHECK(rs.code() < rt.code()); | 1373 DCHECK(rs.code() < rt.code()); |
| 1366 GenInstrImmediate(DADDI, rs, rt, offset); | 1374 GenInstrImmediate(DADDI, rs, rt, offset); |
| 1367 } | 1375 } |
| 1368 | 1376 |
| 1369 | 1377 |
| 1370 void Assembler::bnezc(Register rs, int32_t offset) { | 1378 void Assembler::bnezc(Register rs, int32_t offset) { |
| 1371 DCHECK(IsMipsArchVariant(kMips32r6)); | 1379 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1372 DCHECK(!(rs.is(zero_reg))); | 1380 DCHECK(!(rs.is(zero_reg))); |
| 1373 Instr instr = BNEZC | (rs.code() << kRsShift) | offset; | 1381 Instr instr = POP76 | (rs.code() << kRsShift) | offset; |
| 1374 emit(instr); | 1382 emit(instr); |
| 1375 } | 1383 } |
| 1376 | 1384 |
| 1377 | 1385 |
| 1378 void Assembler::j(int32_t target) { | 1386 void Assembler::j(int32_t target) { |
| 1379 #if DEBUG | 1387 #if DEBUG |
| 1380 // Get pc of delay slot. | 1388 // Get pc of delay slot. |
| 1381 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1389 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
| 1382 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> | 1390 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
| 1383 (kImm26Bits + kImmFieldShift)) == 0; | 1391 (kImm26Bits + kImmFieldShift)) == 0; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> | 1449 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
| 1442 (kImm26Bits+kImmFieldShift)) == 0; | 1450 (kImm26Bits+kImmFieldShift)) == 0; |
| 1443 if (in_range) { | 1451 if (in_range) { |
| 1444 jal(target); | 1452 jal(target); |
| 1445 } else { | 1453 } else { |
| 1446 jalr(t9); | 1454 jalr(t9); |
| 1447 } | 1455 } |
| 1448 } | 1456 } |
| 1449 | 1457 |
| 1450 | 1458 |
| 1459 void Assembler::jic(Register rt, int16_t offset) { |
| 1460 DCHECK(kArchVariant == kMips32r6); |
| 1461 Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) | |
| 1462 static_cast<uint16_t>(offset); |
| 1463 emit(instr); |
| 1464 } |
| 1465 |
| 1466 |
| 1467 void Assembler::jialc(Register rt, int16_t offset) { |
| 1468 DCHECK(kArchVariant == kMips32r6); |
| 1469 positions_recorder()->WriteRecordedPositions(); |
| 1470 GenInstrImmediate(POP76, zero_reg, rt, offset); |
| 1471 } |
| 1472 |
| 1473 |
| 1451 // -------Data-processing-instructions--------- | 1474 // -------Data-processing-instructions--------- |
| 1452 | 1475 |
| 1453 // Arithmetic. | 1476 // Arithmetic. |
| 1454 | 1477 |
| 1455 void Assembler::addu(Register rd, Register rs, Register rt) { | 1478 void Assembler::addu(Register rd, Register rs, Register rt) { |
| 1456 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); | 1479 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); |
| 1457 } | 1480 } |
| 1458 | 1481 |
| 1459 | 1482 |
| 1460 void Assembler::addiu(Register rd, Register rs, int32_t j) { | 1483 void Assembler::addiu(Register rd, Register rs, int32_t j) { |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1755 | 1778 |
| 1756 | 1779 |
| 1757 void Assembler::aui(Register rs, Register rt, int32_t j) { | 1780 void Assembler::aui(Register rs, Register rt, int32_t j) { |
| 1758 // This instruction uses same opcode as 'lui'. The difference in encoding is | 1781 // This instruction uses same opcode as 'lui'. The difference in encoding is |
| 1759 // 'lui' has zero reg. for rs field. | 1782 // 'lui' has zero reg. for rs field. |
| 1760 DCHECK(is_uint16(j)); | 1783 DCHECK(is_uint16(j)); |
| 1761 GenInstrImmediate(LUI, rs, rt, j); | 1784 GenInstrImmediate(LUI, rs, rt, j); |
| 1762 } | 1785 } |
| 1763 | 1786 |
| 1764 | 1787 |
| 1788 // ---------PC-Relative instructions----------- |
| 1789 |
| 1790 void Assembler::addiupc(Register rs, int32_t imm19) { |
| 1791 DCHECK(kArchVariant == kMips32r6); |
| 1792 DCHECK(rs.is_valid()); |
| 1793 DCHECK((kMinInt19 <= imm19) && (imm19 <= kMaxInt19)); |
| 1794 int32_t imm21 = |
| 1795 ADDIUPC << kImm19Bits | static_cast<uint32_t>(imm19 & kImm19Mask); |
| 1796 GenInstrImmediate(PCREL, rs, imm21); |
| 1797 } |
| 1798 |
| 1799 |
| 1800 void Assembler::lwpc(Register rs, int32_t offset19) { |
| 1801 DCHECK(kArchVariant == kMips32r6); |
| 1802 DCHECK(rs.is_valid()); |
| 1803 DCHECK((kMinInt19 <= offset19) && (offset19 <= kMaxInt19)); |
| 1804 int32_t imm21 = |
| 1805 LWPC << kImm19Bits | static_cast<uint32_t>(offset19 & kImm19Mask); |
| 1806 GenInstrImmediate(PCREL, rs, imm21); |
| 1807 } |
| 1808 |
| 1809 |
| 1810 void Assembler::aluipc(Register rs, int16_t imm16) { |
| 1811 DCHECK(kArchVariant == kMips32r6); |
| 1812 DCHECK(rs.is_valid() && is_int16(imm16)); |
| 1813 int32_t imm21 = |
| 1814 ALUIPC << kImm16Bits | static_cast<uint32_t>(imm16 & kImm16Mask); |
| 1815 GenInstrImmediate(PCREL, rs, imm21); |
| 1816 } |
| 1817 |
| 1818 |
| 1765 // -------------Misc-instructions-------------- | 1819 // -------------Misc-instructions-------------- |
| 1766 | 1820 |
| 1767 // Break / Trap instructions. | 1821 // Break / Trap instructions. |
| 1768 void Assembler::break_(uint32_t code, bool break_as_stop) { | 1822 void Assembler::break_(uint32_t code, bool break_as_stop) { |
| 1769 DCHECK((code & ~0xfffff) == 0); | 1823 DCHECK((code & ~0xfffff) == 0); |
| 1770 // We need to invalidate breaks that could be stops as well because the | 1824 // We need to invalidate breaks that could be stops as well because the |
| 1771 // simulator expects a char pointer after the stop instruction. | 1825 // simulator expects a char pointer after the stop instruction. |
| 1772 // See constants-mips.h for explanation. | 1826 // See constants-mips.h for explanation. |
| 1773 DCHECK((break_as_stop && | 1827 DCHECK((break_as_stop && |
| 1774 code <= kMaxStopCode && | 1828 code <= kMaxStopCode && |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1931 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { | 1985 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { |
| 1932 // Should be called via MacroAssembler::Ext. | 1986 // Should be called via MacroAssembler::Ext. |
| 1933 // Ext instr has 'rt' field as dest, and two uint5: msb, lsb. | 1987 // Ext instr has 'rt' field as dest, and two uint5: msb, lsb. |
| 1934 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 1988 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
| 1935 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT); | 1989 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT); |
| 1936 } | 1990 } |
| 1937 | 1991 |
| 1938 | 1992 |
| 1939 void Assembler::bitswap(Register rd, Register rt) { | 1993 void Assembler::bitswap(Register rd, Register rt) { |
| 1940 DCHECK(kArchVariant == kMips32r6); | 1994 DCHECK(kArchVariant == kMips32r6); |
| 1941 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BITSWAP); | 1995 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL); |
| 1942 } | 1996 } |
| 1943 | 1997 |
| 1944 | 1998 |
| 1945 void Assembler::pref(int32_t hint, const MemOperand& rs) { | 1999 void Assembler::pref(int32_t hint, const MemOperand& rs) { |
| 1946 DCHECK(!IsMipsArchVariant(kLoongson)); | 2000 DCHECK(!IsMipsArchVariant(kLoongson)); |
| 1947 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); | 2001 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); |
| 1948 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) | 2002 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) |
| 1949 | (rs.offset_); | 2003 | (rs.offset_); |
| 1950 emit(instr); | 2004 emit(instr); |
| 1951 } | 2005 } |
| 1952 | 2006 |
| 1953 | 2007 |
| 2008 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) { |
| 2009 DCHECK(kArchVariant == kMips32r6); |
| 2010 DCHECK(is_uint3(bp)); |
| 2011 uint16_t sa = (ALIGN << kBp2Bits) | bp; |
| 2012 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL); |
| 2013 } |
| 2014 |
| 2015 |
| 1954 // --------Coprocessor-instructions---------------- | 2016 // --------Coprocessor-instructions---------------- |
| 1955 | 2017 |
| 1956 // Load, store, move. | 2018 // Load, store, move. |
| 1957 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { | 2019 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { |
| 1958 if (is_int16(src.offset_)) { | 2020 if (is_int16(src.offset_)) { |
| 1959 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); | 2021 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); |
| 1960 } else { // Offset > 16 bits, use multiple instructions to load. | 2022 } else { // Offset > 16 bits, use multiple instructions to load. |
| 1961 LoadRegPlusOffsetToAt(src); | 2023 LoadRegPlusOffsetToAt(src); |
| 1962 GenInstrImmediate(LWC1, at, fd, 0); | 2024 GenInstrImmediate(LWC1, at, fd, 0); |
| 1963 } | 2025 } |
| (...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3035 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { | 3097 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { |
| 3036 // No out-of-line constant pool support. | 3098 // No out-of-line constant pool support. |
| 3037 DCHECK(!FLAG_enable_ool_constant_pool); | 3099 DCHECK(!FLAG_enable_ool_constant_pool); |
| 3038 return; | 3100 return; |
| 3039 } | 3101 } |
| 3040 | 3102 |
| 3041 | 3103 |
| 3042 } } // namespace v8::internal | 3104 } } // namespace v8::internal |
| 3043 | 3105 |
| 3044 #endif // V8_TARGET_ARCH_MIPS | 3106 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |