| Index: src/compiler/ia32/code-generator-ia32.cc
|
| diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc
|
| index 1d29372115d31c89dc482af74b297adbbf9776bc..19a76e075f5d077cbc2a0cde0cb129006b82fc61 100644
|
| --- a/src/compiler/ia32/code-generator-ia32.cc
|
| +++ b/src/compiler/ia32/code-generator-ia32.cc
|
| @@ -18,6 +18,9 @@ namespace compiler {
|
| #define __ masm()->
|
|
|
|
|
| +#define kScratchDoubleReg xmm0
|
| +
|
| +
|
| // Adds IA-32 specific methods for decoding operands.
|
| class IA32OperandConverter : public InstructionOperandConverter {
|
| public:
|
| @@ -474,6 +477,14 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| case kSSEFloat32Sqrt:
|
| __ sqrtss(i.OutputDoubleRegister(), i.InputOperand(0));
|
| break;
|
| + case kSSEFloat32Neg: {
|
| + // TODO(bmeurer): Use 128-bit constants.
|
| + // TODO(turbofan): Add AVX version with relaxed register constraints.
|
| + __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
|
| + __ psllq(kScratchDoubleReg, 31);
|
| + __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg);
|
| + break;
|
| + }
|
| case kSSEFloat64Cmp:
|
| __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
|
| break;
|
| @@ -520,6 +531,14 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| __ add(esp, Immediate(kDoubleSize));
|
| break;
|
| }
|
| + case kSSEFloat64Neg: {
|
| + // TODO(bmeurer): Use 128-bit constants.
|
| + // TODO(turbofan): Add AVX version with relaxed register constraints.
|
| + __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
|
| + __ psllq(kScratchDoubleReg, 63);
|
| + __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
|
| + break;
|
| + }
|
| case kSSEFloat64Sqrt:
|
| __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0));
|
| break;
|
| @@ -540,10 +559,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| __ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
|
| break;
|
| case kSSEFloat64ToUint32: {
|
| - XMMRegister scratch = xmm0;
|
| - __ Move(scratch, -2147483648.0);
|
| - __ addsd(scratch, i.InputOperand(0));
|
| - __ cvttsd2si(i.OutputRegister(), scratch);
|
| + __ Move(kScratchDoubleReg, -2147483648.0);
|
| + __ addsd(kScratchDoubleReg, i.InputOperand(0));
|
| + __ cvttsd2si(i.OutputRegister(), kScratchDoubleReg);
|
| __ add(i.OutputRegister(), Immediate(0x80000000));
|
| break;
|
| }
|
| @@ -1303,10 +1321,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
|
| XMMRegister dst = g.ToDoubleRegister(destination);
|
| __ movsd(dst, src);
|
| } else {
|
| - // We rely on having xmm0 available as a fixed scratch register.
|
| Operand dst = g.ToOperand(destination);
|
| - __ movsd(xmm0, src);
|
| - __ movsd(dst, xmm0);
|
| + __ movsd(kScratchDoubleReg, src);
|
| + __ movsd(dst, kScratchDoubleReg);
|
| }
|
| } else {
|
| UNREACHABLE();
|
| @@ -1336,33 +1353,31 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
|
| __ pop(dst);
|
| __ pop(src);
|
| } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
|
| - // XMM register-register swap. We rely on having xmm0
|
| - // available as a fixed scratch register.
|
| + // XMM register-register swap.
|
| XMMRegister src = g.ToDoubleRegister(source);
|
| XMMRegister dst = g.ToDoubleRegister(destination);
|
| - __ movaps(xmm0, src);
|
| + __ movaps(kScratchDoubleReg, src);
|
| __ movaps(src, dst);
|
| - __ movaps(dst, xmm0);
|
| + __ movaps(dst, kScratchDoubleReg);
|
| } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
|
| - // XMM register-memory swap. We rely on having xmm0
|
| - // available as a fixed scratch register.
|
| + // XMM register-memory swap.
|
| XMMRegister reg = g.ToDoubleRegister(source);
|
| Operand other = g.ToOperand(destination);
|
| - __ movsd(xmm0, other);
|
| + __ movsd(kScratchDoubleReg, other);
|
| __ movsd(other, reg);
|
| - __ movaps(reg, xmm0);
|
| + __ movaps(reg, kScratchDoubleReg);
|
| } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) {
|
| // Double-width memory-to-memory.
|
| Operand src0 = g.ToOperand(source);
|
| Operand src1 = g.HighOperand(source);
|
| Operand dst0 = g.ToOperand(destination);
|
| Operand dst1 = g.HighOperand(destination);
|
| - __ movsd(xmm0, dst0); // Save destination in xmm0.
|
| - __ push(src0); // Then use stack to copy source to destination.
|
| + __ movsd(kScratchDoubleReg, dst0); // Save destination in scratch register.
|
| + __ push(src0); // Then use stack to copy source to destination.
|
| __ pop(dst0);
|
| __ push(src1);
|
| __ pop(dst1);
|
| - __ movsd(src0, xmm0);
|
| + __ movsd(src0, kScratchDoubleReg);
|
| } else {
|
| // No other combinations are possible.
|
| UNREACHABLE();
|
|
|