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

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
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 void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 518 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
500 const LocationSummary& locs, 519 const LocationSummary& locs,
501 Token::Kind kind, 520 Token::Kind kind,
502 BranchInstr* branch) { 521 BranchInstr* branch) {
503 __ TraceSimMsg("EmitSmiComparisonOp"); 522 __ TraceSimMsg("EmitSmiComparisonOp");
504 Location left = locs.in(0); 523 Location left = locs.in(0);
505 Location right = locs.in(1); 524 Location right = locs.in(1);
506 ASSERT(!left.IsConstant() || !right.IsConstant()); 525 ASSERT(!left.IsConstant() || !right.IsConstant());
507 526
508 Condition true_condition = TokenKindToSmiCondition(kind); 527 Condition true_condition = TokenKindToSmiCondition(kind);
509 528
510 if (left.IsConstant()) { 529 if (left.IsConstant()) {
511 __ CompareObject(CMPRES, right.reg(), left.constant()); 530 __ CompareObject(CMPRES, TMP1, right.reg(), left.constant());
512 true_condition = FlowGraphCompiler::FlipCondition(true_condition); 531 true_condition = FlowGraphCompiler::FlipCondition(true_condition);
513 } else if (right.IsConstant()) { 532 } else if (right.IsConstant()) {
514 __ CompareObject(CMPRES, left.reg(), right.constant()); 533 __ CompareObject(CMPRES, TMP1, left.reg(), right.constant());
515 } else { 534 } else {
516 __ subu(CMPRES, left.reg(), right.reg()); 535 __ slt(CMPRES, left.reg(), right.reg());
536 __ slt(TMP1, right.reg(), left.reg());
517 } 537 }
518 538
519 if (branch != NULL) { 539 if (branch != NULL) {
520 branch->EmitBranchOnCondition(compiler, true_condition); 540 branch->EmitBranchOnCondition(compiler, true_condition);
521 } else { 541 } else {
522 Register result = locs.out().reg(); 542 Register result = locs.out().reg();
523 Label done, is_true; 543 Label done, is_true;
524 switch (true_condition) { 544 EmitBranchAfterCompare(compiler, true_condition, &is_true);
525 case EQ: __ beq(CMPRES, ZR, &is_true); break;
526 case NE: __ bne(CMPRES, ZR, &is_true); break;
527 case GT: __ bgtz(CMPRES, &is_true); break;
528 case GE: __ bgez(CMPRES, &is_true); break;
529 case LT: __ bltz(CMPRES, &is_true); break;
530 case LE: __ blez(CMPRES, &is_true); break;
531 default:
532 UNREACHABLE();
533 break;
534 }
535 __ LoadObject(result, Bool::False()); 545 __ LoadObject(result, Bool::False());
536 __ b(&done); 546 __ b(&done);
537 __ Bind(&is_true); 547 __ Bind(&is_true);
538 __ LoadObject(result, Bool::True()); 548 __ LoadObject(result, Bool::True());
539 __ Bind(&done); 549 __ Bind(&done);
540 } 550 }
541 } 551 }
542 552
543 553
544 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 554 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 EmitEqualityAsInstanceCall(compiler, 652 EmitEqualityAsInstanceCall(compiler,
643 deopt_id(), 653 deopt_id(),
644 token_pos(), 654 token_pos(),
645 Token::kEQ, // kNE reverse occurs at branch. 655 Token::kEQ, // kNE reverse occurs at branch.
646 locs(), 656 locs(),
647 *ic_data()); 657 *ic_data());
648 if (branch->is_checked()) { 658 if (branch->is_checked()) {
649 EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler); 659 EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler);
650 } 660 }
651 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; 661 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ;
652 __ CompareObject(CMPRES, V0, Bool::True()); 662 __ CompareObject(CMPRES, TMP1, V0, Bool::True());
653 branch->EmitBranchOnCondition(compiler, branch_condition); 663 branch->EmitBranchOnCondition(compiler, branch_condition);
654 } 664 }
655 665
656 666
657 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 667 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
658 const intptr_t kNumInputs = 2; 668 const intptr_t kNumInputs = 2;
659 const intptr_t kNumTemps = 0; 669 const intptr_t kNumTemps = 0;
660 if (operands_class_id() == kMintCid) { 670 if (operands_class_id() == kMintCid) {
661 const intptr_t kNumTemps = 2; 671 const intptr_t kNumTemps = 2;
662 LocationSummary* locs = 672 LocationSummary* locs =
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 } 788 }
779 if (operands_class_id() == kMintCid) { 789 if (operands_class_id() == kMintCid) {
780 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); 790 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
781 return; 791 return;
782 } 792 }
783 if (operands_class_id() == kDoubleCid) { 793 if (operands_class_id() == kDoubleCid) {
784 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 794 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
785 return; 795 return;
786 } 796 }
787 EmitNativeCode(compiler); 797 EmitNativeCode(compiler);
788 __ CompareObject(CMPRES, V0, Bool::True()); 798 __ CompareObject(CMPRES, TMP1, V0, Bool::True());
789 branch->EmitBranchOnCondition(compiler, EQ); 799 branch->EmitBranchOnCondition(compiler, EQ);
790 } 800 }
791 801
792 802
793 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 803 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
794 const intptr_t kNumInputs = 0; 804 const intptr_t kNumInputs = 0;
795 const intptr_t kNumTemps = 3; 805 const intptr_t kNumTemps = 3;
796 LocationSummary* locs = 806 LocationSummary* locs =
797 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 807 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
798 locs->set_temp(0, Location::RegisterLocation(A1)); 808 locs->set_temp(0, Location::RegisterLocation(A1));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 return NULL; 862 return NULL;
853 } 863 }
854 864
855 865
856 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 866 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
857 UNIMPLEMENTED(); 867 UNIMPLEMENTED();
858 } 868 }
859 869
860 870
861 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { 871 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const {
862 UNIMPLEMENTED(); 872 const intptr_t kNumInputs = 1;
863 return NULL; 873 return LocationSummary::Make(kNumInputs,
874 Location::RequiresRegister(),
875 LocationSummary::kNoCall);
864 } 876 }
865 877
866 878
867 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 879 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
868 UNIMPLEMENTED(); 880 Register object = locs()->in(0).reg();
881 Register result = locs()->out().reg();
882 Label load, done;
883 __ andi(CMPRES, object, Immediate(kSmiTagMask));
884 __ bne(CMPRES, ZR, &load);
885 __ LoadImmediate(result, Smi::RawValue(kSmiCid));
886 __ b(&done);
887 __ Bind(&load);
888 __ LoadClassId(result, object);
889 __ SmiTag(result);
890 __ Bind(&done);
869 } 891 }
870 892
871 893
872 CompileType LoadIndexedInstr::ComputeType() const { 894 CompileType LoadIndexedInstr::ComputeType() const {
873 switch (class_id_) { 895 switch (class_id_) {
874 case kArrayCid: 896 case kArrayCid:
875 case kImmutableArrayCid: 897 case kImmutableArrayCid:
876 return CompileType::Dynamic(); 898 return CompileType::Dynamic();
877 899
878 case kTypedDataFloat32ArrayCid: 900 case kTypedDataFloat32ArrayCid:
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 __ sll(index.reg(), index.reg(), 2); 1009 __ sll(index.reg(), index.reg(), 2);
988 break; 1010 break;
989 } 1011 }
990 case 16: { 1012 case 16: {
991 __ sll(index.reg(), index.reg(), 3); 1013 __ sll(index.reg(), index.reg(), 3);
992 break; 1014 break;
993 } 1015 }
994 default: 1016 default:
995 UNREACHABLE(); 1017 UNREACHABLE();
996 } 1018 }
997 __ AddImmediate(index.reg(), 1019 __ addu(index.reg(), array, index.reg());
1020 element_address = Address(index.reg(),
998 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1021 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
999 element_address = Address(array, index.reg());
1000 } 1022 }
1001 1023
1002 if ((representation() == kUnboxedDouble) || 1024 if ((representation() == kUnboxedDouble) ||
1003 (representation() == kUnboxedMint) || 1025 (representation() == kUnboxedMint) ||
1004 (representation() == kUnboxedFloat32x4)) { 1026 (representation() == kUnboxedFloat32x4)) {
1005 UNIMPLEMENTED(); 1027 UNIMPLEMENTED();
1006 } 1028 }
1007 1029
1008 Register result = locs()->out().reg(); 1030 Register result = locs()->out().reg();
1009 if ((index_scale() == 1) && index.IsRegister()) {
1010 __ SmiUntag(index.reg());
1011 }
1012 switch (class_id()) { 1031 switch (class_id()) {
1013 case kTypedDataInt8ArrayCid: 1032 case kTypedDataInt8ArrayCid:
1014 ASSERT(index_scale() == 1); 1033 ASSERT(index_scale() == 1);
1015 __ lb(result, element_address); 1034 __ lb(result, element_address);
1016 __ SmiTag(result); 1035 __ SmiTag(result);
1017 break; 1036 break;
1018 case kTypedDataUint8ArrayCid: 1037 case kTypedDataUint8ArrayCid:
1019 case kTypedDataUint8ClampedArrayCid: 1038 case kTypedDataUint8ClampedArrayCid:
1020 case kExternalTypedDataUint8ArrayCid: 1039 case kExternalTypedDataUint8ArrayCid:
1021 case kExternalTypedDataUint8ClampedArrayCid: 1040 case kExternalTypedDataUint8ClampedArrayCid:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 default: 1073 default:
1055 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1074 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1056 __ lw(result, element_address); 1075 __ lw(result, element_address);
1057 break; 1076 break;
1058 } 1077 }
1059 } 1078 }
1060 1079
1061 1080
1062 Representation StoreIndexedInstr::RequiredInputRepresentation( 1081 Representation StoreIndexedInstr::RequiredInputRepresentation(
1063 intptr_t idx) const { 1082 intptr_t idx) const {
1064 UNIMPLEMENTED(); 1083 // Array can be a Dart object or a pointer to external data.
1065 return kTagged; 1084 if (idx == 0) return kNoRepresentation; // Flexible input representation.
1085 if (idx == 1) return kTagged; // Index is a smi.
1086 ASSERT(idx == 2);
1087 switch (class_id_) {
1088 case kArrayCid:
1089 case kOneByteStringCid:
1090 case kTypedDataInt8ArrayCid:
1091 case kTypedDataUint8ArrayCid:
1092 case kExternalTypedDataUint8ArrayCid:
1093 case kTypedDataUint8ClampedArrayCid:
1094 case kExternalTypedDataUint8ClampedArrayCid:
1095 case kTypedDataInt16ArrayCid:
1096 case kTypedDataUint16ArrayCid:
1097 return kTagged;
1098 case kTypedDataInt32ArrayCid:
1099 case kTypedDataUint32ArrayCid:
1100 return value()->IsSmiValue() ? kTagged : kUnboxedMint;
1101 case kTypedDataFloat32ArrayCid:
1102 case kTypedDataFloat64ArrayCid:
1103 return kUnboxedDouble;
1104 case kTypedDataFloat32x4ArrayCid:
1105 return kUnboxedFloat32x4;
1106 default:
1107 UNIMPLEMENTED();
1108 return kTagged;
1109 }
1066 } 1110 }
1067 1111
1068 1112
1069 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1113 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1070 const intptr_t kNumInputs = 3; 1114 const intptr_t kNumInputs = 3;
1071 const intptr_t kNumTemps = 0; 1115 const intptr_t kNumTemps = 0;
1072 LocationSummary* locs = 1116 LocationSummary* locs =
1073 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1117 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1074 locs->set_in(0, Location::RequiresRegister()); 1118 locs->set_in(0, Location::RequiresRegister());
1075 // The smi index is either untagged (element size == 1), or it is left smi 1119 // The smi index is either untagged (element size == 1), or it is left smi
1076 // tagged (for all element sizes > 1). 1120 // tagged (for all element sizes > 1).
1077 // TODO(regis): Revisit and see if the index can be immediate. 1121 // TODO(regis): Revisit and see if the index can be immediate.
1078 locs->set_in(1, Location::WritableRegister()); 1122 locs->set_in(1, Location::WritableRegister());
1079 switch (class_id()) { 1123 switch (class_id()) {
1080 case kArrayCid: 1124 case kArrayCid:
1081 locs->set_in(2, ShouldEmitStoreBarrier() 1125 locs->set_in(2, ShouldEmitStoreBarrier()
1082 ? Location::WritableRegister() 1126 ? Location::WritableRegister()
1083 : Location::RegisterOrConstant(value())); 1127 : Location::RegisterOrConstant(value()));
1084 break; 1128 break;
1085 case kExternalTypedDataUint8ArrayCid: 1129 case kExternalTypedDataUint8ArrayCid:
1086 case kExternalTypedDataUint8ClampedArrayCid: 1130 case kExternalTypedDataUint8ClampedArrayCid:
1087 case kTypedDataInt8ArrayCid: 1131 case kTypedDataInt8ArrayCid:
1088 case kTypedDataUint8ArrayCid: 1132 case kTypedDataUint8ArrayCid:
1089 case kTypedDataUint8ClampedArrayCid: 1133 case kTypedDataUint8ClampedArrayCid:
1090 case kOneByteStringCid: 1134 case kOneByteStringCid:
1135 locs->set_in(2, Location::RegisterOrSmiConstant(value()));
1136 break;
1091 case kTypedDataInt16ArrayCid: 1137 case kTypedDataInt16ArrayCid:
1092 case kTypedDataUint16ArrayCid: 1138 case kTypedDataUint16ArrayCid:
1093 case kTypedDataInt32ArrayCid: 1139 case kTypedDataInt32ArrayCid:
1094 case kTypedDataUint32ArrayCid: 1140 case kTypedDataUint32ArrayCid:
1141 locs->set_in(2, Location::WritableRegister());
1142 break;
1095 case kTypedDataFloat32ArrayCid: 1143 case kTypedDataFloat32ArrayCid:
1096 case kTypedDataFloat64ArrayCid: 1144 // TODO(regis): Verify.
1145 // Need temp register for float-to-double conversion.
1146 locs->AddTemp(Location::RequiresFpuRegister());
1147 // Fall through.
1148 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
1097 case kTypedDataFloat32x4ArrayCid: 1149 case kTypedDataFloat32x4ArrayCid:
1098 UNIMPLEMENTED(); 1150 locs->set_in(2, Location::RequiresFpuRegister());
1099 break; 1151 break;
1100 default: 1152 default:
1101 UNREACHABLE(); 1153 UNREACHABLE();
1102 return NULL; 1154 return NULL;
1103 } 1155 }
1104 return locs; 1156 return locs;
1105 } 1157 }
1106 1158
1107 1159
1108 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1160 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 27 matching lines...) Expand all
1136 __ sll(index.reg(), index.reg(), 2); 1188 __ sll(index.reg(), index.reg(), 2);
1137 break; 1189 break;
1138 } 1190 }
1139 case 16: { 1191 case 16: {
1140 __ sll(index.reg(), index.reg(), 3); 1192 __ sll(index.reg(), index.reg(), 3);
1141 break; 1193 break;
1142 } 1194 }
1143 default: 1195 default:
1144 UNREACHABLE(); 1196 UNREACHABLE();
1145 } 1197 }
1146 __ AddImmediate(index.reg(), 1198 __ addu(index.reg(), array, index.reg());
1199 element_address = Address(index.reg(),
1147 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1200 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1148 __ addu(TMP1, array, index.reg());
1149 element_address = Address(TMP1);
1150 } 1201 }
1151 1202
1152 switch (class_id()) { 1203 switch (class_id()) {
1153 case kArrayCid: 1204 case kArrayCid:
1154 if (ShouldEmitStoreBarrier()) { 1205 if (ShouldEmitStoreBarrier()) {
1155 Register value = locs()->in(2).reg(); 1206 Register value = locs()->in(2).reg();
1156 __ StoreIntoObject(array, element_address, value); 1207 __ StoreIntoObject(array, element_address, value);
1157 } else if (locs()->in(2).IsConstant()) { 1208 } else if (locs()->in(2).IsConstant()) {
1158 const Object& constant = locs()->in(2).constant(); 1209 const Object& constant = locs()->in(2).constant();
1159 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1210 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1160 } else { 1211 } else {
1161 Register value = locs()->in(2).reg(); 1212 Register value = locs()->in(2).reg();
1162 __ StoreIntoObjectNoBarrier(array, element_address, value); 1213 __ StoreIntoObjectNoBarrier(array, element_address, value);
1163 } 1214 }
1164 break; 1215 break;
1165 case kTypedDataInt8ArrayCid: 1216 case kTypedDataInt8ArrayCid:
1166 case kTypedDataUint8ArrayCid: 1217 case kTypedDataUint8ArrayCid:
1167 case kExternalTypedDataUint8ArrayCid: 1218 case kExternalTypedDataUint8ArrayCid:
1219 case kOneByteStringCid: {
1220 if (locs()->in(2).IsConstant()) {
1221 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1222 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()));
1223 __ sb(TMP, element_address);
1224 } else {
1225 Register value = locs()->in(2).reg();
1226 __ SmiUntag(value);
1227 __ sb(value, element_address);
1228 }
1229 break;
1230 }
1168 case kTypedDataUint8ClampedArrayCid: 1231 case kTypedDataUint8ClampedArrayCid:
1169 case kExternalTypedDataUint8ClampedArrayCid: 1232 case kExternalTypedDataUint8ClampedArrayCid: {
1170 case kOneByteStringCid: 1233 if (locs()->in(2).IsConstant()) {
1234 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1235 intptr_t value = constant.Value();
1236 // Clamp to 0x0 or 0xFF respectively.
1237 if (value > 0xFF) {
1238 value = 0xFF;
1239 } else if (value < 0) {
1240 value = 0;
1241 }
1242 __ LoadImmediate(TMP, static_cast<int8_t>(value));
1243 __ sb(TMP, element_address);
1244 } else {
1245 Register value = locs()->in(2).reg();
1246 Label store_value, bigger, smaller;
1247 __ SmiUntag(value);
1248 __ BranchUnsignedLess(value, 0xFF + 1, &store_value);
1249 __ LoadImmediate(TMP, 0xFF);
1250 __ slti(CMPRES, value, Immediate(1));
1251 __ movn(TMP, ZR, CMPRES);
1252 __ mov(value, TMP);
1253 __ Bind(&store_value);
1254 __ sb(value, element_address);
1255 }
1256 break;
1257 }
1171 case kTypedDataInt16ArrayCid: 1258 case kTypedDataInt16ArrayCid:
1172 case kTypedDataUint16ArrayCid: 1259 case kTypedDataUint16ArrayCid: {
1260 Register value = locs()->in(2).reg();
1261 __ SmiUntag(value);
1262 __ sh(value, element_address);
1263 break;
1264 }
1173 case kTypedDataInt32ArrayCid: 1265 case kTypedDataInt32ArrayCid:
1174 case kTypedDataUint32ArrayCid: 1266 case kTypedDataUint32ArrayCid: {
1267 if (value()->IsSmiValue()) {
1268 ASSERT(RequiredInputRepresentation(2) == kTagged);
1269 Register value = locs()->in(2).reg();
1270 __ SmiUntag(value);
1271 __ sw(value, element_address);
1272 } else {
1273 UNIMPLEMENTED();
1274 }
1275 break;
1276 }
1175 case kTypedDataFloat32ArrayCid: 1277 case kTypedDataFloat32ArrayCid:
1176 case kTypedDataFloat64ArrayCid: 1278 case kTypedDataFloat64ArrayCid:
1177 case kTypedDataFloat32x4ArrayCid: 1279 case kTypedDataFloat32x4ArrayCid:
1178 UNIMPLEMENTED(); 1280 UNIMPLEMENTED();
1179 break; 1281 break;
1180 default: 1282 default:
1181 UNREACHABLE(); 1283 UNREACHABLE();
1182 } 1284 }
1183 } 1285 }
1184 1286
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 1394
1293 if (field_cid != kSmiCid) { 1395 if (field_cid != kSmiCid) {
1294 __ beq(CMPRES, ZR, fail); 1396 __ beq(CMPRES, ZR, fail);
1295 __ LoadClassId(value_cid_reg, value_reg); 1397 __ LoadClassId(value_cid_reg, value_reg);
1296 __ LoadImmediate(TMP1, field_cid); 1398 __ LoadImmediate(TMP1, field_cid);
1297 __ subu(CMPRES, value_cid_reg, TMP1); 1399 __ subu(CMPRES, value_cid_reg, TMP1);
1298 } 1400 }
1299 1401
1300 if (field().is_nullable() && (field_cid != kNullCid)) { 1402 if (field().is_nullable() && (field_cid != kNullCid)) {
1301 __ beq(CMPRES, ZR, &ok); 1403 __ beq(CMPRES, ZR, &ok);
1302 __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null())); 1404 __ subu(CMPRES, value_reg, NULLREG);
1303 __ subu(CMPRES, value_reg, TMP1);
1304 } 1405 }
1305 1406
1306 if (ok_is_fall_through) { 1407 if (ok_is_fall_through) {
1307 __ bne(CMPRES, ZR, fail); 1408 __ bne(CMPRES, ZR, fail);
1308 } else { 1409 } else {
1309 __ beq(CMPRES, ZR, &ok); 1410 __ beq(CMPRES, ZR, &ok);
1310 } 1411 }
1311 } else { 1412 } else {
1312 // Both value's and field's class id is known. 1413 // Both value's and field's class id is known.
1313 if ((value_cid != field_cid) && (value_cid != nullability)) { 1414 if ((value_cid != field_cid) && (value_cid != nullability)) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 // (or null). 1601 // (or null).
1501 if (!type_arguments().IsUninstantiatedIdentity() && 1602 if (!type_arguments().IsUninstantiatedIdentity() &&
1502 !type_arguments().CanShareInstantiatorTypeArguments( 1603 !type_arguments().CanShareInstantiatorTypeArguments(
1503 instantiator_class())) { 1604 instantiator_class())) {
1504 // If the instantiator is null and if the type argument vector 1605 // If the instantiator is null and if the type argument vector
1505 // instantiated from null becomes a vector of dynamic, then use null as 1606 // instantiated from null becomes a vector of dynamic, then use null as
1506 // the type arguments. 1607 // the type arguments.
1507 Label type_arguments_instantiated; 1608 Label type_arguments_instantiated;
1508 const intptr_t len = type_arguments().Length(); 1609 const intptr_t len = type_arguments().Length();
1509 if (type_arguments().IsRawInstantiatedRaw(len)) { 1610 if (type_arguments().IsRawInstantiatedRaw(len)) {
1510 __ BranchEqual(instantiator_reg, 1611 __ beq(instantiator_reg, NULLREG, &type_arguments_instantiated);
1511 reinterpret_cast<intptr_t>(Object::null()),
1512 &type_arguments_instantiated);
1513 } 1612 }
1514 // Instantiate non-null type arguments. 1613 // Instantiate non-null type arguments.
1515 // A runtime call to instantiate the type arguments is required. 1614 // A runtime call to instantiate the type arguments is required.
1516 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1615 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1517 __ LoadObject(TMP1, Object::ZoneHandle()); 1616 __ LoadObject(TMP1, Object::ZoneHandle());
1518 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result. 1617 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result.
1519 __ LoadObject(TMP1, type_arguments()); 1618 __ LoadObject(TMP1, type_arguments());
1520 __ sw(TMP1, Address(SP, 1 * kWordSize)); 1619 __ sw(TMP1, Address(SP, 1 * kWordSize));
1521 // Push instantiator type arguments. 1620 // Push instantiator type arguments.
1522 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); 1621 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 // instantiator_reg is the instantiator type argument vector, i.e. an 1656 // instantiator_reg is the instantiator type argument vector, i.e. an
1558 // AbstractTypeArguments object (or null). 1657 // AbstractTypeArguments object (or null).
1559 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 1658 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
1560 !type_arguments().CanShareInstantiatorTypeArguments( 1659 !type_arguments().CanShareInstantiatorTypeArguments(
1561 instantiator_class())); 1660 instantiator_class()));
1562 // If the instantiator is null and if the type argument vector 1661 // If the instantiator is null and if the type argument vector
1563 // instantiated from null becomes a vector of dynamic, then use null as 1662 // instantiated from null becomes a vector of dynamic, then use null as
1564 // the type arguments. 1663 // the type arguments.
1565 Label type_arguments_instantiated; 1664 Label type_arguments_instantiated;
1566 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 1665 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
1567 __ BranchEqual(instantiator_reg, 1666 __ beq(instantiator_reg, NULLREG, &type_arguments_instantiated);
1568 reinterpret_cast<intptr_t>(Object::null()),
1569 &type_arguments_instantiated);
1570 // Instantiate non-null type arguments. 1667 // Instantiate non-null type arguments.
1571 // In the non-factory case, we rely on the allocation stub to 1668 // In the non-factory case, we rely on the allocation stub to
1572 // instantiate the type arguments. 1669 // instantiate the type arguments.
1573 __ LoadObject(result_reg, type_arguments()); 1670 __ LoadObject(result_reg, type_arguments());
1574 // result_reg: uninstantiated type arguments. 1671 // result_reg: uninstantiated type arguments.
1575 __ Bind(&type_arguments_instantiated); 1672 __ Bind(&type_arguments_instantiated);
1576 1673
1577 // result_reg: uninstantiated or instantiated type arguments. 1674 // result_reg: uninstantiated or instantiated type arguments.
1578 } 1675 }
1579 1676
(...skipping 19 matching lines...) Expand all
1599 // (or null). 1696 // (or null).
1600 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 1697 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
1601 !type_arguments().CanShareInstantiatorTypeArguments( 1698 !type_arguments().CanShareInstantiatorTypeArguments(
1602 instantiator_class())); 1699 instantiator_class()));
1603 1700
1604 // If the instantiator is null and if the type argument vector 1701 // If the instantiator is null and if the type argument vector
1605 // instantiated from null becomes a vector of dynamic, then use null as 1702 // instantiated from null becomes a vector of dynamic, then use null as
1606 // the type arguments and do not pass the instantiator. 1703 // the type arguments and do not pass the instantiator.
1607 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 1704 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
1608 Label instantiator_not_null; 1705 Label instantiator_not_null;
1609 __ BranchNotEqual(instantiator_reg, 1706 __ bne(instantiator_reg, NULLREG, &instantiator_not_null);
1610 reinterpret_cast<intptr_t>(Object::null()), &instantiator_not_null);
1611 // Null was used in VisitExtractConstructorTypeArguments as the 1707 // Null was used in VisitExtractConstructorTypeArguments as the
1612 // instantiated type arguments, no proper instantiator needed. 1708 // instantiated type arguments, no proper instantiator needed.
1613 __ LoadImmediate(instantiator_reg, 1709 __ LoadImmediate(instantiator_reg,
1614 Smi::RawValue(StubCode::kNoInstantiator)); 1710 Smi::RawValue(StubCode::kNoInstantiator));
1615 __ Bind(&instantiator_not_null); 1711 __ Bind(&instantiator_not_null);
1616 // instantiator_reg: instantiator or kNoInstantiator. 1712 // instantiator_reg: instantiator or kNoInstantiator.
1617 } 1713 }
1618 1714
1619 1715
1620 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 1716 LocationSummary* AllocateContextInstr::MakeLocationSummary() const {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 1770
1675 ASSERT(!exception_var().is_captured()); 1771 ASSERT(!exception_var().is_captured());
1676 ASSERT(!stacktrace_var().is_captured()); 1772 ASSERT(!stacktrace_var().is_captured());
1677 1773
1678 __ sw(kExceptionObjectReg, 1774 __ sw(kExceptionObjectReg,
1679 Address(FP, exception_var().index() * kWordSize)); 1775 Address(FP, exception_var().index() * kWordSize));
1680 __ sw(kStackTraceObjectReg, 1776 __ sw(kStackTraceObjectReg,
1681 Address(FP, stacktrace_var().index() * kWordSize)); 1777 Address(FP, stacktrace_var().index() * kWordSize));
1682 1778
1683 Label next; 1779 Label next;
1684 __ mov(T0, RA); // Save return adress. 1780 __ mov(TMP, RA); // Save return adress.
1685 // Restore the pool pointer. 1781 // Restore the pool pointer.
1686 __ bal(&next); // Branch and link to next instruction to get PC in RA. 1782 __ bal(&next); // Branch and link to next instruction to get PC in RA.
1687 __ delay_slot()->mov(T1, RA); // Save PC of the following mov. 1783 __ delay_slot()->mov(CMPRES, RA); // Save PC of the following mov.
1688 1784
1689 // Calculate offset of pool pointer from the PC. 1785 // Calculate offset of pool pointer from the PC.
1690 const intptr_t object_pool_pc_dist = 1786 const intptr_t object_pool_pc_dist =
1691 Instructions::HeaderSize() - Instructions::object_pool_offset() + 1787 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1692 compiler->assembler()->CodeSize(); 1788 compiler->assembler()->CodeSize();
1693 1789
1694 __ Bind(&next); 1790 __ Bind(&next);
1695 __ mov(RA, T0); // Restore return address. 1791 __ mov(RA, TMP); // Restore return address.
1696 __ lw(PP, Address(T1, -object_pool_pc_dist)); 1792 __ lw(PP, Address(CMPRES, -object_pool_pc_dist));
1697 } 1793 }
1698 1794
1699 1795
1700 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { 1796 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const {
1701 const intptr_t kNumInputs = 0; 1797 const intptr_t kNumInputs = 0;
1702 const intptr_t kNumTemps = 0; 1798 const intptr_t kNumTemps = 0;
1703 LocationSummary* summary = 1799 LocationSummary* summary =
1704 new LocationSummary(kNumInputs, 1800 new LocationSummary(kNumInputs,
1705 kNumTemps, 1801 kNumTemps,
1706 LocationSummary::kCallOnSlowPath); 1802 LocationSummary::kCallOnSlowPath);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1749 __ Bind(slow_path->exit_label()); 1845 __ Bind(slow_path->exit_label());
1750 } 1846 }
1751 1847
1752 1848
1753 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { 1849 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const {
1754 const intptr_t kNumInputs = 2; 1850 const intptr_t kNumInputs = 2;
1755 if (op_kind() == Token::kTRUNCDIV) { 1851 if (op_kind() == Token::kTRUNCDIV) {
1756 UNIMPLEMENTED(); 1852 UNIMPLEMENTED();
1757 return NULL; 1853 return NULL;
1758 } else { 1854 } else {
1759 const intptr_t kNumTemps = 0; 1855 const intptr_t kNumTemps = op_kind() == Token::kADD ? 1 : 0;
1760 LocationSummary* summary = 1856 LocationSummary* summary =
1761 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1857 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1762 summary->set_in(0, Location::RequiresRegister()); 1858 summary->set_in(0, Location::RequiresRegister());
1763 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 1859 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
1764 if (op_kind() == Token::kADD) { 1860 if (op_kind() == Token::kADD) {
1765 // Need an extra temp for the overflow detection code. 1861 // Need an extra temp for the overflow detection code.
1766 summary->set_temp(0, Location::RequiresRegister()); 1862 summary->set_temp(0, Location::RequiresRegister());
1767 } 1863 }
1768 // We make use of 3-operand instructions by not requiring result register 1864 // We make use of 3-operand instructions by not requiring result register
1769 // to be identical to first input register as on Intel. 1865 // to be identical to first input register as on Intel.
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 summary->AddTemp(Location::RequiresRegister()); 2497 summary->AddTemp(Location::RequiresRegister());
2402 } 2498 }
2403 return summary; 2499 return summary;
2404 } 2500 }
2405 2501
2406 2502
2407 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2503 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2408 if (null_check()) { 2504 if (null_check()) {
2409 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2505 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2410 kDeoptCheckClass); 2506 kDeoptCheckClass);
2411 __ BranchEqual(locs()->in(0).reg(), 2507 __ beq(locs()->in(0).reg(), NULLREG, deopt);
2412 reinterpret_cast<intptr_t>(Object::null()), deopt);
2413 return; 2508 return;
2414 } 2509 }
2415 2510
2416 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || 2511 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
2417 (unary_checks().NumberOfChecks() > 1)); 2512 (unary_checks().NumberOfChecks() > 1));
2418 Register value = locs()->in(0).reg(); 2513 Register value = locs()->in(0).reg();
2419 Register temp = locs()->temp(0).reg(); 2514 Register temp = locs()->temp(0).reg();
2420 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2515 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2421 kDeoptCheckClass); 2516 kDeoptCheckClass);
2422 Label is_ok; 2517 Label is_ok;
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
2655 } 2750 }
2656 2751
2657 2752
2658 // The comparison result is in CMPRES. 2753 // The comparison result is in CMPRES.
2659 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler, 2754 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
2660 Condition true_condition) { 2755 Condition true_condition) {
2661 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition"); 2756 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition");
2662 if (compiler->CanFallThroughTo(false_successor())) { 2757 if (compiler->CanFallThroughTo(false_successor())) {
2663 // If the next block is the false successor we will fall through to it. 2758 // If the next block is the false successor we will fall through to it.
2664 Label* label = compiler->GetJumpLabel(true_successor()); 2759 Label* label = compiler->GetJumpLabel(true_successor());
2665 switch (true_condition) { 2760 EmitBranchAfterCompare(compiler, true_condition, label);
2666 case EQ: __ beq(CMPRES, ZR, label); break;
2667 case NE: __ bne(CMPRES, ZR, label); break;
2668 case GT: __ bgtz(CMPRES, label); break;
2669 case GE: __ bgez(CMPRES, label); break;
2670 case LT: __ bltz(CMPRES, label); break;
2671 case LE: __ blez(CMPRES, label); break;
2672 default:
2673 UNREACHABLE();
2674 break;
2675 }
2676 } else { 2761 } else {
2677 // If the next block is the true successor we negate comparison and fall 2762 // If the next block is the true successor we negate comparison and fall
2678 // through to it. 2763 // through to it.
2679 Condition false_condition = NegateCondition(true_condition); 2764 Condition false_condition = NegateCondition(true_condition);
2680 Label* label = compiler->GetJumpLabel(false_successor()); 2765 Label* label = compiler->GetJumpLabel(false_successor());
2681 switch (false_condition) { 2766 EmitBranchAfterCompare(compiler, false_condition, label);
2682 case EQ: __ beq(CMPRES, ZR, label); break;
2683 case NE: __ bne(CMPRES, ZR, label); break;
2684 case GT: __ bgtz(CMPRES, label); break;
2685 case GE: __ bgez(CMPRES, label); break;
2686 case LT: __ bltz(CMPRES, label); break;
2687 case LE: __ blez(CMPRES, label); break;
2688 default:
2689 UNREACHABLE();
2690 break;
2691 }
2692 // Fall through or jump to the true successor. 2767 // Fall through or jump to the true successor.
2693 if (!compiler->CanFallThroughTo(true_successor())) { 2768 if (!compiler->CanFallThroughTo(true_successor())) {
2694 __ b(compiler->GetJumpLabel(true_successor())); 2769 __ b(compiler->GetJumpLabel(true_successor()));
2695 } 2770 }
2696 } 2771 }
2697 } 2772 }
2698 2773
2699 2774
2700 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 2775 LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
2701 return LocationSummary::Make(0, 2776 return LocationSummary::Make(0,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2851 locs->set_in(1, Location::RequiresRegister()); 2926 locs->set_in(1, Location::RequiresRegister());
2852 return locs; 2927 return locs;
2853 } 2928 }
2854 2929
2855 2930
2856 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2931 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2857 Register value_reg = locs()->in(0).reg(); 2932 Register value_reg = locs()->in(0).reg();
2858 Register dest_reg = locs()->in(1).reg(); 2933 Register dest_reg = locs()->in(1).reg();
2859 2934
2860 if (value()->NeedsStoreBuffer()) { 2935 if (value()->NeedsStoreBuffer()) {
2861 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), 2936 __ StoreIntoObject(dest_reg,
2862 value_reg); 2937 FieldAddress(dest_reg, offset_in_bytes()), value_reg);
2863 } else { 2938 } else {
2864 __ StoreIntoObjectNoBarrier( 2939 __ StoreIntoObjectNoBarrier(dest_reg,
2865 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); 2940 FieldAddress(dest_reg, offset_in_bytes()), value_reg);
2866 } 2941 }
2867 } 2942 }
2868 2943
2869 2944
2870 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 2945 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
2871 return MakeCallSummary(); 2946 return MakeCallSummary();
2872 } 2947 }
2873 2948
2874 2949
2875 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2950 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 23 matching lines...) Expand all
2899 compiler->GenerateCall(token_pos(), 2974 compiler->GenerateCall(token_pos(),
2900 &label, 2975 &label,
2901 PcDescriptors::kOther, 2976 PcDescriptors::kOther,
2902 locs()); 2977 locs());
2903 __ Drop(2); // Discard type arguments and receiver. 2978 __ Drop(2); // Discard type arguments and receiver.
2904 } 2979 }
2905 2980
2906 } // namespace dart 2981 } // namespace dart
2907 2982
2908 #endif // defined TARGET_ARCH_MIPS 2983 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698