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

Unified Diff: src/arm/fast-codegen-arm.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
« no previous file with comments | « no previous file | src/ast.h » ('j') | src/ast.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/fast-codegen-arm.cc
===================================================================
--- src/arm/fast-codegen-arm.cc (revision 3181)
+++ src/arm/fast-codegen-arm.cc (working copy)
@@ -117,15 +117,51 @@
}
+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);
+ __ pop();
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ __ push(source);
+ TestAndBranch(source, &discard, false_label_);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(true_label_);
+ }
+ }
+}
+
+
void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
case Expression::kEffect:
break;
- case Expression::kValue:
+ case Expression::kValue: // Fall through.
+ case Expression::kTest: // Fall through.
+ case Expression::kValueTest: // Fall through.
+ case Expression::kTestValue:
__ ldr(ip, MemOperand(fp, SlotOffset(source)));
- __ push(ip);
+ Move(context, ip);
break;
}
}
@@ -137,9 +173,12 @@
UNREACHABLE();
case Expression::kEffect:
break;
- case Expression::kValue:
+ case Expression::kValue: // Fall through.
+ case Expression::kTest: // Fall through.
+ case Expression::kValueTest: // Fall through.
+ case Expression::kTestValue:
__ mov(ip, Operand(expr->handle()));
- __ push(ip);
+ Move(context, ip);
break;
}
}
@@ -156,10 +195,49 @@
case Expression::kValue:
__ str(source, MemOperand(sp));
break;
+ case Expression::kTest:
+ ASSERT(!source.is(sp));
+ __ pop();
+ TestAndBranch(source, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ Label discard;
+ __ str(source, MemOperand(sp));
+ TestAndBranch(source, true_label_, &discard);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ __ str(source, MemOperand(sp));
+ TestAndBranch(source, &discard, false_label_);
+ __ bind(&discard);
+ __ pop();
+ __ 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);
+ // Call the runtime to find the boolean value of the source and then
+ // translate it into control flow to the pair of labels.
+ __ push(source);
+ __ CallRuntime(Runtime::kToBool, 1);
+ __ LoadRoot(ip, Heap::kTrueValueRootIndex);
+ __ cmp(r0, ip);
+ __ b(eq, true_label);
+ __ jmp(false_label);
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
// The context is the first argument.
@@ -360,6 +438,28 @@
case Expression::kValue:
if (!result_saved) __ push(r0);
break;
+ case Expression::kTest:
+ if (result_saved) __ pop(r0);
+ TestAndBranch(r0, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ Label discard;
+ if (!result_saved) __ push(r0);
+ TestAndBranch(r0, true_label_, &discard);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ if (!result_saved) __ push(r0);
+ TestAndBranch(r0, &discard, false_label_);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(true_label_);
+ break;
+ }
}
}
@@ -437,6 +537,28 @@
case Expression::kValue:
if (!result_saved) __ push(r0);
break;
+ case Expression::kTest:
+ if (result_saved) __ pop(r0);
+ TestAndBranch(r0, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ Label discard;
+ if (!result_saved) __ push(r0);
+ TestAndBranch(r0, true_label_, &discard);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ Label discard;
+ if (!result_saved) __ push(r0);
+ TestAndBranch(r0, &discard, false_label_);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(true_label_);
+ break;
+ }
}
}
@@ -521,16 +643,44 @@
UNREACHABLE();
case Expression::kEffect:
// Case 'var = temp'. Discard right-hand-side temporary.
- __ pop(ip);
+ __ pop(r0);
+ __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
break;
case Expression::kValue:
// Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
// temporary on the stack.
- __ ldr(ip, MemOperand(sp));
+ __ ldr(r0, MemOperand(sp));
+ __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
break;
+ case Expression::kTest:
+ // Case 'if (var = temp) ...'.
+ __ pop(r0);
+ __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
+ TestAndBranch(r0, true_label_, false_label_);
+ break;
+ case Expression::kValueTest: {
+ // Case '(var = temp) || ...' in value context.
+ Label discard;
+ __ ldr(r0, MemOperand(sp));
+ __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
+ TestAndBranch(r0, true_label_, &discard);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(false_label_);
+ break;
+ }
+ case Expression::kTestValue: {
+ // Case '(var = temp) && ...' in value context.
+ Label discard;
+ __ ldr(r0, MemOperand(sp));
+ __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
+ TestAndBranch(r0, &discard, false_label_);
+ __ bind(&discard);
+ __ pop();
+ __ jmp(true_label_);
+ break;
+ }
}
- // Do the slot assignment.
- __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
}
}
}
@@ -698,52 +848,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 done;
- Expression::Context context = expr->context();
- Expression* left = expr->left();
- Expression* right = expr->right();
-
- // Call the runtime to find the boolean value of the left-hand
- // subexpression. Duplicate the value if it may be needed as the final
- // result.
- if (left->AsLiteral() != NULL) {
- __ mov(r0, Operand(left->AsLiteral()->handle()));
- __ push(r0);
- if (context == Expression::kValue) __ push(r0);
- } else {
- Visit(left);
- ASSERT_EQ(Expression::kValue, left->context());
- if (context == Expression::kValue) {
- __ ldr(r0, MemOperand(sp));
- __ push(r0);
- }
- }
- // The left-hand value is in on top of the stack. It is duplicated on the
- // stack iff the destination location is value.
- __ CallRuntime(Runtime::kToBool, 1);
- if (expr->op() == Token::OR) {
- __ LoadRoot(ip, Heap::kTrueValueRootIndex);
- } else {
- __ LoadRoot(ip, Heap::kFalseValueRootIndex);
- }
- __ cmp(r0, ip);
- __ b(eq, &done);
-
- // Discard the left-hand value if present on the stack.
- if (context == Expression::kValue) __ pop();
- // Save or discard the right-hand value as needed.
- Visit(right);
- ASSERT_EQ(context, right->context());
-
- __ bind(&done);
-}
-
} } // namespace v8::internal
« no previous file with comments | « no previous file | src/ast.h » ('j') | src/ast.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698