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 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1491 // Restore sign if necessary. | 1491 // Restore sign if necessary. |
1492 mov(scratch, sign); | 1492 mov(scratch, sign); |
1493 result = sign; | 1493 result = sign; |
1494 sign = no_reg; | 1494 sign = no_reg; |
1495 Subu(result, zero_reg, input_high); | 1495 Subu(result, zero_reg, input_high); |
1496 Movz(result, input_high, scratch); | 1496 Movz(result, input_high, scratch); |
1497 bind(&done); | 1497 bind(&done); |
1498 } | 1498 } |
1499 | 1499 |
1500 | 1500 |
1501 void MacroAssembler::EmitECMATruncate(Register result, | 1501 void MacroAssembler::TryInlineTruncateDoubleToI(Register result, |
1502 FPURegister double_input, | 1502 DoubleRegister double_input, |
1503 FPURegister single_scratch, | 1503 Label* done) { |
1504 Register scratch, | 1504 DoubleRegister single_scratch = kLithiumScratchDouble.low(); |
1505 Register scratch2, | 1505 Register scratch = at; |
1506 Register scratch3) { | 1506 Register scratch2 = t9; |
1507 ASSERT(!scratch2.is(result)); | |
1508 ASSERT(!scratch3.is(result)); | |
1509 ASSERT(!scratch3.is(scratch2)); | |
1510 ASSERT(!scratch.is(result) && | |
1511 !scratch.is(scratch2) && | |
1512 !scratch.is(scratch3)); | |
1513 ASSERT(!single_scratch.is(double_input)); | |
1514 | |
1515 Label done; | |
1516 Label manual; | |
1517 | 1507 |
1518 // Clear cumulative exception flags and save the FCSR. | 1508 // Clear cumulative exception flags and save the FCSR. |
1519 cfc1(scratch2, FCSR); | 1509 cfc1(scratch2, FCSR); |
1520 ctc1(zero_reg, FCSR); | 1510 ctc1(zero_reg, FCSR); |
1521 // Try a conversion to a signed integer. | 1511 // Try a conversion to a signed integer. |
1522 trunc_w_d(single_scratch, double_input); | 1512 trunc_w_d(single_scratch, double_input); |
1523 mfc1(result, single_scratch); | 1513 mfc1(result, single_scratch); |
1524 // Retrieve and restore the FCSR. | 1514 // Retrieve and restore the FCSR. |
1525 cfc1(scratch, FCSR); | 1515 cfc1(scratch, FCSR); |
1526 ctc1(scratch2, FCSR); | 1516 ctc1(scratch2, FCSR); |
1527 // Check for overflow and NaNs. | 1517 // Check for overflow and NaNs. |
1528 And(scratch, | 1518 And(scratch, |
1529 scratch, | 1519 scratch, |
1530 kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | kFCSRInvalidOpFlagMask); | 1520 kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | kFCSRInvalidOpFlagMask); |
1531 // If we had no exceptions we are done. | 1521 // If we had no exceptions we are done. |
1532 Branch(&done, eq, scratch, Operand(zero_reg)); | 1522 Branch(done, eq, scratch, Operand(zero_reg)); |
1523 } | |
1533 | 1524 |
1534 // Load the double value and perform a manual truncation. | 1525 |
1535 Register input_high = scratch2; | 1526 void MacroAssembler::TruncateDoubleToI(Register result, |
1536 Register input_low = scratch3; | 1527 DoubleRegister double_input) { |
1537 Move(input_low, input_high, double_input); | 1528 Label done; |
1538 EmitOutOfInt32RangeTruncate(result, | 1529 |
1539 input_high, | 1530 TryInlineTruncateDoubleToI(result, double_input, &done); |
1540 input_low, | 1531 |
1541 scratch); | 1532 // If we fell through then inline version didn't succeed - call stub instead. |
1533 push(ra); | |
1534 Subu(sp, sp, Operand(kDoubleSize)); // Put input on stack. | |
1535 sdc1(double_input, MemOperand(sp, 0)); | |
1536 | |
1537 DoubleToIStub stub(sp, result, 0, true, true); | |
1538 CallStub(&stub); | |
1539 | |
1540 Addu(sp, sp, Operand(kDoubleSize)); | |
1541 pop(ra); | |
1542 | |
1542 bind(&done); | 1543 bind(&done); |
1543 } | 1544 } |
1544 | 1545 |
1546 | |
1547 void MacroAssembler::TruncateHeapNumberToI(Register result, Register object) { | |
1548 Label done; | |
1549 DoubleRegister double_scratch = f12; | |
1550 ASSERT(!result.is(object)); | |
1551 | |
1552 ldc1(double_scratch, | |
1553 MemOperand(object, HeapNumber::kValueOffset - kHeapObjectTag)); | |
1554 TryInlineTruncateDoubleToI(result, double_scratch, &done); | |
1555 | |
1556 // If we fell through then inline version didn't succeed - call stub instead. | |
1557 push(ra); | |
1558 DoubleToIStub stub(object, | |
1559 result, | |
1560 HeapNumber::kValueOffset - kHeapObjectTag, | |
1561 true, | |
1562 true); | |
1563 CallStub(&stub); | |
1564 pop(ra); | |
1565 | |
1566 bind(&done); | |
1567 } | |
1568 | |
1569 | |
1570 void MacroAssembler::TruncateNumberToI(Register object, | |
1571 Register result, | |
1572 Register heap_number_map, | |
1573 Register scratch1, | |
1574 Register scratch2, | |
1575 Register scratch3, | |
1576 Label* not_number) { | |
1577 Label done; | |
1578 Label not_in_int32_range; | |
1579 DoubleRegister double_scratch = f12; | |
1580 | |
1581 UntagAndJumpIfSmi(result, object, &done); | |
1582 JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); | |
1583 ConvertToInt32(object, | |
1584 result, | |
1585 scratch1, | |
1586 scratch2, | |
1587 double_scratch, | |
1588 ¬_in_int32_range); | |
rmcilroy_google
2013/09/02 13:26:32
Any particular reason you are not doing using Trun
| |
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 | |
1599 bind(&done); | |
1600 } | |
1601 | |
1545 | 1602 |
1546 void MacroAssembler::GetLeastBitsFromSmi(Register dst, | 1603 void MacroAssembler::GetLeastBitsFromSmi(Register dst, |
1547 Register src, | 1604 Register src, |
1548 int num_least_bits) { | 1605 int num_least_bits) { |
1549 Ext(dst, src, kSmiTagSize, num_least_bits); | 1606 Ext(dst, src, kSmiTagSize, num_least_bits); |
1550 } | 1607 } |
1551 | 1608 |
1552 | 1609 |
1553 void MacroAssembler::GetLeastBitsFromInt32(Register dst, | 1610 void MacroAssembler::GetLeastBitsFromInt32(Register dst, |
1554 Register src, | 1611 Register src, |
(...skipping 3015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4570 Label ok, fail; | 4627 Label ok, fail; |
4571 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK); | 4628 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK); |
4572 Branch(&ok); | 4629 Branch(&ok); |
4573 bind(&fail); | 4630 bind(&fail); |
4574 Abort(kGlobalFunctionsMustHaveInitialMap); | 4631 Abort(kGlobalFunctionsMustHaveInitialMap); |
4575 bind(&ok); | 4632 bind(&ok); |
4576 } | 4633 } |
4577 } | 4634 } |
4578 | 4635 |
4579 | 4636 |
4580 void MacroAssembler::ConvertNumberToInt32(Register object, | |
4581 Register dst, | |
4582 Register heap_number_map, | |
4583 Register scratch1, | |
4584 Register scratch2, | |
4585 Register scratch3, | |
4586 FPURegister double_scratch, | |
4587 Label* not_number) { | |
4588 Label done; | |
4589 Label not_in_int32_range; | |
4590 | |
4591 UntagAndJumpIfSmi(dst, object, &done); | |
4592 JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); | |
4593 ConvertToInt32(object, | |
4594 dst, | |
4595 scratch1, | |
4596 scratch2, | |
4597 double_scratch, | |
4598 ¬_in_int32_range); | |
4599 jmp(&done); | |
4600 | |
4601 bind(¬_in_int32_range); | |
4602 lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset)); | |
4603 lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset)); | |
4604 | |
4605 EmitOutOfInt32RangeTruncate(dst, | |
4606 scratch1, | |
4607 scratch2, | |
4608 scratch3); | |
4609 | |
4610 bind(&done); | |
4611 } | |
4612 | |
4613 | |
4614 void MacroAssembler::LoadNumber(Register object, | 4637 void MacroAssembler::LoadNumber(Register object, |
4615 FPURegister dst, | 4638 FPURegister dst, |
4616 Register heap_number_map, | 4639 Register heap_number_map, |
4617 Register scratch, | 4640 Register scratch, |
4618 Label* not_number) { | 4641 Label* not_number) { |
4619 Label is_smi, done; | 4642 Label is_smi, done; |
4620 | 4643 |
4621 UntagAndJumpIfSmi(scratch, object, &is_smi); | 4644 UntagAndJumpIfSmi(scratch, object, &is_smi); |
4622 JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number); | 4645 JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number); |
4623 | 4646 |
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5635 li(at, Operand(new_space_allocation_top)); | 5658 li(at, Operand(new_space_allocation_top)); |
5636 lw(at, MemOperand(at)); | 5659 lw(at, MemOperand(at)); |
5637 Branch(&no_memento_available, gt, scratch_reg, Operand(at)); | 5660 Branch(&no_memento_available, gt, scratch_reg, Operand(at)); |
5638 lw(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize)); | 5661 lw(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize)); |
5639 Branch(allocation_memento_present, cond, scratch_reg, | 5662 Branch(allocation_memento_present, cond, scratch_reg, |
5640 Operand(Handle<Map>(isolate()->heap()->allocation_memento_map()))); | 5663 Operand(Handle<Map>(isolate()->heap()->allocation_memento_map()))); |
5641 bind(&no_memento_available); | 5664 bind(&no_memento_available); |
5642 } | 5665 } |
5643 | 5666 |
5644 | 5667 |
5668 Register GetRegisterThatIsNotOneOf(Register reg1, | |
5669 Register reg2, | |
5670 Register reg3, | |
5671 Register reg4, | |
5672 Register reg5, | |
5673 Register reg6) { | |
5674 RegList regs = 0; | |
5675 if (reg1.is_valid()) regs |= reg1.bit(); | |
5676 if (reg2.is_valid()) regs |= reg2.bit(); | |
5677 if (reg3.is_valid()) regs |= reg3.bit(); | |
5678 if (reg4.is_valid()) regs |= reg4.bit(); | |
5679 if (reg5.is_valid()) regs |= reg5.bit(); | |
5680 if (reg6.is_valid()) regs |= reg6.bit(); | |
5681 | |
5682 for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { | |
5683 Register candidate = Register::FromAllocationIndex(i); | |
5684 if (regs & candidate.bit()) continue; | |
5685 return candidate; | |
5686 } | |
5687 UNREACHABLE(); | |
5688 return no_reg; | |
5689 } | |
5690 | |
5691 | |
5645 bool AreAliased(Register r1, Register r2, Register r3, Register r4) { | 5692 bool AreAliased(Register r1, Register r2, Register r3, Register r4) { |
5646 if (r1.is(r2)) return true; | 5693 if (r1.is(r2)) return true; |
5647 if (r1.is(r3)) return true; | 5694 if (r1.is(r3)) return true; |
5648 if (r1.is(r4)) return true; | 5695 if (r1.is(r4)) return true; |
5649 if (r2.is(r3)) return true; | 5696 if (r2.is(r3)) return true; |
5650 if (r2.is(r4)) return true; | 5697 if (r2.is(r4)) return true; |
5651 if (r3.is(r4)) return true; | 5698 if (r3.is(r4)) return true; |
5652 return false; | 5699 return false; |
5653 } | 5700 } |
5654 | 5701 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5702 opcode == BGTZL); | 5749 opcode == BGTZL); |
5703 opcode = (cond == eq) ? BEQ : BNE; | 5750 opcode = (cond == eq) ? BEQ : BNE; |
5704 instr = (instr & ~kOpcodeMask) | opcode; | 5751 instr = (instr & ~kOpcodeMask) | opcode; |
5705 masm_.emit(instr); | 5752 masm_.emit(instr); |
5706 } | 5753 } |
5707 | 5754 |
5708 | 5755 |
5709 } } // namespace v8::internal | 5756 } } // namespace v8::internal |
5710 | 5757 |
5711 #endif // V8_TARGET_ARCH_MIPS | 5758 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |