| 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 | 
|---|