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

Side by Side 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, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ast.h » ('j') | src/ast.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 __ RecordJSReturn(); 110 __ RecordJSReturn();
111 __ mov(sp, fp); 111 __ mov(sp, fp);
112 __ ldm(ia_w, sp, fp.bit() | lr.bit()); 112 __ ldm(ia_w, sp, fp.bit() | lr.bit());
113 int num_parameters = function_->scope()->num_parameters(); 113 int num_parameters = function_->scope()->num_parameters();
114 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); 114 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
115 __ Jump(lr); 115 __ Jump(lr);
116 } 116 }
117 } 117 }
118 118
119 119
120 void FastCodeGenerator::Move(Expression::Context context, Register source) {
121 switch (context) {
122 case Expression::kUninitialized:
123 UNREACHABLE();
124 case Expression::kEffect:
125 break;
126 case Expression::kValue:
127 __ push(source);
128 break;
129 case Expression::kTest:
130 TestAndBranch(source, true_label_, false_label_);
131 break;
132 case Expression::kValueTest: {
133 Label discard;
134 __ push(source);
135 TestAndBranch(source, true_label_, &discard);
136 __ bind(&discard);
137 __ pop();
138 __ jmp(false_label_);
139 break;
140 }
141 case Expression::kTestValue: {
142 Label discard;
143 __ push(source);
144 TestAndBranch(source, &discard, false_label_);
145 __ bind(&discard);
146 __ pop();
147 __ jmp(true_label_);
148 }
149 }
150 }
151
152
120 void FastCodeGenerator::Move(Expression::Context context, Slot* source) { 153 void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
121 switch (context) { 154 switch (context) {
122 case Expression::kUninitialized: 155 case Expression::kUninitialized:
123 UNREACHABLE(); 156 UNREACHABLE();
124 case Expression::kEffect: 157 case Expression::kEffect:
125 break; 158 break;
126 case Expression::kValue: 159 case Expression::kValue: // Fall through.
160 case Expression::kTest: // Fall through.
161 case Expression::kValueTest: // Fall through.
162 case Expression::kTestValue:
127 __ ldr(ip, MemOperand(fp, SlotOffset(source))); 163 __ ldr(ip, MemOperand(fp, SlotOffset(source)));
128 __ push(ip); 164 Move(context, ip);
129 break; 165 break;
130 } 166 }
131 } 167 }
132 168
133 169
134 void FastCodeGenerator::Move(Expression::Context context, Literal* expr) { 170 void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
135 switch (context) { 171 switch (context) {
136 case Expression::kUninitialized: 172 case Expression::kUninitialized:
137 UNREACHABLE(); 173 UNREACHABLE();
138 case Expression::kEffect: 174 case Expression::kEffect:
139 break; 175 break;
140 case Expression::kValue: 176 case Expression::kValue: // Fall through.
177 case Expression::kTest: // Fall through.
178 case Expression::kValueTest: // Fall through.
179 case Expression::kTestValue:
141 __ mov(ip, Operand(expr->handle())); 180 __ mov(ip, Operand(expr->handle()));
142 __ push(ip); 181 Move(context, ip);
143 break; 182 break;
144 } 183 }
145 } 184 }
146 185
147 186
148 void FastCodeGenerator::DropAndMove(Expression::Context context, 187 void FastCodeGenerator::DropAndMove(Expression::Context context,
149 Register source) { 188 Register source) {
150 switch (context) { 189 switch (context) {
151 case Expression::kUninitialized: 190 case Expression::kUninitialized:
152 UNREACHABLE(); 191 UNREACHABLE();
153 case Expression::kEffect: 192 case Expression::kEffect:
154 __ pop(); 193 __ pop();
155 break; 194 break;
156 case Expression::kValue: 195 case Expression::kValue:
157 __ str(source, MemOperand(sp)); 196 __ str(source, MemOperand(sp));
158 break; 197 break;
198 case Expression::kTest:
199 ASSERT(!source.is(sp));
200 __ pop();
201 TestAndBranch(source, true_label_, false_label_);
202 break;
203 case Expression::kValueTest: {
204 Label discard;
205 __ str(source, MemOperand(sp));
206 TestAndBranch(source, true_label_, &discard);
207 __ bind(&discard);
208 __ pop();
209 __ jmp(false_label_);
210 break;
211 }
212 case Expression::kTestValue: {
213 Label discard;
214 __ str(source, MemOperand(sp));
215 TestAndBranch(source, &discard, false_label_);
216 __ bind(&discard);
217 __ pop();
218 __ jmp(true_label_);
219 break;
220 }
159 } 221 }
160 } 222 }
161 223
162 224
225 void FastCodeGenerator::TestAndBranch(Register source,
226 Label* true_label,
227 Label* false_label) {
228 ASSERT_NE(NULL, true_label);
229 ASSERT_NE(NULL, false_label);
230 // Call the runtime to find the boolean value of the source and then
231 // translate it into control flow to the pair of labels.
232 __ push(source);
233 __ CallRuntime(Runtime::kToBool, 1);
234 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
235 __ cmp(r0, ip);
236 __ b(eq, true_label);
237 __ jmp(false_label);
238 }
239
240
163 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 241 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
164 // Call the runtime to declare the globals. 242 // Call the runtime to declare the globals.
165 // The context is the first argument. 243 // The context is the first argument.
166 __ mov(r1, Operand(pairs)); 244 __ mov(r1, Operand(pairs));
167 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0))); 245 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0)));
168 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit()); 246 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit());
169 __ CallRuntime(Runtime::kDeclareGlobals, 3); 247 __ CallRuntime(Runtime::kDeclareGlobals, 3);
170 // Return value is ignored. 248 // Return value is ignored.
171 } 249 }
172 250
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 } 431 }
354 switch (expr->context()) { 432 switch (expr->context()) {
355 case Expression::kUninitialized: 433 case Expression::kUninitialized:
356 UNREACHABLE(); 434 UNREACHABLE();
357 case Expression::kEffect: 435 case Expression::kEffect:
358 if (result_saved) __ pop(); 436 if (result_saved) __ pop();
359 break; 437 break;
360 case Expression::kValue: 438 case Expression::kValue:
361 if (!result_saved) __ push(r0); 439 if (!result_saved) __ push(r0);
362 break; 440 break;
441 case Expression::kTest:
442 if (result_saved) __ pop(r0);
443 TestAndBranch(r0, true_label_, false_label_);
444 break;
445 case Expression::kValueTest: {
446 Label discard;
447 if (!result_saved) __ push(r0);
448 TestAndBranch(r0, true_label_, &discard);
449 __ bind(&discard);
450 __ pop();
451 __ jmp(false_label_);
452 break;
453 }
454 case Expression::kTestValue: {
455 Label discard;
456 if (!result_saved) __ push(r0);
457 TestAndBranch(r0, &discard, false_label_);
458 __ bind(&discard);
459 __ pop();
460 __ jmp(true_label_);
461 break;
462 }
363 } 463 }
364 } 464 }
365 465
366 466
367 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 467 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
368 Comment cmnt(masm_, "[ ArrayLiteral"); 468 Comment cmnt(masm_, "[ ArrayLiteral");
369 Label make_clone; 469 Label make_clone;
370 470
371 // Fetch the function's literals array. 471 // Fetch the function's literals array.
372 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 472 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 530
431 switch (expr->context()) { 531 switch (expr->context()) {
432 case Expression::kUninitialized: 532 case Expression::kUninitialized:
433 UNREACHABLE(); 533 UNREACHABLE();
434 case Expression::kEffect: 534 case Expression::kEffect:
435 if (result_saved) __ pop(); 535 if (result_saved) __ pop();
436 break; 536 break;
437 case Expression::kValue: 537 case Expression::kValue:
438 if (!result_saved) __ push(r0); 538 if (!result_saved) __ push(r0);
439 break; 539 break;
540 case Expression::kTest:
541 if (result_saved) __ pop(r0);
542 TestAndBranch(r0, true_label_, false_label_);
543 break;
544 case Expression::kValueTest: {
545 Label discard;
546 if (!result_saved) __ push(r0);
547 TestAndBranch(r0, true_label_, &discard);
548 __ bind(&discard);
549 __ pop();
550 __ jmp(false_label_);
551 break;
552 }
553 case Expression::kTestValue: {
554 Label discard;
555 if (!result_saved) __ push(r0);
556 TestAndBranch(r0, &discard, false_label_);
557 __ bind(&discard);
558 __ pop();
559 __ jmp(true_label_);
560 break;
561 }
440 } 562 }
441 } 563 }
442 564
443 565
444 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 566 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
445 Comment cmnt(masm_, "[ Assignment"); 567 Comment cmnt(masm_, "[ Assignment");
446 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 568 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
447 569
448 // Record the source position for the assignment. 570 // Record the source position for the assignment.
449 SetSourcePosition(expr->position()); 571 SetSourcePosition(expr->position());
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 Move(expr->context(), ip); 636 Move(expr->context(), ip);
515 } else { 637 } else {
516 ASSERT_EQ(Expression::kValue, rhs->context()); 638 ASSERT_EQ(Expression::kValue, rhs->context());
517 Visit(rhs); 639 Visit(rhs);
518 // Load right-hand side into ip. 640 // Load right-hand side into ip.
519 switch (expr->context()) { 641 switch (expr->context()) {
520 case Expression::kUninitialized: 642 case Expression::kUninitialized:
521 UNREACHABLE(); 643 UNREACHABLE();
522 case Expression::kEffect: 644 case Expression::kEffect:
523 // Case 'var = temp'. Discard right-hand-side temporary. 645 // Case 'var = temp'. Discard right-hand-side temporary.
524 __ pop(ip); 646 __ pop(r0);
647 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
525 break; 648 break;
526 case Expression::kValue: 649 case Expression::kValue:
527 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side 650 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
528 // temporary on the stack. 651 // temporary on the stack.
529 __ ldr(ip, MemOperand(sp)); 652 __ ldr(r0, MemOperand(sp));
653 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
530 break; 654 break;
655 case Expression::kTest:
656 // Case 'if (var = temp) ...'.
657 __ pop(r0);
658 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
659 TestAndBranch(r0, true_label_, false_label_);
660 break;
661 case Expression::kValueTest: {
662 // Case '(var = temp) || ...' in value context.
663 Label discard;
664 __ ldr(r0, MemOperand(sp));
665 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
666 TestAndBranch(r0, true_label_, &discard);
667 __ bind(&discard);
668 __ pop();
669 __ jmp(false_label_);
670 break;
671 }
672 case Expression::kTestValue: {
673 // Case '(var = temp) && ...' in value context.
674 Label discard;
675 __ ldr(r0, MemOperand(sp));
676 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
677 TestAndBranch(r0, &discard, false_label_);
678 __ bind(&discard);
679 __ pop();
680 __ jmp(true_label_);
681 break;
682 }
531 } 683 }
532 // Do the slot assignment.
533 __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
534 } 684 }
535 } 685 }
536 } 686 }
537 687
538 688
539 void FastCodeGenerator::VisitProperty(Property* expr) { 689 void FastCodeGenerator::VisitProperty(Property* expr) {
540 Comment cmnt(masm_, "[ Property"); 690 Comment cmnt(masm_, "[ Property");
541 Expression* key = expr->key(); 691 Expression* key = expr->key();
542 uint32_t dummy; 692 uint32_t dummy;
543 693
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 Move(expr->context(), r0); 841 Move(expr->context(), r0);
692 842
693 break; 843 break;
694 } 844 }
695 default: 845 default:
696 UNREACHABLE(); 846 UNREACHABLE();
697 } 847 }
698 } 848 }
699 849
700 850
701 void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
702 // Compile a short-circuited boolean operation in a non-test context.
703
704 // Compile (e0 || e1) as if it were
705 // (let (temp = e0) temp ? temp : e1).
706 // Compile (e0 && e1) as if it were
707 // (let (temp = e0) !temp ? temp : e1).
708
709 Label done;
710 Expression::Context context = expr->context();
711 Expression* left = expr->left();
712 Expression* right = expr->right();
713
714 // Call the runtime to find the boolean value of the left-hand
715 // subexpression. Duplicate the value if it may be needed as the final
716 // result.
717 if (left->AsLiteral() != NULL) {
718 __ mov(r0, Operand(left->AsLiteral()->handle()));
719 __ push(r0);
720 if (context == Expression::kValue) __ push(r0);
721 } else {
722 Visit(left);
723 ASSERT_EQ(Expression::kValue, left->context());
724 if (context == Expression::kValue) {
725 __ ldr(r0, MemOperand(sp));
726 __ push(r0);
727 }
728 }
729 // The left-hand value is in on top of the stack. It is duplicated on the
730 // stack iff the destination location is value.
731 __ CallRuntime(Runtime::kToBool, 1);
732 if (expr->op() == Token::OR) {
733 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
734 } else {
735 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
736 }
737 __ cmp(r0, ip);
738 __ b(eq, &done);
739
740 // Discard the left-hand value if present on the stack.
741 if (context == Expression::kValue) __ pop();
742 // Save or discard the right-hand value as needed.
743 Visit(right);
744 ASSERT_EQ(context, right->context());
745
746 __ bind(&done);
747 }
748
749 } } // namespace v8::internal 851 } } // namespace v8::internal
OLDNEW
« 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