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(); |