| Index: src/x64/fast-codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/fast-codegen-x64.cc (revision 3199)
|
| +++ src/x64/fast-codegen-x64.cc (working copy)
|
| @@ -1138,4 +1138,162 @@
|
| }
|
|
|
|
|
| +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
|
|
|