Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Unified Diff: src/x64/fast-codegen-x64.cc

Issue 339082: Initial implementation of top-level compilation of expressions in test... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/ia32/fast-codegen-ia32.cc ('K') | « src/ia32/fast-codegen-ia32.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/fast-codegen-x64.cc
===================================================================
--- src/x64/fast-codegen-x64.cc (revision 3181)
+++ src/x64/fast-codegen-x64.cc (working copy)
@@ -116,6 +116,41 @@
}
+
+void FastCodeGenerator::Move(Expression::Context context, Register source) {
+ switch (context) {
+ case Expression::kUninitialized:
+ UNREACHABLE();
+ case Expression::kEffect:
+ break;
+ case Expression::kValue:
+ __ push(source);
+ break;
+ case Expression::kTest:
+ TestAndBranch(source, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ Label discard;
+ __ push(source);
+ TestAndBranch(source, true_label_, &discard);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ __ push(source);
+ TestAndBranch(source, &discard, false_label_);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(true_label_);
+ break;
+ }
+ }
+}
+
+
void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
switch (context) {
case Expression::kUninitialized:
@@ -125,6 +160,12 @@
case Expression::kValue:
__ push(Operand(rbp, SlotOffset(source)));
break;
+ case Expression::kTest: // Fall through.
+ case Expression::kValueTest: // Fall through.
+ case Expression::kTestValue:
+ __ movq(rax, Operand(rbp, SlotOffset(source)));
+ Move(context, rax);
+ break;
}
}
@@ -138,6 +179,12 @@
case Expression::kValue:
__ Push(expr->handle());
break;
+ case Expression::kTest: // Fall through.
+ case Expression::kValueTest: // Fall through.
+ case Expression::kTestValue:
+ __ Move(rax, expr->handle());
+ Move(context, rax);
+ break;
}
}
@@ -153,10 +200,65 @@
case Expression::kValue:
__ movq(Operand(rsp, 0), source);
break;
+ case Expression::kTest:
+ ASSERT(!source.is(rsp));
+ __ addq(rsp, Immediate(kPointerSize));
+ TestAndBranch(source, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ Label discard;
+ __ movq(Operand(rsp, 0), source);
+ TestAndBranch(source, true_label_, &discard);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ __ movq(Operand(rsp, 0), source);
+ TestAndBranch(source, &discard, false_label_);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(true_label_);
+ break;
+ }
}
}
+void FastCodeGenerator::TestAndBranch(Register source,
+ Label* true_label,
+ Label* false_label) {
+ ASSERT_NE(NULL, true_label);
+ ASSERT_NE(NULL, false_label);
+ // Use the shared ToBoolean stub to compile the value in the register into
+ // control flow to the code generator's true and false labels. Perform
+ // the fast checks assumed by the stub.
+
+ // The undefined value is false.
+ __ CompareRoot(source, Heap::kUndefinedValueRootIndex);
+ __ j(equal, false_label);
+ __ CompareRoot(source, Heap::kTrueValueRootIndex); // True is true.
+ __ j(equal, true_label);
+ __ CompareRoot(source, Heap::kFalseValueRootIndex); // False is false.
+ __ j(equal, false_label);
+ ASSERT_EQ(0, kSmiTag);
+ __ SmiCompare(source, Smi::FromInt(0)); // The smi zero is false.
+ __ j(equal, false_label);
+ Condition is_smi = masm_->CheckSmi(source); // All other smis are true.
+ __ j(is_smi, true_label);
+
+ // Call the stub for all other cases.
+ __ push(source);
+ ToBooleanStub stub;
+ __ CallStub(&stub);
+ __ testq(rax, rax); // The stub returns nonzero for true.
+ __ j(not_zero, true_label);
+ __ jmp(false_label);
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
__ push(rsi); // The context is the first argument.
@@ -361,6 +463,28 @@
case Expression::kValue:
if (!result_saved) __ push(rax);
break;
+ case Expression::kTest:
+ if (result_saved) __ pop(rax);
+ TestAndBranch(rax, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ Label discard;
+ if (!result_saved) __ push(rax);
+ TestAndBranch(rax, true_label_, &discard);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ if (!result_saved) __ push(rax);
+ TestAndBranch(rax, &discard, false_label_);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(true_label_);
+ break;
+ }
}
}
@@ -435,6 +559,28 @@
case Expression::kValue:
if (!result_saved) __ push(rax);
break;
+ case Expression::kTest:
+ if (result_saved) __ pop(rax);
+ TestAndBranch(rax, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ Label discard;
+ if (!result_saved) __ push(rax);
+ TestAndBranch(rax, true_label_, &discard);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ if (!result_saved) __ push(rax);
+ TestAndBranch(rax, &discard, false_label_);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(true_label_);
+ break;
+ }
}
}
@@ -527,6 +673,34 @@
__ movq(kScratchRegister, Operand(rsp, 0));
__ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
break;
+ case Expression::kTest:
+ // Case 'if (var = temp) ...'.
+ __ pop(rax);
+ __ movq(Operand(rbp, SlotOffset(var->slot())), rax);
+ TestAndBranch(rax, true_label_, false_label_);
William Hesse 2009/10/30 12:09:39 Maybe we should have an operation "TestDropAndBran
Kevin Millikin (Chromium) 2009/10/30 13:45:53 Possibly. This whole chunk of platform-specific c
+ break;
+ case Expression::kValueTest: {
+ // Case '(var = temp) || ...' in value context.
+ Label discard;
+ __ movq(rax, Operand(rsp, 0));
+ __ movq(Operand(rbp, SlotOffset(var->slot())), rax);
+ TestAndBranch(rax, true_label_, &discard);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ // Case '(var = temp) && ...' in value context.
+ Label discard;
+ __ movq(rax, Operand(rsp, 0));
+ __ movq(Operand(rbp, SlotOffset(var->slot())), rax);
+ TestAndBranch(rax, &discard, false_label_);
+ __ bind(&discard);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(true_label_);
+ break;
+ }
}
}
}
@@ -700,93 +874,4 @@
}
-void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
- // Compile a short-circuited boolean operation in a non-test context.
-
- // Compile (e0 || e1) as if it were
- // (let (temp = e0) temp ? temp : e1).
- // Compile (e0 && e1) as if it were
- // (let (temp = e0) !temp ? temp : e1).
-
- Label eval_right, done;
- Label *left_true, *left_false; // Where to branch to if lhs has that value.
- if (expr->op() == Token::OR) {
- left_true = &done;
- left_false = &eval_right;
- } else {
- left_true = &eval_right;
- left_false = &done;
- }
- Expression::Context context = expr->context();
- Expression* left = expr->left();
- Expression* right = expr->right();
-
- // Use the shared ToBoolean stub to find the boolean value of the
- // left-hand subexpression. Load the value into rax to perform some
- // inlined checks assumed by the stub.
-
- // Compile the left-hand value into rax. Put it on the stack if we may
- // need it as the value of the whole expression.
- if (left->AsLiteral() != NULL) {
- __ Move(rax, left->AsLiteral()->handle());
- if (context == Expression::kValue) __ push(rax);
- } else {
- Visit(left);
- ASSERT_EQ(Expression::kValue, left->context());
- switch (context) {
- case Expression::kUninitialized:
- UNREACHABLE();
- case Expression::kEffect:
- // Pop the left-hand value into rax because we will not need it as the
- // final result.
- __ pop(rax);
- break;
- case Expression::kValue:
- // Copy the left-hand value into rax because we may need it as the
- // final result.
- __ movq(rax, Operand(rsp, 0));
- break;
- }
- }
- // The left-hand value is in rax. It is also on the stack iff the
- // destination location is value.
-
- // Perform fast checks assumed by the stub.
- // The undefined value is false.
- __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
- __ j(equal, left_false);
- __ CompareRoot(rax, Heap::kTrueValueRootIndex); // True is true.
- __ j(equal, left_true);
- __ CompareRoot(rax, Heap::kFalseValueRootIndex); // False is false.
- __ j(equal, left_false);
- ASSERT(kSmiTag == 0);
- __ SmiCompare(rax, Smi::FromInt(0)); // The smi zero is false.
- __ j(equal, left_false);
- Condition is_smi = masm_->CheckSmi(rax); // All other smis are true.
- __ j(is_smi, left_true);
-
- // Call the stub for all other cases.
- __ push(rax);
- ToBooleanStub stub;
- __ CallStub(&stub);
- __ testq(rax, rax); // The stub returns nonzero for true.
- if (expr->op() == Token::OR) {
- __ j(not_zero, &done);
- } else {
- __ j(zero, &done);
- }
-
- __ bind(&eval_right);
- // Discard the left-hand value if present on the stack.
- if (context == Expression::kValue) {
- __ addq(rsp, Immediate(kPointerSize));
- }
- // Save or discard the right-hand value as needed.
- Visit(right);
- ASSERT_EQ(context, right->context());
-
- __ bind(&done);
-}
-
-
} } // namespace v8::internal
« src/ia32/fast-codegen-ia32.cc ('K') | « src/ia32/fast-codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698