| 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 af8f8e8aa7b167c56371cee42c79469823ed0a5d..85cc9b4bd44c67e51564345bfe3c31e5bedb44e6 100644
|
| --- a/src/compiler/x64/code-generator-x64.cc
|
| +++ b/src/compiler/x64/code-generator-x64.cc
|
| @@ -1057,6 +1057,42 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
|
| }
|
| break;
|
| + case kSSEFloat32ToUint64: {
|
| + // There does not exist a Float32ToUint64 instruction, so we have to use
|
| + // the Float32ToInt64 instruction.
|
| + if (instr->InputAt(0)->IsDoubleRegister()) {
|
| + __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0));
|
| + } else {
|
| + __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0));
|
| + }
|
| + // Check if the result of the Float32ToInt64 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.0f);
|
| + if (instr->InputAt(0)->IsDoubleRegister()) {
|
| + __ addss(kScratchDoubleReg, i.InputDoubleRegister(0));
|
| + } else {
|
| + __ addss(kScratchDoubleReg, i.InputOperand(0));
|
| + }
|
| + __ Cvttss2siq(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 kSSEFloat64ToUint64: {
|
| // There does not exist a Float64ToUint64 instruction, so we have to use
|
| // the Float64ToInt64 instruction.
|
|
|