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