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