| 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..78e3e561fc301a67d4eb3ce819013bf1e4b52310 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
|
| + // jump to conversion_failed.
|
| + 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));
|
|
|