| Index: src/compiler/x64/code-generator-x64.cc
|
| diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc
|
| index 1c80ad85baa8fd6eb5eec196ea8e00fa17f47782..1d253db81db21cebb62ff95c0f7488f4ef46b3f6 100644
|
| --- a/src/compiler/x64/code-generator-x64.cc
|
| +++ b/src/compiler/x64/code-generator-x64.cc
|
| @@ -1027,6 +1027,42 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
|
| }
|
| break;
|
| + case kSSEFloat64ToUint64: {
|
| + // There does not exist a Float64ToUint64 instruction, so we have to use
|
| + // the Float64ToInt64 instruction.
|
| + if (instr->InputAt(0)->IsDoubleRegister()) {
|
| + __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
|
| + } else {
|
| + __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
|
| + }
|
| + // Check if the result of the Float64ToInt64 conversion is positive, we
|
| + // are already done.
|
| + __ testq(i.OutputRegister(), i.OutputRegister());
|
| + Label done;
|
| + __ j(positive, &done);
|
| + // The result of the first conversion was negative, which means that the
|
| + // input value was not within the positive int64 range. We subtract 2^64
|
| + // and convert it again to see if it is within the uint64 range.
|
| + __ Move(kScratchDoubleReg, -9223372036854775808.0);
|
| + if (instr->InputAt(0)->IsDoubleRegister()) {
|
| + __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0));
|
| + } else {
|
| + __ addsd(kScratchDoubleReg, i.InputOperand(0));
|
| + }
|
| + __ Cvttsd2siq(i.OutputRegister(), kScratchDoubleReg);
|
| + __ testq(i.OutputRegister(), i.OutputRegister());
|
| + // The only possible negative value here is 0x80000000000000000, which is
|
| + // used on x64 to indicate an integer overflow.
|
| + __ j(negative, &done);
|
| + // The input value is within uint64 range and the second conversion worked
|
| + // successfully, but we still have to undo the subtraction we did
|
| + // earlier.
|
| + __ movq(kScratchRegister, Immediate(1));
|
| + __ shlq(kScratchRegister, Immediate(63));
|
| + __ orq(i.OutputRegister(), kScratchRegister);
|
| + __ bind(&done);
|
| + break;
|
| + }
|
| case kSSEInt32ToFloat64:
|
| if (instr->InputAt(0)->IsRegister()) {
|
| __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
|
|
|