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 22f31fe68750246061f9263fed33deac50138461..6a03fc43cf63edd5d0d1620a967ce01888a8f884 100644 |
--- a/src/compiler/ia32/code-generator-ia32.cc |
+++ b/src/compiler/ia32/code-generator-ia32.cc |
@@ -197,10 +197,9 @@ class OutOfLineLoadInteger final : public OutOfLineCode { |
Register const result_; |
}; |
- |
-class OutOfLineLoadFloat final : public OutOfLineCode { |
+class OutOfLineLoadNaN final : public OutOfLineCode { |
public: |
- OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result) |
+ OutOfLineLoadNaN(CodeGenerator* gen, XMMRegister result) |
: OutOfLineCode(gen), result_(result) {} |
void Generate() final { __ pcmpeqd(result_, result_); } |
@@ -271,23 +270,21 @@ class OutOfLineRecordWrite final : public OutOfLineCode { |
} // namespace |
- |
-#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ |
- do { \ |
- auto result = i.OutputDoubleRegister(); \ |
- auto offset = i.InputRegister(0); \ |
- if (instr->InputAt(1)->IsRegister()) { \ |
- __ cmp(offset, i.InputRegister(1)); \ |
- } else { \ |
- __ cmp(offset, i.InputImmediate(1)); \ |
- } \ |
- OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \ |
- __ j(above_equal, ool->entry()); \ |
- __ asm_instr(result, i.MemoryOperand(2)); \ |
- __ bind(ool->exit()); \ |
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ |
+ do { \ |
+ auto result = i.OutputDoubleRegister(); \ |
+ auto offset = i.InputRegister(0); \ |
+ if (instr->InputAt(1)->IsRegister()) { \ |
+ __ cmp(offset, i.InputRegister(1)); \ |
+ } else { \ |
+ __ cmp(offset, i.InputImmediate(1)); \ |
+ } \ |
+ OutOfLineCode* ool = new (zone()) OutOfLineLoadNaN(this, result); \ |
+ __ j(above_equal, ool->entry()); \ |
+ __ asm_instr(result, i.MemoryOperand(2)); \ |
+ __ bind(ool->exit()); \ |
} while (false) |
- |
#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
do { \ |
auto result = i.OutputRegister(); \ |
@@ -990,12 +987,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
// when there is a (v)mulss depending on the result. |
__ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); |
break; |
- case kSSEFloat32Max: |
- __ maxss(i.InputDoubleRegister(0), i.InputOperand(1)); |
- break; |
- case kSSEFloat32Min: |
- __ minss(i.InputDoubleRegister(0), i.InputOperand(1)); |
- break; |
case kSSEFloat32Sqrt: |
__ sqrtss(i.OutputDoubleRegister(), i.InputOperand(0)); |
break; |
@@ -1038,12 +1029,59 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
// when there is a (v)mulsd depending on the result. |
__ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); |
break; |
- case kSSEFloat64Max: |
- __ maxsd(i.InputDoubleRegister(0), i.InputOperand(1)); |
+ case kSSEFloat64Max: { |
+ Label compare_nan, compare_swap, done_compare; |
+ if (instr->InputAt(1)->IsFPRegister()) { |
+ __ ucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); |
+ } else { |
+ __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); |
+ } |
+ auto ool = new (zone()) OutOfLineLoadNaN(this, i.OutputDoubleRegister()); |
+ __ j(parity_even, ool->entry()); |
+ __ j(above, &done_compare, Label::kNear); |
+ __ j(below, &compare_swap, Label::kNear); |
+ __ movmskpd(i.TempRegister(0), i.InputDoubleRegister(0)); |
+ __ test(i.TempRegister(0), Immediate(1)); |
+ __ j(zero, &done_compare, Label::kNear); |
+ __ bind(&compare_swap); |
+ if (instr->InputAt(1)->IsFPRegister()) { |
+ __ movsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); |
+ } else { |
+ __ movsd(i.InputDoubleRegister(0), i.InputOperand(1)); |
+ } |
+ __ bind(&done_compare); |
+ __ bind(ool->exit()); |
break; |
- case kSSEFloat64Min: |
- __ minsd(i.InputDoubleRegister(0), i.InputOperand(1)); |
+ } |
+ case kSSEFloat64Min: { |
+ Label compare_swap, done_compare; |
+ if (instr->InputAt(1)->IsFPRegister()) { |
+ __ ucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); |
+ } else { |
+ __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); |
+ } |
+ auto ool = new (zone()) OutOfLineLoadNaN(this, i.OutputDoubleRegister()); |
+ __ j(parity_even, ool->entry()); |
+ __ j(below, &done_compare, Label::kNear); |
+ __ j(above, &compare_swap, Label::kNear); |
+ if (instr->InputAt(1)->IsFPRegister()) { |
+ __ movmskpd(i.TempRegister(0), i.InputDoubleRegister(1)); |
+ } else { |
+ __ movsd(kScratchDoubleReg, i.InputOperand(1)); |
+ __ movmskpd(i.TempRegister(0), kScratchDoubleReg); |
+ } |
+ __ test(i.TempRegister(0), Immediate(1)); |
+ __ j(zero, &done_compare, Label::kNear); |
+ __ bind(&compare_swap); |
+ if (instr->InputAt(1)->IsFPRegister()) { |
+ __ movsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); |
+ } else { |
+ __ movsd(i.InputDoubleRegister(0), i.InputOperand(1)); |
+ } |
+ __ bind(&done_compare); |
+ __ bind(ool->exit()); |
break; |
+ } |
case kSSEFloat64Mod: { |
// TODO(dcarney): alignment is wrong. |
__ sub(esp, Immediate(kDoubleSize)); |
@@ -1190,18 +1228,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
__ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); |
break; |
} |
- case kAVXFloat32Max: { |
- CpuFeatureScope avx_scope(masm(), AVX); |
- __ vmaxss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
- i.InputOperand(1)); |
- break; |
- } |
- case kAVXFloat32Min: { |
- CpuFeatureScope avx_scope(masm(), AVX); |
- __ vminss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
- i.InputOperand(1)); |
- break; |
- } |
case kAVXFloat64Add: { |
CpuFeatureScope avx_scope(masm(), AVX); |
__ vaddsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
@@ -1229,18 +1255,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
__ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); |
break; |
} |
- case kAVXFloat64Max: { |
- CpuFeatureScope avx_scope(masm(), AVX); |
- __ vmaxsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
- i.InputOperand(1)); |
- break; |
- } |
- case kAVXFloat64Min: { |
- CpuFeatureScope avx_scope(masm(), AVX); |
- __ vminsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
- i.InputOperand(1)); |
- break; |
- } |
case kAVXFloat32Abs: { |
// TODO(bmeurer): Use RIP relative 128-bit constants. |
__ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); |