Revision: 3200 Author: [email protected] Date: Mon Nov 2 07:01:06 2009 Log: Commiting changelist issue 348039 outside the codereview tool. Add comparisons to fast compiler
http://code.google.com/p/v8/source/detail?r=3200 Modified: /branches/bleeding_edge/src/arm/fast-codegen-arm.cc /branches/bleeding_edge/src/compiler.cc /branches/bleeding_edge/src/fast-codegen.cc /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc /branches/bleeding_edge/src/x64/codegen-x64.cc /branches/bleeding_edge/src/x64/fast-codegen-x64.cc ======================================= --- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Mon Nov 2 05:30:24 2009 +++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Mon Nov 2 07:01:06 2009 @@ -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 ======================================= --- /branches/bleeding_edge/src/compiler.cc Mon Nov 2 06:12:48 2009 +++ /branches/bleeding_edge/src/compiler.cc Mon Nov 2 07:01:06 2009 @@ -969,7 +969,9 @@ void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) { - BAILOUT("CompareOperation"); + ProcessExpression(expr->left(), Expression::kValue); + CHECK_BAILOUT; + ProcessExpression(expr->right(), Expression::kValue); } ======================================= --- /branches/bleeding_edge/src/fast-codegen.cc Mon Nov 2 06:12:48 2009 +++ /branches/bleeding_edge/src/fast-codegen.cc Mon Nov 2 07:01:06 2009 @@ -499,11 +499,6 @@ void FastCodeGenerator::VisitThrow(Throw* expr) { UNREACHABLE(); } - - -void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { - UNREACHABLE(); -} void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { ======================================= --- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Mon Nov 2 05:30:24 2009 +++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Mon Nov 2 07:01:06 2009 @@ -1122,6 +1122,164 @@ UNREACHABLE(); } } + + +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 __ ======================================= --- /branches/bleeding_edge/src/x64/codegen-x64.cc Fri Oct 30 03:22:31 2009 +++ /branches/bleeding_edge/src/x64/codegen-x64.cc Mon Nov 2 07:01:06 2009 @@ -6580,11 +6580,11 @@ __ 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. ======================================= --- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Mon Nov 2 05:30:24 2009 +++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Mon Nov 2 07:01:06 2009 @@ -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 --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
