Commiting changelist issue 348039 outside the codereview tool. Add comparisons to fast compiler
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3200 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
1affb78938
commit
84542872f6
@ -1110,4 +1110,169 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
ASSERT_EQ(Expression::kValue, expr->left()->context());
|
||||
ASSERT_EQ(Expression::kValue, expr->right()->context());
|
||||
Visit(expr->left());
|
||||
Visit(expr->right());
|
||||
|
||||
// Convert current context to test context: Pre-test code.
|
||||
Label push_true;
|
||||
Label push_false;
|
||||
Label done;
|
||||
Label* saved_true = true_label_;
|
||||
Label* saved_false = false_label_;
|
||||
switch (expr->context()) {
|
||||
case Expression::kUninitialized:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
case Expression::kValue:
|
||||
true_label_ = &push_true;
|
||||
false_label_ = &push_false;
|
||||
break;
|
||||
|
||||
case Expression::kEffect:
|
||||
true_label_ = &done;
|
||||
false_label_ = &done;
|
||||
break;
|
||||
|
||||
case Expression::kTest:
|
||||
break;
|
||||
|
||||
case Expression::kValueTest:
|
||||
true_label_ = &push_true;
|
||||
break;
|
||||
|
||||
case Expression::kTestValue:
|
||||
false_label_ = &push_false;
|
||||
break;
|
||||
}
|
||||
// Convert current context to test context: End pre-test code.
|
||||
|
||||
switch (expr->op()) {
|
||||
case Token::IN: {
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_JS);
|
||||
__ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
||||
__ cmp(r0, ip);
|
||||
__ b(eq, true_label_);
|
||||
__ jmp(false_label_);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::INSTANCEOF: {
|
||||
InstanceofStub stub;
|
||||
__ CallStub(&stub);
|
||||
__ tst(r0, r0);
|
||||
__ b(eq, true_label_); // The stub returns 0 for true.
|
||||
__ jmp(false_label_);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Condition cc = eq;
|
||||
bool strict = false;
|
||||
switch (expr->op()) {
|
||||
case Token::EQ_STRICT:
|
||||
strict = true;
|
||||
// Fall through
|
||||
case Token::EQ:
|
||||
cc = eq;
|
||||
__ pop(r0);
|
||||
__ pop(r1);
|
||||
break;
|
||||
case Token::LT:
|
||||
cc = lt;
|
||||
__ pop(r0);
|
||||
__ pop(r1);
|
||||
break;
|
||||
case Token::GT:
|
||||
// Reverse left and right sizes to obtain ECMA-262 conversion order.
|
||||
cc = lt;
|
||||
__ pop(r1);
|
||||
__ pop(r0);
|
||||
break;
|
||||
case Token::LTE:
|
||||
// Reverse left and right sizes to obtain ECMA-262 conversion order.
|
||||
cc = ge;
|
||||
__ pop(r1);
|
||||
__ pop(r0);
|
||||
break;
|
||||
case Token::GTE:
|
||||
cc = ge;
|
||||
__ pop(r0);
|
||||
__ pop(r1);
|
||||
break;
|
||||
case Token::IN:
|
||||
case Token::INSTANCEOF:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// The comparison stub expects the smi vs. smi case to be handled
|
||||
// before it is called.
|
||||
Label slow_case;
|
||||
__ orr(r2, r0, Operand(r1));
|
||||
__ tst(r2, Operand(kSmiTagMask));
|
||||
__ b(ne, &slow_case);
|
||||
__ cmp(r1, r0);
|
||||
__ b(cc, true_label_);
|
||||
__ jmp(false_label_);
|
||||
|
||||
__ bind(&slow_case);
|
||||
CompareStub stub(cc, strict);
|
||||
__ CallStub(&stub);
|
||||
__ tst(r0, r0);
|
||||
__ b(cc, true_label_);
|
||||
__ jmp(false_label_);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert current context to test context: Post-test code.
|
||||
switch (expr->context()) {
|
||||
case Expression::kUninitialized:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
case Expression::kValue:
|
||||
__ bind(&push_true);
|
||||
__ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
||||
__ push(ip);
|
||||
__ jmp(&done);
|
||||
__ bind(&push_false);
|
||||
__ LoadRoot(ip, Heap::kFalseValueRootIndex);
|
||||
__ push(ip);
|
||||
__ bind(&done);
|
||||
break;
|
||||
|
||||
case Expression::kEffect:
|
||||
__ bind(&done);
|
||||
break;
|
||||
|
||||
case Expression::kTest:
|
||||
break;
|
||||
|
||||
case Expression::kValueTest:
|
||||
__ bind(&push_true);
|
||||
__ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
||||
__ push(ip);
|
||||
__ jmp(saved_true);
|
||||
break;
|
||||
|
||||
case Expression::kTestValue:
|
||||
__ bind(&push_false);
|
||||
__ LoadRoot(ip, Heap::kFalseValueRootIndex);
|
||||
__ push(ip);
|
||||
__ jmp(saved_false);
|
||||
break;
|
||||
}
|
||||
true_label_ = saved_true;
|
||||
false_label_ = saved_false;
|
||||
// Convert current context to test context: End post-test code.
|
||||
}
|
||||
|
||||
|
||||
#undef __
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -969,7 +969,9 @@ void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
|
||||
|
||||
void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) {
|
||||
BAILOUT("CompareOperation");
|
||||
ProcessExpression(expr->left(), Expression::kValue);
|
||||
CHECK_BAILOUT;
|
||||
ProcessExpression(expr->right(), Expression::kValue);
|
||||
}
|
||||
|
||||
|
||||
|
@ -501,11 +501,6 @@ void FastCodeGenerator::VisitThrow(Throw* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1124,6 +1124,164 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
ASSERT_EQ(Expression::kValue, expr->left()->context());
|
||||
ASSERT_EQ(Expression::kValue, expr->right()->context());
|
||||
Visit(expr->left());
|
||||
Visit(expr->right());
|
||||
|
||||
// Convert current context to test context: Pre-test code.
|
||||
Label push_true;
|
||||
Label push_false;
|
||||
Label done;
|
||||
Label* saved_true = true_label_;
|
||||
Label* saved_false = false_label_;
|
||||
switch (expr->context()) {
|
||||
case Expression::kUninitialized:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
case Expression::kValue:
|
||||
true_label_ = &push_true;
|
||||
false_label_ = &push_false;
|
||||
break;
|
||||
|
||||
case Expression::kEffect:
|
||||
true_label_ = &done;
|
||||
false_label_ = &done;
|
||||
break;
|
||||
|
||||
case Expression::kTest:
|
||||
break;
|
||||
|
||||
case Expression::kValueTest:
|
||||
true_label_ = &push_true;
|
||||
break;
|
||||
|
||||
case Expression::kTestValue:
|
||||
false_label_ = &push_false;
|
||||
break;
|
||||
}
|
||||
// Convert current context to test context: End pre-test code.
|
||||
|
||||
switch (expr->op()) {
|
||||
case Token::IN: {
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ cmp(eax, Factory::true_value());
|
||||
__ j(equal, true_label_);
|
||||
__ jmp(false_label_);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::INSTANCEOF: {
|
||||
InstanceofStub stub;
|
||||
__ CallStub(&stub);
|
||||
__ test(eax, Operand(eax));
|
||||
__ j(zero, true_label_); // The stub returns 0 for true.
|
||||
__ jmp(false_label_);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Condition cc = no_condition;
|
||||
bool strict = false;
|
||||
switch (expr->op()) {
|
||||
case Token::EQ_STRICT:
|
||||
strict = true;
|
||||
// Fall through
|
||||
case Token::EQ:
|
||||
cc = equal;
|
||||
__ pop(eax);
|
||||
__ pop(edx);
|
||||
break;
|
||||
case Token::LT:
|
||||
cc = less;
|
||||
__ pop(eax);
|
||||
__ pop(edx);
|
||||
break;
|
||||
case Token::GT:
|
||||
// Reverse left and right sizes to obtain ECMA-262 conversion order.
|
||||
cc = less;
|
||||
__ pop(edx);
|
||||
__ pop(eax);
|
||||
break;
|
||||
case Token::LTE:
|
||||
// Reverse left and right sizes to obtain ECMA-262 conversion order.
|
||||
cc = greater_equal;
|
||||
__ pop(edx);
|
||||
__ pop(eax);
|
||||
break;
|
||||
case Token::GTE:
|
||||
cc = greater_equal;
|
||||
__ pop(eax);
|
||||
__ pop(edx);
|
||||
break;
|
||||
case Token::IN:
|
||||
case Token::INSTANCEOF:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// The comparison stub expects the smi vs. smi case to be handled
|
||||
// before it is called.
|
||||
Label slow_case;
|
||||
__ mov(ecx, Operand(edx));
|
||||
__ or_(ecx, Operand(eax));
|
||||
__ test(ecx, Immediate(kSmiTagMask));
|
||||
__ j(not_zero, &slow_case, not_taken);
|
||||
__ cmp(edx, Operand(eax));
|
||||
__ j(cc, true_label_);
|
||||
__ jmp(false_label_);
|
||||
|
||||
__ bind(&slow_case);
|
||||
CompareStub stub(cc, strict);
|
||||
__ CallStub(&stub);
|
||||
__ test(eax, Operand(eax));
|
||||
__ j(cc, true_label_);
|
||||
__ jmp(false_label_);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert current context to test context: Post-test code.
|
||||
switch (expr->context()) {
|
||||
case Expression::kUninitialized:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
case Expression::kValue:
|
||||
__ bind(&push_true);
|
||||
__ push(Immediate(Factory::true_value()));
|
||||
__ jmp(&done);
|
||||
__ bind(&push_false);
|
||||
__ push(Immediate(Factory::false_value()));
|
||||
__ bind(&done);
|
||||
break;
|
||||
|
||||
case Expression::kEffect:
|
||||
__ bind(&done);
|
||||
break;
|
||||
|
||||
case Expression::kTest:
|
||||
break;
|
||||
|
||||
case Expression::kValueTest:
|
||||
__ bind(&push_true);
|
||||
__ push(Immediate(Factory::true_value()));
|
||||
__ jmp(saved_true);
|
||||
break;
|
||||
|
||||
case Expression::kTestValue:
|
||||
__ bind(&push_false);
|
||||
__ push(Immediate(Factory::false_value()));
|
||||
__ jmp(saved_false);
|
||||
break;
|
||||
}
|
||||
true_label_ = saved_true;
|
||||
false_label_ = saved_false;
|
||||
// Convert current context to test context: End post-test code.
|
||||
}
|
||||
|
||||
|
||||
#undef __
|
||||
|
||||
|
||||
|
@ -6580,11 +6580,11 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
|
||||
__ jmp(&loop);
|
||||
|
||||
__ bind(&is_instance);
|
||||
__ xor_(rax, rax);
|
||||
__ xorl(rax, rax);
|
||||
__ ret(2 * kPointerSize);
|
||||
|
||||
__ bind(&is_not_instance);
|
||||
__ Move(rax, Smi::FromInt(1));
|
||||
__ movl(rax, Immediate(1));
|
||||
__ ret(2 * kPointerSize);
|
||||
|
||||
// Slow-case: Go through the JavaScript implementation.
|
||||
|
@ -1138,4 +1138,162 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
ASSERT_EQ(Expression::kValue, expr->left()->context());
|
||||
ASSERT_EQ(Expression::kValue, expr->right()->context());
|
||||
Visit(expr->left());
|
||||
Visit(expr->right());
|
||||
|
||||
// Convert current context to test context: Pre-test code.
|
||||
Label push_true;
|
||||
Label push_false;
|
||||
Label done;
|
||||
Label* saved_true = true_label_;
|
||||
Label* saved_false = false_label_;
|
||||
switch (expr->context()) {
|
||||
case Expression::kUninitialized:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
case Expression::kValue:
|
||||
true_label_ = &push_true;
|
||||
false_label_ = &push_false;
|
||||
break;
|
||||
|
||||
case Expression::kEffect:
|
||||
true_label_ = &done;
|
||||
false_label_ = &done;
|
||||
break;
|
||||
|
||||
case Expression::kTest:
|
||||
break;
|
||||
|
||||
case Expression::kValueTest:
|
||||
true_label_ = &push_true;
|
||||
break;
|
||||
|
||||
case Expression::kTestValue:
|
||||
false_label_ = &push_false;
|
||||
break;
|
||||
}
|
||||
// Convert current context to test context: End pre-test code.
|
||||
|
||||
switch (expr->op()) {
|
||||
case Token::IN: {
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ CompareRoot(rax, Heap::kTrueValueRootIndex);
|
||||
__ j(equal, true_label_);
|
||||
__ jmp(false_label_);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::INSTANCEOF: {
|
||||
InstanceofStub stub;
|
||||
__ CallStub(&stub);
|
||||
__ testq(rax, rax);
|
||||
__ j(zero, true_label_); // The stub returns 0 for true.
|
||||
__ jmp(false_label_);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Condition cc = no_condition;
|
||||
bool strict = false;
|
||||
switch (expr->op()) {
|
||||
case Token::EQ_STRICT:
|
||||
strict = true;
|
||||
// Fall through
|
||||
case Token::EQ:
|
||||
cc = equal;
|
||||
__ pop(rax);
|
||||
__ pop(rdx);
|
||||
break;
|
||||
case Token::LT:
|
||||
cc = less;
|
||||
__ pop(rax);
|
||||
__ pop(rdx);
|
||||
break;
|
||||
case Token::GT:
|
||||
// Reverse left and right sizes to obtain ECMA-262 conversion order.
|
||||
cc = less;
|
||||
__ pop(rdx);
|
||||
__ pop(rax);
|
||||
break;
|
||||
case Token::LTE:
|
||||
// Reverse left and right sizes to obtain ECMA-262 conversion order.
|
||||
cc = greater_equal;
|
||||
__ pop(rdx);
|
||||
__ pop(rax);
|
||||
break;
|
||||
case Token::GTE:
|
||||
cc = greater_equal;
|
||||
__ pop(rax);
|
||||
__ pop(rdx);
|
||||
break;
|
||||
case Token::IN:
|
||||
case Token::INSTANCEOF:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// The comparison stub expects the smi vs. smi case to be handled
|
||||
// before it is called.
|
||||
Label slow_case;
|
||||
__ JumpIfNotBothSmi(rax, rdx, &slow_case);
|
||||
__ SmiCompare(rdx, rax);
|
||||
__ j(cc, true_label_);
|
||||
__ jmp(false_label_);
|
||||
|
||||
__ bind(&slow_case);
|
||||
CompareStub stub(cc, strict);
|
||||
__ CallStub(&stub);
|
||||
__ testq(rax, rax);
|
||||
__ j(cc, true_label_);
|
||||
__ jmp(false_label_);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert current context to test context: Post-test code.
|
||||
switch (expr->context()) {
|
||||
case Expression::kUninitialized:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
case Expression::kValue:
|
||||
__ bind(&push_true);
|
||||
__ PushRoot(Heap::kTrueValueRootIndex);
|
||||
__ jmp(&done);
|
||||
__ bind(&push_false);
|
||||
__ PushRoot(Heap::kFalseValueRootIndex);
|
||||
__ bind(&done);
|
||||
break;
|
||||
|
||||
case Expression::kEffect:
|
||||
__ bind(&done);
|
||||
break;
|
||||
|
||||
case Expression::kTest:
|
||||
break;
|
||||
|
||||
case Expression::kValueTest:
|
||||
__ bind(&push_true);
|
||||
__ PushRoot(Heap::kTrueValueRootIndex);
|
||||
__ jmp(saved_true);
|
||||
break;
|
||||
|
||||
case Expression::kTestValue:
|
||||
__ bind(&push_false);
|
||||
__ PushRoot(Heap::kFalseValueRootIndex);
|
||||
__ jmp(saved_false);
|
||||
break;
|
||||
}
|
||||
true_label_ = saved_true;
|
||||
false_label_ = saved_false;
|
||||
// Convert current context to test context: End post-test code.
|
||||
}
|
||||
|
||||
|
||||
#undef __
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
Loading…
Reference in New Issue
Block a user