OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 addiu(rd, rd, 1); | 1291 addiu(rd, rd, 1); |
1292 Branch(&loop, ne, mask, Operand(zero_reg), USE_DELAY_SLOT); | 1292 Branch(&loop, ne, mask, Operand(zero_reg), USE_DELAY_SLOT); |
1293 srl(mask, mask, 1); | 1293 srl(mask, mask, 1); |
1294 bind(&end); | 1294 bind(&end); |
1295 } else { | 1295 } else { |
1296 clz(rd, rs); | 1296 clz(rd, rs); |
1297 } | 1297 } |
1298 } | 1298 } |
1299 | 1299 |
1300 | 1300 |
1301 // Tries to get a signed int32 out of a double precision floating point heap | |
1302 // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the | |
1303 // 32bits signed integer range. | |
1304 // This method implementation differs from the ARM version for performance | |
1305 // reasons. | |
1306 void MacroAssembler::ConvertToInt32(Register source, | |
1307 Register dest, | |
1308 Register scratch, | |
1309 Register scratch2, | |
1310 FPURegister double_scratch, | |
1311 Label *not_int32) { | |
1312 Label right_exponent, done; | |
1313 // Get exponent word (ENDIAN issues). | |
1314 lw(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset)); | |
1315 // Get exponent alone in scratch2. | |
1316 And(scratch2, scratch, Operand(HeapNumber::kExponentMask)); | |
1317 // Load dest with zero. We use this either for the final shift or | |
1318 // for the answer. | |
1319 mov(dest, zero_reg); | |
1320 // Check whether the exponent matches a 32 bit signed int that is not a Smi. | |
1321 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). This is | |
1322 // the exponent that we are fastest at and also the highest exponent we can | |
1323 // handle here. | |
1324 const uint32_t non_smi_exponent = | |
1325 (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift; | |
1326 // If we have a match of the int32-but-not-Smi exponent then skip some logic. | |
1327 Branch(&right_exponent, eq, scratch2, Operand(non_smi_exponent)); | |
1328 // If the exponent is higher than that then go to not_int32 case. This | |
1329 // catches numbers that don't fit in a signed int32, infinities and NaNs. | |
1330 Branch(not_int32, gt, scratch2, Operand(non_smi_exponent)); | |
1331 | |
1332 // We know the exponent is smaller than 30 (biased). If it is less than | |
1333 // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, i.e. | |
1334 // it rounds to zero. | |
1335 const uint32_t zero_exponent = | |
1336 (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift; | |
1337 Subu(scratch2, scratch2, Operand(zero_exponent)); | |
1338 // Dest already has a Smi zero. | |
1339 Branch(&done, lt, scratch2, Operand(zero_reg)); | |
1340 bind(&right_exponent); | |
1341 | |
1342 // MIPS FPU instructions implementing double precision to integer | |
1343 // conversion using round to zero. Since the FP value was qualified | |
1344 // above, the resulting integer should be a legal int32. | |
1345 // The original 'Exponent' word is still in scratch. | |
1346 lwc1(double_scratch, FieldMemOperand(source, HeapNumber::kMantissaOffset)); | |
1347 mtc1(scratch, FPURegister::from_code(double_scratch.code() + 1)); | |
1348 trunc_w_d(double_scratch, double_scratch); | |
1349 mfc1(dest, double_scratch); | |
1350 | |
1351 bind(&done); | |
1352 } | |
1353 | |
1354 | |
1355 void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode, | 1301 void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode, |
1356 Register result, | 1302 Register result, |
1357 DoubleRegister double_input, | 1303 DoubleRegister double_input, |
1358 Register scratch, | 1304 Register scratch, |
1359 DoubleRegister double_scratch, | 1305 DoubleRegister double_scratch, |
1360 Register except_flag, | 1306 Register except_flag, |
1361 CheckForInexactConversion check_inexact) { | 1307 CheckForInexactConversion check_inexact) { |
1362 ASSERT(!result.is(scratch)); | 1308 ASSERT(!result.is(scratch)); |
1363 ASSERT(!double_input.is(double_scratch)); | 1309 ASSERT(!double_input.is(double_scratch)); |
1364 ASSERT(!except_flag.is(scratch)); | 1310 ASSERT(!except_flag.is(scratch)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 // Move the converted value into the result register. | 1355 // Move the converted value into the result register. |
1410 mfc1(result, double_scratch); | 1356 mfc1(result, double_scratch); |
1411 | 1357 |
1412 // Check for fpu exceptions. | 1358 // Check for fpu exceptions. |
1413 And(except_flag, except_flag, Operand(except_mask)); | 1359 And(except_flag, except_flag, Operand(except_mask)); |
1414 | 1360 |
1415 bind(&done); | 1361 bind(&done); |
1416 } | 1362 } |
1417 | 1363 |
1418 | 1364 |
1419 void MacroAssembler::EmitOutOfInt32RangeTruncate(Register result, | |
1420 Register input_high, | |
1421 Register input_low, | |
1422 Register scratch) { | |
1423 Label done, normal_exponent, restore_sign; | |
1424 // Extract the biased exponent in result. | |
1425 Ext(result, | |
1426 input_high, | |
1427 HeapNumber::kExponentShift, | |
1428 HeapNumber::kExponentBits); | |
1429 | |
1430 // Check for Infinity and NaNs, which should return 0. | |
1431 Subu(scratch, result, HeapNumber::kExponentMask); | |
1432 Movz(result, zero_reg, scratch); | |
1433 Branch(&done, eq, scratch, Operand(zero_reg)); | |
1434 | |
1435 // Express exponent as delta to (number of mantissa bits + 31). | |
1436 Subu(result, | |
1437 result, | |
1438 Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits + 31)); | |
1439 | |
1440 // If the delta is strictly positive, all bits would be shifted away, | |
1441 // which means that we can return 0. | |
1442 Branch(&normal_exponent, le, result, Operand(zero_reg)); | |
1443 mov(result, zero_reg); | |
1444 Branch(&done); | |
1445 | |
1446 bind(&normal_exponent); | |
1447 const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1; | |
1448 // Calculate shift. | |
1449 Addu(scratch, result, Operand(kShiftBase + HeapNumber::kMantissaBits)); | |
1450 | |
1451 // Save the sign. | |
1452 Register sign = result; | |
1453 result = no_reg; | |
1454 And(sign, input_high, Operand(HeapNumber::kSignMask)); | |
1455 | |
1456 // On ARM shifts > 31 bits are valid and will result in zero. On MIPS we need | |
1457 // to check for this specific case. | |
1458 Label high_shift_needed, high_shift_done; | |
1459 Branch(&high_shift_needed, lt, scratch, Operand(32)); | |
1460 mov(input_high, zero_reg); | |
1461 Branch(&high_shift_done); | |
1462 bind(&high_shift_needed); | |
1463 | |
1464 // Set the implicit 1 before the mantissa part in input_high. | |
1465 Or(input_high, | |
1466 input_high, | |
1467 Operand(1 << HeapNumber::kMantissaBitsInTopWord)); | |
1468 // Shift the mantissa bits to the correct position. | |
1469 // We don't need to clear non-mantissa bits as they will be shifted away. | |
1470 // If they weren't, it would mean that the answer is in the 32bit range. | |
1471 sllv(input_high, input_high, scratch); | |
1472 | |
1473 bind(&high_shift_done); | |
1474 | |
1475 // Replace the shifted bits with bits from the lower mantissa word. | |
1476 Label pos_shift, shift_done; | |
1477 li(at, 32); | |
1478 subu(scratch, at, scratch); | |
1479 Branch(&pos_shift, ge, scratch, Operand(zero_reg)); | |
1480 | |
1481 // Negate scratch. | |
1482 Subu(scratch, zero_reg, scratch); | |
1483 sllv(input_low, input_low, scratch); | |
1484 Branch(&shift_done); | |
1485 | |
1486 bind(&pos_shift); | |
1487 srlv(input_low, input_low, scratch); | |
1488 | |
1489 bind(&shift_done); | |
1490 Or(input_high, input_high, Operand(input_low)); | |
1491 // Restore sign if necessary. | |
1492 mov(scratch, sign); | |
1493 result = sign; | |
1494 sign = no_reg; | |
1495 Subu(result, zero_reg, input_high); | |
1496 Movz(result, input_high, scratch); | |
1497 bind(&done); | |
1498 } | |
1499 | |
1500 | |
1501 void MacroAssembler::TryInlineTruncateDoubleToI(Register result, | 1365 void MacroAssembler::TryInlineTruncateDoubleToI(Register result, |
1502 DoubleRegister double_input, | 1366 DoubleRegister double_input, |
1503 Label* done) { | 1367 Label* done) { |
1504 DoubleRegister single_scratch = kLithiumScratchDouble.low(); | 1368 DoubleRegister single_scratch = kLithiumScratchDouble.low(); |
1505 Register scratch = at; | 1369 Register scratch = at; |
1506 Register scratch2 = t9; | 1370 Register scratch2 = t9; |
1507 | 1371 |
1508 // Clear cumulative exception flags and save the FCSR. | 1372 // Clear cumulative exception flags and save the FCSR. |
1509 cfc1(scratch2, FCSR); | 1373 cfc1(scratch2, FCSR); |
1510 ctc1(zero_reg, FCSR); | 1374 ctc1(zero_reg, FCSR); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 CallStub(&stub); | 1427 CallStub(&stub); |
1564 pop(ra); | 1428 pop(ra); |
1565 | 1429 |
1566 bind(&done); | 1430 bind(&done); |
1567 } | 1431 } |
1568 | 1432 |
1569 | 1433 |
1570 void MacroAssembler::TruncateNumberToI(Register object, | 1434 void MacroAssembler::TruncateNumberToI(Register object, |
1571 Register result, | 1435 Register result, |
1572 Register heap_number_map, | 1436 Register heap_number_map, |
1573 Register scratch1, | 1437 Register scratch, |
1574 Register scratch2, | |
1575 Register scratch3, | |
1576 Label* not_number) { | 1438 Label* not_number) { |
1577 Label done; | 1439 Label done; |
1578 Label not_in_int32_range; | 1440 ASSERT(!result.is(object)); |
1579 DoubleRegister double_scratch = f12; | |
1580 | 1441 |
1581 UntagAndJumpIfSmi(result, object, &done); | 1442 UntagAndJumpIfSmi(result, object, &done); |
1582 JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); | 1443 JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number); |
1583 ConvertToInt32(object, | 1444 TruncateHeapNumberToI(result, object); |
1584 result, | |
1585 scratch1, | |
1586 scratch2, | |
1587 double_scratch, | |
1588 ¬_in_int32_range); | |
1589 jmp(&done); | |
1590 | |
1591 bind(¬_in_int32_range); | |
1592 lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset)); | |
1593 lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset)); | |
1594 EmitOutOfInt32RangeTruncate(result, | |
1595 scratch1, | |
1596 scratch2, | |
1597 scratch3); | |
1598 | 1445 |
1599 bind(&done); | 1446 bind(&done); |
1600 } | 1447 } |
1601 | 1448 |
1602 | 1449 |
1603 void MacroAssembler::GetLeastBitsFromSmi(Register dst, | 1450 void MacroAssembler::GetLeastBitsFromSmi(Register dst, |
1604 Register src, | 1451 Register src, |
1605 int num_least_bits) { | 1452 int num_least_bits) { |
1606 Ext(dst, src, kSmiTagSize, num_least_bits); | 1453 Ext(dst, src, kSmiTagSize, num_least_bits); |
1607 } | 1454 } |
(...skipping 4141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5749 opcode == BGTZL); | 5596 opcode == BGTZL); |
5750 opcode = (cond == eq) ? BEQ : BNE; | 5597 opcode = (cond == eq) ? BEQ : BNE; |
5751 instr = (instr & ~kOpcodeMask) | opcode; | 5598 instr = (instr & ~kOpcodeMask) | opcode; |
5752 masm_.emit(instr); | 5599 masm_.emit(instr); |
5753 } | 5600 } |
5754 | 5601 |
5755 | 5602 |
5756 } } // namespace v8::internal | 5603 } } // namespace v8::internal |
5757 | 5604 |
5758 #endif // V8_TARGET_ARCH_MIPS | 5605 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |