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

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: 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
948 void Assembler::GenInstrJump(Opcode opcode, 956 void Assembler::GenInstrJump(Opcode opcode,
949 uint32_t address) { 957 uint32_t address) {
950 BlockTrampolinePoolScope block_trampoline_pool(this); 958 BlockTrampolinePoolScope block_trampoline_pool(this);
951 DCHECK(is_uint26(address)); 959 DCHECK(is_uint26(address));
952 Instr instr = opcode | address; 960 Instr instr = opcode | address;
953 emit(instr); 961 emit(instr);
954 BlockTrampolinePoolFor(1); // For associated delay slot. 962 BlockTrampolinePoolFor(1); // For associated delay slot.
955 } 963 }
956 964
957 965
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 } else { 1091 } else {
1084 L->link_to(pc_offset()); 1092 L->link_to(pc_offset());
1085 if (!trampoline_emitted_) { 1093 if (!trampoline_emitted_) {
1086 unbound_labels_count_++; 1094 unbound_labels_count_++;
1087 next_buffer_check_ -= kTrampolineSlotsSize; 1095 next_buffer_check_ -= kTrampolineSlotsSize;
1088 } 1096 }
1089 return kEndOfChain; 1097 return kEndOfChain;
1090 } 1098 }
1091 } 1099 }
1092 1100
1093 int32_t offset = target_pos - pc_offset(); 1101 int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1094 DCHECK((offset & 3) == 0); 1102 DCHECK((offset & 3) == 0);
1095 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width. 1103 DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width.
1096 1104
1097 return offset; 1105 return offset;
1098 } 1106 }
1099 1107
1100 1108
1101 void Assembler::label_at_put(Label* L, int at_offset) { 1109 void Assembler::label_at_put(Label* L, int at_offset) {
1102 int target_pos; 1110 int target_pos;
1103 if (L->is_bound()) { 1111 if (L->is_bound()) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 void Assembler::beqc(Register rs, Register rt, int16_t offset) { 1337 void Assembler::beqc(Register rs, Register rt, int16_t offset) {
1330 DCHECK(kArchVariant == kMips64r6); 1338 DCHECK(kArchVariant == kMips64r6);
1331 DCHECK(rs.code() < rt.code()); 1339 DCHECK(rs.code() < rt.code());
1332 GenInstrImmediate(ADDI, rs, rt, offset); 1340 GenInstrImmediate(ADDI, rs, rt, offset);
1333 } 1341 }
1334 1342
1335 1343
1336 void Assembler::beqzc(Register rs, int32_t offset) { 1344 void Assembler::beqzc(Register rs, int32_t offset) {
1337 DCHECK(kArchVariant == kMips64r6); 1345 DCHECK(kArchVariant == kMips64r6);
1338 DCHECK(!(rs.is(zero_reg))); 1346 DCHECK(!(rs.is(zero_reg)));
1339 Instr instr = BEQZC | (rs.code() << kRsShift) | offset; 1347 Instr instr = POP66 | (rs.code() << kRsShift) |
1348 (static_cast<uint32_t>(offset) & kImm21Mask);
1340 emit(instr); 1349 emit(instr);
1341 } 1350 }
1342 1351
1343 1352
1344 void Assembler::bnec(Register rs, Register rt, int16_t offset) { 1353 void Assembler::bnec(Register rs, Register rt, int16_t offset) {
1345 DCHECK(kArchVariant == kMips64r6); 1354 DCHECK(kArchVariant == kMips64r6);
1346 DCHECK(rs.code() < rt.code()); 1355 DCHECK(rs.code() < rt.code());
1347 GenInstrImmediate(DADDI, rs, rt, offset); 1356 GenInstrImmediate(DADDI, rs, rt, offset);
1348 } 1357 }
1349 1358
1350 1359
1351 void Assembler::bnezc(Register rs, int32_t offset) { 1360 void Assembler::bnezc(Register rs, int32_t offset) {
1352 DCHECK(kArchVariant == kMips64r6); 1361 DCHECK(kArchVariant == kMips64r6);
1353 DCHECK(!(rs.is(zero_reg))); 1362 DCHECK(!(rs.is(zero_reg)));
1354 Instr instr = BNEZC | (rs.code() << kRsShift) | offset; 1363 Instr instr = POP76 | (rs.code() << kRsShift) | offset;
1355 emit(instr); 1364 emit(instr);
1356 } 1365 }
1357 1366
1358 1367
1359 void Assembler::j(int64_t target) { 1368 void Assembler::j(int64_t target) {
1360 #if DEBUG 1369 #if DEBUG
1361 // Get pc of delay slot. 1370 // Get pc of delay slot.
1362 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize); 1371 uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1363 bool in_range = (ipc ^ static_cast<uint64_t>(target) >> 1372 bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1364 (kImm26Bits + kImmFieldShift)) == 0; 1373 (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) >> 1431 bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1423 (kImm26Bits+kImmFieldShift)) == 0; 1432 (kImm26Bits+kImmFieldShift)) == 0;
1424 if (in_range) { 1433 if (in_range) {
1425 jal(target); 1434 jal(target);
1426 } else { 1435 } else {
1427 jalr(t9); 1436 jalr(t9);
1428 } 1437 }
1429 } 1438 }
1430 1439
1431 1440
1441 void Assembler::jic(Register rt, int16_t offset) {
1442 DCHECK(kArchVariant == kMips64r6);
1443 Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) |
1444 static_cast<uint16_t>(offset);
1445 emit(instr);
1446 }
1447
1448
1449 void Assembler::jialc(Register rt, int16_t offset) {
1450 DCHECK(kArchVariant == kMips64r6);
1451 positions_recorder()->WriteRecordedPositions();
1452 GenInstrImmediate(POP76, zero_reg, rt, offset);
1453 }
1454
1455
1432 // -------Data-processing-instructions--------- 1456 // -------Data-processing-instructions---------
1433 1457
1434 // Arithmetic. 1458 // Arithmetic.
1435 1459
1436 void Assembler::addu(Register rd, Register rs, Register rt) { 1460 void Assembler::addu(Register rd, Register rs, Register rt) {
1437 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 1461 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1438 } 1462 }
1439 1463
1440 1464
1441 void Assembler::addiu(Register rd, Register rs, int32_t j) { 1465 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) { 1976 void Assembler::sd(Register rd, const MemOperand& rs) {
1953 if (is_int16(rs.offset_)) { 1977 if (is_int16(rs.offset_)) {
1954 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_); 1978 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
1955 } else { // Offset > 16 bits, use multiple instructions to store. 1979 } else { // Offset > 16 bits, use multiple instructions to store.
1956 LoadRegPlusOffsetToAt(rs); 1980 LoadRegPlusOffsetToAt(rs);
1957 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); 1981 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0));
1958 } 1982 }
1959 } 1983 }
1960 1984
1961 1985
1986 // ---------PC-Relative instructions-----------
1987
1988 void Assembler::addiupc(Register rs, int32_t imm19) {
1989 DCHECK(kArchVariant == kMips64r6);
1990 DCHECK(rs.is_valid());
1991 DCHECK((kMinInt19 <= imm19) && (imm19 <= kMaxInt19));
1992 int32_t imm21 =
1993 ADDIUPC << kImm19Bits | static_cast<uint32_t>(imm19 & kImm19Mask);
1994 GenInstrImmediate(PCREL, rs, imm21);
1995 }
1996
1997
1998 void Assembler::lwpc(Register rs, int32_t offset19) {
1999 DCHECK(kArchVariant == kMips64r6);
2000 DCHECK(rs.is_valid());
2001 DCHECK((kMinInt19 <= offset19) && (offset19 <= kMaxInt19));
2002 int32_t imm21 =
2003 LWPC << kImm19Bits | static_cast<uint32_t>(offset19 & kImm19Mask);
2004 GenInstrImmediate(PCREL, rs, imm21);
2005 }
2006
2007
2008 void Assembler::ldpc(Register rs, int32_t offset18) {
2009 DCHECK(kArchVariant == kMips64r6);
2010 DCHECK(rs.is_valid());
2011 DCHECK((kMinInt18 <= offset18) && (offset18 <= kMaxInt18));
2012 int32_t imm21 =
2013 LDPC << kImm18Bits | static_cast<uint32_t>(offset18 & kImm18Mask);
2014 GenInstrImmediate(PCREL, rs, imm21);
2015 }
2016
2017
2018 void Assembler::aluipc(Register rs, int16_t imm16) {
2019 DCHECK(kArchVariant == kMips64r6);
2020 DCHECK(rs.is_valid() && is_int16(imm16));
2021 int32_t imm21 =
2022 ALUIPC << kImm16Bits | static_cast<uint32_t>(imm16 & kImm16Mask);
2023 GenInstrImmediate(PCREL, rs, imm21);
2024 }
2025
2026
1962 // -------------Misc-instructions-------------- 2027 // -------------Misc-instructions--------------
1963 2028
1964 // Break / Trap instructions. 2029 // Break / Trap instructions.
1965 void Assembler::break_(uint32_t code, bool break_as_stop) { 2030 void Assembler::break_(uint32_t code, bool break_as_stop) {
1966 DCHECK((code & ~0xfffff) == 0); 2031 DCHECK((code & ~0xfffff) == 0);
1967 // We need to invalidate breaks that could be stops as well because the 2032 // We need to invalidate breaks that could be stops as well because the
1968 // simulator expects a char pointer after the stop instruction. 2033 // simulator expects a char pointer after the stop instruction.
1969 // See constants-mips.h for explanation. 2034 // See constants-mips.h for explanation.
1970 DCHECK((break_as_stop && 2035 DCHECK((break_as_stop &&
1971 code <= kMaxStopCode && 2036 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) { 2265 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2201 // Should be called via MacroAssembler::Ext. 2266 // Should be called via MacroAssembler::Ext.
2202 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb. 2267 // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
2203 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6); 2268 DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2204 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT); 2269 GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
2205 } 2270 }
2206 2271
2207 2272
2208 void Assembler::bitswap(Register rd, Register rt) { 2273 void Assembler::bitswap(Register rd, Register rt) {
2209 DCHECK(kArchVariant == kMips64r6); 2274 DCHECK(kArchVariant == kMips64r6);
2210 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BITSWAP); 2275 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
2211 } 2276 }
2212 2277
2213 2278
2214 void Assembler::dbitswap(Register rd, Register rt) { 2279 void Assembler::dbitswap(Register rd, Register rt) {
2215 DCHECK(kArchVariant == kMips64r6); 2280 DCHECK(kArchVariant == kMips64r6);
2216 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBITSWAP); 2281 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
2217 } 2282 }
2218 2283
2219 2284
2220 void Assembler::pref(int32_t hint, const MemOperand& rs) { 2285 void Assembler::pref(int32_t hint, const MemOperand& rs) {
2221 DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); 2286 DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
2222 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) 2287 Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
2223 | (rs.offset_); 2288 | (rs.offset_);
2224 emit(instr); 2289 emit(instr);
2225 } 2290 }
2226 2291
2227 2292
2293 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
2294 DCHECK(kArchVariant == kMips64r6);
2295 DCHECK(is_uint3(bp));
2296 uint16_t sa = (ALIGN << kBp2Bits) | bp;
2297 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
2298 }
2299
2300
2301 void Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
2302 DCHECK(kArchVariant == kMips64r6);
2303 DCHECK(is_uint3(bp));
2304 uint16_t sa = (DALIGN << kBp3Bits) | bp;
2305 GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
2306 }
2307
2308
2228 // --------Coprocessor-instructions---------------- 2309 // --------Coprocessor-instructions----------------
2229 2310
2230 // Load, store, move. 2311 // Load, store, move.
2231 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { 2312 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
2232 if (is_int16(src.offset_)) { 2313 if (is_int16(src.offset_)) {
2233 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 2314 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
2234 } else { // Offset > 16 bits, use multiple instructions to load. 2315 } else { // Offset > 16 bits, use multiple instructions to load.
2235 LoadRegPlusOffsetToAt(src); 2316 LoadRegPlusOffsetToAt(src);
2236 GenInstrImmediate(LWC1, at, fd, 0); 2317 GenInstrImmediate(LWC1, at, fd, 0);
2237 } 2318 }
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
3127 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 3208 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3128 // No out-of-line constant pool support. 3209 // No out-of-line constant pool support.
3129 DCHECK(!FLAG_enable_ool_constant_pool); 3210 DCHECK(!FLAG_enable_ool_constant_pool);
3130 return; 3211 return;
3131 } 3212 }
3132 3213
3133 3214
3134 } } // namespace v8::internal 3215 } } // namespace v8::internal
3135 3216
3136 #endif // V8_TARGET_ARCH_MIPS64 3217 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698