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 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 Register rs, | 952 Register rs, |
953 FPURegister ft, | 953 FPURegister ft, |
954 int32_t j) { | 954 int32_t j) { |
955 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); | 955 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); |
956 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) | 956 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) |
957 | (j & kImm16Mask); | 957 | (j & kImm16Mask); |
958 emit(instr); | 958 emit(instr); |
959 } | 959 } |
960 | 960 |
961 | 961 |
| 962 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t j) { |
| 963 DCHECK(rs.is_valid() && (is_uint21(j))); |
| 964 Instr instr = opcode | (rs.code() << kRsShift) | (j & kImm21Mask); |
| 965 emit(instr); |
| 966 } |
| 967 |
| 968 |
| 969 void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26) { |
| 970 DCHECK(is_int26(offset26)); |
| 971 Instr instr = opcode | (offset26 & kImm26Mask); |
| 972 emit(instr); |
| 973 } |
| 974 |
| 975 |
962 void Assembler::GenInstrJump(Opcode opcode, | 976 void Assembler::GenInstrJump(Opcode opcode, |
963 uint32_t address) { | 977 uint32_t address) { |
964 BlockTrampolinePoolScope block_trampoline_pool(this); | 978 BlockTrampolinePoolScope block_trampoline_pool(this); |
965 DCHECK(is_uint26(address)); | 979 DCHECK(is_uint26(address)); |
966 Instr instr = opcode | address; | 980 Instr instr = opcode | address; |
967 emit(instr); | 981 emit(instr); |
968 BlockTrampolinePoolFor(1); // For associated delay slot. | 982 BlockTrampolinePoolFor(1); // For associated delay slot. |
969 } | 983 } |
970 | 984 |
971 | 985 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 beq(zero_reg, zero_reg, offset); | 1163 beq(zero_reg, zero_reg, offset); |
1150 } | 1164 } |
1151 | 1165 |
1152 | 1166 |
1153 void Assembler::bal(int16_t offset) { | 1167 void Assembler::bal(int16_t offset) { |
1154 positions_recorder()->WriteRecordedPositions(); | 1168 positions_recorder()->WriteRecordedPositions(); |
1155 bgezal(zero_reg, offset); | 1169 bgezal(zero_reg, offset); |
1156 } | 1170 } |
1157 | 1171 |
1158 | 1172 |
| 1173 void Assembler::bc(int32_t offset) { |
| 1174 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1175 GenInstrImmediate(BC, offset); |
| 1176 } |
| 1177 |
| 1178 |
| 1179 void Assembler::balc(int32_t offset) { |
| 1180 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1181 positions_recorder()->WriteRecordedPositions(); |
| 1182 GenInstrImmediate(BALC, offset); |
| 1183 } |
| 1184 |
| 1185 |
1159 void Assembler::beq(Register rs, Register rt, int16_t offset) { | 1186 void Assembler::beq(Register rs, Register rt, int16_t offset) { |
1160 BlockTrampolinePoolScope block_trampoline_pool(this); | 1187 BlockTrampolinePoolScope block_trampoline_pool(this); |
1161 GenInstrImmediate(BEQ, rs, rt, offset); | 1188 GenInstrImmediate(BEQ, rs, rt, offset); |
1162 BlockTrampolinePoolFor(1); // For associated delay slot. | 1189 BlockTrampolinePoolFor(1); // For associated delay slot. |
1163 } | 1190 } |
1164 | 1191 |
1165 | 1192 |
1166 void Assembler::bgez(Register rs, int16_t offset) { | 1193 void Assembler::bgez(Register rs, int16_t offset) { |
1167 BlockTrampolinePoolScope block_trampoline_pool(this); | 1194 BlockTrampolinePoolScope block_trampoline_pool(this); |
1168 GenInstrImmediate(REGIMM, rs, BGEZ, offset); | 1195 GenInstrImmediate(REGIMM, rs, BGEZ, offset); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 void Assembler::beqc(Register rs, Register rt, int16_t offset) { | 1375 void Assembler::beqc(Register rs, Register rt, int16_t offset) { |
1349 DCHECK(IsMipsArchVariant(kMips32r6)); | 1376 DCHECK(IsMipsArchVariant(kMips32r6)); |
1350 DCHECK(rs.code() < rt.code()); | 1377 DCHECK(rs.code() < rt.code()); |
1351 GenInstrImmediate(ADDI, rs, rt, offset); | 1378 GenInstrImmediate(ADDI, rs, rt, offset); |
1352 } | 1379 } |
1353 | 1380 |
1354 | 1381 |
1355 void Assembler::beqzc(Register rs, int32_t offset) { | 1382 void Assembler::beqzc(Register rs, int32_t offset) { |
1356 DCHECK(IsMipsArchVariant(kMips32r6)); | 1383 DCHECK(IsMipsArchVariant(kMips32r6)); |
1357 DCHECK(!(rs.is(zero_reg))); | 1384 DCHECK(!(rs.is(zero_reg))); |
1358 Instr instr = BEQZC | (rs.code() << kRsShift) | offset; | 1385 Instr instr = POP66 | (rs.code() << kRsShift) | (offset & kImm21Mask); |
1359 emit(instr); | 1386 emit(instr); |
1360 } | 1387 } |
1361 | 1388 |
1362 | 1389 |
1363 void Assembler::bnec(Register rs, Register rt, int16_t offset) { | 1390 void Assembler::bnec(Register rs, Register rt, int16_t offset) { |
1364 DCHECK(IsMipsArchVariant(kMips32r6)); | 1391 DCHECK(IsMipsArchVariant(kMips32r6)); |
1365 DCHECK(rs.code() < rt.code()); | 1392 DCHECK(rs.code() < rt.code()); |
1366 GenInstrImmediate(DADDI, rs, rt, offset); | 1393 GenInstrImmediate(DADDI, rs, rt, offset); |
1367 } | 1394 } |
1368 | 1395 |
1369 | 1396 |
1370 void Assembler::bnezc(Register rs, int32_t offset) { | 1397 void Assembler::bnezc(Register rs, int32_t offset) { |
1371 DCHECK(IsMipsArchVariant(kMips32r6)); | 1398 DCHECK(IsMipsArchVariant(kMips32r6)); |
1372 DCHECK(!(rs.is(zero_reg))); | 1399 DCHECK(!(rs.is(zero_reg))); |
1373 Instr instr = BNEZC | (rs.code() << kRsShift) | offset; | 1400 Instr instr = POP76 | (rs.code() << kRsShift) | offset; |
1374 emit(instr); | 1401 emit(instr); |
1375 } | 1402 } |
1376 | 1403 |
1377 | 1404 |
1378 void Assembler::j(int32_t target) { | 1405 void Assembler::j(int32_t target) { |
1379 #if DEBUG | 1406 #if DEBUG |
1380 // Get pc of delay slot. | 1407 // Get pc of delay slot. |
1381 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1408 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1382 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> | 1409 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
1383 (kImm26Bits + kImmFieldShift)) == 0; | 1410 (kImm26Bits + kImmFieldShift)) == 0; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 | 1442 |
1416 | 1443 |
1417 void Assembler::jalr(Register rs, Register rd) { | 1444 void Assembler::jalr(Register rs, Register rd) { |
1418 BlockTrampolinePoolScope block_trampoline_pool(this); | 1445 BlockTrampolinePoolScope block_trampoline_pool(this); |
1419 positions_recorder()->WriteRecordedPositions(); | 1446 positions_recorder()->WriteRecordedPositions(); |
1420 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); | 1447 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); |
1421 BlockTrampolinePoolFor(1); // For associated delay slot. | 1448 BlockTrampolinePoolFor(1); // For associated delay slot. |
1422 } | 1449 } |
1423 | 1450 |
1424 | 1451 |
1425 void Assembler::j_or_jr(int32_t target, Register rs) { | 1452 void Assembler::jic(Register rt, int16_t offset) { |
1426 // Get pc of delay slot. | 1453 DCHECK(IsMipsArchVariant(kMips32r6)); |
1427 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1454 Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) | |
1428 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> | 1455 (offset & kImm16Mask); |
1429 (kImm26Bits + kImmFieldShift)) == 0; | 1456 emit(instr); |
1430 if (in_range) { | |
1431 j(target); | |
1432 } else { | |
1433 jr(t9); | |
1434 } | |
1435 } | 1457 } |
1436 | 1458 |
1437 | 1459 |
1438 void Assembler::jal_or_jalr(int32_t target, Register rs) { | 1460 void Assembler::jialc(Register rt, int16_t offset) { |
1439 // Get pc of delay slot. | 1461 DCHECK(IsMipsArchVariant(kMips32r6)); |
1440 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1462 positions_recorder()->WriteRecordedPositions(); |
1441 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> | 1463 GenInstrImmediate(POP76, zero_reg, rt, offset); |
1442 (kImm26Bits+kImmFieldShift)) == 0; | |
1443 if (in_range) { | |
1444 jal(target); | |
1445 } else { | |
1446 jalr(t9); | |
1447 } | |
1448 } | 1464 } |
1449 | 1465 |
1450 | 1466 |
1451 // -------Data-processing-instructions--------- | 1467 // -------Data-processing-instructions--------- |
1452 | 1468 |
1453 // Arithmetic. | 1469 // Arithmetic. |
1454 | 1470 |
1455 void Assembler::addu(Register rd, Register rs, Register rt) { | 1471 void Assembler::addu(Register rd, Register rs, Register rt) { |
1456 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); | 1472 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); |
1457 } | 1473 } |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1750 | 1766 |
1751 void Assembler::lui(Register rd, int32_t j) { | 1767 void Assembler::lui(Register rd, int32_t j) { |
1752 DCHECK(is_uint16(j)); | 1768 DCHECK(is_uint16(j)); |
1753 GenInstrImmediate(LUI, zero_reg, rd, j); | 1769 GenInstrImmediate(LUI, zero_reg, rd, j); |
1754 } | 1770 } |
1755 | 1771 |
1756 | 1772 |
1757 void Assembler::aui(Register rs, Register rt, int32_t j) { | 1773 void Assembler::aui(Register rs, Register rt, int32_t j) { |
1758 // This instruction uses same opcode as 'lui'. The difference in encoding is | 1774 // This instruction uses same opcode as 'lui'. The difference in encoding is |
1759 // 'lui' has zero reg. for rs field. | 1775 // 'lui' has zero reg. for rs field. |
| 1776 DCHECK(!(rs.is(zero_reg))); |
1760 DCHECK(is_uint16(j)); | 1777 DCHECK(is_uint16(j)); |
1761 GenInstrImmediate(LUI, rs, rt, j); | 1778 GenInstrImmediate(LUI, rs, rt, j); |
1762 } | 1779 } |
1763 | 1780 |
1764 | 1781 |
| 1782 // ---------PC-Relative instructions----------- |
| 1783 |
| 1784 void Assembler::addiupc(Register rs, int32_t imm19) { |
| 1785 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1786 DCHECK(rs.is_valid() && is_int19(imm19)); |
| 1787 int32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask); |
| 1788 GenInstrImmediate(PCREL, rs, imm21); |
| 1789 } |
| 1790 |
| 1791 |
| 1792 void Assembler::lwpc(Register rs, int32_t offset19) { |
| 1793 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1794 DCHECK(rs.is_valid() && is_int19(offset19)); |
| 1795 int32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask); |
| 1796 GenInstrImmediate(PCREL, rs, imm21); |
| 1797 } |
| 1798 |
| 1799 |
| 1800 void Assembler::auipc(Register rs, int16_t imm16) { |
| 1801 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1802 DCHECK(rs.is_valid() && is_int16(imm16)); |
| 1803 int32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask); |
| 1804 GenInstrImmediate(PCREL, rs, imm21); |
| 1805 } |
| 1806 |
| 1807 |
| 1808 void Assembler::aluipc(Register rs, int16_t imm16) { |
| 1809 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 1810 DCHECK(rs.is_valid() && is_int16(imm16)); |
| 1811 int32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask); |
| 1812 GenInstrImmediate(PCREL, rs, imm21); |
| 1813 } |
| 1814 |
| 1815 |
1765 // -------------Misc-instructions-------------- | 1816 // -------------Misc-instructions-------------- |
1766 | 1817 |
1767 // Break / Trap instructions. | 1818 // Break / Trap instructions. |
1768 void Assembler::break_(uint32_t code, bool break_as_stop) { | 1819 void Assembler::break_(uint32_t code, bool break_as_stop) { |
1769 DCHECK((code & ~0xfffff) == 0); | 1820 DCHECK((code & ~0xfffff) == 0); |
1770 // We need to invalidate breaks that could be stops as well because the | 1821 // We need to invalidate breaks that could be stops as well because the |
1771 // simulator expects a char pointer after the stop instruction. | 1822 // simulator expects a char pointer after the stop instruction. |
1772 // See constants-mips.h for explanation. | 1823 // See constants-mips.h for explanation. |
1773 DCHECK((break_as_stop && | 1824 DCHECK((break_as_stop && |
1774 code <= kMaxStopCode && | 1825 code <= kMaxStopCode && |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1930 | 1981 |
1931 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { | 1982 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { |
1932 // Should be called via MacroAssembler::Ext. | 1983 // Should be called via MacroAssembler::Ext. |
1933 // Ext instr has 'rt' field as dest, and two uint5: msb, lsb. | 1984 // Ext instr has 'rt' field as dest, and two uint5: msb, lsb. |
1934 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 1985 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
1935 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT); | 1986 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT); |
1936 } | 1987 } |
1937 | 1988 |
1938 | 1989 |
1939 void Assembler::bitswap(Register rd, Register rt) { | 1990 void Assembler::bitswap(Register rd, Register rt) { |
1940 DCHECK(kArchVariant == kMips32r6); | 1991 DCHECK(IsMipsArchVariant(kMips32r6)); |
1941 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BITSWAP); | 1992 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL); |
1942 } | 1993 } |
1943 | 1994 |
1944 | 1995 |
1945 void Assembler::pref(int32_t hint, const MemOperand& rs) { | 1996 void Assembler::pref(int32_t hint, const MemOperand& rs) { |
1946 DCHECK(!IsMipsArchVariant(kLoongson)); | 1997 DCHECK(!IsMipsArchVariant(kLoongson)); |
1947 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); | 1998 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); |
1948 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) | 1999 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) |
1949 | (rs.offset_); | 2000 | (rs.offset_); |
1950 emit(instr); | 2001 emit(instr); |
1951 } | 2002 } |
1952 | 2003 |
1953 | 2004 |
| 2005 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) { |
| 2006 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2007 DCHECK(is_uint3(bp)); |
| 2008 uint16_t sa = (ALIGN << kBp2Bits) | bp; |
| 2009 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL); |
| 2010 } |
| 2011 |
| 2012 |
1954 // --------Coprocessor-instructions---------------- | 2013 // --------Coprocessor-instructions---------------- |
1955 | 2014 |
1956 // Load, store, move. | 2015 // Load, store, move. |
1957 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { | 2016 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { |
1958 if (is_int16(src.offset_)) { | 2017 if (is_int16(src.offset_)) { |
1959 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); | 2018 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); |
1960 } else { // Offset > 16 bits, use multiple instructions to load. | 2019 } else { // Offset > 16 bits, use multiple instructions to load. |
1961 LoadRegPlusOffsetToAt(src); | 2020 LoadRegPlusOffsetToAt(src); |
1962 GenInstrImmediate(LWC1, at, fd, 0); | 2021 GenInstrImmediate(LWC1, at, fd, 0); |
1963 } | 2022 } |
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3029 if (patched) { | 3088 if (patched) { |
3030 CpuFeatures::FlushICache(pc + 2, sizeof(Address)); | 3089 CpuFeatures::FlushICache(pc + 2, sizeof(Address)); |
3031 } | 3090 } |
3032 } | 3091 } |
3033 | 3092 |
3034 | 3093 |
3035 } // namespace internal | 3094 } // namespace internal |
3036 } // namespace v8 | 3095 } // namespace v8 |
3037 | 3096 |
3038 #endif // V8_TARGET_ARCH_MIPS | 3097 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |