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

Side by Side Diff: src/mips/macro-assembler-mips.cc

Issue 23444033: MIPS: Improve TruncateNumberToI implementation after DoubleToIStub usage (r16461). (Closed) Base URL: git@github.com:paul99/v8m-rb.git@master
Patch Set: Created 7 years, 3 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
« no previous file with comments | « src/mips/macro-assembler-mips.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 &not_in_int32_range);
1589 jmp(&done);
1590
1591 bind(&not_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
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
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698