| Index: src/code-stubs.cc
|
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc
|
| index 518022dceb6088c5d610d583f0e035f60412a1ed..9a8e4f91912d24c35ac5795055ac24a6335575e6 100644
|
| --- a/src/code-stubs.cc
|
| +++ b/src/code-stubs.cc
|
| @@ -2342,8 +2342,78 @@
|
| CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* lhs_map,
|
| compiler::Node* rhs, compiler::Node* rhs_map,
|
| CodeStubAssembler::Label* if_equal, CodeStubAssembler::Label* if_notequal) {
|
| - assembler->BranchIfSimd128Equal(lhs, lhs_map, rhs, rhs_map, if_equal,
|
| - if_notequal);
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef compiler::Node Node;
|
| +
|
| + // Check if {lhs} and {rhs} have the same map.
|
| + Label if_mapsame(assembler), if_mapnotsame(assembler);
|
| + assembler->Branch(assembler->WordEqual(lhs_map, rhs_map), &if_mapsame,
|
| + &if_mapnotsame);
|
| +
|
| + assembler->Bind(&if_mapsame);
|
| + {
|
| + // Both {lhs} and {rhs} are Simd128Values with the same map, need special
|
| + // handling for Float32x4 because of NaN comparisons.
|
| + Label if_float32x4(assembler), if_notfloat32x4(assembler);
|
| + Node* float32x4_map =
|
| + assembler->HeapConstant(assembler->factory()->float32x4_map());
|
| + assembler->Branch(assembler->WordEqual(lhs_map, float32x4_map),
|
| + &if_float32x4, &if_notfloat32x4);
|
| +
|
| + assembler->Bind(&if_float32x4);
|
| + {
|
| + // Both {lhs} and {rhs} are Float32x4, compare the lanes individually
|
| + // using a floating point comparison.
|
| + for (int offset = Float32x4::kValueOffset - kHeapObjectTag;
|
| + offset < Float32x4::kSize - kHeapObjectTag;
|
| + offset += sizeof(float)) {
|
| + // Load the floating point values for {lhs} and {rhs}.
|
| + Node* lhs_value = assembler->Load(MachineType::Float32(), lhs,
|
| + assembler->IntPtrConstant(offset));
|
| + Node* rhs_value = assembler->Load(MachineType::Float32(), rhs,
|
| + assembler->IntPtrConstant(offset));
|
| +
|
| + // Perform a floating point comparison.
|
| + Label if_valueequal(assembler), if_valuenotequal(assembler);
|
| + assembler->Branch(assembler->Float32Equal(lhs_value, rhs_value),
|
| + &if_valueequal, &if_valuenotequal);
|
| + assembler->Bind(&if_valuenotequal);
|
| + assembler->Goto(if_notequal);
|
| + assembler->Bind(&if_valueequal);
|
| + }
|
| +
|
| + // All 4 lanes match, {lhs} and {rhs} considered equal.
|
| + assembler->Goto(if_equal);
|
| + }
|
| +
|
| + assembler->Bind(&if_notfloat32x4);
|
| + {
|
| + // For other Simd128Values we just perform a bitwise comparison.
|
| + for (int offset = Simd128Value::kValueOffset - kHeapObjectTag;
|
| + offset < Simd128Value::kSize - kHeapObjectTag;
|
| + offset += kPointerSize) {
|
| + // Load the word values for {lhs} and {rhs}.
|
| + Node* lhs_value = assembler->Load(MachineType::Pointer(), lhs,
|
| + assembler->IntPtrConstant(offset));
|
| + Node* rhs_value = assembler->Load(MachineType::Pointer(), rhs,
|
| + assembler->IntPtrConstant(offset));
|
| +
|
| + // Perform a bitwise word-comparison.
|
| + Label if_valueequal(assembler), if_valuenotequal(assembler);
|
| + assembler->Branch(assembler->WordEqual(lhs_value, rhs_value),
|
| + &if_valueequal, &if_valuenotequal);
|
| + assembler->Bind(&if_valuenotequal);
|
| + assembler->Goto(if_notequal);
|
| + assembler->Bind(&if_valueequal);
|
| + }
|
| +
|
| + // Bitwise comparison succeeded, {lhs} and {rhs} considered equal.
|
| + assembler->Goto(if_equal);
|
| + }
|
| + }
|
| +
|
| + assembler->Bind(&if_mapnotsame);
|
| + assembler->Goto(if_notequal);
|
| }
|
|
|
| // ES6 section 7.2.12 Abstract Equality Comparison
|
|
|