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

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

Issue 1144373003: MIPS: Implemented PC-relative instructions for R6. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Corrections according review comments. 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 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 Register rs, 938 Register rs,
939 FPURegister ft, 939 FPURegister ft,
940 int32_t j) { 940 int32_t j) {
941 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); 941 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
942 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) 942 Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
943 | (j & kImm16Mask); 943 | (j & kImm16Mask);
944 emit(instr); 944 emit(instr);
945 } 945 }
946 946
947 947
948 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t j) {
949 DCHECK(rs.is_valid() && (is_uint21(j)));
950 Instr instr = opcode | (rs.code() << kRsShift) | (j & kImm21Mask);
951 emit(instr);
952 }
953
954
955 void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26) {
956 DCHECK(is_int26(offset26));
957 Instr instr = opcode | (offset26 & kImm26Mask);
958 emit(instr);
959 }
960
961
948 void Assembler::GenInstrJump(Opcode opcode, 962 void Assembler::GenInstrJump(Opcode opcode,
949 uint32_t address) { 963 uint32_t address) {
950 BlockTrampolinePoolScope block_trampoline_pool(this); 964 BlockTrampolinePoolScope block_trampoline_pool(this);
951 DCHECK(is_uint26(address)); 965 DCHECK(is_uint26(address));
952 Instr instr = opcode | address; 966 Instr instr = opcode | address;
953 emit(instr); 967 emit(instr);
954 BlockTrampolinePoolFor(1); // For associated delay slot. 968 BlockTrampolinePoolFor(1); // For associated delay slot.
955 } 969 }
956 970
957 971
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 } else { 1097 } else {
1084 L->link_to(pc_offset()); 1098 L->link_to(pc_offset());
1085 if (!trampoline_emitted_) { 1099 if (!trampoline_emitted_) {
1086 unbound_labels_count_++; 1100 unbound_labels_count_++;
1087 next_buffer_check_ -= kTrampolineSlotsSize; 1101 next_buffer_check_ -= kTrampolineSlotsSize;
1088 } 1102 }
1089 return kEndOfChain; 1103 return kEndOfChain;
1090 } 1104 }
1091 } 1105 }
1092 1106
1093 int32_t offset = target_pos - pc_offset(); 1107 int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1094 DCHECK((offset & 3) == 0); 1108 DCHECK((offset & 3) == 0);
1095 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width. 1109 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width.
1096 1110
1097 return offset; 1111 return offset;
1098 } 1112 }
1099 1113
1100 1114
1101 void Assembler::label_at_put(Label* L, int at_offset) { 1115 void Assembler::label_at_put(Label* L, int at_offset) {
1102 int target_pos; 1116 int target_pos;
1103 if (L->is_bound()) { 1117 if (L->is_bound()) {
(...skipping 26 matching lines...) Expand all
1130 beq(zero_reg, zero_reg, offset); 1144 beq(zero_reg, zero_reg, offset);
1131 } 1145 }
1132 1146
1133 1147
1134 void Assembler::bal(int16_t offset) { 1148 void Assembler::bal(int16_t offset) {
1135 positions_recorder()->WriteRecordedPositions(); 1149 positions_recorder()->WriteRecordedPositions();
1136 bgezal(zero_reg, offset); 1150 bgezal(zero_reg, offset);
1137 } 1151 }
1138 1152
1139 1153
1154 void Assembler::bc(int32_t offset) {
1155 DCHECK(kArchVariant == kMips64r6);
1156 GenInstrImmediate(BC, offset);
1157 }
1158
1159
1160 void Assembler::balc(int32_t offset) {
1161 DCHECK(kArchVariant == kMips64r6);
1162 positions_recorder()->WriteRecordedPositions();
1163 GenInstrImmediate(BALC, offset);
1164 }
1165
1166
1140 void Assembler::beq(Register rs, Register rt, int16_t offset) { 1167 void Assembler::beq(Register rs, Register rt, int16_t offset) {
1141 BlockTrampolinePoolScope block_trampoline_pool(this); 1168 BlockTrampolinePoolScope block_trampoline_pool(this);
1142 GenInstrImmediate(BEQ, rs, rt, offset); 1169 GenInstrImmediate(BEQ, rs, rt, offset);
1143 BlockTrampolinePoolFor(1); // For associated delay slot. 1170 BlockTrampolinePoolFor(1); // For associated delay slot.
1144 } 1171 }
1145 1172
1146 1173
1147 void Assembler::bgez(Register rs, int16_t offset) { 1174 void Assembler::bgez(Register rs, int16_t offset) {
1148 BlockTrampolinePoolScope block_trampoline_pool(this); 1175 BlockTrampolinePoolScope block_trampoline_pool(this);
1149 GenInstrImmediate(REGIMM, rs, BGEZ, offset); 1176 GenInstrImmediate(REGIMM, rs, BGEZ, offset);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 void Assembler::beqc(Register rs, Register rt, int16_t offset) { 1356 void Assembler::beqc(Register rs, Register rt, int16_t offset) {
1330 DCHECK(kArchVariant == kMips64r6); 1357 DCHECK(kArchVariant == kMips64r6);
1331 DCHECK(rs.code() < rt.code()); 1358 DCHECK(rs.code() < rt.code());
1332 GenInstrImmediate(ADDI, rs, rt, offset); 1359 GenInstrImmediate(ADDI, rs, rt, offset);
1333 } 1360 }
1334 1361
1335 1362
1336 void Assembler::beqzc(Register rs, int32_t offset) { 1363 void Assembler::beqzc(Register rs, int32_t offset) {
1337 DCHECK(kArchVariant == kMips64r6); 1364 DCHECK(kArchVariant == kMips64r6);
1338 DCHECK(!(rs.is(zero_reg))); 1365 DCHECK(!(rs.is(zero_reg)));
1339 Instr instr = BEQZC | (rs.code() << kRsShift) | offset; 1366 Instr instr = POP66 | (rs.code() << kRsShift) | (offset & kImm21Mask);
1340 emit(instr); 1367 emit(instr);
1341 } 1368 }
1342 1369
1343 1370
1344 void Assembler::bnec(Register rs, Register rt, int16_t offset) { 1371 void Assembler::bnec(Register rs, Register rt, int16_t offset) {
1345 DCHECK(kArchVariant == kMips64r6); 1372 DCHECK(kArchVariant == kMips64r6);
1346 DCHECK(rs.code() < rt.code()); 1373 DCHECK(rs.code() < rt.code());
1347 GenInstrImmediate(DADDI, rs, rt, offset); 1374 GenInstrImmediate(DADDI, rs, rt, offset);
1348 } 1375 }
1349 1376
1350 1377
1351 void Assembler::bnezc(Register rs, int32_t offset) { 1378 void Assembler::bnezc(Register rs, int32_t offset) {
1352 DCHECK(kArchVariant == kMips64r6); 1379 DCHECK(kArchVariant == kMips64r6);
1353 DCHECK(!(rs.is(zero_reg))); 1380 DCHECK(!(rs.is(zero_reg)));
1354 Instr instr = BNEZC | (rs.code() << kRsShift) | offset; 1381 Instr instr = POP76 | (rs.code() << kRsShift) | offset;
1355 emit(instr); 1382 emit(instr);
1356 } 1383 }
1357 1384
1358 1385
1359 void Assembler::j(int64_t target) { 1386 void Assembler::j(int64_t target) {
1360 #if DEBUG 1387 #if DEBUG
1361 // Get pc of delay slot. 1388 // Get pc of delay slot.
1362 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1389 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1363 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1390 bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1364 (kImm26Bits + kImmFieldShift)) == 0; 1391 (kImm26Bits + kImmFieldShift)) == 0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 1423
1397 1424
1398 void Assembler::jalr(Register rs, Register rd) { 1425 void Assembler::jalr(Register rs, Register rd) {
1399 BlockTrampolinePoolScope block_trampoline_pool(this); 1426 BlockTrampolinePoolScope block_trampoline_pool(this);
1400 positions_recorder()->WriteRecordedPositions(); 1427 positions_recorder()->WriteRecordedPositions();
1401 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); 1428 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
1402 BlockTrampolinePoolFor(1); // For associated delay slot. 1429 BlockTrampolinePoolFor(1); // For associated delay slot.
1403 } 1430 }
1404 1431
1405 1432
1406 void Assembler::j_or_jr(int64_t target, Register rs) { 1433 void Assembler::jic(Register rt, int16_t offset) {
1407 // Get pc of delay slot. 1434 DCHECK(kArchVariant == kMips64r6);
1408 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1435 Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) |
1409 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1436 (offset & kImm16Mask);
1410 (kImm26Bits + kImmFieldShift)) == 0; 1437 emit(instr);
1411 if (in_range) {
1412 j(target);
1413 } else {
1414 jr(t9);
1415 }
1416 } 1438 }
1417 1439
1418 1440
1419 void Assembler::jal_or_jalr(int64_t target, Register rs) { 1441 void Assembler::jialc(Register rt, int16_t offset) {
1420 // Get pc of delay slot. 1442 DCHECK(kArchVariant == kMips64r6);
1421 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1443 positions_recorder()->WriteRecordedPositions();
1422 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1444 GenInstrImmediate(POP76, zero_reg, rt, offset);
1423 (kImm26Bits+kImmFieldShift)) == 0;
1424 if (in_range) {
1425 jal(target);
1426 } else {
1427 jalr(t9);
1428 }
1429 } 1445 }
1430 1446
1431 1447
1432 // -------Data-processing-instructions--------- 1448 // -------Data-processing-instructions---------
1433 1449
1434 // Arithmetic. 1450 // Arithmetic.
1435 1451
1436 void Assembler::addu(Register rd, Register rs, Register rt) { 1452 void Assembler::addu(Register rd, Register rs, Register rt) {
1437 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 1453 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1438 } 1454 }
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 1905
1890 void Assembler::lui(Register rd, int32_t j) { 1906 void Assembler::lui(Register rd, int32_t j) {
1891 DCHECK(is_uint16(j)); 1907 DCHECK(is_uint16(j));
1892 GenInstrImmediate(LUI, zero_reg, rd, j); 1908 GenInstrImmediate(LUI, zero_reg, rd, j);
1893 } 1909 }
1894 1910
1895 1911
1896 void Assembler::aui(Register rs, Register rt, int32_t j) { 1912 void Assembler::aui(Register rs, Register rt, int32_t j) {
1897 // This instruction uses same opcode as 'lui'. The difference in encoding is 1913 // This instruction uses same opcode as 'lui'. The difference in encoding is
1898 // 'lui' has zero reg. for rs field. 1914 // 'lui' has zero reg. for rs field.
1915 DCHECK(!(rs.is(zero_reg)));
1899 DCHECK(is_uint16(j)); 1916 DCHECK(is_uint16(j));
1900 GenInstrImmediate(LUI, rs, rt, j); 1917 GenInstrImmediate(LUI, rs, rt, j);
1901 } 1918 }
1902 1919
1903 1920
1904 void Assembler::daui(Register rs, Register rt, int32_t j) { 1921 void Assembler::daui(Register rs, Register rt, int32_t j) {
1905 DCHECK(is_uint16(j)); 1922 DCHECK(is_uint16(j));
1906 GenInstrImmediate(DAUI, rs, rt, j); 1923 GenInstrImmediate(DAUI, rs, rt, j);
1907 } 1924 }
1908 1925
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 void Assembler::sd(Register rd, const MemOperand& rs) { 1969 void Assembler::sd(Register rd, const MemOperand& rs) {
1953 if (is_int16(rs.offset_)) { 1970 if (is_int16(rs.offset_)) {
1954 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_); 1971 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
1955 } else { // Offset > 16 bits, use multiple instructions to store. 1972 } else { // Offset > 16 bits, use multiple instructions to store.
1956 LoadRegPlusOffsetToAt(rs); 1973 LoadRegPlusOffsetToAt(rs);
1957 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); 1974 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0));
1958 } 1975 }
1959 } 1976 }
1960 1977
1961 1978
1979 // ---------PC-Relative instructions-----------
1980
1981 void Assembler::addiupc(Register rs, int32_t imm19) {
1982 DCHECK(kArchVariant == kMips64r6);
1983 DCHECK(rs.is_valid() && is_int19(imm19));
1984 int32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask);
1985 GenInstrImmediate(PCREL, rs, imm21);
1986 }
1987
1988
1989 void Assembler::lwpc(Register rs, int32_t offset19) {
1990 DCHECK(kArchVariant == kMips64r6);
1991 DCHECK(rs.is_valid() && is_int19(offset19));
1992 int32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask);
1993 GenInstrImmediate(PCREL, rs, imm21);
1994 }
1995
1996
1997 void Assembler::lwupc(Register rs, int32_t offset19) {
1998 DCHECK(kArchVariant == kMips64r6);
1999 DCHECK(rs.is_valid() && is_int19(offset19));
2000 int32_t imm21 = LWUPC << kImm19Bits | (offset19 & kImm19Mask);
2001 GenInstrImmediate(PCREL, rs, imm21);
2002 }
2003
2004
2005 void Assembler::ldpc(Register rs, int32_t offset18) {
2006 DCHECK(kArchVariant == kMips64r6);
2007 DCHECK(rs.is_valid() && is_int18(offset18));
2008 int32_t imm21 = LDPC << kImm18Bits | (offset18 & kImm18Mask);
2009 GenInstrImmediate(PCREL, rs, imm21);
2010 }
2011
2012
2013 void Assembler::auipc(Register rs, int16_t imm16) {
2014 DCHECK(kArchVariant == kMips64r6);
2015 DCHECK(rs.is_valid() && is_int16(imm16));
2016 int32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask);
2017 GenInstrImmediate(PCREL, rs, imm21);
2018 }
2019
2020
2021 void Assembler::aluipc(Register rs, int16_t imm16) {
2022 DCHECK(kArchVariant == kMips64r6);
2023 DCHECK(rs.is_valid() && is_int16(imm16));
2024 int32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask);
2025 GenInstrImmediate(PCREL, rs, imm21);
2026 }
2027
2028
1962 // -------------Misc-instructions-------------- 2029 // -------------Misc-instructions--------------
1963 2030
1964 // Break / Trap instructions. 2031 // Break / Trap instructions.
1965 void Assembler::break_(uint32_t code, bool break_as_stop) { 2032 void Assembler::break_(uint32_t code, bool break_as_stop) {
1966 DCHECK((code & ~0xfffff) == 0); 2033 DCHECK((code & ~0xfffff) == 0);
1967 // We need to invalidate breaks that could be stops as well because the 2034 // We need to invalidate breaks that could be stops as well because the
1968 // simulator expects a char pointer after the stop instruction. 2035 // simulator expects a char pointer after the stop instruction.
1969 // See constants-mips.h for explanation. 2036 // See constants-mips.h for explanation.
1970 DCHECK((break_as_stop && 2037 DCHECK((break_as_stop &&
1971 code <= kMaxStopCode && 2038 code <= kMaxStopCode &&
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) { 2267 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2201 // Should be called via MacroAssembler::Ext. 2268 // Should be called via MacroAssembler::Ext.
2202 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb. 2269 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
2203 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6); 2270 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2204 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT); 2271 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
2205 } 2272 }
2206 2273
2207 2274
2208 void Assembler::bitswap(Register rd, Register rt) { 2275 void Assembler::bitswap(Register rd, Register rt) {
2209 DCHECK(kArchVariant == kMips64r6); 2276 DCHECK(kArchVariant == kMips64r6);
2210 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BITSWAP); 2277 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
2211 } 2278 }
2212 2279
2213 2280
2214 void Assembler::dbitswap(Register rd, Register rt) { 2281 void Assembler::dbitswap(Register rd, Register rt) {
2215 DCHECK(kArchVariant == kMips64r6); 2282 DCHECK(kArchVariant == kMips64r6);
2216 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBITSWAP); 2283 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
2217 } 2284 }
2218 2285
2219 2286
2220 void Assembler::pref(int32_t hint, const MemOperand& rs) { 2287 void Assembler::pref(int32_t hint, const MemOperand& rs) {
2221 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); 2288 DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
2222 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) 2289 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
2223 | (rs.offset_); 2290 | (rs.offset_);
2224 emit(instr); 2291 emit(instr);
2225 } 2292 }
2226 2293
2227 2294
2295 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
2296 DCHECK(kArchVariant == kMips64r6);
2297 DCHECK(is_uint3(bp));
2298 uint16_t sa = (ALIGN << kBp2Bits) | bp;
2299 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
2300 }
2301
2302
2303 void Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
2304 DCHECK(kArchVariant == kMips64r6);
2305 DCHECK(is_uint3(bp));
2306 uint16_t sa = (DALIGN << kBp3Bits) | bp;
2307 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
2308 }
2309
2310
2228 // --------Coprocessor-instructions---------------- 2311 // --------Coprocessor-instructions----------------
2229 2312
2230 // Load, store, move. 2313 // Load, store, move.
2231 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { 2314 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
2232 if (is_int16(src.offset_)) { 2315 if (is_int16(src.offset_)) {
2233 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 2316 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
2234 } else { // Offset > 16 bits, use multiple instructions to load. 2317 } else { // Offset > 16 bits, use multiple instructions to load.
2235 LoadRegPlusOffsetToAt(src); 2318 LoadRegPlusOffsetToAt(src);
2236 GenInstrImmediate(LWC1, at, fd, 0); 2319 GenInstrImmediate(LWC1, at, fd, 0);
2237 } 2320 }
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
3127 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 3210 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3128 // No out-of-line constant pool support. 3211 // No out-of-line constant pool support.
3129 DCHECK(!FLAG_enable_ool_constant_pool); 3212 DCHECK(!FLAG_enable_ool_constant_pool);
3130 return; 3213 return;
3131 } 3214 }
3132 3215
3133 3216
3134 } } // namespace v8::internal 3217 } } // namespace v8::internal
3135 3218
3136 #endif // V8_TARGET_ARCH_MIPS64 3219 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698