OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 DCHECK(!tmp.is(rt)); | 1185 DCHECK(!tmp.is(rt)); |
1186 sll(tmp, rs, sa); | 1186 sll(tmp, rs, sa); |
1187 Addu(rd, rt, tmp); | 1187 Addu(rd, rt, tmp); |
1188 } | 1188 } |
1189 } | 1189 } |
1190 | 1190 |
1191 | 1191 |
1192 // ------------Pseudo-instructions------------- | 1192 // ------------Pseudo-instructions------------- |
1193 | 1193 |
1194 void MacroAssembler::Ulw(Register rd, const MemOperand& rs) { | 1194 void MacroAssembler::Ulw(Register rd, const MemOperand& rs) { |
1195 lwr(rd, rs); | 1195 DCHECK(!rd.is(at)); |
1196 lwl(rd, MemOperand(rs.rm(), rs.offset() + 3)); | 1196 DCHECK(!rs.rm().is(at)); |
| 1197 if (IsMipsArchVariant(kMips32r6)) { |
| 1198 lw(rd, rs); |
| 1199 } else { |
| 1200 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1201 IsMipsArchVariant(kLoongson)); |
| 1202 if (is_int16(rs.offset()) && is_int16(rs.offset() + 3)) { |
| 1203 if (!rd.is(rs.rm())) { |
| 1204 lwr(rd, MemOperand(rs.rm(), rs.offset() + kMipsLwrOffset)); |
| 1205 lwl(rd, MemOperand(rs.rm(), rs.offset() + kMipsLwlOffset)); |
| 1206 } else { |
| 1207 lwr(at, MemOperand(rs.rm(), rs.offset() + kMipsLwrOffset)); |
| 1208 lwl(at, MemOperand(rs.rm(), rs.offset() + kMipsLwlOffset)); |
| 1209 mov(rd, at); |
| 1210 } |
| 1211 } else { // Offset > 16 bits, use multiple instructions to load. |
| 1212 LoadRegPlusOffsetToAt(rs); |
| 1213 lwr(rd, MemOperand(at, kMipsLwrOffset)); |
| 1214 lwl(rd, MemOperand(at, kMipsLwlOffset)); |
| 1215 } |
| 1216 } |
1197 } | 1217 } |
1198 | 1218 |
1199 | 1219 |
1200 void MacroAssembler::Usw(Register rd, const MemOperand& rs) { | 1220 void MacroAssembler::Usw(Register rd, const MemOperand& rs) { |
1201 swr(rd, rs); | 1221 DCHECK(!rd.is(at)); |
1202 swl(rd, MemOperand(rs.rm(), rs.offset() + 3)); | 1222 DCHECK(!rs.rm().is(at)); |
| 1223 if (IsMipsArchVariant(kMips32r6)) { |
| 1224 sw(rd, rs); |
| 1225 } else { |
| 1226 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1227 IsMipsArchVariant(kLoongson)); |
| 1228 if (is_int16(rs.offset()) && is_int16(rs.offset() + 3)) { |
| 1229 swr(rd, MemOperand(rs.rm(), rs.offset() + kMipsSwrOffset)); |
| 1230 swl(rd, MemOperand(rs.rm(), rs.offset() + kMipsSwlOffset)); |
| 1231 } else { |
| 1232 LoadRegPlusOffsetToAt(rs); |
| 1233 swr(rd, MemOperand(at, kMipsSwrOffset)); |
| 1234 swl(rd, MemOperand(at, kMipsSwlOffset)); |
| 1235 } |
| 1236 } |
| 1237 } |
| 1238 |
| 1239 void MacroAssembler::Ulh(Register rd, const MemOperand& rs) { |
| 1240 DCHECK(!rd.is(at)); |
| 1241 DCHECK(!rs.rm().is(at)); |
| 1242 if (IsMipsArchVariant(kMips32r6)) { |
| 1243 lh(rd, rs); |
| 1244 } else { |
| 1245 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1246 IsMipsArchVariant(kLoongson)); |
| 1247 if (is_int16(rs.offset()) && is_int16(rs.offset() + 1)) { |
| 1248 #if defined(V8_TARGET_LITTLE_ENDIAN) |
| 1249 lbu(at, rs); |
| 1250 lb(rd, MemOperand(rs.rm(), rs.offset() + 1)); |
| 1251 #elif defined(V8_TARGET_BIG_ENDIAN) |
| 1252 lbu(at, MemOperand(rs.rm(), rs.offset() + 1)); |
| 1253 lb(rd, rs); |
| 1254 #endif |
| 1255 } else { // Offset > 16 bits, use multiple instructions to load. |
| 1256 LoadRegPlusOffsetToAt(rs); |
| 1257 #if defined(V8_TARGET_LITTLE_ENDIAN) |
| 1258 lb(rd, MemOperand(at, 1)); |
| 1259 lbu(at, MemOperand(at, 0)); |
| 1260 #elif defined(V8_TARGET_BIG_ENDIAN) |
| 1261 lb(rd, MemOperand(at, 0)); |
| 1262 lbu(at, MemOperand(at, 1)); |
| 1263 #endif |
| 1264 } |
| 1265 sll(rd, rd, 8); |
| 1266 or_(rd, rd, at); |
| 1267 } |
| 1268 } |
| 1269 |
| 1270 void MacroAssembler::Ulhu(Register rd, const MemOperand& rs) { |
| 1271 DCHECK(!rd.is(at)); |
| 1272 DCHECK(!rs.rm().is(at)); |
| 1273 if (IsMipsArchVariant(kMips32r6)) { |
| 1274 lhu(rd, rs); |
| 1275 } else { |
| 1276 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1277 IsMipsArchVariant(kLoongson)); |
| 1278 if (is_int16(rs.offset()) && is_int16(rs.offset() + 1)) { |
| 1279 #if defined(V8_TARGET_LITTLE_ENDIAN) |
| 1280 lbu(at, rs); |
| 1281 lbu(rd, MemOperand(rs.rm(), rs.offset() + 1)); |
| 1282 #elif defined(V8_TARGET_BIG_ENDIAN) |
| 1283 lbu(at, MemOperand(rs.rm(), rs.offset() + 1)); |
| 1284 lbu(rd, rs); |
| 1285 #endif |
| 1286 } else { // Offset > 16 bits, use multiple instructions to load. |
| 1287 LoadRegPlusOffsetToAt(rs); |
| 1288 #if defined(V8_TARGET_LITTLE_ENDIAN) |
| 1289 lbu(rd, MemOperand(at, 1)); |
| 1290 lbu(at, MemOperand(at, 0)); |
| 1291 #elif defined(V8_TARGET_BIG_ENDIAN) |
| 1292 lbu(rd, MemOperand(at, 0)); |
| 1293 lbu(at, MemOperand(at, 1)); |
| 1294 #endif |
| 1295 } |
| 1296 sll(rd, rd, 8); |
| 1297 or_(rd, rd, at); |
| 1298 } |
| 1299 } |
| 1300 |
| 1301 void MacroAssembler::Ush(Register rd, const MemOperand& rs, Register scratch) { |
| 1302 DCHECK(!rd.is(at)); |
| 1303 DCHECK(!rs.rm().is(at)); |
| 1304 DCHECK(!rs.rm().is(scratch)); |
| 1305 DCHECK(!scratch.is(at)); |
| 1306 if (IsMipsArchVariant(kMips32r6)) { |
| 1307 sh(rd, rs); |
| 1308 } else { |
| 1309 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1310 IsMipsArchVariant(kLoongson)); |
| 1311 MemOperand source = rs; |
| 1312 // If offset > 16 bits, load address to at with offset 0. |
| 1313 if (!is_int16(rs.offset()) || !is_int16(rs.offset() + 1)) { |
| 1314 LoadRegPlusOffsetToAt(rs); |
| 1315 source = MemOperand(at, 0); |
| 1316 } |
| 1317 |
| 1318 if (!scratch.is(rd)) { |
| 1319 mov(scratch, rd); |
| 1320 } |
| 1321 |
| 1322 #if defined(V8_TARGET_LITTLE_ENDIAN) |
| 1323 sb(scratch, source); |
| 1324 srl(scratch, scratch, 8); |
| 1325 sb(scratch, MemOperand(source.rm(), source.offset() + 1)); |
| 1326 #elif defined(V8_TARGET_BIG_ENDIAN) |
| 1327 sb(scratch, MemOperand(source.rm(), source.offset() + 1)); |
| 1328 srl(scratch, scratch, 8); |
| 1329 sb(scratch, source); |
| 1330 #endif |
| 1331 } |
| 1332 } |
| 1333 |
| 1334 void MacroAssembler::Ulwc1(FPURegister fd, const MemOperand& rs, |
| 1335 Register scratch) { |
| 1336 if (IsMipsArchVariant(kMips32r6)) { |
| 1337 lwc1(fd, rs); |
| 1338 } else { |
| 1339 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1340 IsMipsArchVariant(kLoongson)); |
| 1341 Ulw(scratch, rs); |
| 1342 mtc1(scratch, fd); |
| 1343 } |
| 1344 } |
| 1345 |
| 1346 void MacroAssembler::Uswc1(FPURegister fd, const MemOperand& rs, |
| 1347 Register scratch) { |
| 1348 if (IsMipsArchVariant(kMips32r6)) { |
| 1349 swc1(fd, rs); |
| 1350 } else { |
| 1351 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1352 IsMipsArchVariant(kLoongson)); |
| 1353 mfc1(scratch, fd); |
| 1354 Usw(scratch, rs); |
| 1355 } |
| 1356 } |
| 1357 |
| 1358 void MacroAssembler::Uldc1(FPURegister fd, const MemOperand& rs, |
| 1359 Register scratch) { |
| 1360 DCHECK(!scratch.is(at)); |
| 1361 if (IsMipsArchVariant(kMips32r6)) { |
| 1362 ldc1(fd, rs); |
| 1363 } else { |
| 1364 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1365 IsMipsArchVariant(kLoongson)); |
| 1366 Ulw(scratch, MemOperand(rs.rm(), rs.offset() + Register::kMantissaOffset)); |
| 1367 mtc1(scratch, fd); |
| 1368 Ulw(scratch, MemOperand(rs.rm(), rs.offset() + Register::kExponentOffset)); |
| 1369 Mthc1(scratch, fd); |
| 1370 } |
| 1371 } |
| 1372 |
| 1373 void MacroAssembler::Usdc1(FPURegister fd, const MemOperand& rs, |
| 1374 Register scratch) { |
| 1375 DCHECK(!scratch.is(at)); |
| 1376 if (IsMipsArchVariant(kMips32r6)) { |
| 1377 sdc1(fd, rs); |
| 1378 } else { |
| 1379 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || |
| 1380 IsMipsArchVariant(kLoongson)); |
| 1381 mfc1(scratch, fd); |
| 1382 Usw(scratch, MemOperand(rs.rm(), rs.offset() + Register::kMantissaOffset)); |
| 1383 Mfhc1(scratch, fd); |
| 1384 Usw(scratch, MemOperand(rs.rm(), rs.offset() + Register::kExponentOffset)); |
| 1385 } |
1203 } | 1386 } |
1204 | 1387 |
1205 | 1388 |
1206 void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) { | 1389 void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) { |
1207 AllowDeferredHandleDereference smi_check; | 1390 AllowDeferredHandleDereference smi_check; |
1208 if (value->IsSmi()) { | 1391 if (value->IsSmi()) { |
1209 li(dst, Operand(value), mode); | 1392 li(dst, Operand(value), mode); |
1210 } else { | 1393 } else { |
1211 DCHECK(value->IsHeapObject()); | 1394 DCHECK(value->IsHeapObject()); |
1212 if (isolate()->heap()->InNewSpace(*value)) { | 1395 if (isolate()->heap()->InNewSpace(*value)) { |
(...skipping 5316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6529 if (mag.shift > 0) sra(result, result, mag.shift); | 6712 if (mag.shift > 0) sra(result, result, mag.shift); |
6530 srl(at, dividend, 31); | 6713 srl(at, dividend, 31); |
6531 Addu(result, result, Operand(at)); | 6714 Addu(result, result, Operand(at)); |
6532 } | 6715 } |
6533 | 6716 |
6534 | 6717 |
6535 } // namespace internal | 6718 } // namespace internal |
6536 } // namespace v8 | 6719 } // namespace v8 |
6537 | 6720 |
6538 #endif // V8_TARGET_ARCH_MIPS | 6721 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |