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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 3152042: Simplified the full codegens by removing the Expression::kTestValue... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ast.h » ('j') | no next file with comments »
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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 switch (location_) { 259 switch (location_) {
260 case kAccumulator: 260 case kAccumulator:
261 if (!reg.is(result_register())) __ mov(result_register(), reg); 261 if (!reg.is(result_register())) __ mov(result_register(), reg);
262 break; 262 break;
263 case kStack: 263 case kStack:
264 __ push(reg); 264 __ push(reg);
265 break; 265 break;
266 } 266 }
267 break; 267 break;
268 268
269 case Expression::kValueTest:
270 case Expression::kTestValue:
271 // Push an extra copy of the value in case it's needed.
272 __ push(reg);
273 // Fall through.
274
275 case Expression::kTest: 269 case Expression::kTest:
276 // We always call the runtime on ARM, so push the value as argument. 270 // For simplicity we always test the accumulator register.
277 __ push(reg); 271 if (!reg.is(result_register())) __ mov(result_register(), reg);
278 DoTest(context); 272 DoTest(true_label_, false_label_, NULL);
279 break; 273 break;
280 } 274 }
281 } 275 }
282 276
283 277
284 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) { 278 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
285 switch (context) { 279 switch (context) {
286 case Expression::kUninitialized: 280 case Expression::kUninitialized:
287 UNREACHABLE(); 281 UNREACHABLE();
288 case Expression::kEffect: 282 case Expression::kEffect:
289 // Nothing to do. 283 // Nothing to do.
290 break; 284 break;
291 case Expression::kValue: 285 case Expression::kValue:
292 case Expression::kTest: 286 case Expression::kTest:
293 case Expression::kValueTest:
294 case Expression::kTestValue:
295 // On ARM we have to move the value into a register to do anything 287 // On ARM we have to move the value into a register to do anything
296 // with it. 288 // with it.
297 Move(result_register(), slot); 289 Move(result_register(), slot);
298 Apply(context, result_register()); 290 Apply(context, result_register());
299 break; 291 break;
300 } 292 }
301 } 293 }
302 294
303 295
304 void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) { 296 void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
305 switch (context) { 297 switch (context) {
306 case Expression::kUninitialized: 298 case Expression::kUninitialized:
307 UNREACHABLE(); 299 UNREACHABLE();
308 case Expression::kEffect: 300 case Expression::kEffect:
309 break; 301 break;
310 // Nothing to do. 302 // Nothing to do.
311 case Expression::kValue: 303 case Expression::kValue:
312 case Expression::kTest: 304 case Expression::kTest:
313 case Expression::kValueTest:
314 case Expression::kTestValue:
315 // On ARM we have to move the value into a register to do anything 305 // On ARM we have to move the value into a register to do anything
316 // with it. 306 // with it.
317 __ mov(result_register(), Operand(lit->handle())); 307 __ mov(result_register(), Operand(lit->handle()));
318 Apply(context, result_register()); 308 Apply(context, result_register());
319 break; 309 break;
320 } 310 }
321 } 311 }
322 312
323 313
324 void FullCodeGenerator::ApplyTOS(Expression::Context context) { 314 void FullCodeGenerator::ApplyTOS(Expression::Context context) {
325 switch (context) { 315 switch (context) {
326 case Expression::kUninitialized: 316 case Expression::kUninitialized:
327 UNREACHABLE(); 317 UNREACHABLE();
328 318
329 case Expression::kEffect: 319 case Expression::kEffect:
330 __ Drop(1); 320 __ Drop(1);
331 break; 321 break;
332 322
333 case Expression::kValue: 323 case Expression::kValue:
334 switch (location_) { 324 switch (location_) {
335 case kAccumulator: 325 case kAccumulator:
336 __ pop(result_register()); 326 __ pop(result_register());
337 break; 327 break;
338 case kStack: 328 case kStack:
339 break; 329 break;
340 } 330 }
341 break; 331 break;
342 332
343 case Expression::kValueTest:
344 case Expression::kTestValue:
345 // Duplicate the value on the stack in case it's needed.
346 __ ldr(ip, MemOperand(sp));
347 __ push(ip);
348 // Fall through.
349
350 case Expression::kTest: 333 case Expression::kTest:
351 DoTest(context); 334 __ pop(result_register());
335 DoTest(true_label_, false_label_, NULL);
352 break; 336 break;
353 } 337 }
354 } 338 }
355 339
356 340
357 void FullCodeGenerator::DropAndApply(int count, 341 void FullCodeGenerator::DropAndApply(int count,
358 Expression::Context context, 342 Expression::Context context,
359 Register reg) { 343 Register reg) {
360 ASSERT(count > 0); 344 ASSERT(count > 0);
361 ASSERT(!reg.is(sp)); 345 ASSERT(!reg.is(sp));
(...skipping 12 matching lines...) Expand all
374 if (!reg.is(result_register())) __ mov(result_register(), reg); 358 if (!reg.is(result_register())) __ mov(result_register(), reg);
375 break; 359 break;
376 case kStack: 360 case kStack:
377 if (count > 1) __ Drop(count - 1); 361 if (count > 1) __ Drop(count - 1);
378 __ str(reg, MemOperand(sp)); 362 __ str(reg, MemOperand(sp));
379 break; 363 break;
380 } 364 }
381 break; 365 break;
382 366
383 case Expression::kTest: 367 case Expression::kTest:
384 if (count > 1) __ Drop(count - 1); 368 __ Drop(count);
385 __ str(reg, MemOperand(sp)); 369 if (!reg.is(result_register())) __ mov(result_register(), reg);
386 DoTest(context); 370 DoTest(true_label_, false_label_, NULL);
387 break;
388
389 case Expression::kValueTest:
390 case Expression::kTestValue:
391 if (count == 1) {
392 __ str(reg, MemOperand(sp));
393 __ push(reg);
394 } else { // count > 1
395 __ Drop(count - 2);
396 __ str(reg, MemOperand(sp, kPointerSize));
397 __ str(reg, MemOperand(sp));
398 }
399 DoTest(context);
400 break; 371 break;
401 } 372 }
402 } 373 }
403 374
404 void FullCodeGenerator::PrepareTest(Label* materialize_true, 375 void FullCodeGenerator::PrepareTest(Label* materialize_true,
405 Label* materialize_false, 376 Label* materialize_false,
406 Label** if_true, 377 Label** if_true,
407 Label** if_false) { 378 Label** if_false) {
408 switch (context_) { 379 switch (context_) {
409 case Expression::kUninitialized: 380 case Expression::kUninitialized:
410 UNREACHABLE(); 381 UNREACHABLE();
411 break; 382 break;
412 case Expression::kEffect: 383 case Expression::kEffect:
413 // In an effect context, the true and the false case branch to the 384 // In an effect context, the true and the false case branch to the
414 // same label. 385 // same label.
415 *if_true = *if_false = materialize_true; 386 *if_true = *if_false = materialize_true;
416 break; 387 break;
417 case Expression::kValue: 388 case Expression::kValue:
418 *if_true = materialize_true; 389 *if_true = materialize_true;
419 *if_false = materialize_false; 390 *if_false = materialize_false;
420 break; 391 break;
421 case Expression::kTest: 392 case Expression::kTest:
422 *if_true = true_label_; 393 *if_true = true_label_;
423 *if_false = false_label_; 394 *if_false = false_label_;
424 break; 395 break;
425 case Expression::kValueTest:
426 *if_true = materialize_true;
427 *if_false = false_label_;
428 break;
429 case Expression::kTestValue:
430 *if_true = true_label_;
431 *if_false = materialize_false;
432 break;
433 } 396 }
434 } 397 }
435 398
436 399
437 void FullCodeGenerator::Apply(Expression::Context context, 400 void FullCodeGenerator::Apply(Expression::Context context,
438 Label* materialize_true, 401 Label* materialize_true,
439 Label* materialize_false) { 402 Label* materialize_false) {
440 switch (context) { 403 switch (context) {
441 case Expression::kUninitialized: 404 case Expression::kUninitialized:
442 405
(...skipping 21 matching lines...) Expand all
464 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 427 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
465 __ push(ip); 428 __ push(ip);
466 break; 429 break;
467 } 430 }
468 __ bind(&done); 431 __ bind(&done);
469 break; 432 break;
470 } 433 }
471 434
472 case Expression::kTest: 435 case Expression::kTest:
473 break; 436 break;
474
475 case Expression::kValueTest:
476 __ bind(materialize_true);
477 switch (location_) {
478 case kAccumulator:
479 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
480 break;
481 case kStack:
482 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
483 __ push(ip);
484 break;
485 }
486 __ jmp(true_label_);
487 break;
488
489 case Expression::kTestValue:
490 __ bind(materialize_false);
491 switch (location_) {
492 case kAccumulator:
493 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
494 break;
495 case kStack:
496 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
497 __ push(ip);
498 break;
499 }
500 __ jmp(false_label_);
501 break;
502 } 437 }
503 } 438 }
504 439
505 440
506 // Convert constant control flow (true or false) to the result expected for 441 // Convert constant control flow (true or false) to the result expected for
507 // a given expression context. 442 // a given expression context.
508 void FullCodeGenerator::Apply(Expression::Context context, bool flag) { 443 void FullCodeGenerator::Apply(Expression::Context context, bool flag) {
509 switch (context) { 444 switch (context) {
510 case Expression::kUninitialized: 445 case Expression::kUninitialized:
511 UNREACHABLE(); 446 UNREACHABLE();
(...skipping 10 matching lines...) Expand all
522 case kStack: 457 case kStack:
523 __ LoadRoot(ip, value_root_index); 458 __ LoadRoot(ip, value_root_index);
524 __ push(ip); 459 __ push(ip);
525 break; 460 break;
526 } 461 }
527 break; 462 break;
528 } 463 }
529 case Expression::kTest: 464 case Expression::kTest:
530 __ b(flag ? true_label_ : false_label_); 465 __ b(flag ? true_label_ : false_label_);
531 break; 466 break;
532 case Expression::kTestValue:
533 switch (location_) {
534 case kAccumulator:
535 // If value is false it's needed.
536 if (!flag) __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
537 break;
538 case kStack:
539 // If value is false it's needed.
540 if (!flag) {
541 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
542 __ push(ip);
543 }
544 break;
545 }
546 __ b(flag ? true_label_ : false_label_);
547 break;
548 case Expression::kValueTest:
549 switch (location_) {
550 case kAccumulator:
551 // If value is true it's needed.
552 if (flag) __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
553 break;
554 case kStack:
555 // If value is true it's needed.
556 if (flag) {
557 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
558 __ push(ip);
559 }
560 break;
561 }
562 __ b(flag ? true_label_ : false_label_);
563 break;
564 } 467 }
565 } 468 }
566 469
567 470
568 void FullCodeGenerator::DoTest(Expression::Context context) { 471 void FullCodeGenerator::DoTest(Label* if_true,
569 // The value to test is pushed on the stack, and duplicated on the stack 472 Label* if_false,
570 // if necessary (for value/test and test/value contexts). 473 Label* fall_through) {
571 ASSERT_NE(NULL, true_label_);
572 ASSERT_NE(NULL, false_label_);
573
574 // Call the runtime to find the boolean value of the source and then 474 // Call the runtime to find the boolean value of the source and then
575 // translate it into control flow to the pair of labels. 475 // translate it into control flow to the pair of labels.
476 __ push(result_register());
576 __ CallRuntime(Runtime::kToBool, 1); 477 __ CallRuntime(Runtime::kToBool, 1);
577 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 478 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
578 __ cmp(r0, ip); 479 __ cmp(r0, ip);
480 Split(eq, if_true, if_false, fall_through);
481 }
579 482
580 // Complete based on the context.
581 switch (context) {
582 case Expression::kUninitialized:
583 case Expression::kEffect:
584 case Expression::kValue:
585 UNREACHABLE();
586 483
587 case Expression::kTest: 484 void FullCodeGenerator::Split(Condition cc,
588 __ b(eq, true_label_); 485 Label* if_true,
589 __ jmp(false_label_); 486 Label* if_false,
590 break; 487 Label* fall_through) {
591 488 if (if_false == fall_through) {
592 case Expression::kValueTest: { 489 __ b(cc, if_true);
593 Label discard; 490 } else if (if_true == fall_through) {
594 switch (location_) { 491 __ b(NegateCondition(cc), if_false);
595 case kAccumulator: 492 } else {
596 __ b(ne, &discard); 493 __ b(cc, if_true);
597 __ pop(result_register()); 494 __ b(if_false);
598 __ jmp(true_label_);
599 break;
600 case kStack:
601 __ b(eq, true_label_);
602 break;
603 }
604 __ bind(&discard);
605 __ Drop(1);
606 __ jmp(false_label_);
607 break;
608 }
609
610 case Expression::kTestValue: {
611 Label discard;
612 switch (location_) {
613 case kAccumulator:
614 __ b(eq, &discard);
615 __ pop(result_register());
616 __ jmp(false_label_);
617 break;
618 case kStack:
619 __ b(ne, false_label_);
620 break;
621 }
622 __ bind(&discard);
623 __ Drop(1);
624 __ jmp(true_label_);
625 break;
626 }
627 } 495 }
628 } 496 }
629 497
630 498
631 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) { 499 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
632 switch (slot->type()) { 500 switch (slot->type()) {
633 case Slot::PARAMETER: 501 case Slot::PARAMETER:
634 case Slot::LOCAL: 502 case Slot::LOCAL:
635 return MemOperand(fp, SlotOffset(slot)); 503 return MemOperand(fp, SlotOffset(slot));
636 case Slot::CONTEXT: { 504 case Slot::CONTEXT: {
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 968
1101 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 969 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1102 Comment cmnt(masm_, "[ RegExpLiteral"); 970 Comment cmnt(masm_, "[ RegExpLiteral");
1103 Label materialized; 971 Label materialized;
1104 // Registers will be used as follows: 972 // Registers will be used as follows:
1105 // r4 = JS function, literals array 973 // r4 = JS function, literals array
1106 // r3 = literal index 974 // r3 = literal index
1107 // r2 = RegExp pattern 975 // r2 = RegExp pattern
1108 // r1 = RegExp flags 976 // r1 = RegExp flags
1109 // r0 = temp + materialized value (RegExp literal) 977 // r0 = temp + materialized value (RegExp literal)
1110 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 978 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1111 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); 979 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
1112 int literal_offset = 980 int literal_offset =
1113 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 981 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1114 __ ldr(r0, FieldMemOperand(r4, literal_offset)); 982 __ ldr(r0, FieldMemOperand(r4, literal_offset));
1115 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 983 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1116 __ cmp(r0, ip); 984 __ cmp(r0, ip);
1117 __ b(ne, &materialized); 985 __ b(ne, &materialized);
986
987 // Create regexp literal using runtime function.
988 // Result will be in r0.
1118 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); 989 __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
1119 __ mov(r2, Operand(expr->pattern())); 990 __ mov(r2, Operand(expr->pattern()));
1120 __ mov(r1, Operand(expr->flags())); 991 __ mov(r1, Operand(expr->flags()));
1121 __ Push(r4, r3, r2, r1); 992 __ Push(r4, r3, r2, r1);
1122 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 993 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
994
1123 __ bind(&materialized); 995 __ bind(&materialized);
1124 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 996 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1125 __ push(r0); 997 __ push(r0);
1126 __ mov(r0, Operand(Smi::FromInt(size))); 998 __ mov(r0, Operand(Smi::FromInt(size)));
1127 __ push(r0); 999 __ push(r0);
1128 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 1000 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1001
1129 // After this, registers are used as follows: 1002 // After this, registers are used as follows:
1130 // r0: Newly allocated regexp. 1003 // r0: Newly allocated regexp.
1131 // r1: Materialized regexp 1004 // r1: Materialized regexp.
1132 // r2: temp. 1005 // r2: temp.
1133 __ pop(r1); 1006 __ pop(r1);
1134 __ CopyFields(r0, r1, r2.bit(), size / kPointerSize); 1007 __ CopyFields(r0, r1, r2.bit(), size / kPointerSize);
1135 Apply(context_, r0); 1008 Apply(context_, r0);
1136 } 1009 }
1137 1010
1138 1011
1139 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1012 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1140 Comment cmnt(masm_, "[ ObjectLiteral"); 1013 Comment cmnt(masm_, "[ ObjectLiteral");
1141 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1014 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 ASSERT(args->length() == 1); 1751 ASSERT(args->length() == 1);
1879 1752
1880 VisitForValue(args->at(0), kAccumulator); 1753 VisitForValue(args->at(0), kAccumulator);
1881 1754
1882 Label materialize_true, materialize_false; 1755 Label materialize_true, materialize_false;
1883 Label* if_true = NULL; 1756 Label* if_true = NULL;
1884 Label* if_false = NULL; 1757 Label* if_false = NULL;
1885 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1758 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1886 1759
1887 __ tst(r0, Operand(kSmiTagMask | 0x80000000)); 1760 __ tst(r0, Operand(kSmiTagMask | 0x80000000));
1888 __ b(eq, if_true); 1761 Split(eq, if_true, if_false, NULL);
1889 __ b(if_false);
1890 1762
1891 Apply(context_, if_true, if_false); 1763 Apply(context_, if_true, if_false);
1892 } 1764 }
1893 1765
1894 1766
1895 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { 1767 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
1896 ASSERT(args->length() == 1); 1768 ASSERT(args->length() == 1);
1897 1769
1898 VisitForValue(args->at(0), kAccumulator); 1770 VisitForValue(args->at(0), kAccumulator);
1899 1771
1900 Label materialize_true, materialize_false; 1772 Label materialize_true, materialize_false;
1901 Label* if_true = NULL; 1773 Label* if_true = NULL;
1902 Label* if_false = NULL; 1774 Label* if_false = NULL;
1903 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1775 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1904 __ BranchOnSmi(r0, if_false); 1776 __ BranchOnSmi(r0, if_false);
1905 __ LoadRoot(ip, Heap::kNullValueRootIndex); 1777 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1906 __ cmp(r0, ip); 1778 __ cmp(r0, ip);
1907 __ b(eq, if_true); 1779 __ b(eq, if_true);
1908 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 1780 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1909 // Undetectable objects behave like undefined when tested with typeof. 1781 // Undetectable objects behave like undefined when tested with typeof.
1910 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); 1782 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset));
1911 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 1783 __ tst(r1, Operand(1 << Map::kIsUndetectable));
1912 __ b(ne, if_false); 1784 __ b(ne, if_false);
1913 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 1785 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset));
1914 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); 1786 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
1915 __ b(lt, if_false); 1787 __ b(lt, if_false);
1916 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); 1788 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
1917 __ b(le, if_true); 1789 Split(le, if_true, if_false, NULL);
1918 __ b(if_false);
1919 1790
1920 Apply(context_, if_true, if_false); 1791 Apply(context_, if_true, if_false);
1921 } 1792 }
1922 1793
1923 1794
1924 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { 1795 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
1925 ASSERT(args->length() == 1); 1796 ASSERT(args->length() == 1);
1926 1797
1927 VisitForValue(args->at(0), kAccumulator); 1798 VisitForValue(args->at(0), kAccumulator);
1928 1799
1929 Label materialize_true, materialize_false; 1800 Label materialize_true, materialize_false;
1930 Label* if_true = NULL; 1801 Label* if_true = NULL;
1931 Label* if_false = NULL; 1802 Label* if_false = NULL;
1932 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1803 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1933 1804
1934 __ BranchOnSmi(r0, if_false); 1805 __ BranchOnSmi(r0, if_false);
1935 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); 1806 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
1936 __ b(ge, if_true); 1807 Split(ge, if_true, if_false, NULL);
1937 __ b(if_false);
1938 1808
1939 Apply(context_, if_true, if_false); 1809 Apply(context_, if_true, if_false);
1940 } 1810 }
1941 1811
1942 1812
1943 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { 1813 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
1944 ASSERT(args->length() == 1); 1814 ASSERT(args->length() == 1);
1945 1815
1946 VisitForValue(args->at(0), kAccumulator); 1816 VisitForValue(args->at(0), kAccumulator);
1947 1817
1948 Label materialize_true, materialize_false; 1818 Label materialize_true, materialize_false;
1949 Label* if_true = NULL; 1819 Label* if_true = NULL;
1950 Label* if_false = NULL; 1820 Label* if_false = NULL;
1951 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1821 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1952 1822
1953 __ BranchOnSmi(r0, if_false); 1823 __ BranchOnSmi(r0, if_false);
1954 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 1824 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
1955 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); 1825 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
1956 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 1826 __ tst(r1, Operand(1 << Map::kIsUndetectable));
1957 __ b(ne, if_true); 1827 Split(ne, if_true, if_false, NULL);
1958 __ b(if_false);
1959 1828
1960 Apply(context_, if_true, if_false); 1829 Apply(context_, if_true, if_false);
1961 } 1830 }
1962 1831
1963 1832
1964 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( 1833 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
1965 ZoneList<Expression*>* args) { 1834 ZoneList<Expression*>* args) {
1966 1835
1967 ASSERT(args->length() == 1); 1836 ASSERT(args->length() == 1);
1968 1837
(...skipping 17 matching lines...) Expand all
1986 1855
1987 VisitForValue(args->at(0), kAccumulator); 1856 VisitForValue(args->at(0), kAccumulator);
1988 1857
1989 Label materialize_true, materialize_false; 1858 Label materialize_true, materialize_false;
1990 Label* if_true = NULL; 1859 Label* if_true = NULL;
1991 Label* if_false = NULL; 1860 Label* if_false = NULL;
1992 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1861 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1993 1862
1994 __ BranchOnSmi(r0, if_false); 1863 __ BranchOnSmi(r0, if_false);
1995 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); 1864 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
1996 __ b(eq, if_true); 1865 Split(eq, if_true, if_false, NULL);
1997 __ b(if_false);
1998 1866
1999 Apply(context_, if_true, if_false); 1867 Apply(context_, if_true, if_false);
2000 } 1868 }
2001 1869
2002 1870
2003 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { 1871 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
2004 ASSERT(args->length() == 1); 1872 ASSERT(args->length() == 1);
2005 1873
2006 VisitForValue(args->at(0), kAccumulator); 1874 VisitForValue(args->at(0), kAccumulator);
2007 1875
2008 Label materialize_true, materialize_false; 1876 Label materialize_true, materialize_false;
2009 Label* if_true = NULL; 1877 Label* if_true = NULL;
2010 Label* if_false = NULL; 1878 Label* if_false = NULL;
2011 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1879 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
2012 1880
2013 __ BranchOnSmi(r0, if_false); 1881 __ BranchOnSmi(r0, if_false);
2014 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); 1882 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
2015 __ b(eq, if_true); 1883 Split(eq, if_true, if_false, NULL);
2016 __ b(if_false);
2017 1884
2018 Apply(context_, if_true, if_false); 1885 Apply(context_, if_true, if_false);
2019 } 1886 }
2020 1887
2021 1888
2022 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { 1889 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
2023 ASSERT(args->length() == 1); 1890 ASSERT(args->length() == 1);
2024 1891
2025 VisitForValue(args->at(0), kAccumulator); 1892 VisitForValue(args->at(0), kAccumulator);
2026 1893
2027 Label materialize_true, materialize_false; 1894 Label materialize_true, materialize_false;
2028 Label* if_true = NULL; 1895 Label* if_true = NULL;
2029 Label* if_false = NULL; 1896 Label* if_false = NULL;
2030 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1897 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
2031 1898
2032 __ BranchOnSmi(r0, if_false); 1899 __ BranchOnSmi(r0, if_false);
2033 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); 1900 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
2034 __ b(eq, if_true); 1901 Split(eq, if_true, if_false, NULL);
2035 __ b(if_false);
2036 1902
2037 Apply(context_, if_true, if_false); 1903 Apply(context_, if_true, if_false);
2038 } 1904 }
2039 1905
2040 1906
2041 1907
2042 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { 1908 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
2043 ASSERT(args->length() == 0); 1909 ASSERT(args->length() == 0);
2044 1910
2045 Label materialize_true, materialize_false; 1911 Label materialize_true, materialize_false;
2046 Label* if_true = NULL; 1912 Label* if_true = NULL;
2047 Label* if_false = NULL; 1913 Label* if_false = NULL;
2048 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1914 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
2049 1915
2050 // Get the frame pointer for the calling frame. 1916 // Get the frame pointer for the calling frame.
2051 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 1917 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2052 1918
2053 // Skip the arguments adaptor frame if it exists. 1919 // Skip the arguments adaptor frame if it exists.
2054 Label check_frame_marker; 1920 Label check_frame_marker;
2055 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset)); 1921 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset));
2056 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1922 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2057 __ b(ne, &check_frame_marker); 1923 __ b(ne, &check_frame_marker);
2058 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset)); 1924 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset));
2059 1925
2060 // Check the marker in the calling frame. 1926 // Check the marker in the calling frame.
2061 __ bind(&check_frame_marker); 1927 __ bind(&check_frame_marker);
2062 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); 1928 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
2063 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 1929 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
2064 __ b(eq, if_true); 1930 Split(eq, if_true, if_false, NULL);
2065 __ b(if_false);
2066 1931
2067 Apply(context_, if_true, if_false); 1932 Apply(context_, if_true, if_false);
2068 } 1933 }
2069 1934
2070 1935
2071 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { 1936 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) {
2072 ASSERT(args->length() == 2); 1937 ASSERT(args->length() == 2);
2073 1938
2074 // Load the two objects into registers and perform the comparison. 1939 // Load the two objects into registers and perform the comparison.
2075 VisitForValue(args->at(0), kStack); 1940 VisitForValue(args->at(0), kStack);
2076 VisitForValue(args->at(1), kAccumulator); 1941 VisitForValue(args->at(1), kAccumulator);
2077 1942
2078 Label materialize_true, materialize_false; 1943 Label materialize_true, materialize_false;
2079 Label* if_true = NULL; 1944 Label* if_true = NULL;
2080 Label* if_false = NULL; 1945 Label* if_false = NULL;
2081 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1946 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
2082 1947
2083 __ pop(r1); 1948 __ pop(r1);
2084 __ cmp(r0, r1); 1949 __ cmp(r0, r1);
2085 __ b(eq, if_true); 1950 Split(eq, if_true, if_false, NULL);
2086 __ b(if_false);
2087 1951
2088 Apply(context_, if_true, if_false); 1952 Apply(context_, if_true, if_false);
2089 } 1953 }
2090 1954
2091 1955
2092 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 1956 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2093 ASSERT(args->length() == 1); 1957 ASSERT(args->length() == 1);
2094 1958
2095 // ArgumentsAccessStub expects the key in edx and the formal 1959 // ArgumentsAccessStub expects the key in edx and the formal
2096 // parameter count in eax. 1960 // parameter count in eax.
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
2745 case Expression::kValue: 2609 case Expression::kValue:
2746 __ LoadRoot(result_register(), Heap::kUndefinedValueRootIndex); 2610 __ LoadRoot(result_register(), Heap::kUndefinedValueRootIndex);
2747 switch (location_) { 2611 switch (location_) {
2748 case kAccumulator: 2612 case kAccumulator:
2749 break; 2613 break;
2750 case kStack: 2614 case kStack:
2751 __ push(result_register()); 2615 __ push(result_register());
2752 break; 2616 break;
2753 } 2617 }
2754 break; 2618 break;
2755 case Expression::kTestValue:
2756 // Value is false so it's needed.
2757 __ LoadRoot(result_register(), Heap::kUndefinedValueRootIndex);
2758 switch (location_) {
2759 case kAccumulator:
2760 break;
2761 case kStack:
2762 __ push(result_register());
2763 break;
2764 }
2765 // Fall through.
2766 case Expression::kTest: 2619 case Expression::kTest:
2767 case Expression::kValueTest:
2768 __ jmp(false_label_); 2620 __ jmp(false_label_);
2769 break; 2621 break;
2770 } 2622 }
2771 break; 2623 break;
2772 } 2624 }
2773 2625
2774 case Token::NOT: { 2626 case Token::NOT: {
2775 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 2627 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
2776 Label materialize_true, materialize_false; 2628 Label materialize_true, materialize_false;
2777 Label* if_true = NULL; 2629 Label* if_true = NULL;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 // Save result for postfix expressions. 2790 // Save result for postfix expressions.
2939 if (expr->is_postfix()) { 2791 if (expr->is_postfix()) {
2940 switch (context_) { 2792 switch (context_) {
2941 case Expression::kUninitialized: 2793 case Expression::kUninitialized:
2942 UNREACHABLE(); 2794 UNREACHABLE();
2943 case Expression::kEffect: 2795 case Expression::kEffect:
2944 // Do not save result. 2796 // Do not save result.
2945 break; 2797 break;
2946 case Expression::kValue: 2798 case Expression::kValue:
2947 case Expression::kTest: 2799 case Expression::kTest:
2948 case Expression::kValueTest:
2949 case Expression::kTestValue:
2950 // Save the result on the stack. If we have a named or keyed property 2800 // Save the result on the stack. If we have a named or keyed property
2951 // we store the result under the receiver that is currently on top 2801 // we store the result under the receiver that is currently on top
2952 // of the stack. 2802 // of the stack.
2953 switch (assign_type) { 2803 switch (assign_type) {
2954 case VARIABLE: 2804 case VARIABLE:
2955 __ push(r0); 2805 __ push(r0);
2956 break; 2806 break;
2957 case NAMED_PROPERTY: 2807 case NAMED_PROPERTY:
2958 __ str(r0, MemOperand(sp, kPointerSize)); 2808 __ str(r0, MemOperand(sp, kPointerSize));
2959 break; 2809 break;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3027 } 2877 }
3028 } else { 2878 } else {
3029 Apply(context_, r0); 2879 Apply(context_, r0);
3030 } 2880 }
3031 break; 2881 break;
3032 } 2882 }
3033 } 2883 }
3034 } 2884 }
3035 2885
3036 2886
3037 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
3038 Comment cmnt(masm_, "[ BinaryOperation");
3039 switch (expr->op()) {
3040 case Token::COMMA:
3041 VisitForEffect(expr->left());
3042 Visit(expr->right());
3043 break;
3044
3045 case Token::OR:
3046 case Token::AND:
3047 EmitLogicalOperation(expr);
3048 break;
3049
3050 case Token::ADD:
3051 case Token::SUB:
3052 case Token::DIV:
3053 case Token::MOD:
3054 case Token::MUL:
3055 case Token::BIT_OR:
3056 case Token::BIT_AND:
3057 case Token::BIT_XOR:
3058 case Token::SHL:
3059 case Token::SHR:
3060 case Token::SAR:
3061 VisitForValue(expr->left(), kStack);
3062 VisitForValue(expr->right(), kAccumulator);
3063 EmitBinaryOp(expr->op(), context_);
3064 break;
3065
3066 default:
3067 UNREACHABLE();
3068 }
3069 }
3070
3071
3072 void FullCodeGenerator::EmitNullCompare(bool strict, 2887 void FullCodeGenerator::EmitNullCompare(bool strict,
3073 Register obj, 2888 Register obj,
3074 Register null_const, 2889 Register null_const,
3075 Label* if_true, 2890 Label* if_true,
3076 Label* if_false, 2891 Label* if_false,
3077 Register scratch) { 2892 Register scratch) {
3078 __ cmp(obj, null_const); 2893 __ cmp(obj, null_const);
3079 if (strict) { 2894 if (strict) {
3080 __ b(eq, if_true); 2895 Split(eq, if_true, if_false, NULL);
3081 } else { 2896 } else {
3082 __ b(eq, if_true); 2897 __ b(eq, if_true);
3083 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 2898 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3084 __ cmp(obj, ip); 2899 __ cmp(obj, ip);
3085 __ b(eq, if_true); 2900 __ b(eq, if_true);
3086 __ BranchOnSmi(obj, if_false); 2901 __ BranchOnSmi(obj, if_false);
3087 // It can be an undetectable object. 2902 // It can be an undetectable object.
3088 __ ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); 2903 __ ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
3089 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); 2904 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
3090 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); 2905 __ tst(scratch, Operand(1 << Map::kIsUndetectable));
3091 __ b(ne, if_true); 2906 Split(ne, if_true, if_false, NULL);
3092 } 2907 }
3093 __ jmp(if_false);
3094 } 2908 }
3095 2909
3096 2910
3097 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 2911 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
3098 Comment cmnt(masm_, "[ CompareOperation"); 2912 Comment cmnt(masm_, "[ CompareOperation");
3099 2913
3100 // Always perform the comparison for its control flow. Pack the result 2914 // Always perform the comparison for its control flow. Pack the result
3101 // into the expression's context after the comparison is performed. 2915 // into the expression's context after the comparison is performed.
3102 2916
3103 Label materialize_true, materialize_false; 2917 Label materialize_true, materialize_false;
3104 Label* if_true = NULL; 2918 Label* if_true = NULL;
3105 Label* if_false = NULL; 2919 Label* if_false = NULL;
3106 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 2920 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
3107 2921
3108 VisitForValue(expr->left(), kStack); 2922 VisitForValue(expr->left(), kStack);
3109 switch (expr->op()) { 2923 switch (expr->op()) {
3110 case Token::IN: 2924 case Token::IN:
3111 VisitForValue(expr->right(), kStack); 2925 VisitForValue(expr->right(), kStack);
3112 __ InvokeBuiltin(Builtins::IN, CALL_JS); 2926 __ InvokeBuiltin(Builtins::IN, CALL_JS);
3113 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 2927 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
3114 __ cmp(r0, ip); 2928 __ cmp(r0, ip);
3115 __ b(eq, if_true); 2929 Split(eq, if_true, if_false, NULL);
3116 __ jmp(if_false);
3117 break; 2930 break;
3118 2931
3119 case Token::INSTANCEOF: { 2932 case Token::INSTANCEOF: {
3120 VisitForValue(expr->right(), kStack); 2933 VisitForValue(expr->right(), kStack);
3121 InstanceofStub stub; 2934 InstanceofStub stub;
3122 __ CallStub(&stub); 2935 __ CallStub(&stub);
2936 // The stub returns 0 for true.
3123 __ tst(r0, r0); 2937 __ tst(r0, r0);
3124 __ b(eq, if_true); // The stub returns 0 for true. 2938 Split(eq, if_true, if_false, NULL);
3125 __ jmp(if_false);
3126 break; 2939 break;
3127 } 2940 }
3128 2941
3129 default: { 2942 default: {
3130 VisitForValue(expr->right(), kAccumulator); 2943 VisitForValue(expr->right(), kAccumulator);
3131 Condition cc = eq; 2944 Condition cc = eq;
3132 bool strict = false; 2945 bool strict = false;
3133 switch (expr->op()) { 2946 switch (expr->op()) {
3134 case Token::EQ_STRICT: 2947 case Token::EQ_STRICT:
3135 strict = true; 2948 strict = true;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3184 __ orr(r2, r0, Operand(r1)); 2997 __ orr(r2, r0, Operand(r1));
3185 __ BranchOnNotSmi(r2, &slow_case); 2998 __ BranchOnNotSmi(r2, &slow_case);
3186 __ cmp(r1, r0); 2999 __ cmp(r1, r0);
3187 __ b(cc, if_true); 3000 __ b(cc, if_true);
3188 __ jmp(if_false); 3001 __ jmp(if_false);
3189 3002
3190 __ bind(&slow_case); 3003 __ bind(&slow_case);
3191 CompareStub stub(cc, strict, kBothCouldBeNaN, true, r1, r0); 3004 CompareStub stub(cc, strict, kBothCouldBeNaN, true, r1, r0);
3192 __ CallStub(&stub); 3005 __ CallStub(&stub);
3193 __ cmp(r0, Operand(0)); 3006 __ cmp(r0, Operand(0));
3194 __ b(cc, if_true); 3007 Split(cc, if_true, if_false, NULL);
3195 __ jmp(if_false);
3196 } 3008 }
3197 } 3009 }
3198 3010
3199 // Convert the result of the comparison into one expected for this 3011 // Convert the result of the comparison into one expected for this
3200 // expression's context. 3012 // expression's context.
3201 Apply(context_, if_true, if_false); 3013 Apply(context_, if_true, if_false);
3202 } 3014 }
3203 3015
3204 3016
3205 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 3017 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3251 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3063 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3252 __ add(pc, r1, Operand(masm_->CodeObject())); 3064 __ add(pc, r1, Operand(masm_->CodeObject()));
3253 } 3065 }
3254 3066
3255 3067
3256 #undef __ 3068 #undef __
3257 3069
3258 } } // namespace v8::internal 3070 } } // namespace v8::internal
3259 3071
3260 #endif // V8_TARGET_ARCH_ARM 3072 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698