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

Side by Side Diff: src/mips64/assembler-mips64.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/mips64/assembler-mips64.h ('k') | src/mips64/constants-mips64.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 949 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 Register rs, 960 Register rs,
961 FPURegister ft, 961 FPURegister ft,
962 int32_t j) { 962 int32_t j) {
963 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); 963 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
964 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) 964 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
965 | (j & kImm16Mask); 965 | (j & kImm16Mask);
966 emit(instr); 966 emit(instr);
967 } 967 }
968 968
969 969
970 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t j) {
971 DCHECK(rs.is_valid() && (is_uint21(j)));
972 Instr instr = opcode | (rs.code() << kRsShift) | (j & kImm21Mask);
973 emit(instr);
974 }
975
976
977 void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26) {
978 DCHECK(is_int26(offset26));
979 Instr instr = opcode | (offset26 & kImm26Mask);
980 emit(instr);
981 }
982
983
970 void Assembler::GenInstrJump(Opcode opcode, 984 void Assembler::GenInstrJump(Opcode opcode,
971 uint32_t address) { 985 uint32_t address) {
972 BlockTrampolinePoolScope block_trampoline_pool(this); 986 BlockTrampolinePoolScope block_trampoline_pool(this);
973 DCHECK(is_uint26(address)); 987 DCHECK(is_uint26(address));
974 Instr instr = opcode | address; 988 Instr instr = opcode | address;
975 emit(instr); 989 emit(instr);
976 BlockTrampolinePoolFor(1); // For associated delay slot. 990 BlockTrampolinePoolFor(1); // For associated delay slot.
977 } 991 }
978 992
979 993
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 } else { 1118 } else {
1105 L->link_to(pc_offset()); 1119 L->link_to(pc_offset());
1106 if (!trampoline_emitted_) { 1120 if (!trampoline_emitted_) {
1107 unbound_labels_count_++; 1121 unbound_labels_count_++;
1108 next_buffer_check_ -= kTrampolineSlotsSize; 1122 next_buffer_check_ -= kTrampolineSlotsSize;
1109 } 1123 }
1110 return kEndOfChain; 1124 return kEndOfChain;
1111 } 1125 }
1112 } 1126 }
1113 1127
1114 int32_t offset = target_pos - pc_offset(); 1128 int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1115 DCHECK((offset & 3) == 0); 1129 DCHECK((offset & 3) == 0);
1116 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width. 1130 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width.
1117 1131
1118 return offset; 1132 return offset;
1119 } 1133 }
1120 1134
1121 1135
1122 void Assembler::label_at_put(Label* L, int at_offset) { 1136 void Assembler::label_at_put(Label* L, int at_offset) {
1123 int target_pos; 1137 int target_pos;
1124 if (L->is_bound()) { 1138 if (L->is_bound()) {
(...skipping 26 matching lines...) Expand all
1151 beq(zero_reg, zero_reg, offset); 1165 beq(zero_reg, zero_reg, offset);
1152 } 1166 }
1153 1167
1154 1168
1155 void Assembler::bal(int16_t offset) { 1169 void Assembler::bal(int16_t offset) {
1156 positions_recorder()->WriteRecordedPositions(); 1170 positions_recorder()->WriteRecordedPositions();
1157 bgezal(zero_reg, offset); 1171 bgezal(zero_reg, offset);
1158 } 1172 }
1159 1173
1160 1174
1175 void Assembler::bc(int32_t offset) {
1176 DCHECK(kArchVariant == kMips64r6);
1177 GenInstrImmediate(BC, offset);
1178 }
1179
1180
1181 void Assembler::balc(int32_t offset) {
1182 DCHECK(kArchVariant == kMips64r6);
1183 positions_recorder()->WriteRecordedPositions();
1184 GenInstrImmediate(BALC, offset);
1185 }
1186
1187
1161 void Assembler::beq(Register rs, Register rt, int16_t offset) { 1188 void Assembler::beq(Register rs, Register rt, int16_t offset) {
1162 BlockTrampolinePoolScope block_trampoline_pool(this); 1189 BlockTrampolinePoolScope block_trampoline_pool(this);
1163 GenInstrImmediate(BEQ, rs, rt, offset); 1190 GenInstrImmediate(BEQ, rs, rt, offset);
1164 BlockTrampolinePoolFor(1); // For associated delay slot. 1191 BlockTrampolinePoolFor(1); // For associated delay slot.
1165 } 1192 }
1166 1193
1167 1194
1168 void Assembler::bgez(Register rs, int16_t offset) { 1195 void Assembler::bgez(Register rs, int16_t offset) {
1169 BlockTrampolinePoolScope block_trampoline_pool(this); 1196 BlockTrampolinePoolScope block_trampoline_pool(this);
1170 GenInstrImmediate(REGIMM, rs, BGEZ, offset); 1197 GenInstrImmediate(REGIMM, rs, BGEZ, offset);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 void Assembler::beqc(Register rs, Register rt, int16_t offset) { 1377 void Assembler::beqc(Register rs, Register rt, int16_t offset) {
1351 DCHECK(kArchVariant == kMips64r6); 1378 DCHECK(kArchVariant == kMips64r6);
1352 DCHECK(rs.code() < rt.code()); 1379 DCHECK(rs.code() < rt.code());
1353 GenInstrImmediate(ADDI, rs, rt, offset); 1380 GenInstrImmediate(ADDI, rs, rt, offset);
1354 } 1381 }
1355 1382
1356 1383
1357 void Assembler::beqzc(Register rs, int32_t offset) { 1384 void Assembler::beqzc(Register rs, int32_t offset) {
1358 DCHECK(kArchVariant == kMips64r6); 1385 DCHECK(kArchVariant == kMips64r6);
1359 DCHECK(!(rs.is(zero_reg))); 1386 DCHECK(!(rs.is(zero_reg)));
1360 Instr instr = BEQZC | (rs.code() << kRsShift) | offset; 1387 Instr instr = POP66 | (rs.code() << kRsShift) | (offset & kImm21Mask);
1361 emit(instr); 1388 emit(instr);
1362 } 1389 }
1363 1390
1364 1391
1365 void Assembler::bnec(Register rs, Register rt, int16_t offset) { 1392 void Assembler::bnec(Register rs, Register rt, int16_t offset) {
1366 DCHECK(kArchVariant == kMips64r6); 1393 DCHECK(kArchVariant == kMips64r6);
1367 DCHECK(rs.code() < rt.code()); 1394 DCHECK(rs.code() < rt.code());
1368 GenInstrImmediate(DADDI, rs, rt, offset); 1395 GenInstrImmediate(DADDI, rs, rt, offset);
1369 } 1396 }
1370 1397
1371 1398
1372 void Assembler::bnezc(Register rs, int32_t offset) { 1399 void Assembler::bnezc(Register rs, int32_t offset) {
1373 DCHECK(kArchVariant == kMips64r6); 1400 DCHECK(kArchVariant == kMips64r6);
1374 DCHECK(!(rs.is(zero_reg))); 1401 DCHECK(!(rs.is(zero_reg)));
1375 Instr instr = BNEZC | (rs.code() << kRsShift) | offset; 1402 Instr instr = POP76 | (rs.code() << kRsShift) | offset;
1376 emit(instr); 1403 emit(instr);
1377 } 1404 }
1378 1405
1379 1406
1380 void Assembler::j(int64_t target) { 1407 void Assembler::j(int64_t target) {
1381 #if DEBUG 1408 #if DEBUG
1382 // Get pc of delay slot. 1409 // Get pc of delay slot.
1383 if (target != kEndOfJumpChain) { 1410 if (target != kEndOfJumpChain) {
1384 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1411 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1385 bool in_range = ((ipc ^ static_cast<uint64_t>(target)) >> 1412 bool in_range = ((ipc ^ static_cast<uint64_t>(target)) >>
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 1448
1422 1449
1423 void Assembler::jalr(Register rs, Register rd) { 1450 void Assembler::jalr(Register rs, Register rd) {
1424 BlockTrampolinePoolScope block_trampoline_pool(this); 1451 BlockTrampolinePoolScope block_trampoline_pool(this);
1425 positions_recorder()->WriteRecordedPositions(); 1452 positions_recorder()->WriteRecordedPositions();
1426 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); 1453 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
1427 BlockTrampolinePoolFor(1); // For associated delay slot. 1454 BlockTrampolinePoolFor(1); // For associated delay slot.
1428 } 1455 }
1429 1456
1430 1457
1431 void Assembler::j_or_jr(int64_t target, Register rs) { 1458 void Assembler::jic(Register rt, int16_t offset) {
1432 // Get pc of delay slot. 1459 DCHECK(kArchVariant == kMips64r6);
1433 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1460 Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) |
1434 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1461 (offset & kImm16Mask);
1435 (kImm26Bits + kImmFieldShift)) == 0; 1462 emit(instr);
1436 if (in_range) {
1437 j(target);
1438 } else {
1439 jr(t9);
1440 }
1441 } 1463 }
1442 1464
1443 1465
1444 void Assembler::jal_or_jalr(int64_t target, Register rs) { 1466 void Assembler::jialc(Register rt, int16_t offset) {
1445 // Get pc of delay slot. 1467 DCHECK(kArchVariant == kMips64r6);
1446 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1468 positions_recorder()->WriteRecordedPositions();
1447 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1469 GenInstrImmediate(POP76, zero_reg, rt, offset);
1448 (kImm26Bits+kImmFieldShift)) == 0;
1449 if (in_range) {
1450 jal(target);
1451 } else {
1452 jalr(t9);
1453 }
1454 } 1470 }
1455 1471
1456 1472
1457 // -------Data-processing-instructions--------- 1473 // -------Data-processing-instructions---------
1458 1474
1459 // Arithmetic. 1475 // Arithmetic.
1460 1476
1461 void Assembler::addu(Register rd, Register rs, Register rt) { 1477 void Assembler::addu(Register rd, Register rs, Register rt) {
1462 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 1478 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1463 } 1479 }
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 1930
1915 void Assembler::lui(Register rd, int32_t j) { 1931 void Assembler::lui(Register rd, int32_t j) {
1916 DCHECK(is_uint16(j)); 1932 DCHECK(is_uint16(j));
1917 GenInstrImmediate(LUI, zero_reg, rd, j); 1933 GenInstrImmediate(LUI, zero_reg, rd, j);
1918 } 1934 }
1919 1935
1920 1936
1921 void Assembler::aui(Register rs, Register rt, int32_t j) { 1937 void Assembler::aui(Register rs, Register rt, int32_t j) {
1922 // This instruction uses same opcode as 'lui'. The difference in encoding is 1938 // This instruction uses same opcode as 'lui'. The difference in encoding is
1923 // 'lui' has zero reg. for rs field. 1939 // 'lui' has zero reg. for rs field.
1940 DCHECK(!(rs.is(zero_reg)));
1924 DCHECK(is_uint16(j)); 1941 DCHECK(is_uint16(j));
1925 GenInstrImmediate(LUI, rs, rt, j); 1942 GenInstrImmediate(LUI, rs, rt, j);
1926 } 1943 }
1927 1944
1928 1945
1929 void Assembler::daui(Register rs, Register rt, int32_t j) { 1946 void Assembler::daui(Register rs, Register rt, int32_t j) {
1930 DCHECK(is_uint16(j)); 1947 DCHECK(is_uint16(j));
1931 GenInstrImmediate(DAUI, rs, rt, j); 1948 GenInstrImmediate(DAUI, rs, rt, j);
1932 } 1949 }
1933 1950
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1977 void Assembler::sd(Register rd, const MemOperand& rs) { 1994 void Assembler::sd(Register rd, const MemOperand& rs) {
1978 if (is_int16(rs.offset_)) { 1995 if (is_int16(rs.offset_)) {
1979 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_); 1996 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
1980 } else { // Offset > 16 bits, use multiple instructions to store. 1997 } else { // Offset > 16 bits, use multiple instructions to store.
1981 LoadRegPlusOffsetToAt(rs); 1998 LoadRegPlusOffsetToAt(rs);
1982 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); 1999 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0));
1983 } 2000 }
1984 } 2001 }
1985 2002
1986 2003
2004 // ---------PC-Relative instructions-----------
2005
2006 void Assembler::addiupc(Register rs, int32_t imm19) {
2007 DCHECK(kArchVariant == kMips64r6);
2008 DCHECK(rs.is_valid() && is_int19(imm19));
2009 int32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask);
2010 GenInstrImmediate(PCREL, rs, imm21);
2011 }
2012
2013
2014 void Assembler::lwpc(Register rs, int32_t offset19) {
2015 DCHECK(kArchVariant == kMips64r6);
2016 DCHECK(rs.is_valid() && is_int19(offset19));
2017 int32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask);
2018 GenInstrImmediate(PCREL, rs, imm21);
2019 }
2020
2021
2022 void Assembler::lwupc(Register rs, int32_t offset19) {
2023 DCHECK(kArchVariant == kMips64r6);
2024 DCHECK(rs.is_valid() && is_int19(offset19));
2025 int32_t imm21 = LWUPC << kImm19Bits | (offset19 & kImm19Mask);
2026 GenInstrImmediate(PCREL, rs, imm21);
2027 }
2028
2029
2030 void Assembler::ldpc(Register rs, int32_t offset18) {
2031 DCHECK(kArchVariant == kMips64r6);
2032 DCHECK(rs.is_valid() && is_int18(offset18));
2033 int32_t imm21 = LDPC << kImm18Bits | (offset18 & kImm18Mask);
2034 GenInstrImmediate(PCREL, rs, imm21);
2035 }
2036
2037
2038 void Assembler::auipc(Register rs, int16_t imm16) {
2039 DCHECK(kArchVariant == kMips64r6);
2040 DCHECK(rs.is_valid() && is_int16(imm16));
2041 int32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask);
2042 GenInstrImmediate(PCREL, rs, imm21);
2043 }
2044
2045
2046 void Assembler::aluipc(Register rs, int16_t imm16) {
2047 DCHECK(kArchVariant == kMips64r6);
2048 DCHECK(rs.is_valid() && is_int16(imm16));
2049 int32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask);
2050 GenInstrImmediate(PCREL, rs, imm21);
2051 }
2052
2053
1987 // -------------Misc-instructions-------------- 2054 // -------------Misc-instructions--------------
1988 2055
1989 // Break / Trap instructions. 2056 // Break / Trap instructions.
1990 void Assembler::break_(uint32_t code, bool break_as_stop) { 2057 void Assembler::break_(uint32_t code, bool break_as_stop) {
1991 DCHECK((code & ~0xfffff) == 0); 2058 DCHECK((code & ~0xfffff) == 0);
1992 // We need to invalidate breaks that could be stops as well because the 2059 // We need to invalidate breaks that could be stops as well because the
1993 // simulator expects a char pointer after the stop instruction. 2060 // simulator expects a char pointer after the stop instruction.
1994 // See constants-mips.h for explanation. 2061 // See constants-mips.h for explanation.
1995 DCHECK((break_as_stop && 2062 DCHECK((break_as_stop &&
1996 code <= kMaxStopCode && 2063 code <= kMaxStopCode &&
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) { 2292 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2226 // Should be called via MacroAssembler::Ext. 2293 // Should be called via MacroAssembler::Ext.
2227 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb. 2294 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
2228 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6); 2295 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2229 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT); 2296 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
2230 } 2297 }
2231 2298
2232 2299
2233 void Assembler::bitswap(Register rd, Register rt) { 2300 void Assembler::bitswap(Register rd, Register rt) {
2234 DCHECK(kArchVariant == kMips64r6); 2301 DCHECK(kArchVariant == kMips64r6);
2235 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BITSWAP); 2302 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
2236 } 2303 }
2237 2304
2238 2305
2239 void Assembler::dbitswap(Register rd, Register rt) { 2306 void Assembler::dbitswap(Register rd, Register rt) {
2240 DCHECK(kArchVariant == kMips64r6); 2307 DCHECK(kArchVariant == kMips64r6);
2241 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBITSWAP); 2308 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
2242 } 2309 }
2243 2310
2244 2311
2245 void Assembler::pref(int32_t hint, const MemOperand& rs) { 2312 void Assembler::pref(int32_t hint, const MemOperand& rs) {
2246 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); 2313 DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
2247 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) 2314 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
2248 | (rs.offset_); 2315 | (rs.offset_);
2249 emit(instr); 2316 emit(instr);
2250 } 2317 }
2251 2318
2252 2319
2320 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
2321 DCHECK(kArchVariant == kMips64r6);
2322 DCHECK(is_uint3(bp));
2323 uint16_t sa = (ALIGN << kBp2Bits) | bp;
2324 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
2325 }
2326
2327
2328 void Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
2329 DCHECK(kArchVariant == kMips64r6);
2330 DCHECK(is_uint3(bp));
2331 uint16_t sa = (DALIGN << kBp3Bits) | bp;
2332 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
2333 }
2334
2335
2253 // --------Coprocessor-instructions---------------- 2336 // --------Coprocessor-instructions----------------
2254 2337
2255 // Load, store, move. 2338 // Load, store, move.
2256 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { 2339 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
2257 if (is_int16(src.offset_)) { 2340 if (is_int16(src.offset_)) {
2258 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 2341 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
2259 } else { // Offset > 16 bits, use multiple instructions to load. 2342 } else { // Offset > 16 bits, use multiple instructions to load.
2260 LoadRegPlusOffsetToAt(src); 2343 LoadRegPlusOffsetToAt(src);
2261 GenInstrImmediate(LWC1, at, fd, 0); 2344 GenInstrImmediate(LWC1, at, fd, 0);
2262 } 2345 }
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after
3155 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 3238 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
3156 CpuFeatures::FlushICache(pc, 4 * Assembler::kInstrSize); 3239 CpuFeatures::FlushICache(pc, 4 * Assembler::kInstrSize);
3157 } 3240 }
3158 } 3241 }
3159 3242
3160 3243
3161 } // namespace internal 3244 } // namespace internal
3162 } // namespace v8 3245 } // namespace v8
3163 3246
3164 #endif // V8_TARGET_ARCH_MIPS64 3247 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/assembler-mips64.h ('k') | src/mips64/constants-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698