[intrinsics] Kill the %_IsMinusZero intrinsic.

By now only the default %TypedArray%.prototype.sort compare function
and the JS implementation of SameValueZero were still using the odd
%_IsMinusZero intrinsic, whose semantics both included a number check
(actually HeapNumber test) plus testing if the heap number stores the
special -0 value. In both cases we already know that we deal with
number so we can reduce it to a simple number test for -0, which can
be expressed via dividing 1 by that value and checking the sign of
the result. In case of the compare function, we can be even smarter
and work with the reciprocal values in case x and y are equal to 0
(although long term we should probably rewrite the fast case for
the typed array sorting function in C++ anyway, which will be way,
way faster than our handwritten callback-style, type-feedback
polluted JS implementation).

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1680783002

Cr-Commit-Position: refs/heads/master@{#33833}
This commit is contained in:
bmeurer 2016-02-08 22:28:07 -08:00 committed by Commit bot
parent edeaa188a6
commit 00f7d1f5f8
50 changed files with 16 additions and 790 deletions

View File

@ -69,8 +69,6 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceMathSqrt(node); return ReduceMathSqrt(node);
case Runtime::kInlineValueOf: case Runtime::kInlineValueOf:
return ReduceValueOf(node); return ReduceValueOf(node);
case Runtime::kInlineIsMinusZero:
return ReduceIsMinusZero(node);
case Runtime::kInlineFixedArrayGet: case Runtime::kInlineFixedArrayGet:
return ReduceFixedArrayGet(node); return ReduceFixedArrayGet(node);
case Runtime::kInlineFixedArraySet: case Runtime::kInlineFixedArraySet:
@ -338,30 +336,6 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
} }
Reduction JSIntrinsicLowering::ReduceIsMinusZero(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* double_lo =
graph()->NewNode(machine()->Float64ExtractLowWord32(), value);
Node* check1 = graph()->NewNode(machine()->Word32Equal(), double_lo,
jsgraph()->ZeroConstant());
Node* double_hi =
graph()->NewNode(machine()->Float64ExtractHighWord32(), value);
Node* check2 = graph()->NewNode(
machine()->Word32Equal(), double_hi,
jsgraph()->Int32Constant(static_cast<int32_t>(0x80000000)));
ReplaceWithValue(node, node, effect);
Node* and_result = graph()->NewNode(machine()->Word32And(), check1, check2);
return Change(node, machine()->Word32Equal(), and_result,
jsgraph()->Int32Constant(1));
}
Reduction JSIntrinsicLowering::ReduceFixedArrayGet(Node* node) { Reduction JSIntrinsicLowering::ReduceFixedArrayGet(Node* node) {
Node* base = node->InputAt(0); Node* base = node->InputAt(0);
Node* index = node->InputAt(1); Node* index = node->InputAt(1);

View File

@ -44,7 +44,6 @@ class JSIntrinsicLowering final : public AdvancedReducer {
Reduction ReduceDoubleHi(Node* node); Reduction ReduceDoubleHi(Node* node);
Reduction ReduceDoubleLo(Node* node); Reduction ReduceDoubleLo(Node* node);
Reduction ReduceIncrementStatsCounter(Node* node); Reduction ReduceIncrementStatsCounter(Node* node);
Reduction ReduceIsMinusZero(Node* node);
Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type); Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
Reduction ReduceIsJSReceiver(Node* node); Reduction ReduceIsJSReceiver(Node* node);
Reduction ReduceIsSmi(Node* node); Reduction ReduceIsSmi(Node* node);

View File

@ -1564,7 +1564,6 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
case Runtime::kInlineIsArray: case Runtime::kInlineIsArray:
case Runtime::kInlineIsDate: case Runtime::kInlineIsDate:
case Runtime::kInlineIsTypedArray: case Runtime::kInlineIsTypedArray:
case Runtime::kInlineIsMinusZero:
case Runtime::kInlineIsRegExp: case Runtime::kInlineIsRegExp:
return Type::Boolean(); return Type::Boolean();
case Runtime::kInlineDoubleLo: case Runtime::kInlineDoubleLo:

View File

@ -1743,14 +1743,6 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegister(instr->value());
LOperand* scratch = TempRegister();
return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* value = UseRegisterAtStart(instr->value()); LOperand* value = UseRegisterAtStart(instr->value());

View File

@ -47,7 +47,6 @@ class LCodeGen;
V(ClampIToUint8) \ V(ClampIToUint8) \
V(ClampTToUint8) \ V(ClampTToUint8) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
@ -991,22 +990,6 @@ class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
public:
LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LIsStringAndBranch final : public LControlInstruction<1, 1> { class LIsStringAndBranch final : public LControlInstruction<1, 1> {
public: public:
LIsStringAndBranch(LOperand* value, LOperand* temp) { LIsStringAndBranch(LOperand* value, LOperand* temp) {

View File

@ -2313,33 +2313,6 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
Register scratch = ToRegister(instr->temp());
if (rep.IsDouble()) {
DwVfpRegister value = ToDoubleRegister(instr->value());
__ VFPCompareAndSetFlags(value, 0.0);
EmitFalseBranch(instr, ne);
__ VmovHigh(scratch, value);
__ cmp(scratch, Operand(0x80000000));
} else {
Register value = ToRegister(instr->value());
__ CheckMap(value,
scratch,
Heap::kHeapNumberMapRootIndex,
instr->FalseLabel(chunk()),
DO_SMI_CHECK);
__ ldr(scratch, FieldMemOperand(value, HeapNumber::kExponentOffset));
__ ldr(ip, FieldMemOperand(value, HeapNumber::kMantissaOffset));
__ cmp(scratch, Operand(0x80000000));
__ cmp(ip, Operand(0x00000000), eq);
}
EmitBranch(instr, eq);
}
Condition LCodeGen::EmitIsString(Register input, Condition LCodeGen::EmitIsString(Register input,
Register temp1, Register temp1,
Label* is_not_string, Label* is_not_string,

View File

@ -1567,14 +1567,6 @@ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegister(instr->value());
LOperand* scratch = TempRegister();
return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* value = UseRegisterAtStart(instr->value()); LOperand* value = UseRegisterAtStart(instr->value());

View File

@ -55,7 +55,6 @@ class LCodeGen;
V(CmpMapAndBranch) \ V(CmpMapAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpT) \ V(CmpT) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(ConstantD) \ V(ConstantD) \
V(ConstantE) \ V(ConstantE) \
@ -1146,22 +1145,6 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
public:
LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LCompareNumericAndBranch final : public LControlInstruction<2, 0> { class LCompareNumericAndBranch final : public LControlInstruction<2, 0> {
public: public:
LCompareNumericAndBranch(LOperand* left, LOperand* right) { LCompareNumericAndBranch(LOperand* left, LOperand* right) {

View File

@ -2327,24 +2327,6 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
Register scratch = ToRegister(instr->temp());
if (rep.IsDouble()) {
__ JumpIfMinusZero(ToDoubleRegister(instr->value()),
instr->TrueLabel(chunk()));
} else {
Register value = ToRegister(instr->value());
__ JumpIfNotHeapNumber(value, instr->FalseLabel(chunk()), DO_SMI_CHECK);
__ Ldr(scratch, FieldMemOperand(value, HeapNumber::kValueOffset));
__ JumpIfMinusZero(scratch, instr->TrueLabel(chunk()));
}
EmitGoto(instr->FalseDestination(chunk()));
}
void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
LOperand* left = instr->left(); LOperand* left = instr->left();
LOperand* right = instr->right(); LOperand* right = instr->right();

View File

@ -783,7 +783,6 @@ bool HInstruction::CanDeoptimize() {
case HValue::kCompareGeneric: case HValue::kCompareGeneric:
case HValue::kCompareHoleAndBranch: case HValue::kCompareHoleAndBranch:
case HValue::kCompareMap: case HValue::kCompareMap:
case HValue::kCompareMinusZeroAndBranch:
case HValue::kCompareNumericAndBranch: case HValue::kCompareNumericAndBranch:
case HValue::kCompareObjectEqAndBranch: case HValue::kCompareObjectEqAndBranch:
case HValue::kConstant: case HValue::kConstant:
@ -3326,31 +3325,6 @@ bool HCompareNumericAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
} }
bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
if (FLAG_fold_constants && value()->IsConstant()) {
HConstant* constant = HConstant::cast(value());
if (constant->HasDoubleValue()) {
*block = IsMinusZero(constant->DoubleValue())
? FirstSuccessor() : SecondSuccessor();
return true;
}
}
if (value()->representation().IsSmiOrInteger32()) {
// A Smi or Integer32 cannot contain minus zero.
*block = SecondSuccessor();
return true;
}
*block = NULL;
return false;
}
void HCompareMinusZeroAndBranch::InferRepresentation(
HInferRepresentationPhase* h_infer) {
ChangeRepresentation(value()->representation());
}
std::ostream& HGoto::PrintDataTo(std::ostream& os) const { // NOLINT std::ostream& HGoto::PrintDataTo(std::ostream& os) const { // NOLINT
return os << *SuccessorAt(0); return os << *SuccessorAt(0);
} }

View File

@ -79,7 +79,6 @@ class LChunkBuilder;
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CompareHoleAndBranch) \ V(CompareHoleAndBranch) \
V(CompareGeneric) \ V(CompareGeneric) \
V(CompareMinusZeroAndBranch) \
V(CompareObjectEqAndBranch) \ V(CompareObjectEqAndBranch) \
V(CompareMap) \ V(CompareMap) \
V(Constant) \ V(Constant) \
@ -4345,27 +4344,6 @@ class HCompareHoleAndBranch final : public HUnaryControlInstruction {
}; };
class HCompareMinusZeroAndBranch final : public HUnaryControlInstruction {
public:
DECLARE_INSTRUCTION_FACTORY_P1(HCompareMinusZeroAndBranch, HValue*);
void InferRepresentation(HInferRepresentationPhase* h_infer) override;
Representation RequiredInputRepresentation(int index) override {
return representation();
}
bool KnownSuccessorBlock(HBasicBlock** block) override;
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch)
private:
explicit HCompareMinusZeroAndBranch(HValue* value)
: HUnaryControlInstruction(value, NULL, NULL) {
}
};
class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> { class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> {
public: public:
DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*); DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*);

View File

@ -71,12 +71,6 @@ void HRangeAnalysisPhase::Run() {
instr->to().IsSmiOrInteger32()); instr->to().IsSmiOrInteger32());
PropagateMinusZeroChecks(instr->value()); PropagateMinusZeroChecks(instr->value());
} }
} else if (value->IsCompareMinusZeroAndBranch()) {
HCompareMinusZeroAndBranch* instr =
HCompareMinusZeroAndBranch::cast(value);
if (instr->value()->representation().IsSmiOrInteger32()) {
PropagateMinusZeroChecks(instr->value());
}
} }
} }

