Commit 84542872 authored by whesse@chromium.org's avatar whesse@chromium.org

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
parent 1affb789
...@@ -1110,4 +1110,169 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -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 } } // namespace v8::internal
...@@ -969,7 +969,9 @@ void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -969,7 +969,9 @@ void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
void CodeGenSelector::VisitCompareOperation(CompareOperation* 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) { ...@@ -501,11 +501,6 @@ void FastCodeGenerator::VisitThrow(Throw* expr) {
} }
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
UNREACHABLE();
}
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -1124,6 +1124,164 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -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 __ #undef __
......
...@@ -6580,11 +6580,11 @@ void InstanceofStub::Generate(MacroAssembler* masm) { ...@@ -6580,11 +6580,11 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ jmp(&loop); __ jmp(&loop);
__ bind(&is_instance); __ bind(&is_instance);
__ xor_(rax, rax); __ xorl(rax, rax);
__ ret(2 * kPointerSize); __ ret(2 * kPointerSize);
__ bind(&is_not_instance); __ bind(&is_not_instance);
__ Move(rax, Smi::FromInt(1)); __ movl(rax, Immediate(1));
__ ret(2 * kPointerSize); __ ret(2 * kPointerSize);
// Slow-case: Go through the JavaScript implementation. // Slow-case: Go through the JavaScript implementation.
......
...@@ -1138,4 +1138,162 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -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 } } // namespace v8::internal
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment