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

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

Issue 1144373003: MIPS: Implemented PC-relative instructions for R6. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Implementation BC and BALC. 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
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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
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)
paul.l... 2015/06/10 03:49:25 nit: don't delete the line here, there should be 2
ilija.pavlovic 2015/06/12 09:51:32 Done.
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)
296 // for BlockTrampolinePoolScope buffer. 295 // for BlockTrampolinePoolScope buffer.
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
969 void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26) {
970 DCHECK((kMinInt26 <= offset26) && (offset26 <= kMaxInt26));
paul.l... 2015/06/10 03:49:25 You should be able to use is_int26() here - define
ilija.pavlovic 2015/06/12 09:51:32 Done.
971 Instr instr = opcode | static_cast<uint32_t>(offset26 & kImm26Mask);
paul.l... 2015/06/10 03:49:25 I don't think you need the cast here -- all the ty
ilija.pavlovic 2015/06/12 09:51:32 Done.
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));
paul.l... 2015/06/10 03:49:25 I suspect we will need positions_recorder()->Write
ilija.pavlovic 2015/06/12 09:51:32 Added "positions_recorder()->WriteRecordedPosition
1181 GenInstrImmediate(BALC, offset);
1182 }
1183
1184
1159 void Assembler::beq(Register rs, Register rt, int16_t offset) { 1185 void Assembler::beq(Register rs, Register rt, int16_t offset) {
1160 BlockTrampolinePoolScope block_trampoline_pool(this); 1186 BlockTrampolinePoolScope block_trampoline_pool(this);
1161 GenInstrImmediate(BEQ, rs, rt, offset); 1187 GenInstrImmediate(BEQ, rs, rt, offset);
1162 BlockTrampolinePoolFor(1); // For associated delay slot. 1188 BlockTrampolinePoolFor(1); // For associated delay slot.
1163 } 1189 }
1164 1190
1165 1191
1166 void Assembler::bgez(Register rs, int16_t offset) { 1192 void Assembler::bgez(Register rs, int16_t offset) {
1167 BlockTrampolinePoolScope block_trampoline_pool(this); 1193 BlockTrampolinePoolScope block_trampoline_pool(this);
1168 GenInstrImmediate(REGIMM, rs, BGEZ, offset); 1194 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) { 1374 void Assembler::beqc(Register rs, Register rt, int16_t offset) {
1349 DCHECK(IsMipsArchVariant(kMips32r6)); 1375 DCHECK(IsMipsArchVariant(kMips32r6));
1350 DCHECK(rs.code() < rt.code()); 1376 DCHECK(rs.code() < rt.code());
1351 GenInstrImmediate(ADDI, rs, rt, offset); 1377 GenInstrImmediate(ADDI, rs, rt, offset);
1352 } 1378 }
1353 1379
1354 1380
1355 void Assembler::beqzc(Register rs, int32_t offset) { 1381 void Assembler::beqzc(Register rs, int32_t offset) {
1356 DCHECK(IsMipsArchVariant(kMips32r6)); 1382 DCHECK(IsMipsArchVariant(kMips32r6));
1357 DCHECK(!(rs.is(zero_reg))); 1383 DCHECK(!(rs.is(zero_reg)));
1358 Instr instr = BEQZC | (rs.code() << kRsShift) | offset; 1384 Instr instr = POP66 | (rs.code() << kRsShift) |
1385 static_cast<uint32_t>(offset & kImm21Mask);
paul.l... 2015/06/10 03:49:25 Again, I think the cast is not needed. The code wi
ilija.pavlovic 2015/06/12 09:51:32 The static cast removed here and in instances belo
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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> 1468 bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
1442 (kImm26Bits+kImmFieldShift)) == 0; 1469 (kImm26Bits+kImmFieldShift)) == 0;
1443 if (in_range) { 1470 if (in_range) {
1444 jal(target); 1471 jal(target);
1445 } else { 1472 } else {
1446 jalr(t9); 1473 jalr(t9);
1447 } 1474 }
1448 } 1475 }
1449 1476
1450 1477
1478 void Assembler::jic(Register rt, int16_t offset) {
1479 DCHECK(IsMipsArchVariant(kMips32r6));
1480 Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) |
1481 static_cast<uint16_t>(offset);
1482 emit(instr);
1483 }
1484
1485
1486 void Assembler::jialc(Register rt, int16_t offset) {
1487 DCHECK(IsMipsArchVariant(kMips32r6));
1488 positions_recorder()->WriteRecordedPositions();
1489 GenInstrImmediate(POP76, zero_reg, rt, offset);
1490 }
1491
1492
1451 // -------Data-processing-instructions--------- 1493 // -------Data-processing-instructions---------
1452 1494
1453 // Arithmetic. 1495 // Arithmetic.
1454 1496
1455 void Assembler::addu(Register rd, Register rs, Register rt) { 1497 void Assembler::addu(Register rd, Register rs, Register rt) {
1456 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 1498 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1457 } 1499 }
1458 1500
1459 1501
1460 void Assembler::addiu(Register rd, Register rs, int32_t j) { 1502 void Assembler::addiu(Register rd, Register rs, int32_t j) {
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1749 1791
1750 1792
1751 void Assembler::lui(Register rd, int32_t j) { 1793 void Assembler::lui(Register rd, int32_t j) {
1752 DCHECK(is_uint16(j)); 1794 DCHECK(is_uint16(j));
1753 GenInstrImmediate(LUI, zero_reg, rd, j); 1795 GenInstrImmediate(LUI, zero_reg, rd, j);
1754 } 1796 }
1755 1797
1756 1798
1757 void Assembler::aui(Register rs, Register rt, int32_t j) { 1799 void Assembler::aui(Register rs, Register rt, int32_t j) {
1758 // This instruction uses same opcode as 'lui'. The difference in encoding is 1800 // This instruction uses same opcode as 'lui'. The difference in encoding is
1759 // 'lui' has zero reg. for rs field. 1801 // 'lui' has zero reg. for rs field.
paul.l... 2015/06/10 03:49:25 You should add DCHECK(rs != zero_reg); (I know it
ilija.pavlovic 2015/06/12 09:51:32 Ok :-))) Done.
1760 DCHECK(is_uint16(j)); 1802 DCHECK(is_uint16(j));
1761 GenInstrImmediate(LUI, rs, rt, j); 1803 GenInstrImmediate(LUI, rs, rt, j);
1762 } 1804 }
1763 1805
1764 1806
1807 // ---------PC-Relative instructions-----------
1808
1809 void Assembler::addiupc(Register rs, int32_t imm19) {
1810 DCHECK(IsMipsArchVariant(kMips32r6));
1811 DCHECK(rs.is_valid());
1812 DCHECK((kMinInt19 <= imm19) && (imm19 <= kMaxInt19));
paul.l... 2015/06/10 03:49:25 I think is_int19() will do, here and below.
ilija.pavlovic 2015/06/12 09:51:32 Done.
1813 int32_t imm21 =
1814 ADDIUPC << kImm19Bits | static_cast<uint32_t>(imm19 & kImm19Mask);
1815 GenInstrImmediate(PCREL, rs, imm21);
1816 }
1817
1818
1819 void Assembler::lwpc(Register rs, int32_t offset19) {
1820 DCHECK(IsMipsArchVariant(kMips32r6));
1821 DCHECK(rs.is_valid());
1822 DCHECK((kMinInt19 <= offset19) && (offset19 <= kMaxInt19));
1823 int32_t imm21 =
1824 LWPC << kImm19Bits | static_cast<uint32_t>(offset19 & kImm19Mask);
1825 GenInstrImmediate(PCREL, rs, imm21);
1826 }
1827
1828
1829 void Assembler::auipc(Register rs, int16_t imm16) {
1830 DCHECK(IsMipsArchVariant(kMips32r6));
1831 DCHECK(rs.is_valid() && is_int16(imm16));
1832 int32_t imm21 =
1833 AUIPC << kImm16Bits | static_cast<uint32_t>(imm16 & kImm16Mask);
1834 GenInstrImmediate(PCREL, rs, imm21);
1835 }
1836
1837
1838 void Assembler::aluipc(Register rs, int16_t imm16) {
1839 DCHECK(IsMipsArchVariant(kMips32r6));
1840 DCHECK(rs.is_valid() && is_int16(imm16));
1841 int32_t imm21 =
1842 ALUIPC << kImm16Bits | static_cast<uint32_t>(imm16 & kImm16Mask);
1843 GenInstrImmediate(PCREL, rs, imm21);
1844 }
1845
1846
1765 // -------------Misc-instructions-------------- 1847 // -------------Misc-instructions--------------
1766 1848
1767 // Break / Trap instructions. 1849 // Break / Trap instructions.
1768 void Assembler::break_(uint32_t code, bool break_as_stop) { 1850 void Assembler::break_(uint32_t code, bool break_as_stop) {
1769 DCHECK((code & ~0xfffff) == 0); 1851 DCHECK((code & ~0xfffff) == 0);
1770 // We need to invalidate breaks that could be stops as well because the 1852 // We need to invalidate breaks that could be stops as well because the
1771 // simulator expects a char pointer after the stop instruction. 1853 // simulator expects a char pointer after the stop instruction.
1772 // See constants-mips.h for explanation. 1854 // See constants-mips.h for explanation.
1773 DCHECK((break_as_stop && 1855 DCHECK((break_as_stop &&
1774 code <= kMaxStopCode && 1856 code <= kMaxStopCode &&
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1930 2012
1931 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { 2013 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
1932 // Should be called via MacroAssembler::Ext. 2014 // Should be called via MacroAssembler::Ext.
1933 // Ext instr has 'rt' field as dest, and two uint5: msb, lsb. 2015 // Ext instr has 'rt' field as dest, and two uint5: msb, lsb.
1934 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2016 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
1935 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT); 2017 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
1936 } 2018 }
1937 2019
1938 2020
1939 void Assembler::bitswap(Register rd, Register rt) { 2021 void Assembler::bitswap(Register rd, Register rt) {
1940 DCHECK(kArchVariant == kMips32r6); 2022 DCHECK(IsMipsArchVariant(kMips32r6));
1941 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BITSWAP); 2023 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
1942 } 2024 }
1943 2025
1944 2026
1945 void Assembler::pref(int32_t hint, const MemOperand& rs) { 2027 void Assembler::pref(int32_t hint, const MemOperand& rs) {
1946 DCHECK(!IsMipsArchVariant(kLoongson)); 2028 DCHECK(!IsMipsArchVariant(kLoongson));
1947 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); 2029 DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
1948 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) 2030 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
1949 | (rs.offset_); 2031 | (rs.offset_);
1950 emit(instr); 2032 emit(instr);
1951 } 2033 }
1952 2034
1953 2035
2036 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
2037 DCHECK(IsMipsArchVariant(kMips32r6));
2038 DCHECK(is_uint3(bp));
2039 uint16_t sa = (ALIGN << kBp2Bits) | bp;
2040 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
2041 }
2042
2043
1954 // --------Coprocessor-instructions---------------- 2044 // --------Coprocessor-instructions----------------
1955 2045
1956 // Load, store, move. 2046 // Load, store, move.
1957 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { 2047 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
1958 if (is_int16(src.offset_)) { 2048 if (is_int16(src.offset_)) {
1959 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 2049 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
1960 } else { // Offset > 16 bits, use multiple instructions to load. 2050 } else { // Offset > 16 bits, use multiple instructions to load.
1961 LoadRegPlusOffsetToAt(src); 2051 LoadRegPlusOffsetToAt(src);
1962 GenInstrImmediate(LWC1, at, fd, 0); 2052 GenInstrImmediate(LWC1, at, fd, 0);
1963 } 2053 }
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
3035 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 3125 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3036 // No out-of-line constant pool support. 3126 // No out-of-line constant pool support.
3037 DCHECK(!FLAG_enable_ool_constant_pool); 3127 DCHECK(!FLAG_enable_ool_constant_pool);
3038 return; 3128 return;
3039 } 3129 }
3040 3130
3041 3131
3042 } } // namespace v8::internal 3132 } } // namespace v8::internal
3043 3133
3044 #endif // V8_TARGET_ARCH_MIPS 3134 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698