| Index: src/ia32/full-codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/full-codegen-ia32.cc (revision 5316)
|
| +++ src/ia32/full-codegen-ia32.cc (working copy)
|
| @@ -246,21 +246,8 @@
|
| case Expression::kTest:
|
| // For simplicity we always test the accumulator register.
|
| if (!reg.is(result_register())) __ mov(result_register(), reg);
|
| - DoTest(context);
|
| + DoTest(true_label_, false_label_, NULL);
|
| break;
|
| -
|
| - case Expression::kValueTest:
|
| - case Expression::kTestValue:
|
| - if (!reg.is(result_register())) __ mov(result_register(), reg);
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - break;
|
| - case kStack:
|
| - __ push(result_register());
|
| - break;
|
| - }
|
| - DoTest(context);
|
| - break;
|
| }
|
| }
|
|
|
| @@ -289,21 +276,8 @@
|
| case Expression::kTest:
|
| // For simplicity we always test the accumulator register.
|
| Move(result_register(), slot);
|
| - DoTest(context);
|
| + DoTest(true_label_, false_label_, NULL);
|
| break;
|
| -
|
| - case Expression::kValueTest:
|
| - case Expression::kTestValue:
|
| - Move(result_register(), slot);
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - break;
|
| - case kStack:
|
| - __ push(result_register());
|
| - break;
|
| - }
|
| - DoTest(context);
|
| - break;
|
| }
|
| }
|
|
|
| @@ -330,21 +304,8 @@
|
| case Expression::kTest:
|
| // For simplicity we always test the accumulator register.
|
| __ mov(result_register(), lit->handle());
|
| - DoTest(context);
|
| + DoTest(true_label_, false_label_, NULL);
|
| break;
|
| -
|
| - case Expression::kValueTest:
|
| - case Expression::kTestValue:
|
| - __ mov(result_register(), lit->handle());
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - break;
|
| - case kStack:
|
| - __ push(result_register());
|
| - break;
|
| - }
|
| - DoTest(context);
|
| - break;
|
| }
|
| }
|
|
|
| @@ -371,21 +332,8 @@
|
| case Expression::kTest:
|
| // For simplicity we always test the accumulator register.
|
| __ pop(result_register());
|
| - DoTest(context);
|
| + DoTest(true_label_, false_label_, NULL);
|
| break;
|
| -
|
| - case Expression::kValueTest:
|
| - case Expression::kTestValue:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ pop(result_register());
|
| - break;
|
| - case kStack:
|
| - __ mov(result_register(), Operand(esp, 0));
|
| - break;
|
| - }
|
| - DoTest(context);
|
| - break;
|
| }
|
| }
|
|
|
| @@ -420,24 +368,8 @@
|
| // For simplicity we always test the accumulator register.
|
| __ Drop(count);
|
| if (!reg.is(result_register())) __ mov(result_register(), reg);
|
| - DoTest(context);
|
| + DoTest(true_label_, false_label_, NULL);
|
| break;
|
| -
|
| - case Expression::kValueTest:
|
| - case Expression::kTestValue:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ Drop(count);
|
| - if (!reg.is(result_register())) __ mov(result_register(), reg);
|
| - break;
|
| - case kStack:
|
| - if (count > 1) __ Drop(count - 1);
|
| - __ mov(result_register(), reg);
|
| - __ mov(Operand(esp, 0), result_register());
|
| - break;
|
| - }
|
| - DoTest(context);
|
| - break;
|
| }
|
| }
|
|
|
| @@ -463,14 +395,6 @@
|
| *if_true = true_label_;
|
| *if_false = false_label_;
|
| break;
|
| - case Expression::kValueTest:
|
| - *if_true = materialize_true;
|
| - *if_false = false_label_;
|
| - break;
|
| - case Expression::kTestValue:
|
| - *if_true = true_label_;
|
| - *if_false = materialize_false;
|
| - break;
|
| }
|
| }
|
|
|
| @@ -510,32 +434,6 @@
|
|
|
| case Expression::kTest:
|
| break;
|
| -
|
| - case Expression::kValueTest:
|
| - __ bind(materialize_true);
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ mov(result_register(), Factory::true_value());
|
| - break;
|
| - case kStack:
|
| - __ push(Immediate(Factory::true_value()));
|
| - break;
|
| - }
|
| - __ jmp(true_label_);
|
| - break;
|
| -
|
| - case Expression::kTestValue:
|
| - __ bind(materialize_false);
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ mov(result_register(), Factory::false_value());
|
| - break;
|
| - case kStack:
|
| - __ push(Immediate(Factory::false_value()));
|
| - break;
|
| - }
|
| - __ jmp(false_label_);
|
| - break;
|
| }
|
| }
|
|
|
| @@ -565,76 +463,13 @@
|
| case Expression::kTest:
|
| __ jmp(flag ? true_label_ : false_label_);
|
| break;
|
| - case Expression::kTestValue:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - // If value is false it's needed.
|
| - if (!flag) __ mov(result_register(), Factory::false_value());
|
| - break;
|
| - case kStack:
|
| - // If value is false it's needed.
|
| - if (!flag) __ push(Immediate(Factory::false_value()));
|
| - break;
|
| - }
|
| - __ jmp(flag ? true_label_ : false_label_);
|
| - break;
|
| - case Expression::kValueTest:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - // If value is true it's needed.
|
| - if (flag) __ mov(result_register(), Factory::true_value());
|
| - break;
|
| - case kStack:
|
| - // If value is true it's needed.
|
| - if (flag) __ push(Immediate(Factory::true_value()));
|
| - break;
|
| - }
|
| - __ jmp(flag ? true_label_ : false_label_);
|
| - break;
|
| }
|
| }
|
|
|
|
|
| -void FullCodeGenerator::DoTest(Expression::Context context) {
|
| - // The value to test is in the accumulator. If the value might be needed
|
| - // on the stack (value/test and test/value contexts with a stack location
|
| - // desired), then the value is already duplicated on the stack.
|
| - ASSERT_NE(NULL, true_label_);
|
| - ASSERT_NE(NULL, false_label_);
|
| -
|
| - // In value/test and test/value expression contexts with stack as the
|
| - // desired location, there is already an extra value on the stack. Use a
|
| - // label to discard it if unneeded.
|
| - Label discard;
|
| - Label* if_true = true_label_;
|
| - Label* if_false = false_label_;
|
| - switch (context) {
|
| - case Expression::kUninitialized:
|
| - case Expression::kEffect:
|
| - case Expression::kValue:
|
| - UNREACHABLE();
|
| - case Expression::kTest:
|
| - break;
|
| - case Expression::kValueTest:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - break;
|
| - case kStack:
|
| - if_false = &discard;
|
| - break;
|
| - }
|
| - break;
|
| - case Expression::kTestValue:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - break;
|
| - case kStack:
|
| - if_true = &discard;
|
| - break;
|
| - }
|
| - break;
|
| - }
|
| -
|
| +void FullCodeGenerator::DoTest(Label* if_true,
|
| + Label* if_false,
|
| + Label* fall_through) {
|
| // Emit the inlined tests assumed by the stub.
|
| __ cmp(result_register(), Factory::undefined_value());
|
| __ j(equal, if_false);
|
| @@ -648,83 +483,28 @@
|
| __ test(result_register(), Immediate(kSmiTagMask));
|
| __ j(zero, if_true);
|
|
|
| - // Save a copy of the value if it may be needed and isn't already saved.
|
| - switch (context) {
|
| - case Expression::kUninitialized:
|
| - case Expression::kEffect:
|
| - case Expression::kValue:
|
| - UNREACHABLE();
|
| - case Expression::kTest:
|
| - break;
|
| - case Expression::kValueTest:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ push(result_register());
|
| - break;
|
| - case kStack:
|
| - break;
|
| - }
|
| - break;
|
| - case Expression::kTestValue:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ push(result_register());
|
| - break;
|
| - case kStack:
|
| - break;
|
| - }
|
| - break;
|
| - }
|
| -
|
| // Call the ToBoolean stub for all other cases.
|
| ToBooleanStub stub;
|
| __ push(result_register());
|
| __ CallStub(&stub);
|
| __ test(eax, Operand(eax));
|
|
|
| - // The stub returns nonzero for true. Complete based on the context.
|
| - switch (context) {
|
| - case Expression::kUninitialized:
|
| - case Expression::kEffect:
|
| - case Expression::kValue:
|
| - UNREACHABLE();
|
| + // The stub returns nonzero for true.
|
| + Split(not_zero, if_true, if_false, fall_through);
|
| +}
|
|
|
| - case Expression::kTest:
|
| - __ j(not_zero, true_label_);
|
| - __ jmp(false_label_);
|
| - break;
|
|
|
| - case Expression::kValueTest:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ j(zero, &discard);
|
| - __ pop(result_register());
|
| - __ jmp(true_label_);
|
| - break;
|
| - case kStack:
|
| - __ j(not_zero, true_label_);
|
| - break;
|
| - }
|
| - __ bind(&discard);
|
| - __ Drop(1);
|
| - __ jmp(false_label_);
|
| - break;
|
| -
|
| - case Expression::kTestValue:
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ j(not_zero, &discard);
|
| - __ pop(result_register());
|
| - __ jmp(false_label_);
|
| - break;
|
| - case kStack:
|
| - __ j(zero, false_label_);
|
| - break;
|
| - }
|
| - __ bind(&discard);
|
| - __ Drop(1);
|
| - __ jmp(true_label_);
|
| - break;
|
| +void FullCodeGenerator::Split(Condition cc,
|
| + Label* if_true,
|
| + Label* if_false,
|
| + Label* fall_through) {
|
| + if (if_false == fall_through) {
|
| + __ j(cc, if_true);
|
| + } else if (if_true == fall_through) {
|
| + __ j(NegateCondition(cc), if_false);
|
| + } else {
|
| + __ j(cc, if_true);
|
| + __ jmp(if_false);
|
| }
|
| }
|
|
|
| @@ -1203,7 +983,7 @@
|
| __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
| __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
|
| int literal_offset =
|
| - FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
|
| + FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
|
| __ mov(ebx, FieldOperand(ecx, literal_offset));
|
| __ cmp(ebx, Factory::undefined_value());
|
| __ j(not_equal, &materialized);
|
| @@ -1961,8 +1741,7 @@
|
| PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
|
|
| __ test(eax, Immediate(kSmiTagMask));
|
| - __ j(zero, if_true);
|
| - __ jmp(if_false);
|
| + Split(zero, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1979,8 +1758,7 @@
|
| PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
|
|
| __ test(eax, Immediate(kSmiTagMask | 0x80000000));
|
| - __ j(zero, if_true);
|
| - __ jmp(if_false);
|
| + Split(zero, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2009,8 +1787,7 @@
|
| __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
|
| __ j(below, if_false);
|
| __ cmp(ecx, LAST_JS_OBJECT_TYPE);
|
| - __ j(below_equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(below_equal, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2029,8 +1806,7 @@
|
| __ test(eax, Immediate(kSmiTagMask));
|
| __ j(equal, if_false);
|
| __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ebx);
|
| - __ j(above_equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(above_equal, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2051,8 +1827,7 @@
|
| __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
| __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
|
| __ test(ebx, Immediate(1 << Map::kIsUndetectable));
|
| - __ j(not_zero, if_true);
|
| - __ jmp(if_false);
|
| + Split(not_zero, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2090,8 +1865,7 @@
|
| __ test(eax, Immediate(kSmiTagMask));
|
| __ j(zero, if_false);
|
| __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
|
| - __ j(equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(equal, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2110,8 +1884,7 @@
|
| __ test(eax, Immediate(kSmiTagMask));
|
| __ j(equal, if_false);
|
| __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
|
| - __ j(equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(equal, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2130,8 +1903,7 @@
|
| __ test(eax, Immediate(kSmiTagMask));
|
| __ j(equal, if_false);
|
| __ CmpObjectType(eax, JS_REGEXP_TYPE, ebx);
|
| - __ j(equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(equal, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2160,8 +1932,7 @@
|
| __ bind(&check_frame_marker);
|
| __ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset),
|
| Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
|
| - __ j(equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(equal, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2181,8 +1952,7 @@
|
|
|
| __ pop(ebx);
|
| __ cmp(eax, Operand(ebx));
|
| - __ j(equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(equal, if_true, if_false, NULL);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2845,19 +2615,7 @@
|
| break;
|
| }
|
| break;
|
| - case Expression::kTestValue:
|
| - // Value is false so it's needed.
|
| - switch (location_) {
|
| - case kAccumulator:
|
| - __ mov(result_register(), Factory::undefined_value());
|
| - break;
|
| - case kStack:
|
| - __ push(Immediate(Factory::undefined_value()));
|
| - break;
|
| - }
|
| - // Fall through.
|
| case Expression::kTest:
|
| - case Expression::kValueTest:
|
| __ jmp(false_label_);
|
| break;
|
| }
|
| @@ -3038,8 +2796,6 @@
|
| break;
|
| case Expression::kValue:
|
| case Expression::kTest:
|
| - case Expression::kValueTest:
|
| - case Expression::kTestValue:
|
| // Save the result on the stack. If we have a named or keyed property
|
| // we store the result under the receiver that is currently on top
|
| // of the stack.
|
| @@ -3146,41 +2902,6 @@
|
| }
|
|
|
|
|
| -void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
|
| - Comment cmnt(masm_, "[ BinaryOperation");
|
| - switch (expr->op()) {
|
| - case Token::COMMA:
|
| - VisitForEffect(expr->left());
|
| - Visit(expr->right());
|
| - break;
|
| -
|
| - case Token::OR:
|
| - case Token::AND:
|
| - EmitLogicalOperation(expr);
|
| - break;
|
| -
|
| - case Token::ADD:
|
| - case Token::SUB:
|
| - case Token::DIV:
|
| - case Token::MOD:
|
| - case Token::MUL:
|
| - case Token::BIT_OR:
|
| - case Token::BIT_AND:
|
| - case Token::BIT_XOR:
|
| - case Token::SHL:
|
| - case Token::SHR:
|
| - case Token::SAR:
|
| - VisitForValue(expr->left(), kStack);
|
| - VisitForValue(expr->right(), kAccumulator);
|
| - EmitBinaryOp(expr->op(), context_);
|
| - break;
|
| -
|
| - default:
|
| - UNREACHABLE();
|
| - }
|
| -}
|
| -
|
| -
|
| void FullCodeGenerator::EmitNullCompare(bool strict,
|
| Register obj,
|
| Register null_const,
|
| @@ -3189,7 +2910,7 @@
|
| Register scratch) {
|
| __ cmp(obj, Operand(null_const));
|
| if (strict) {
|
| - __ j(equal, if_true);
|
| + Split(equal, if_true, if_false, NULL);
|
| } else {
|
| __ j(equal, if_true);
|
| __ cmp(obj, Factory::undefined_value());
|
| @@ -3200,9 +2921,8 @@
|
| __ mov(scratch, FieldOperand(obj, HeapObject::kMapOffset));
|
| __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
|
| __ test(scratch, Immediate(1 << Map::kIsUndetectable));
|
| - __ j(not_zero, if_true);
|
| + Split(not_zero, if_true, if_false, NULL);
|
| }
|
| - __ jmp(if_false);
|
| }
|
|
|
|
|
| @@ -3223,8 +2943,7 @@
|
| VisitForValue(expr->right(), kStack);
|
| __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
| __ cmp(eax, Factory::true_value());
|
| - __ j(equal, if_true);
|
| - __ jmp(if_false);
|
| + Split(equal, if_true, if_false, NULL);
|
| break;
|
|
|
| case Token::INSTANCEOF: {
|
| @@ -3232,8 +2951,8 @@
|
| InstanceofStub stub;
|
| __ CallStub(&stub);
|
| __ test(eax, Operand(eax));
|
| - __ j(zero, if_true); // The stub returns 0 for true.
|
| - __ jmp(if_false);
|
| + // The stub returns 0 for true.
|
| + Split(zero, if_true, if_false, NULL);
|
| break;
|
| }
|
|
|
| @@ -3304,8 +3023,7 @@
|
| CompareStub stub(cc, strict);
|
| __ CallStub(&stub);
|
| __ test(eax, Operand(eax));
|
| - __ j(cc, if_true);
|
| - __ jmp(if_false);
|
| + Split(cc, if_true, if_false, NULL);
|
| }
|
| }
|
|
|
|
|