View File

@ -12232,15 +12232,6 @@ void HOptimizedGraphBuilder::GenerateIsJSReceiver(CallRuntime* call) {
} }
void HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) {
DCHECK(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* value = Pop();
HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value);
return ast_context()->ReturnControl(result, call->id());
}
void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
DCHECK(call->arguments()->length() == 1); DCHECK(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));

View File

@ -2225,7 +2225,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
F(ToNumber) \ F(ToNumber) \
F(IsJSReceiver) \ F(IsJSReceiver) \
F(MathPow) \ F(MathPow) \
F(IsMinusZero) \
F(HasCachedArrayIndex) \ F(HasCachedArrayIndex) \
F(GetCachedArrayIndex) \ F(GetCachedArrayIndex) \
F(FastOneByteArrayJoin) \ F(FastOneByteArrayJoin) \

View File

@ -2217,34 +2217,6 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
Register scratch = ToRegister(instr->temp());
if (rep.IsDouble()) {
XMMRegister value = ToDoubleRegister(instr->value());
XMMRegister xmm_scratch = double_scratch0();
__ xorps(xmm_scratch, xmm_scratch);
__ ucomisd(xmm_scratch, value);
EmitFalseBranch(instr, not_equal);
__ movmskpd(scratch, value);
__ test(scratch, Immediate(1));
EmitBranch(instr, not_zero);
} else {
Register value = ToRegister(instr->value());
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
__ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
__ cmp(FieldOperand(value, HeapNumber::kExponentOffset),
Immediate(0x1));
EmitFalseBranch(instr, no_overflow);
__ cmp(FieldOperand(value, HeapNumber::kMantissaOffset),
Immediate(0x00000000));
EmitBranch(instr, equal);
}
}
Condition LCodeGen::EmitIsString(Register input, Condition LCodeGen::EmitIsString(Register input,
Register temp1, Register temp1,
Label* is_not_string, Label* is_not_string,

View File

@ -1709,14 +1709,6 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegister(instr->value());
LOperand* scratch = TempRegister();
return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* temp = TempRegister(); LOperand* temp = TempRegister();

View File

@ -51,7 +51,6 @@ class LCodeGen;
V(ClampIToUint8) \ V(ClampIToUint8) \
V(ClampTToUint8) \ V(ClampTToUint8) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
@ -974,22 +973,6 @@ class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
public:
LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LIsStringAndBranch final : public LControlInstruction<1, 1> { class LIsStringAndBranch final : public LControlInstruction<1, 1> {
public: public:
LIsStringAndBranch(LOperand* value, LOperand* temp) { LIsStringAndBranch(LOperand* value, LOperand* temp) {

View File

@ -2221,32 +2221,6 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
Register scratch = ToRegister(instr->temp());
if (rep.IsDouble()) {
DoubleRegister value = ToDoubleRegister(instr->value());
EmitFalseBranchF(instr, ne, value, kDoubleRegZero);
__ FmoveHigh(scratch, value);
__ li(at, 0x80000000);
} else {
Register value = ToRegister(instr->value());
__ CheckMap(value,
scratch,
Heap::kHeapNumberMapRootIndex,
instr->FalseLabel(chunk()),
DO_SMI_CHECK);
__ lw(scratch, FieldMemOperand(value, HeapNumber::kExponentOffset));
EmitFalseBranch(instr, ne, scratch, Operand(0x80000000));
__ lw(scratch, FieldMemOperand(value, HeapNumber::kMantissaOffset));
__ mov(at, zero_reg);
}
EmitBranch(instr, eq, scratch, Operand(at));
}
Condition LCodeGen::EmitIsString(Register input, Condition LCodeGen::EmitIsString(Register input,
Register temp1, Register temp1,
Label* is_not_string, Label* is_not_string,

View File

@ -1690,14 +1690,6 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegister(instr->value());
LOperand* scratch = TempRegister();
return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* temp = TempRegister(); LOperand* temp = TempRegister();

View File

@ -47,7 +47,6 @@ class LCodeGen;
V(ClampIToUint8) \ V(ClampIToUint8) \
V(ClampTToUint8) \ V(ClampTToUint8) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
@ -969,22 +968,6 @@ class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
public:
LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LIsStringAndBranch final : public LControlInstruction<1, 1> { class LIsStringAndBranch final : public LControlInstruction<1, 1> {
public: public:
LIsStringAndBranch(LOperand* value, LOperand* temp) { LIsStringAndBranch(LOperand* value, LOperand* temp) {

View File

@ -2338,35 +2338,6 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
Register scratch = ToRegister(instr->temp());
if (rep.IsDouble()) {
DoubleRegister value = ToDoubleRegister(instr->value());
EmitFalseBranchF(instr, ne, value, kDoubleRegZero);
__ FmoveHigh(scratch, value);
// Only use low 32-bits of value.
__ dsll32(scratch, scratch, 0);
__ dsrl32(scratch, scratch, 0);
__ li(at, 0x80000000);
} else {
Register value = ToRegister(instr->value());
__ CheckMap(value,
scratch,
Heap::kHeapNumberMapRootIndex,
instr->FalseLabel(chunk()),
DO_SMI_CHECK);
__ lwu(scratch, FieldMemOperand(value, HeapNumber::kExponentOffset));
EmitFalseBranch(instr, ne, scratch, Operand(0x80000000));
__ lwu(scratch, FieldMemOperand(value, HeapNumber::kMantissaOffset));
__ mov(at, zero_reg);
}
EmitBranch(instr, eq, scratch, Operand(at));
}
Condition LCodeGen::EmitIsString(Register input, Condition LCodeGen::EmitIsString(Register input,
Register temp1, Register temp1,
Label* is_not_string, Label* is_not_string,

View File

@ -1696,14 +1696,6 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegister(instr->value());
LOperand* scratch = TempRegister();
return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* temp = TempRegister(); LOperand* temp = TempRegister();

View File

@ -49,7 +49,6 @@ class LCodeGen;
V(ClampIToUint8) \ V(ClampIToUint8) \
V(ClampTToUint8) \ V(ClampTToUint8) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
@ -987,22 +986,6 @@ class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
public:
LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LIsStringAndBranch final : public LControlInstruction<1, 1> { class LIsStringAndBranch final : public LControlInstruction<1, 1> {
public: public:
LIsStringAndBranch(LOperand* value, LOperand* temp) { LIsStringAndBranch(LOperand* value, LOperand* temp) {

View File

@ -2374,27 +2374,6 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
Register scratch = ToRegister(instr->temp());
if (rep.IsDouble()) {
DoubleRegister value = ToDoubleRegister(instr->value());
__ fcmpu(value, kDoubleRegZero);
EmitFalseBranch(instr, ne);
__ TestDoubleSign(value, scratch);
EmitBranch(instr, lt);
} else {
Register value = ToRegister(instr->value());
__ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex,
instr->FalseLabel(chunk()), DO_SMI_CHECK);
__ TestHeapNumberIsMinusZero(value, scratch, ip);
EmitBranch(instr, eq);
}
}
Condition LCodeGen::EmitIsString(Register input, Register temp1, Condition LCodeGen::EmitIsString(Register input, Register temp1,
Label* is_not_string, Label* is_not_string,
SmiCheck check_needed = INLINE_SMI_CHECK) { SmiCheck check_needed = INLINE_SMI_CHECK) {

View File

@ -1706,14 +1706,6 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegister(instr->value());
LOperand* scratch = TempRegister();
return new (zone()) LCompareMinusZeroAndBranch(value, scratch);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* value = UseRegisterAtStart(instr->value()); LOperand* value = UseRegisterAtStart(instr->value());

View File

@ -47,7 +47,6 @@ class LCodeGen;
V(ClampIToUint8) \ V(ClampIToUint8) \
V(ClampTToUint8) \ V(ClampTToUint8) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
@ -953,22 +952,6 @@ class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
public:
LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LIsStringAndBranch final : public LControlInstruction<1, 1> { class LIsStringAndBranch final : public LControlInstruction<1, 1> {
public: public:
LIsStringAndBranch(LOperand* value, LOperand* temp) { LIsStringAndBranch(LOperand* value, LOperand* temp) {

View File

@ -2283,33 +2283,6 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
if (rep.IsDouble()) {
XMMRegister value = ToDoubleRegister(instr->value());
XMMRegister xmm_scratch = double_scratch0();
__ Xorpd(xmm_scratch, xmm_scratch);
__ Ucomisd(xmm_scratch, value);
EmitFalseBranch(instr, not_equal);
__ Movmskpd(kScratchRegister, value);
__ testl(kScratchRegister, Immediate(1));
EmitBranch(instr, not_zero);
} else {
Register value = ToRegister(instr->value());
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
__ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
__ cmpl(FieldOperand(value, HeapNumber::kExponentOffset),
Immediate(0x1));
EmitFalseBranch(instr, no_overflow);
__ cmpl(FieldOperand(value, HeapNumber::kMantissaOffset),
Immediate(0x00000000));
EmitBranch(instr, equal);
}
}
Condition LCodeGen::EmitIsString(Register input, Condition LCodeGen::EmitIsString(Register input,
Register temp1, Register temp1,
Label* is_not_string, Label* is_not_string,

View File

@ -1702,13 +1702,6 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegister(instr->value());
return new(zone()) LCompareMinusZeroAndBranch(value);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* value = UseRegisterAtStart(instr->value()); LOperand* value = UseRegisterAtStart(instr->value());

View File

@ -47,7 +47,6 @@ class LCodeGen;
V(ClampIToUint8) \ V(ClampIToUint8) \
V(ClampTToUint8) \ V(ClampTToUint8) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
@ -967,20 +966,6 @@ class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 0> {
public:
explicit LCompareMinusZeroAndBranch(LOperand* value) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LIsStringAndBranch final : public LControlInstruction<1, 1> { class LIsStringAndBranch final : public LControlInstruction<1, 1> {
public: public:
explicit LIsStringAndBranch(LOperand* value, LOperand* temp) { explicit LIsStringAndBranch(LOperand* value, LOperand* temp) {

View File

@ -2505,29 +2505,6 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
} }
void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Representation rep = instr->hydrogen()->value()->representation();
DCHECK(!rep.IsInteger32());
if (rep.IsDouble()) {
X87Register input = ToX87Register(instr->value());
X87LoadForUsage(input);
__ FXamMinusZero();
EmitBranch(instr, equal);
} else {
Register value = ToRegister(instr->value());
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
__ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
__ cmp(FieldOperand(value, HeapNumber::kExponentOffset),
Immediate(0x1));
EmitFalseBranch(instr, no_overflow);
__ cmp(FieldOperand(value, HeapNumber::kMantissaOffset),
Immediate(0x00000000));
EmitBranch(instr, equal);
}
}
Condition LCodeGen::EmitIsString(Register input, Condition LCodeGen::EmitIsString(Register input,
Register temp1, Register temp1,
Label* is_not_string, Label* is_not_string,

View File

@ -1715,13 +1715,6 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
} }
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
HCompareMinusZeroAndBranch* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
return new (zone()) LCompareMinusZeroAndBranch(value);
}
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
DCHECK(instr->value()->representation().IsTagged()); DCHECK(instr->value()->representation().IsTagged());
LOperand* temp = TempRegister(); LOperand* temp = TempRegister();

View File

@ -52,7 +52,6 @@ class LCodeGen;
V(ClampTToUint8NoSSE2) \ V(ClampTToUint8NoSSE2) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(ClobberDoubles) \ V(ClobberDoubles) \
V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
@ -990,18 +989,6 @@ class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
}; };
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 0> {
public:
explicit LCompareMinusZeroAndBranch(LOperand* value) { inputs_[0] = value; }
LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
"cmp-minus-zero-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
};
class LIsStringAndBranch final : public LControlInstruction<1, 1> { class LIsStringAndBranch final : public LControlInstruction<1, 1> {
public: public:
LIsStringAndBranch(LOperand* value, LOperand* temp) { LIsStringAndBranch(LOperand* value, LOperand* temp) {

View File

@ -3024,32 +3024,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
__ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
__ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
__ ldr(r1, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
__ cmp(r2, Operand(0x80000000));
__ cmp(r1, Operand(0x00000000), eq);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(eq, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -2833,33 +2833,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
// Only a HeapNumber can be -0.0, so return false if we have something else.
__ JumpIfNotHeapNumber(x0, if_false, DO_SMI_CHECK);
// Test the bit pattern.
__ Ldr(x10, FieldMemOperand(x0, HeapNumber::kValueOffset));
__ Cmp(x10, 1); // Set V on 0x8000000000000000.
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(vs, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -535,7 +535,6 @@ class FullCodeGenerator: public AstVisitor {
F(IsJSReceiver) \ F(IsJSReceiver) \
F(IsSimdValue) \ F(IsSimdValue) \
F(MathPow) \ F(MathPow) \
F(IsMinusZero) \
F(HasCachedArrayIndex) \ F(HasCachedArrayIndex) \
F(GetCachedArrayIndex) \ F(GetCachedArrayIndex) \
F(GetSuperConstructor) \ F(GetSuperConstructor) \

View File

@ -2903,33 +2903,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
__ CheckMap(eax, map, if_false, DO_SMI_CHECK);
// Check if the exponent half is 0x80000000. Comparing against 1 and
// checking for overflow is the shortest possible encoding.
__ cmp(FieldOperand(eax, HeapNumber::kExponentOffset), Immediate(0x1));
__ j(no_overflow, if_false);
__ cmp(FieldOperand(eax, HeapNumber::kMantissaOffset), Immediate(0x0));
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -3010,36 +3010,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
__ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
__ lw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
__ lw(a1, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
__ li(t0, 0x80000000);
Label not_nan;
__ Branch(&not_nan, ne, a2, Operand(t0));
__ mov(t0, zero_reg);
__ mov(a2, a1);
__ bind(&not_nan);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(eq, a2, Operand(t0), if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -3020,36 +3020,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
__ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
__ lwu(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
__ lwu(a1, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
__ li(a4, 0x80000000);
Label not_nan;
__ Branch(&not_nan, ne, a2, Operand(a4));
__ mov(a4, zero_reg);
__ mov(a2, a1);
__ bind(&not_nan);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(eq, a2, Operand(a4), if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -3011,28 +3011,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
&if_false, &fall_through);
__ CheckMap(r3, r4, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
__ TestHeapNumberIsMinusZero(r3, r4, r5);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(eq, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -2889,33 +2889,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
__ CheckMap(rax, map, if_false, DO_SMI_CHECK);
__ cmpl(FieldOperand(rax, HeapNumber::kExponentOffset),
Immediate(0x1));
__ j(no_overflow, if_false);
__ cmpl(FieldOperand(rax, HeapNumber::kMantissaOffset),
Immediate(0x00000000));
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -2903,33 +2903,6 @@ void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
} }
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
__ CheckMap(eax, map, if_false, DO_SMI_CHECK);
// Check if the exponent half is 0x80000000. Comparing against 1 and
// checking for overflow is the shortest possible encoding.
__ cmp(FieldOperand(eax, HeapNumber::kExponentOffset), Immediate(0x1));
__ j(no_overflow, if_false);
__ cmp(FieldOperand(eax, HeapNumber::kMantissaOffset), Immediate(0x0));
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1); DCHECK(args->length() == 1);

View File

@ -43,11 +43,11 @@ utils.ImportFromExperimental(function(from) {
// ES5, section 9.12 // ES5, section 9.12
function SameValue(x, y) { function SameValue(x, y) {
if (typeof x != typeof y) return false; if (typeof x !== typeof y) return false;
if (IS_NUMBER(x)) { if (IS_NUMBER(x)) {
if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
// x is +0 and y is -0 or vice versa. // x is +0 and y is -0 or vice versa.
if (x === 0 && y === 0 && %_IsMinusZero(x) != %_IsMinusZero(y)) { if (x === 0 && y === 0 && 1/x !== 1/y) {
return false; return false;
} }
} }
@ -58,7 +58,7 @@ function SameValue(x, y) {
// ES6, section 7.2.4 // ES6, section 7.2.4
function SameValueZero(x, y) { function SameValueZero(x, y) {
if (typeof x != typeof y) return false; if (typeof x !== typeof y) return false;
if (IS_NUMBER(x)) { if (IS_NUMBER(x)) {
if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
} }

View File

@ -567,22 +567,20 @@ function TypedArrayReverse() {
function TypedArrayComparefn(x, y) { function TypedArrayComparefn(x, y) {
if (IsNaN(x) && IsNaN(y)) { if (x === 0 && x === y) {
return IsNaN(y) ? 0 : 1; x = 1 / x;
y = 1 / y;
} }
if (IsNaN(x)) { if (x < y) {
return -1;
} else if (x > y) {
return 1;
} else if (IsNaN(x) && IsNaN(y)) {
return IsNaN(y) ? 0 : 1;
} else if (IsNaN(x)) {
return 1; return 1;
} }
if (x === 0 && x === y) { return 0;
if (%_IsMinusZero(x)) {
if (!%_IsMinusZero(y)) {
return -1;
}
} else if (%_IsMinusZero(y)) {
return 1;
}
}
return x - y;
} }

View File

@ -2207,25 +2207,6 @@ void MacroAssembler::TestDoubleIsMinusZero(DoubleRegister input,
#endif #endif
} }
void MacroAssembler::TestHeapNumberIsMinusZero(Register input,
Register scratch1,
Register scratch2) {
#if V8_TARGET_ARCH_PPC64
LoadP(scratch1, FieldMemOperand(input, HeapNumber::kValueOffset));
rotldi(scratch1, scratch1, 1);
cmpi(scratch1, Operand(1));
#else
lwz(scratch1, FieldMemOperand(input, HeapNumber::kExponentOffset));
lwz(scratch2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
Label done;
cmpi(scratch2, Operand::Zero());
bne(&done);
lis(scratch2, Operand(SIGN_EXT_IMM16(0x8000)));
cmp(scratch1, scratch2);
bind(&done);
#endif
}
void MacroAssembler::TestDoubleSign(DoubleRegister input, Register scratch) { void MacroAssembler::TestDoubleSign(DoubleRegister input, Register scratch) {
#if V8_TARGET_ARCH_PPC64 #if V8_TARGET_ARCH_PPC64
MovDoubleToInt64(scratch, input); MovDoubleToInt64(scratch, input);

View File

@ -876,8 +876,6 @@ class MacroAssembler : public Assembler {
// CR_EQ in cr7 holds the result. // CR_EQ in cr7 holds the result.
void TestDoubleIsMinusZero(DoubleRegister input, Register scratch1, void TestDoubleIsMinusZero(DoubleRegister input, Register scratch1,
Register scratch2); Register scratch2);
void TestHeapNumberIsMinusZero(Register input, Register scratch1,
Register scratch2);
// Check the sign of a double. // Check the sign of a double.
// CR_LT in cr7 holds the result. // CR_LT in cr7 holds the result.

View File

@ -238,16 +238,6 @@ RUNTIME_FUNCTION(Runtime_MathFround) {
} }
RUNTIME_FUNCTION(Runtime_IsMinusZero) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, obj, 0);
if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
HeapNumber* number = HeapNumber::cast(obj);
return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
}
RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) { RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK(args.length() == 1); DCHECK(args.length() == 1);

View File

@ -388,7 +388,6 @@ namespace internal {
F(RoundNumber, 1, 1) \ F(RoundNumber, 1, 1) \
F(MathSqrt, 1, 1) \ F(MathSqrt, 1, 1) \
F(MathFround, 1, 1) \ F(MathFround, 1, 1) \
F(IsMinusZero, 1, 1) \
F(GenerateRandomNumbers, 1, 1) F(GenerateRandomNumbers, 1, 1)

View File

@ -104,18 +104,6 @@ TEST(IsFunction) {
} }
TEST(IsMinusZero) {
FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
T.CheckFalse(T.Val(1));
T.CheckFalse(T.Val(1.1));
T.CheckTrue(T.Val(-0.0));
T.CheckFalse(T.Val(-2));
T.CheckFalse(T.Val(-2.3));
T.CheckFalse(T.undefined());
}
TEST(IsRegExp) { TEST(IsRegExp) {
FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags); FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);

View File

@ -37,31 +37,8 @@ assertEquals(0, add(0, 0));
assertEquals(-0, add(-0, -0)); assertEquals(-0, add(-0, -0));
function test(x, y) {
assertTrue(%_IsMinusZero(-0));
assertTrue(%_IsMinusZero(1/(-Infinity)));
assertTrue(%_IsMinusZero(x));
assertFalse(%_IsMinusZero(0));
assertFalse(%_IsMinusZero(1/Infinity));
assertFalse(%_IsMinusZero(0.1));
assertFalse(%_IsMinusZero(-0.2));
assertFalse(%_IsMinusZero({}));
assertFalse(%_IsMinusZero(""));
assertFalse(%_IsMinusZero("-0"));
assertFalse(%_IsMinusZero(function() {}));
assertFalse(%_IsMinusZero(y));
}
test(-0, 1.2);
test(-0, 1.2);
%OptimizeFunctionOnNextCall(test);
test(-0, 1.2);
assertOptimized(test);
function testsin() { function testsin() {
assertTrue(%_IsMinusZero(Math.sin(-0))); assertEquals(-0, Math.sin(-0));
} }
testsin(); testsin();
@ -71,8 +48,7 @@ testsin();
function testfloor() { function testfloor() {
assertTrue(%_IsMinusZero(Math.floor(-0))); assertEquals(-0, Math.floor(-0));
assertFalse(%_IsMinusZero(Math.floor(2)));
} }
testfloor(); testfloor();

View File

@ -26,10 +26,6 @@ function test() {
assertTrue(%_IsJSReceiver(new Date())); assertTrue(%_IsJSReceiver(new Date()));
assertFalse(%_IsJSReceiver(1)); assertFalse(%_IsJSReceiver(1));
assertTrue(%_IsMinusZero(-0.0));
assertFalse(%_IsMinusZero(1));
assertFalse(%_IsMinusZero(""));
} }