[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:
parent
edeaa188a6
commit
00f7d1f5f8
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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:
|
||||||
|
@ -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());
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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());
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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*);
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)));
|
||||||
|
@ -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) \
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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());
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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());
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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) \
|
||||||
|
@ -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);
|
||||||
|
@ -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(¬_nan, ne, a2, Operand(t0));
|
|
||||||
__ mov(t0, zero_reg);
|
|
||||||
__ mov(a2, a1);
|
|
||||||
__ bind(¬_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);
|
||||||
|
@ -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(¬_nan, ne, a2, Operand(a4));
|
|
||||||
__ mov(a4, zero_reg);
|
|
||||||
__ mov(a2, a1);
|
|
||||||
__ bind(¬_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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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(""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user