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

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: 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 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 =
951 opcode | (rs.code() << kRsShift) | static_cast<uint32_t>(j & kImm21Mask);
952 emit(instr);
953 }
954
955
956 void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26) {
957 DCHECK((kMinInt26 <= offset26) && (offset26 <= kMaxInt26));
958 Instr instr = opcode | static_cast<uint32_t>(offset26 & kImm26Mask);
959 emit(instr);
960 }
961
962
948 void Assembler::GenInstrJump(Opcode opcode, 963 void Assembler::GenInstrJump(Opcode opcode,
949 uint32_t address) { 964 uint32_t address) {
950 BlockTrampolinePoolScope block_trampoline_pool(this); 965 BlockTrampolinePoolScope block_trampoline_pool(this);
951 DCHECK(is_uint26(address)); 966 DCHECK(is_uint26(address));
952 Instr instr = opcode | address; 967 Instr instr = opcode | address;
953 emit(instr); 968 emit(instr);
954 BlockTrampolinePoolFor(1); // For associated delay slot. 969 BlockTrampolinePoolFor(1); // For associated delay slot.
955 } 970 }
956 971
957 972
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 } else { 1098 } else {
1084 L->link_to(pc_offset()); 1099 L->link_to(pc_offset());
1085 if (!trampoline_emitted_) { 1100 if (!trampoline_emitted_) {
1086 unbound_labels_count_++; 1101 unbound_labels_count_++;
1087 next_buffer_check_ -= kTrampolineSlotsSize; 1102 next_buffer_check_ -= kTrampolineSlotsSize;
1088 } 1103 }
1089 return kEndOfChain; 1104 return kEndOfChain;
1090 } 1105 }
1091 } 1106 }
1092 1107
1093 int32_t offset = target_pos - pc_offset(); 1108 int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1094 DCHECK((offset & 3) == 0); 1109 DCHECK((offset & 3) == 0);
1095 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width. 1110 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width.
1096 1111
1097 return offset; 1112 return offset;
1098 } 1113 }
1099 1114
1100 1115
1101 void Assembler::label_at_put(Label* L, int at_offset) { 1116 void Assembler::label_at_put(Label* L, int at_offset) {
1102 int target_pos; 1117 int target_pos;
1103 if (L->is_bound()) { 1118 if (L->is_bound()) {
(...skipping 26 matching lines...) Expand all
1130 beq(zero_reg, zero_reg, offset); 1145 beq(zero_reg, zero_reg, offset);
1131 } 1146 }
1132 1147
1133 1148
1134 void Assembler::bal(int16_t offset) { 1149 void Assembler::bal(int16_t offset) {
1135 positions_recorder()->WriteRecordedPositions(); 1150 positions_recorder()->WriteRecordedPositions();
1136 bgezal(zero_reg, offset); 1151 bgezal(zero_reg, offset);
1137 } 1152 }
1138 1153
1139 1154
1155 void Assembler::bc(int32_t offset) {
1156 DCHECK(kArchVariant == kMips64r6);
1157 GenInstrImmediate(BC, offset);
1158 }
1159
1160
1161 void Assembler::balc(int32_t offset) {
1162 DCHECK(kArchVariant == kMips64r6);
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) |
1367 (static_cast<uint32_t>(offset) & kImm21Mask);
1340 emit(instr); 1368 emit(instr);
1341 } 1369 }
1342 1370
1343 1371
1344 void Assembler::bnec(Register rs, Register rt, int16_t offset) { 1372 void Assembler::bnec(Register rs, Register rt, int16_t offset) {
1345 DCHECK(kArchVariant == kMips64r6); 1373 DCHECK(kArchVariant == kMips64r6);
1346 DCHECK(rs.code() < rt.code()); 1374 DCHECK(rs.code() < rt.code());
1347 GenInstrImmediate(DADDI, rs, rt, offset); 1375 GenInstrImmediate(DADDI, rs, rt, offset);
1348 } 1376 }
1349 1377
1350 1378
1351 void Assembler::bnezc(Register rs, int32_t offset) { 1379 void Assembler::bnezc(Register rs, int32_t offset) {
1352 DCHECK(kArchVariant == kMips64r6); 1380 DCHECK(kArchVariant == kMips64r6);
1353 DCHECK(!(rs.is(zero_reg))); 1381 DCHECK(!(rs.is(zero_reg)));
1354 Instr instr = BNEZC | (rs.code() << kRsShift) | offset; 1382 Instr instr = POP76 | (rs.code() << kRsShift) | offset;
1355 emit(instr); 1383 emit(instr);
1356 } 1384 }
1357 1385
1358 1386
1359 void Assembler::j(int64_t target) { 1387 void Assembler::j(int64_t target) {
1360 #if DEBUG 1388 #if DEBUG
1361 // Get pc of delay slot. 1389 // Get pc of delay slot.
1362 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1390 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1363 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1391 bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1364 (kImm26Bits + kImmFieldShift)) == 0; 1392 (kImm26Bits + kImmFieldShift)) == 0;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1450 bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1423 (kImm26Bits+kImmFieldShift)) == 0; 1451 (kImm26Bits+kImmFieldShift)) == 0;
1424 if (in_range) { 1452 if (in_range) {
1425 jal(target); 1453 jal(target);
1426 } else { 1454 } else {
1427 jalr(t9); 1455 jalr(t9);
1428 } 1456 }
1429 } 1457 }
1430 1458
1431 1459
1460 void Assembler::jic(Register rt, int16_t offset) {
1461 DCHECK(kArchVariant == kMips64r6);
1462 Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) |
1463 static_cast<uint16_t>(offset);
1464 emit(instr);
1465 }
1466
1467
1468 void Assembler::jialc(Register rt, int16_t offset) {
1469 DCHECK(kArchVariant == kMips64r6);
1470 positions_recorder()->WriteRecordedPositions();
1471 GenInstrImmediate(POP76, zero_reg, rt, offset);
1472 }
1473
1474
1432 // -------Data-processing-instructions--------- 1475 // -------Data-processing-instructions---------
1433 1476
1434 // Arithmetic. 1477 // Arithmetic.
1435 1478
1436 void Assembler::addu(Register rd, Register rs, Register rt) { 1479 void Assembler::addu(Register rd, Register rs, Register rt) {
1437 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 1480 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1438 } 1481 }
1439 1482
1440 1483
1441 void Assembler::addiu(Register rd, Register rs, int32_t j) { 1484 void Assembler::addiu(Register rd, Register rs, int32_t j) {
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 void Assembler::sd(Register rd, const MemOperand& rs) { 1995 void Assembler::sd(Register rd, const MemOperand& rs) {
1953 if (is_int16(rs.offset_)) { 1996 if (is_int16(rs.offset_)) {
1954 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_); 1997 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
1955 } else { // Offset > 16 bits, use multiple instructions to store. 1998 } else { // Offset > 16 bits, use multiple instructions to store.
1956 LoadRegPlusOffsetToAt(rs); 1999 LoadRegPlusOffsetToAt(rs);
1957 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); 2000 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0));
1958 } 2001 }
1959 } 2002 }
1960 2003
1961 2004
2005 // ---------PC-Relative instructions-----------
2006
2007 void Assembler::addiupc(Register rs, int32_t imm19) {
2008 DCHECK(kArchVariant == kMips64r6);
2009 DCHECK(rs.is_valid());
2010 DCHECK((kMinInt19 <= imm19) && (imm19 <= kMaxInt19));
2011 int32_t imm21 =
2012 ADDIUPC << kImm19Bits | static_cast<uint32_t>(imm19 & kImm19Mask);
2013 GenInstrImmediate(PCREL, rs, imm21);
2014 }
2015
2016
2017 void Assembler::lwpc(Register rs, int32_t offset19) {
2018 DCHECK(kArchVariant == kMips64r6);
2019 DCHECK(rs.is_valid());
2020 DCHECK((kMinInt19 <= offset19) && (offset19 <= kMaxInt19));
2021 int32_t imm21 =
2022 LWPC << kImm19Bits | static_cast<uint32_t>(offset19 & kImm19Mask);
2023 GenInstrImmediate(PCREL, rs, imm21);
2024 }
2025
2026
2027 void Assembler::lwupc(Register rs, int32_t offset19) {
2028 DCHECK(kArchVariant == kMips64r6);
2029 DCHECK(rs.is_valid());
2030 DCHECK((kMinInt19 <= offset19) && (offset19 <= kMaxInt19));
2031 int32_t imm21 =
2032 LWUPC << kImm19Bits | static_cast<uint32_t>(offset19 & kImm19Mask);
2033 GenInstrImmediate(PCREL, rs, imm21);
2034 }
2035
2036
2037 void Assembler::ldpc(Register rs, int32_t offset18) {
2038 DCHECK(kArchVariant == kMips64r6);
2039 DCHECK(rs.is_valid());
2040 DCHECK((kMinInt18 <= offset18) && (offset18 <= kMaxInt18));
2041 int32_t imm21 =
2042 LDPC << kImm18Bits | static_cast<uint32_t>(offset18 & kImm18Mask);
2043 GenInstrImmediate(PCREL, rs, imm21);
2044 }
2045
2046
2047 void Assembler::auipc(Register rs, int16_t imm16) {
2048 DCHECK(kArchVariant == kMips64r6);
2049 DCHECK(rs.is_valid() && is_int16(imm16));
2050 int32_t imm21 =
2051 AUIPC << kImm16Bits | static_cast<uint32_t>(imm16 & kImm16Mask);
2052 GenInstrImmediate(PCREL, rs, imm21);
2053 }
2054
2055
2056 void Assembler::aluipc(Register rs, int16_t imm16) {
2057 DCHECK(kArchVariant == kMips64r6);
2058 DCHECK(rs.is_valid() && is_int16(imm16));
2059 int32_t imm21 =
2060 ALUIPC << kImm16Bits | static_cast<uint32_t>(imm16 & kImm16Mask);
2061 GenInstrImmediate(PCREL, rs, imm21);
2062 }
2063
2064
1962 // -------------Misc-instructions-------------- 2065 // -------------Misc-instructions--------------
1963 2066
1964 // Break / Trap instructions. 2067 // Break / Trap instructions.
1965 void Assembler::break_(uint32_t code, bool break_as_stop) { 2068 void Assembler::break_(uint32_t code, bool break_as_stop) {
1966 DCHECK((code & ~0xfffff) == 0); 2069 DCHECK((code & ~0xfffff) == 0);
1967 // We need to invalidate breaks that could be stops as well because the 2070 // We need to invalidate breaks that could be stops as well because the
1968 // simulator expects a char pointer after the stop instruction. 2071 // simulator expects a char pointer after the stop instruction.
1969 // See constants-mips.h for explanation. 2072 // See constants-mips.h for explanation.
1970 DCHECK((break_as_stop && 2073 DCHECK((break_as_stop &&
1971 code <= kMaxStopCode && 2074 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) { 2303 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2201 // Should be called via MacroAssembler::Ext. 2304 // Should be called via MacroAssembler::Ext.
2202 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb. 2305 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
2203 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6); 2306 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2204 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT); 2307 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
2205 } 2308 }
2206 2309
2207 2310
2208 void Assembler::bitswap(Register rd, Register rt) { 2311 void Assembler::bitswap(Register rd, Register rt) {
2209 DCHECK(kArchVariant == kMips64r6); 2312 DCHECK(kArchVariant == kMips64r6);
2210 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BITSWAP); 2313 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
2211 } 2314 }
2212 2315
2213 2316
2214 void Assembler::dbitswap(Register rd, Register rt) { 2317 void Assembler::dbitswap(Register rd, Register rt) {
2215 DCHECK(kArchVariant == kMips64r6); 2318 DCHECK(kArchVariant == kMips64r6);
2216 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBITSWAP); 2319 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
2217 } 2320 }
2218 2321
2219 2322
2220 void Assembler::pref(int32_t hint, const MemOperand& rs) { 2323 void Assembler::pref(int32_t hint, const MemOperand& rs) {
2221 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); 2324 DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
2222 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) 2325 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
2223 | (rs.offset_); 2326 | (rs.offset_);
2224 emit(instr); 2327 emit(instr);
2225 } 2328 }
2226 2329
2227 2330
2331 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
2332 DCHECK(kArchVariant == kMips64r6);
2333 DCHECK(is_uint3(bp));
2334 uint16_t sa = (ALIGN << kBp2Bits) | bp;
2335 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
2336 }
2337
2338
2339 void Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
2340 DCHECK(kArchVariant == kMips64r6);
2341 DCHECK(is_uint3(bp));
2342 uint16_t sa = (DALIGN << kBp3Bits) | bp;
2343 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
2344 }
2345
2346
2228 // --------Coprocessor-instructions---------------- 2347 // --------Coprocessor-instructions----------------
2229 2348
2230 // Load, store, move. 2349 // Load, store, move.
2231 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { 2350 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
2232 if (is_int16(src.offset_)) { 2351 if (is_int16(src.offset_)) {
2233 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 2352 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
2234 } else { // Offset > 16 bits, use multiple instructions to load. 2353 } else { // Offset > 16 bits, use multiple instructions to load.
2235 LoadRegPlusOffsetToAt(src); 2354 LoadRegPlusOffsetToAt(src);
2236 GenInstrImmediate(LWC1, at, fd, 0); 2355 GenInstrImmediate(LWC1, at, fd, 0);
2237 } 2356 }
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
3127 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 3246 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3128 // No out-of-line constant pool support. 3247 // No out-of-line constant pool support.
3129 DCHECK(!FLAG_enable_ool_constant_pool); 3248 DCHECK(!FLAG_enable_ool_constant_pool);
3130 return; 3249 return;
3131 } 3250 }
3132 3251
3133 3252
3134 } } // namespace v8::internal 3253 } } // namespace v8::internal
3135 3254
3136 #endif // V8_TARGET_ARCH_MIPS64 3255 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698