Chromium Code Reviews| Index: src/x64/macro-assembler-x64.cc |
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
| index 0c605d826dd1f80fa4db3dec59fed95477c350c2..70f30aa78137a11a2af404f21d59d427fa559b30 100644 |
| --- a/src/x64/macro-assembler-x64.cc |
| +++ b/src/x64/macro-assembler-x64.cc |
| @@ -2992,6 +2992,117 @@ void MacroAssembler::LoadUint32(XMMRegister dst, |
| } |
| +void MacroAssembler::SlowTruncateToI(Register result_reg, |
| + Register input_reg, |
| + int offset) { |
| + DoubleToIStub stub(input_reg, result_reg, offset, true); |
| + call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); |
| +} |
| + |
| + |
| +void MacroAssembler::TruncateHeapNumberToI(Register result_reg, |
| + Register input_reg) { |
| + Label done; |
| + movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| + cvttsd2siq(result_reg, xmm0); |
| + Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); |
| + cmpq(result_reg, kScratchRegister); |
| + j(not_equal, &done, Label::kNear); |
| + |
| + // Slow case. |
| + if (input_reg.is(result_reg)) { |
| + subq(rsp, Immediate(kDoubleSize)); |
| + movsd(MemOperand(rsp, 0), xmm0); |
| + SlowTruncateToI(result_reg, rsp, 0); |
| + addq(rsp, Immediate(kDoubleSize)); |
| + } else { |
| + SlowTruncateToI(result_reg, input_reg); |
| + } |
| + |
| + bind(&done); |
| +} |
| + |
| + |
| +void MacroAssembler::TruncateDoubleToI(Register result_reg, |
| + XMMRegister input_reg) { |
| + Label done; |
| + cvttsd2siq(result_reg, input_reg); |
| + movq(kScratchRegister, |
| + V8_INT64_C(0x8000000000000000), |
| + RelocInfo::NONE64); |
| + cmpq(result_reg, kScratchRegister); |
| + j(not_equal, &done, Label::kNear); |
| + |
| + subq(rsp, Immediate(kDoubleSize)); |
| + movsd(MemOperand(rsp, 0), input_reg); |
| + SlowTruncateToI(result_reg, rsp, 0); |
| + addq(rsp, Immediate(kDoubleSize)); |
| + |
| + bind(&done); |
| +} |
| + |
| + |
| +void MacroAssembler::DoubleToI(Register result_reg, |
| + XMMRegister input_reg, |
| + XMMRegister scratch, |
| + MinusZeroMode minus_zero_mode, |
| + Label* conversion_failed, |
| + Label::Distance dst) { |
| + cvttsd2si(result_reg, input_reg); |
| + cvtlsi2sd(xmm0, result_reg); |
| + ucomisd(xmm0, input_reg); |
| + j(not_equal, conversion_failed, dst); |
| + j(parity_even, conversion_failed, dst); // NaN. |
| + if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { |
| + Label done; |
| + // The integer converted back is equal to the original. We |
| + // only have to test if we got -0 as an input. |
| + testl(result_reg, result_reg); |
| + j(not_zero, &done, Label::kNear); |
| + movmskpd(result_reg, input_reg); |
| + // Bit 0 contains the sign of the double in input_reg. |
| + // If input was positive, we are ok and return 0, otherwise |
|
titzer
2013/09/05 14:03:37
"otherwise deoptimize" -> "otherwise goto conversi
oliv
2013/09/05 16:01:51
Done.
|
| + // deoptimize. |
| + andl(result_reg, Immediate(1)); |
| + j(not_zero, conversion_failed, dst); |
| + bind(&done); |
| + } |
| +} |
| + |
| + |
| +void MacroAssembler::TaggedToI(Register result_reg, |
| + Register input_reg, |
| + XMMRegister temp, |
| + MinusZeroMode minus_zero_mode, |
| + Label* lost_precision, |
| + Label::Distance dst) { |
| + Label done; |
| + ASSERT(!temp.is(xmm0)); |
| + |
| + // Heap number map check. |
| + CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
| + Heap::kHeapNumberMapRootIndex); |
| + j(not_equal, lost_precision, dst); |
| + |
| + movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| + cvttsd2si(result_reg, xmm0); |
| + cvtlsi2sd(temp, result_reg); |
| + ucomisd(xmm0, temp); |
| + RecordComment("Deferred TaggedToI: lost precision"); |
| + j(not_equal, lost_precision, dst); |
| + RecordComment("Deferred TaggedToI: NaN"); |
| + j(parity_even, lost_precision, dst); // NaN. |
| + if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { |
| + testl(result_reg, result_reg); |
| + j(not_zero, &done, Label::kNear); |
| + movmskpd(result_reg, xmm0); |
| + andl(result_reg, Immediate(1)); |
| + j(not_zero, lost_precision, dst); |
| + } |
| + bind(&done); |
| +} |
| + |
| + |
| void MacroAssembler::LoadInstanceDescriptors(Register map, |
| Register descriptors) { |
| movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); |