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

Side by Side Diff: runtime/vm/intermediate_language_mips.cc

Issue 16022011: Enables optimization on MIPS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | « runtime/vm/instructions_mips.h ('k') | runtime/vm/simulator_mips.cc » ('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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 // A finally clause may leave a previously pushed return value if it 85 // A finally clause may leave a previously pushed return value if it
86 // has its own return instruction. Method that have finally are currently 86 // has its own return instruction. Method that have finally are currently
87 // not optimized. 87 // not optimized.
88 if (!compiler->HasFinally()) { 88 if (!compiler->HasFinally()) {
89 Label stack_ok; 89 Label stack_ok;
90 __ Comment("Stack Check"); 90 __ Comment("Stack Check");
91 __ TraceSimMsg("Stack Check"); 91 __ TraceSimMsg("Stack Check");
92 const intptr_t fp_sp_dist = 92 const intptr_t fp_sp_dist =
93 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; 93 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
94 ASSERT(fp_sp_dist <= 0); 94 ASSERT(fp_sp_dist <= 0);
95 __ subu(T2, SP, FP); 95 __ subu(TMP1, SP, FP);
96 96
97 __ BranchEqual(T2, fp_sp_dist, &stack_ok); 97 __ BranchEqual(TMP1, fp_sp_dist, &stack_ok);
98 __ break_(0); 98 __ break_(0);
99 99
100 __ Bind(&stack_ok); 100 __ Bind(&stack_ok);
101 } 101 }
102 #endif 102 #endif
103 // This sequence is patched by a debugger breakpoint. There is no need for 103 // This sequence is patched by a debugger breakpoint. There is no need for
104 // extra NOP instructions here because the sequence patched in for a 104 // extra NOP instructions here because the sequence patched in for a
105 // breakpoint is shorter than the sequence here. 105 // breakpoint is shorter than the sequence here.
106 __ LeaveDartFrameAndReturn(); 106 __ LeaveDartFrameAndReturn();
107 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 107 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 locs->set_in(0, Location::RequiresRegister()); 321 locs->set_in(0, Location::RequiresRegister());
322 locs->set_in(1, Location::RequiresRegister()); 322 locs->set_in(1, Location::RequiresRegister());
323 locs->set_temp(0, Location::RequiresRegister()); 323 locs->set_temp(0, Location::RequiresRegister());
324 locs->set_out(Location::RequiresRegister()); 324 locs->set_out(Location::RequiresRegister());
325 return locs; 325 return locs;
326 } 326 }
327 if (IsPolymorphic()) { 327 if (IsPolymorphic()) {
328 const intptr_t kNumTemps = 1; 328 const intptr_t kNumTemps = 1;
329 LocationSummary* locs = 329 LocationSummary* locs =
330 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 330 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
331 UNIMPLEMENTED(); // TODO(regis): Verify register allocation. 331 locs->set_in(0, Location::RegisterLocation(A1));
332 locs->set_in(1, Location::RegisterLocation(A0));
333 locs->set_temp(0, Location::RegisterLocation(T0));
334 locs->set_out(Location::RegisterLocation(V0));
332 return locs; 335 return locs;
333 } 336 }
334 const intptr_t kNumTemps = 1; 337 const intptr_t kNumTemps = 1;
335 LocationSummary* locs = 338 LocationSummary* locs =
336 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 339 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
337 locs->set_in(0, Location::RegisterLocation(A1)); 340 locs->set_in(0, Location::RegisterLocation(A1));
338 locs->set_in(1, Location::RegisterLocation(A0)); 341 locs->set_in(1, Location::RegisterLocation(A0));
339 locs->set_temp(0, Location::RegisterLocation(T0)); 342 locs->set_temp(0, Location::RegisterLocation(T0));
340 locs->set_out(Location::RegisterLocation(V0)); 343 locs->set_out(Location::RegisterLocation(V0));
341 return locs; 344 return locs;
(...skipping 14 matching lines...) Expand all
356 if (!compiler->is_optimizing()) { 359 if (!compiler->is_optimizing()) {
357 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 360 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
358 deopt_id, 361 deopt_id,
359 token_pos); 362 token_pos);
360 } 363 }
361 const int kNumberOfArguments = 2; 364 const int kNumberOfArguments = 2;
362 const Array& kNoArgumentNames = Array::Handle(); 365 const Array& kNoArgumentNames = Array::Handle();
363 const int kNumArgumentsChecked = 2; 366 const int kNumArgumentsChecked = 2;
364 367
365 Label check_identity; 368 Label check_identity;
366 __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null())); 369 __ beq(A1, NULLREG, &check_identity);
367 __ beq(A1, TMP1, &check_identity); 370 __ beq(A0, NULLREG, &check_identity);
368 __ beq(A0, TMP1, &check_identity);
369 371
370 ICData& equality_ic_data = ICData::ZoneHandle(); 372 ICData& equality_ic_data = ICData::ZoneHandle();
371 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 373 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
372 ASSERT(!original_ic_data.IsNull()); 374 ASSERT(!original_ic_data.IsNull());
373 if (original_ic_data.NumberOfChecks() == 0) { 375 if (original_ic_data.NumberOfChecks() == 0) {
374 // IC call for reoptimization populates original ICData. 376 // IC call for reoptimization populates original ICData.
375 equality_ic_data = original_ic_data.raw(); 377 equality_ic_data = original_ic_data.raw();
376 } else { 378 } else {
377 // Megamorphic call. 379 // Megamorphic call.
378 equality_ic_data = original_ic_data.AsUnaryClassChecks(); 380 equality_ic_data = original_ic_data.AsUnaryClassChecks();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 case Token::kGT: return GT; 491 case Token::kGT: return GT;
490 case Token::kLTE: return LE; 492 case Token::kLTE: return LE;
491 case Token::kGTE: return GE; 493 case Token::kGTE: return GE;
492 default: 494 default:
493 UNREACHABLE(); 495 UNREACHABLE();
494 return VS; 496 return VS;
495 } 497 }
496 } 498 }
497 499
498 500
501 // Branches on condition c assuming comparison results in CMPRES and TMP1.
502 static void EmitBranchAfterCompare(
503 FlowGraphCompiler* compiler, Condition c, Label* is_true) {
504 switch (c) {
505 case EQ: __ beq(CMPRES, TMP1, is_true); break;
506 case NE: __ bne(CMPRES, TMP1, is_true); break;
507 case GT: __ bne(TMP1, ZR, is_true); break;
508 case GE: __ beq(CMPRES, ZR, is_true); break;
509 case LT: __ bne(CMPRES, ZR, is_true); break;
510 case LE: __ beq(TMP1, ZR, is_true); break;
511 default:
512 UNREACHABLE();
513 break;
514 }
515 }
516
517
499 static Condition FlipCondition(Condition condition) { 518 static Condition FlipCondition(Condition condition) {
500 UNIMPLEMENTED(); 519 UNIMPLEMENTED();
501 return condition; 520 return condition;
502 } 521 }
503 522
504 523
505 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 524 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
506 const LocationSummary& locs, 525 const LocationSummary& locs,
507 Token::Kind kind, 526 Token::Kind kind,
508 BranchInstr* branch) { 527 BranchInstr* branch) {
509 __ TraceSimMsg("EmitSmiComparisonOp"); 528 __ TraceSimMsg("EmitSmiComparisonOp");
510 Location left = locs.in(0); 529 Location left = locs.in(0);
511 Location right = locs.in(1); 530 Location right = locs.in(1);
512 ASSERT(!left.IsConstant() || !right.IsConstant()); 531 ASSERT(!left.IsConstant() || !right.IsConstant());
513 532
514 Condition true_condition = TokenKindToSmiCondition(kind); 533 Condition true_condition = TokenKindToSmiCondition(kind);
515 534
516 if (left.IsConstant()) { 535 if (left.IsConstant()) {
517 __ CompareObject(CMPRES, right.reg(), left.constant()); 536 __ CompareObject(CMPRES, TMP1, right.reg(), left.constant());
518 true_condition = FlipCondition(true_condition); 537 true_condition = FlipCondition(true_condition);
519 } else if (right.IsConstant()) { 538 } else if (right.IsConstant()) {
520 __ CompareObject(CMPRES, left.reg(), right.constant()); 539 __ CompareObject(CMPRES, TMP1, left.reg(), right.constant());
521 } else { 540 } else {
522 __ subu(CMPRES, left.reg(), right.reg()); 541 __ slt(CMPRES, left.reg(), right.reg());
542 __ slt(TMP1, right.reg(), left.reg());
523 } 543 }
524 544
525 if (branch != NULL) { 545 if (branch != NULL) {
526 branch->EmitBranchOnCondition(compiler, true_condition); 546 branch->EmitBranchOnCondition(compiler, true_condition);
527 } else { 547 } else {
528 Register result = locs.out().reg(); 548 Register result = locs.out().reg();
529 Label done, is_true; 549 Label done, is_true;
530 switch (true_condition) { 550 EmitBranchAfterCompare(compiler, true_condition, &is_true);
531 case EQ: __ beq(CMPRES, ZR, &is_true); break;
532 case NE: __ bne(CMPRES, ZR, &is_true); break;
533 case GT: __ bgtz(CMPRES, &is_true); break;
534 case GE: __ bgez(CMPRES, &is_true); break;
535 case LT: __ bltz(CMPRES, &is_true); break;
536 case LE: __ blez(CMPRES, &is_true); break;
537 default:
538 UNREACHABLE();
539 break;
540 }
541 __ LoadObject(result, Bool::False()); 551 __ LoadObject(result, Bool::False());
542 __ b(&done); 552 __ b(&done);
543 __ Bind(&is_true); 553 __ Bind(&is_true);
544 __ LoadObject(result, Bool::True()); 554 __ LoadObject(result, Bool::True());
545 __ Bind(&done); 555 __ Bind(&done);
546 } 556 }
547 } 557 }
548 558
549 559
550 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 560 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 EmitEqualityAsInstanceCall(compiler, 658 EmitEqualityAsInstanceCall(compiler,
649 deopt_id(), 659 deopt_id(),
650 token_pos(), 660 token_pos(),
651 Token::kEQ, // kNE reverse occurs at branch. 661 Token::kEQ, // kNE reverse occurs at branch.
652 locs(), 662 locs(),
653 *ic_data()); 663 *ic_data());
654 if (branch->is_checked()) { 664 if (branch->is_checked()) {
655 EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler); 665 EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler);
656 } 666 }
657 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; 667 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ;
658 __ CompareObject(CMPRES, V0, Bool::True()); 668 __ CompareObject(CMPRES, TMP1, V0, Bool::True());
659 branch->EmitBranchOnCondition(compiler, branch_condition); 669 branch->EmitBranchOnCondition(compiler, branch_condition);
660 } 670 }
661 671
662 672
663 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 673 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
664 const intptr_t kNumInputs = 2; 674 const intptr_t kNumInputs = 2;
665 const intptr_t kNumTemps = 0; 675 const intptr_t kNumTemps = 0;
666 if (operands_class_id() == kMintCid) { 676 if (operands_class_id() == kMintCid) {
667 const intptr_t kNumTemps = 2; 677 const intptr_t kNumTemps = 2;
668 LocationSummary* locs = 678 LocationSummary* locs =
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 } 794 }
785 if (operands_class_id() == kMintCid) { 795 if (operands_class_id() == kMintCid) {
786 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); 796 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
787 return; 797 return;
788 } 798 }
789 if (operands_class_id() == kDoubleCid) { 799 if (operands_class_id() == kDoubleCid) {
790 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 800 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
791 return; 801 return;
792 } 802 }
793 EmitNativeCode(compiler); 803 EmitNativeCode(compiler);
794 __ CompareObject(CMPRES, V0, Bool::True()); 804 __ CompareObject(CMPRES, TMP1, V0, Bool::True());
795 branch->EmitBranchOnCondition(compiler, EQ); 805 branch->EmitBranchOnCondition(compiler, EQ);
796 } 806 }
797 807
798 808
799 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 809 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
800 const intptr_t kNumInputs = 0; 810 const intptr_t kNumInputs = 0;
801 const intptr_t kNumTemps = 3; 811 const intptr_t kNumTemps = 3;
802 LocationSummary* locs = 812 LocationSummary* locs =
803 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 813 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
804 locs->set_temp(0, Location::RegisterLocation(A1)); 814 locs->set_temp(0, Location::RegisterLocation(A1));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 return NULL; 868 return NULL;
859 } 869 }
860 870
861 871
862 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 872 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
863 UNIMPLEMENTED(); 873 UNIMPLEMENTED();
864 } 874 }
865 875
866 876
867 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { 877 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const {
868 UNIMPLEMENTED(); 878 const intptr_t kNumInputs = 1;
869 return NULL; 879 return LocationSummary::Make(kNumInputs,
880 Location::RequiresRegister(),
881 LocationSummary::kNoCall);
870 } 882 }
871 883
872 884
873 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 885 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
874 UNIMPLEMENTED(); 886 Register object = locs()->in(0).reg();
887 Register result = locs()->out().reg();
888 Label load, done;
889 __ andi(CMPRES, object, Immediate(kSmiTagMask));
890 __ bne(CMPRES, ZR, &load);
891 __ LoadImmediate(result, Smi::RawValue(kSmiCid));
892 __ b(&done);
893 __ Bind(&load);
894 __ LoadClassId(result, object);
895 __ SmiTag(result);
896 __ Bind(&done);
875 } 897 }
876 898
877 899
878 CompileType LoadIndexedInstr::ComputeType() const { 900 CompileType LoadIndexedInstr::ComputeType() const {
879 switch (class_id_) { 901 switch (class_id_) {
880 case kArrayCid: 902 case kArrayCid:
881 case kImmutableArrayCid: 903 case kImmutableArrayCid:
882 return CompileType::Dynamic(); 904 return CompileType::Dynamic();
883 905
884 case kTypedDataFloat32ArrayCid: 906 case kTypedDataFloat32ArrayCid:
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 __ sll(index.reg(), index.reg(), 2); 1015 __ sll(index.reg(), index.reg(), 2);
994 break; 1016 break;
995 } 1017 }
996 case 16: { 1018 case 16: {
997 __ sll(index.reg(), index.reg(), 3); 1019 __ sll(index.reg(), index.reg(), 3);
998 break; 1020 break;
999 } 1021 }
1000 default: 1022 default:
1001 UNREACHABLE(); 1023 UNREACHABLE();
1002 } 1024 }
1003 __ AddImmediate(index.reg(), 1025 __ addu(index.reg(), array, index.reg());
1026 element_address = Address(index.reg(),
1004 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1027 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1005 element_address = Address(array, index.reg());
1006 } 1028 }
1007 1029
1008 if ((representation() == kUnboxedDouble) || 1030 if ((representation() == kUnboxedDouble) ||
1009 (representation() == kUnboxedMint) || 1031 (representation() == kUnboxedMint) ||
1010 (representation() == kUnboxedFloat32x4)) { 1032 (representation() == kUnboxedFloat32x4)) {
1011 UNIMPLEMENTED(); 1033 UNIMPLEMENTED();
1012 } 1034 }
1013 1035
1014 Register result = locs()->out().reg(); 1036 Register result = locs()->out().reg();
1015 if ((index_scale() == 1) && index.IsRegister()) {
1016 __ SmiUntag(index.reg());
1017 }
1018 switch (class_id()) { 1037 switch (class_id()) {
1019 case kTypedDataInt8ArrayCid: 1038 case kTypedDataInt8ArrayCid:
1020 ASSERT(index_scale() == 1); 1039 ASSERT(index_scale() == 1);
1021 __ lb(result, element_address); 1040 __ lb(result, element_address);
1022 __ SmiTag(result); 1041 __ SmiTag(result);
1023 break; 1042 break;
1024 case kTypedDataUint8ArrayCid: 1043 case kTypedDataUint8ArrayCid:
1025 case kTypedDataUint8ClampedArrayCid: 1044 case kTypedDataUint8ClampedArrayCid:
1026 case kExternalTypedDataUint8ArrayCid: 1045 case kExternalTypedDataUint8ArrayCid:
1027 case kExternalTypedDataUint8ClampedArrayCid: 1046 case kExternalTypedDataUint8ClampedArrayCid:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 default: 1079 default:
1061 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1080 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1062 __ lw(result, element_address); 1081 __ lw(result, element_address);
1063 break; 1082 break;
1064 } 1083 }
1065 } 1084 }
1066 1085
1067 1086
1068 Representation StoreIndexedInstr::RequiredInputRepresentation( 1087 Representation StoreIndexedInstr::RequiredInputRepresentation(
1069 intptr_t idx) const { 1088 intptr_t idx) const {
1070 UNIMPLEMENTED(); 1089 // Array can be a Dart object or a pointer to external data.
1071 return kTagged; 1090 if (idx == 0) return kNoRepresentation; // Flexible input representation.
1091 if (idx == 1) return kTagged; // Index is a smi.
1092 ASSERT(idx == 2);
1093 switch (class_id_) {
1094 case kArrayCid:
1095 case kOneByteStringCid:
1096 case kTypedDataInt8ArrayCid:
1097 case kTypedDataUint8ArrayCid:
1098 case kExternalTypedDataUint8ArrayCid:
1099 case kTypedDataUint8ClampedArrayCid:
1100 case kExternalTypedDataUint8ClampedArrayCid:
1101 case kTypedDataInt16ArrayCid:
1102 case kTypedDataUint16ArrayCid:
1103 return kTagged;
1104 case kTypedDataInt32ArrayCid:
1105 case kTypedDataUint32ArrayCid:
1106 return value()->IsSmiValue() ? kTagged : kUnboxedMint;
1107 case kTypedDataFloat32ArrayCid:
1108 case kTypedDataFloat64ArrayCid:
1109 return kUnboxedDouble;
1110 case kTypedDataFloat32x4ArrayCid:
1111 return kUnboxedFloat32x4;
1112 default:
1113 UNIMPLEMENTED();
1114 return kTagged;
1115 }
1072 } 1116 }
1073 1117
1074 1118
1075 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1119 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1076 const intptr_t kNumInputs = 3; 1120 const intptr_t kNumInputs = 3;
1077 const intptr_t kNumTemps = 0; 1121 const intptr_t kNumTemps = 0;
1078 LocationSummary* locs = 1122 LocationSummary* locs =
1079 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1123 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1080 locs->set_in(0, Location::RequiresRegister()); 1124 locs->set_in(0, Location::RequiresRegister());
1081 // The smi index is either untagged (element size == 1), or it is left smi 1125 // The smi index is either untagged (element size == 1), or it is left smi
1082 // tagged (for all element sizes > 1). 1126 // tagged (for all element sizes > 1).
1083 // TODO(regis): Revisit and see if the index can be immediate. 1127 // TODO(regis): Revisit and see if the index can be immediate.
1084 locs->set_in(1, Location::WritableRegister()); 1128 locs->set_in(1, Location::WritableRegister());
1085 switch (class_id()) { 1129 switch (class_id()) {
1086 case kArrayCid: 1130 case kArrayCid:
1087 locs->set_in(2, ShouldEmitStoreBarrier() 1131 locs->set_in(2, ShouldEmitStoreBarrier()
1088 ? Location::WritableRegister() 1132 ? Location::WritableRegister()
1089 : Location::RegisterOrConstant(value())); 1133 : Location::RegisterOrConstant(value()));
1090 break; 1134 break;
1091 case kExternalTypedDataUint8ArrayCid: 1135 case kExternalTypedDataUint8ArrayCid:
1092 case kExternalTypedDataUint8ClampedArrayCid: 1136 case kExternalTypedDataUint8ClampedArrayCid:
1093 case kTypedDataInt8ArrayCid: 1137 case kTypedDataInt8ArrayCid:
1094 case kTypedDataUint8ArrayCid: 1138 case kTypedDataUint8ArrayCid:
1095 case kTypedDataUint8ClampedArrayCid: 1139 case kTypedDataUint8ClampedArrayCid:
1096 case kOneByteStringCid: 1140 case kOneByteStringCid:
1141 locs->set_in(2, Location::RegisterOrSmiConstant(value()));
1142 break;
1097 case kTypedDataInt16ArrayCid: 1143 case kTypedDataInt16ArrayCid:
1098 case kTypedDataUint16ArrayCid: 1144 case kTypedDataUint16ArrayCid:
1099 case kTypedDataInt32ArrayCid: 1145 case kTypedDataInt32ArrayCid:
1100 case kTypedDataUint32ArrayCid: 1146 case kTypedDataUint32ArrayCid:
1147 locs->set_in(2, Location::WritableRegister());
1148 break;
1101 case kTypedDataFloat32ArrayCid: 1149 case kTypedDataFloat32ArrayCid:
1102 case kTypedDataFloat64ArrayCid: 1150 // TODO(regis): Verify.
1151 // Need temp register for float-to-double conversion.
1152 locs->AddTemp(Location::RequiresFpuRegister());
1153 // Fall through.
1154 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
1103 case kTypedDataFloat32x4ArrayCid: 1155 case kTypedDataFloat32x4ArrayCid:
1104 UNIMPLEMENTED(); 1156 locs->set_in(2, Location::RequiresFpuRegister());
1105 break; 1157 break;
1106 default: 1158 default:
1107 UNREACHABLE(); 1159 UNREACHABLE();
1108 return NULL; 1160 return NULL;
1109 } 1161 }
1110 return locs; 1162 return locs;
1111 } 1163 }
1112 1164
1113 1165
1114 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1166 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 27 matching lines...) Expand all
1142 __ sll(index.reg(), index.reg(), 2); 1194 __ sll(index.reg(), index.reg(), 2);
1143 break; 1195 break;
1144 } 1196 }
1145 case 16: { 1197 case 16: {
1146 __ sll(index.reg(), index.reg(), 3); 1198 __ sll(index.reg(), index.reg(), 3);
1147 break; 1199 break;
1148 } 1200 }
1149 default: 1201 default:
1150 UNREACHABLE(); 1202 UNREACHABLE();
1151 } 1203 }
1152 __ AddImmediate(index.reg(), 1204 __ addu(index.reg(), array, index.reg());
1205 element_address = Address(index.reg(),
1153 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1206 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1154 __ addu(TMP1, array, index.reg());
1155 element_address = Address(TMP1);
1156 } 1207 }
1157 1208
1158 switch (class_id()) { 1209 switch (class_id()) {
1159 case kArrayCid: 1210 case kArrayCid:
1160 if (ShouldEmitStoreBarrier()) { 1211 if (ShouldEmitStoreBarrier()) {
1161 Register value = locs()->in(2).reg(); 1212 Register value = locs()->in(2).reg();
1162 __ StoreIntoObject(array, element_address, value); 1213 __ StoreIntoObject(array, element_address, value);
1163 } else if (locs()->in(2).IsConstant()) { 1214 } else if (locs()->in(2).IsConstant()) {
1164 const Object& constant = locs()->in(2).constant(); 1215 const Object& constant = locs()->in(2).constant();
1165 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1216 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1166 } else { 1217 } else {
1167 Register value = locs()->in(2).reg(); 1218 Register value = locs()->in(2).reg();
1168 __ StoreIntoObjectNoBarrier(array, element_address, value); 1219 __ StoreIntoObjectNoBarrier(array, element_address, value);
1169 } 1220 }
1170 break; 1221 break;
1171 case kTypedDataInt8ArrayCid: 1222 case kTypedDataInt8ArrayCid:
1172 case kTypedDataUint8ArrayCid: 1223 case kTypedDataUint8ArrayCid:
1173 case kExternalTypedDataUint8ArrayCid: 1224 case kExternalTypedDataUint8ArrayCid:
1225 case kOneByteStringCid: {
1226 if (locs()->in(2).IsConstant()) {
1227 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1228 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()));
1229 __ sb(TMP, element_address);
1230 } else {
1231 Register value = locs()->in(2).reg();
1232 __ SmiUntag(value);
1233 __ sb(value, element_address);
1234 }
1235 break;
1236 }
1174 case kTypedDataUint8ClampedArrayCid: 1237 case kTypedDataUint8ClampedArrayCid:
1175 case kExternalTypedDataUint8ClampedArrayCid: 1238 case kExternalTypedDataUint8ClampedArrayCid: {
1176 case kOneByteStringCid: 1239 if (locs()->in(2).IsConstant()) {
1240 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1241 intptr_t value = constant.Value();
1242 // Clamp to 0x0 or 0xFF respectively.
1243 if (value > 0xFF) {
1244 value = 0xFF;
1245 } else if (value < 0) {
1246 value = 0;
1247 }
1248 __ LoadImmediate(TMP, static_cast<int8_t>(value));
1249 __ sb(TMP, element_address);
1250 } else {
1251 Register value = locs()->in(2).reg();
1252 Label store_value, bigger, smaller;
1253 __ SmiUntag(value);
1254 __ BranchUnsignedLess(value, 0xFF + 1, &store_value);
1255 __ LoadImmediate(TMP, 0xFF);
1256 __ slti(CMPRES, value, Immediate(1));
1257 __ movn(TMP, ZR, CMPRES);
1258 __ mov(value, TMP);
1259 __ Bind(&store_value);
1260 __ sb(value, element_address);
1261 }
1262 break;
1263 }
1177 case kTypedDataInt16ArrayCid: 1264 case kTypedDataInt16ArrayCid:
1178 case kTypedDataUint16ArrayCid: 1265 case kTypedDataUint16ArrayCid: {
1266 Register value = locs()->in(2).reg();
1267 __ SmiUntag(value);
1268 __ sh(value, element_address);
1269 break;
1270 }
1179 case kTypedDataInt32ArrayCid: 1271 case kTypedDataInt32ArrayCid:
1180 case kTypedDataUint32ArrayCid: 1272 case kTypedDataUint32ArrayCid: {
1273 if (value()->IsSmiValue()) {
1274 ASSERT(RequiredInputRepresentation(2) == kTagged);
1275 Register value = locs()->in(2).reg();
1276 __ SmiUntag(value);
1277 __ sw(value, element_address);
1278 } else {
1279 UNIMPLEMENTED();
1280 }
1281 break;
1282 }
1181 case kTypedDataFloat32ArrayCid: 1283 case kTypedDataFloat32ArrayCid:
1182 case kTypedDataFloat64ArrayCid: 1284 case kTypedDataFloat64ArrayCid:
1183 case kTypedDataFloat32x4ArrayCid: 1285 case kTypedDataFloat32x4ArrayCid:
1184 UNIMPLEMENTED(); 1286 UNIMPLEMENTED();
1185 break; 1287 break;
1186 default: 1288 default:
1187 UNREACHABLE(); 1289 UNREACHABLE();
1188 } 1290 }
1189 } 1291 }
1190 1292
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 1400
1299 if (field_cid != kSmiCid) { 1401 if (field_cid != kSmiCid) {
1300 __ beq(CMPRES, ZR, fail); 1402 __ beq(CMPRES, ZR, fail);
1301 __ LoadClassId(value_cid_reg, value_reg); 1403 __ LoadClassId(value_cid_reg, value_reg);
1302 __ LoadImmediate(TMP1, field_cid); 1404 __ LoadImmediate(TMP1, field_cid);
1303 __ subu(CMPRES, value_cid_reg, TMP1); 1405 __ subu(CMPRES, value_cid_reg, TMP1);
1304 } 1406 }
1305 1407
1306 if (field().is_nullable() && (field_cid != kNullCid)) { 1408 if (field().is_nullable() && (field_cid != kNullCid)) {
1307 __ beq(CMPRES, ZR, &ok); 1409 __ beq(CMPRES, ZR, &ok);
1308 __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null())); 1410 __ subu(CMPRES, value_reg, NULLREG);
1309 __ subu(CMPRES, value_reg, TMP1);
1310 } 1411 }
1311 1412
1312 if (ok_is_fall_through) { 1413 if (ok_is_fall_through) {
1313 __ bne(CMPRES, ZR, fail); 1414 __ bne(CMPRES, ZR, fail);
1314 } else { 1415 } else {
1315 __ beq(CMPRES, ZR, &ok); 1416 __ beq(CMPRES, ZR, &ok);
1316 } 1417 }
1317 } else { 1418 } else {
1318 // Both value's and field's class id is known. 1419 // Both value's and field's class id is known.
1319 if ((value_cid != field_cid) && (value_cid != nullability)) { 1420 if ((value_cid != field_cid) && (value_cid != nullability)) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 // (or null). 1607 // (or null).
1507 if (!type_arguments().IsUninstantiatedIdentity() && 1608 if (!type_arguments().IsUninstantiatedIdentity() &&
1508 !type_arguments().CanShareInstantiatorTypeArguments( 1609 !type_arguments().CanShareInstantiatorTypeArguments(
1509 instantiator_class())) { 1610 instantiator_class())) {
1510 // If the instantiator is null and if the type argument vector 1611 // If the instantiator is null and if the type argument vector
1511 // instantiated from null becomes a vector of dynamic, then use null as 1612 // instantiated from null becomes a vector of dynamic, then use null as
1512 // the type arguments. 1613 // the type arguments.
1513 Label type_arguments_instantiated; 1614 Label type_arguments_instantiated;
1514 const intptr_t len = type_arguments().Length(); 1615 const intptr_t len = type_arguments().Length();
1515 if (type_arguments().IsRawInstantiatedRaw(len)) { 1616 if (type_arguments().IsRawInstantiatedRaw(len)) {
1516 __ BranchEqual(instantiator_reg, 1617 __ beq(instantiator_reg, NULLREG, &type_arguments_instantiated);
1517 reinterpret_cast<intptr_t>(Object::null()),
1518 &type_arguments_instantiated);
1519 } 1618 }
1520 // Instantiate non-null type arguments. 1619 // Instantiate non-null type arguments.
1521 // A runtime call to instantiate the type arguments is required. 1620 // A runtime call to instantiate the type arguments is required.
1522 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1621 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1523 __ LoadObject(TMP1, Object::ZoneHandle()); 1622 __ LoadObject(TMP1, Object::ZoneHandle());
1524 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result. 1623 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result.
1525 __ LoadObject(TMP1, type_arguments()); 1624 __ LoadObject(TMP1, type_arguments());
1526 __ sw(TMP1, Address(SP, 1 * kWordSize)); 1625 __ sw(TMP1, Address(SP, 1 * kWordSize));
1527 // Push instantiator type arguments. 1626 // Push instantiator type arguments.
1528 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); 1627 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 // instantiator_reg is the instantiator type argument vector, i.e. an 1662 // instantiator_reg is the instantiator type argument vector, i.e. an
1564 // AbstractTypeArguments object (or null). 1663 // AbstractTypeArguments object (or null).
1565 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 1664 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
1566 !type_arguments().CanShareInstantiatorTypeArguments( 1665 !type_arguments().CanShareInstantiatorTypeArguments(
1567 instantiator_class())); 1666 instantiator_class()));
1568 // If the instantiator is null and if the type argument vector 1667 // If the instantiator is null and if the type argument vector
1569 // instantiated from null becomes a vector of dynamic, then use null as 1668 // instantiated from null becomes a vector of dynamic, then use null as
1570 // the type arguments. 1669 // the type arguments.
1571 Label type_arguments_instantiated; 1670 Label type_arguments_instantiated;
1572 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 1671 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
1573 __ BranchEqual(instantiator_reg, 1672 __ beq(instantiator_reg, NULLREG, &type_arguments_instantiated);
1574 reinterpret_cast<intptr_t>(Object::null()),
1575 &type_arguments_instantiated);
1576 // Instantiate non-null type arguments. 1673 // Instantiate non-null type arguments.
1577 // In the non-factory case, we rely on the allocation stub to 1674 // In the non-factory case, we rely on the allocation stub to
1578 // instantiate the type arguments. 1675 // instantiate the type arguments.
1579 __ LoadObject(result_reg, type_arguments()); 1676 __ LoadObject(result_reg, type_arguments());
1580 // result_reg: uninstantiated type arguments. 1677 // result_reg: uninstantiated type arguments.
1581 __ Bind(&type_arguments_instantiated); 1678 __ Bind(&type_arguments_instantiated);
1582 1679
1583 // result_reg: uninstantiated or instantiated type arguments. 1680 // result_reg: uninstantiated or instantiated type arguments.
1584 } 1681 }
1585 1682
(...skipping 19 matching lines...) Expand all
1605 // (or null). 1702 // (or null).
1606 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 1703 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
1607 !type_arguments().CanShareInstantiatorTypeArguments( 1704 !type_arguments().CanShareInstantiatorTypeArguments(
1608 instantiator_class())); 1705 instantiator_class()));
1609 1706
1610 // If the instantiator is null and if the type argument vector 1707 // If the instantiator is null and if the type argument vector
1611 // instantiated from null becomes a vector of dynamic, then use null as 1708 // instantiated from null becomes a vector of dynamic, then use null as
1612 // the type arguments and do not pass the instantiator. 1709 // the type arguments and do not pass the instantiator.
1613 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 1710 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
1614 Label instantiator_not_null; 1711 Label instantiator_not_null;
1615 __ BranchNotEqual(instantiator_reg, 1712 __ bne(instantiator_reg, NULLREG, &instantiator_not_null);
1616 reinterpret_cast<intptr_t>(Object::null()), &instantiator_not_null);
1617 // Null was used in VisitExtractConstructorTypeArguments as the 1713 // Null was used in VisitExtractConstructorTypeArguments as the
1618 // instantiated type arguments, no proper instantiator needed. 1714 // instantiated type arguments, no proper instantiator needed.
1619 __ LoadImmediate(instantiator_reg, 1715 __ LoadImmediate(instantiator_reg,
1620 Smi::RawValue(StubCode::kNoInstantiator)); 1716 Smi::RawValue(StubCode::kNoInstantiator));
1621 __ Bind(&instantiator_not_null); 1717 __ Bind(&instantiator_not_null);
1622 // instantiator_reg: instantiator or kNoInstantiator. 1718 // instantiator_reg: instantiator or kNoInstantiator.
1623 } 1719 }
1624 1720
1625 1721
1626 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 1722 LocationSummary* AllocateContextInstr::MakeLocationSummary() const {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 1776
1681 ASSERT(!exception_var().is_captured()); 1777 ASSERT(!exception_var().is_captured());
1682 ASSERT(!stacktrace_var().is_captured()); 1778 ASSERT(!stacktrace_var().is_captured());
1683 1779
1684 __ sw(kExceptionObjectReg, 1780 __ sw(kExceptionObjectReg,
1685 Address(FP, exception_var().index() * kWordSize)); 1781 Address(FP, exception_var().index() * kWordSize));
1686 __ sw(kStackTraceObjectReg, 1782 __ sw(kStackTraceObjectReg,
1687 Address(FP, stacktrace_var().index() * kWordSize)); 1783 Address(FP, stacktrace_var().index() * kWordSize));
1688 1784
1689 Label next; 1785 Label next;
1690 __ mov(T0, RA); // Save return adress. 1786 __ mov(TMP, RA); // Save return adress.
1691 // Restore the pool pointer. 1787 // Restore the pool pointer.
1692 __ bal(&next); // Branch and link to next instruction to get PC in RA. 1788 __ bal(&next); // Branch and link to next instruction to get PC in RA.
1693 __ delay_slot()->mov(T1, RA); // Save PC of the following mov. 1789 __ delay_slot()->mov(CMPRES, RA); // Save PC of the following mov.
1694 1790
1695 // Calculate offset of pool pointer from the PC. 1791 // Calculate offset of pool pointer from the PC.
1696 const intptr_t object_pool_pc_dist = 1792 const intptr_t object_pool_pc_dist =
1697 Instructions::HeaderSize() - Instructions::object_pool_offset() + 1793 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1698 compiler->assembler()->CodeSize(); 1794 compiler->assembler()->CodeSize();
1699 1795
1700 __ Bind(&next); 1796 __ Bind(&next);
1701 __ mov(RA, T0); // Restore return address. 1797 __ mov(RA, TMP); // Restore return address.
1702 __ lw(PP, Address(T1, -object_pool_pc_dist)); 1798 __ lw(PP, Address(CMPRES, -object_pool_pc_dist));
1703 } 1799 }
1704 1800
1705 1801
1706 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { 1802 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const {
1707 const intptr_t kNumInputs = 0; 1803 const intptr_t kNumInputs = 0;
1708 const intptr_t kNumTemps = 0; 1804 const intptr_t kNumTemps = 0;
1709 LocationSummary* summary = 1805 LocationSummary* summary =
1710 new LocationSummary(kNumInputs, 1806 new LocationSummary(kNumInputs,
1711 kNumTemps, 1807 kNumTemps,
1712 LocationSummary::kCallOnSlowPath); 1808 LocationSummary::kCallOnSlowPath);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1755 __ Bind(slow_path->exit_label()); 1851 __ Bind(slow_path->exit_label());
1756 } 1852 }
1757 1853
1758 1854
1759 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { 1855 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const {
1760 const intptr_t kNumInputs = 2; 1856 const intptr_t kNumInputs = 2;
1761 if (op_kind() == Token::kTRUNCDIV) { 1857 if (op_kind() == Token::kTRUNCDIV) {
1762 UNIMPLEMENTED(); 1858 UNIMPLEMENTED();
1763 return NULL; 1859 return NULL;
1764 } else { 1860 } else {
1765 const intptr_t kNumTemps = 0; 1861 const intptr_t kNumTemps = op_kind() == Token::kADD ? 1 : 0;
1766 LocationSummary* summary = 1862 LocationSummary* summary =
1767 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1863 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1768 summary->set_in(0, Location::RequiresRegister()); 1864 summary->set_in(0, Location::RequiresRegister());
1769 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 1865 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
1770 if (op_kind() == Token::kADD) { 1866 if (op_kind() == Token::kADD) {
1771 // Need an extra temp for the overflow detection code. 1867 // Need an extra temp for the overflow detection code.
1772 summary->set_temp(0, Location::RequiresRegister()); 1868 summary->set_temp(0, Location::RequiresRegister());
1773 } 1869 }
1774 // We make use of 3-operand instructions by not requiring result register 1870 // We make use of 3-operand instructions by not requiring result register
1775 // to be identical to first input register as on Intel. 1871 // to be identical to first input register as on Intel.
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
2407 summary->AddTemp(Location::RequiresRegister()); 2503 summary->AddTemp(Location::RequiresRegister());
2408 } 2504 }
2409 return summary; 2505 return summary;
2410 } 2506 }
2411 2507
2412 2508
2413 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2509 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2414 if (null_check()) { 2510 if (null_check()) {
2415 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2511 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2416 kDeoptCheckClass); 2512 kDeoptCheckClass);
2417 __ BranchEqual(locs()->in(0).reg(), 2513 __ beq(locs()->in(0).reg(), NULLREG, deopt);
2418 reinterpret_cast<intptr_t>(Object::null()), deopt);
2419 return; 2514 return;
2420 } 2515 }
2421 2516
2422 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || 2517 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
2423 (unary_checks().NumberOfChecks() > 1)); 2518 (unary_checks().NumberOfChecks() > 1));
2424 Register value = locs()->in(0).reg(); 2519 Register value = locs()->in(0).reg();
2425 Register temp = locs()->temp(0).reg(); 2520 Register temp = locs()->temp(0).reg();
2426 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2521 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2427 kDeoptCheckClass); 2522 kDeoptCheckClass);
2428 Label is_ok; 2523 Label is_ok;
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 } 2756 }
2662 2757
2663 2758
2664 // The comparison result is in CMPRES. 2759 // The comparison result is in CMPRES.
2665 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler, 2760 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
2666 Condition true_condition) { 2761 Condition true_condition) {
2667 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition"); 2762 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition");
2668 if (compiler->CanFallThroughTo(false_successor())) { 2763 if (compiler->CanFallThroughTo(false_successor())) {
2669 // If the next block is the false successor we will fall through to it. 2764 // If the next block is the false successor we will fall through to it.
2670 Label* label = compiler->GetJumpLabel(true_successor()); 2765 Label* label = compiler->GetJumpLabel(true_successor());
2671 switch (true_condition) { 2766 EmitBranchAfterCompare(compiler, true_condition, label);
2672 case EQ: __ beq(CMPRES, ZR, label); break;
2673 case NE: __ bne(CMPRES, ZR, label); break;
2674 case GT: __ bgtz(CMPRES, label); break;
2675 case GE: __ bgez(CMPRES, label); break;
2676 case LT: __ bltz(CMPRES, label); break;
2677 case LE: __ blez(CMPRES, label); break;
2678 default:
2679 UNREACHABLE();
2680 break;
2681 }
2682 } else { 2767 } else {
2683 // If the next block is the true successor we negate comparison and fall 2768 // If the next block is the true successor we negate comparison and fall
2684 // through to it. 2769 // through to it.
2685 Condition false_condition = NegateCondition(true_condition); 2770 Condition false_condition = NegateCondition(true_condition);
2686 Label* label = compiler->GetJumpLabel(false_successor()); 2771 Label* label = compiler->GetJumpLabel(false_successor());
2687 switch (false_condition) { 2772 EmitBranchAfterCompare(compiler, false_condition, label);
2688 case EQ: __ beq(CMPRES, ZR, label); break;
2689 case NE: __ bne(CMPRES, ZR, label); break;
2690 case GT: __ bgtz(CMPRES, label); break;
2691 case GE: __ bgez(CMPRES, label); break;
2692 case LT: __ bltz(CMPRES, label); break;
2693 case LE: __ blez(CMPRES, label); break;
2694 default:
2695 UNREACHABLE();
2696 break;
2697 }
2698 // Fall through or jump to the true successor. 2773 // Fall through or jump to the true successor.
2699 if (!compiler->CanFallThroughTo(true_successor())) { 2774 if (!compiler->CanFallThroughTo(true_successor())) {
2700 __ b(compiler->GetJumpLabel(true_successor())); 2775 __ b(compiler->GetJumpLabel(true_successor()));
2701 } 2776 }
2702 } 2777 }
2703 } 2778 }
2704 2779
2705 2780
2706 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 2781 LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
2707 return LocationSummary::Make(0, 2782 return LocationSummary::Make(0,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 locs->set_in(1, Location::RequiresRegister()); 2932 locs->set_in(1, Location::RequiresRegister());
2858 return locs; 2933 return locs;
2859 } 2934 }
2860 2935
2861 2936
2862 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2937 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2863 Register value_reg = locs()->in(0).reg(); 2938 Register value_reg = locs()->in(0).reg();
2864 Register dest_reg = locs()->in(1).reg(); 2939 Register dest_reg = locs()->in(1).reg();
2865 2940
2866 if (value()->NeedsStoreBuffer()) { 2941 if (value()->NeedsStoreBuffer()) {
2867 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), 2942 __ StoreIntoObject(dest_reg,
2868 value_reg); 2943 FieldAddress(dest_reg, offset_in_bytes()), value_reg);
2869 } else { 2944 } else {
2870 __ StoreIntoObjectNoBarrier( 2945 __ StoreIntoObjectNoBarrier(dest_reg,
2871 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); 2946 FieldAddress(dest_reg, offset_in_bytes()), value_reg);
2872 } 2947 }
2873 } 2948 }
2874 2949
2875 2950
2876 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 2951 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
2877 return MakeCallSummary(); 2952 return MakeCallSummary();
2878 } 2953 }
2879 2954
2880 2955
2881 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2956 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 23 matching lines...) Expand all
2905 compiler->GenerateCall(token_pos(), 2980 compiler->GenerateCall(token_pos(),
2906 &label, 2981 &label,
2907 PcDescriptors::kOther, 2982 PcDescriptors::kOther,
2908 locs()); 2983 locs());
2909 __ Drop(2); // Discard type arguments and receiver. 2984 __ Drop(2); // Discard type arguments and receiver.
2910 } 2985 }
2911 2986
2912 } // namespace dart 2987 } // namespace dart
2913 2988
2914 #endif // defined TARGET_ARCH_MIPS 2989 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/instructions_mips.h ('k') | runtime/vm/simulator_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698