Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: src/mips/assembler-mips.cc

Issue 1195793002: MIPS: Implemented PC-relative instructions for R6. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips/assembler-mips.h ('k') | src/mips/constants-mips.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/mips/assembler-mips.h ('k') | src/mips/constants-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698