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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/instructions_mips.h ('k') | runtime/vm/simulator_mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_mips.cc
===================================================================
--- runtime/vm/intermediate_language_mips.cc (revision 23188)
+++ runtime/vm/intermediate_language_mips.cc (working copy)
@@ -92,9 +92,9 @@
const intptr_t fp_sp_dist =
(kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
ASSERT(fp_sp_dist <= 0);
- __ subu(T2, SP, FP);
+ __ subu(TMP1, SP, FP);
- __ BranchEqual(T2, fp_sp_dist, &stack_ok);
+ __ BranchEqual(TMP1, fp_sp_dist, &stack_ok);
__ break_(0);
__ Bind(&stack_ok);
@@ -328,7 +328,10 @@
const intptr_t kNumTemps = 1;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
- UNIMPLEMENTED(); // TODO(regis): Verify register allocation.
+ locs->set_in(0, Location::RegisterLocation(A1));
+ locs->set_in(1, Location::RegisterLocation(A0));
+ locs->set_temp(0, Location::RegisterLocation(T0));
+ locs->set_out(Location::RegisterLocation(V0));
return locs;
}
const intptr_t kNumTemps = 1;
@@ -363,9 +366,8 @@
const int kNumArgumentsChecked = 2;
Label check_identity;
- __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
- __ beq(A1, TMP1, &check_identity);
- __ beq(A0, TMP1, &check_identity);
+ __ beq(A1, NULLREG, &check_identity);
+ __ beq(A0, NULLREG, &check_identity);
ICData& equality_ic_data = ICData::ZoneHandle();
if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
@@ -496,6 +498,23 @@
}
+// Branches on condition c assuming comparison results in CMPRES and TMP1.
+static void EmitBranchAfterCompare(
+ FlowGraphCompiler* compiler, Condition c, Label* is_true) {
+ switch (c) {
+ case EQ: __ beq(CMPRES, TMP1, is_true); break;
+ case NE: __ bne(CMPRES, TMP1, is_true); break;
+ case GT: __ bne(TMP1, ZR, is_true); break;
+ case GE: __ beq(CMPRES, ZR, is_true); break;
+ case LT: __ bne(CMPRES, ZR, is_true); break;
+ case LE: __ beq(TMP1, ZR, is_true); break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+
static Condition FlipCondition(Condition condition) {
UNIMPLEMENTED();
return condition;
@@ -514,12 +533,13 @@
Condition true_condition = TokenKindToSmiCondition(kind);
if (left.IsConstant()) {
- __ CompareObject(CMPRES, right.reg(), left.constant());
+ __ CompareObject(CMPRES, TMP1, right.reg(), left.constant());
true_condition = FlipCondition(true_condition);
} else if (right.IsConstant()) {
- __ CompareObject(CMPRES, left.reg(), right.constant());
+ __ CompareObject(CMPRES, TMP1, left.reg(), right.constant());
} else {
- __ subu(CMPRES, left.reg(), right.reg());
+ __ slt(CMPRES, left.reg(), right.reg());
+ __ slt(TMP1, right.reg(), left.reg());
}
if (branch != NULL) {
@@ -527,17 +547,7 @@
} else {
Register result = locs.out().reg();
Label done, is_true;
- switch (true_condition) {
- case EQ: __ beq(CMPRES, ZR, &is_true); break;
- case NE: __ bne(CMPRES, ZR, &is_true); break;
- case GT: __ bgtz(CMPRES, &is_true); break;
- case GE: __ bgez(CMPRES, &is_true); break;
- case LT: __ bltz(CMPRES, &is_true); break;
- case LE: __ blez(CMPRES, &is_true); break;
- default:
- UNREACHABLE();
- break;
- }
+ EmitBranchAfterCompare(compiler, true_condition, &is_true);
__ LoadObject(result, Bool::False());
__ b(&done);
__ Bind(&is_true);
@@ -655,7 +665,7 @@
EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler);
}
Condition branch_condition = (kind() == Token::kNE) ? NE : EQ;
- __ CompareObject(CMPRES, V0, Bool::True());
+ __ CompareObject(CMPRES, TMP1, V0, Bool::True());
branch->EmitBranchOnCondition(compiler, branch_condition);
}
@@ -791,7 +801,7 @@
return;
}
EmitNativeCode(compiler);
- __ CompareObject(CMPRES, V0, Bool::True());
+ __ CompareObject(CMPRES, TMP1, V0, Bool::True());
branch->EmitBranchOnCondition(compiler, EQ);
}
@@ -865,13 +875,25 @@
LocationSummary* LoadClassIdInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
+ const intptr_t kNumInputs = 1;
+ return LocationSummary::Make(kNumInputs,
+ Location::RequiresRegister(),
+ LocationSummary::kNoCall);
}
void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
+ Register object = locs()->in(0).reg();
+ Register result = locs()->out().reg();
+ Label load, done;
+ __ andi(CMPRES, object, Immediate(kSmiTagMask));
+ __ bne(CMPRES, ZR, &load);
+ __ LoadImmediate(result, Smi::RawValue(kSmiCid));
+ __ b(&done);
+ __ Bind(&load);
+ __ LoadClassId(result, object);
+ __ SmiTag(result);
+ __ Bind(&done);
}
@@ -1000,9 +1022,9 @@
default:
UNREACHABLE();
}
- __ AddImmediate(index.reg(),
+ __ addu(index.reg(), array, index.reg());
+ element_address = Address(index.reg(),
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
- element_address = Address(array, index.reg());
}
if ((representation() == kUnboxedDouble) ||
@@ -1012,9 +1034,6 @@
}
Register result = locs()->out().reg();
- if ((index_scale() == 1) && index.IsRegister()) {
- __ SmiUntag(index.reg());
- }
switch (class_id()) {
case kTypedDataInt8ArrayCid:
ASSERT(index_scale() == 1);
@@ -1067,8 +1086,33 @@
Representation StoreIndexedInstr::RequiredInputRepresentation(
intptr_t idx) const {
- UNIMPLEMENTED();
- return kTagged;
+ // Array can be a Dart object or a pointer to external data.
+ if (idx == 0) return kNoRepresentation; // Flexible input representation.
+ if (idx == 1) return kTagged; // Index is a smi.
+ ASSERT(idx == 2);
+ switch (class_id_) {
+ case kArrayCid:
+ case kOneByteStringCid:
+ case kTypedDataInt8ArrayCid:
+ case kTypedDataUint8ArrayCid:
+ case kExternalTypedDataUint8ArrayCid:
+ case kTypedDataUint8ClampedArrayCid:
+ case kExternalTypedDataUint8ClampedArrayCid:
+ case kTypedDataInt16ArrayCid:
+ case kTypedDataUint16ArrayCid:
+ return kTagged;
+ case kTypedDataInt32ArrayCid:
+ case kTypedDataUint32ArrayCid:
+ return value()->IsSmiValue() ? kTagged : kUnboxedMint;
+ case kTypedDataFloat32ArrayCid:
+ case kTypedDataFloat64ArrayCid:
+ return kUnboxedDouble;
+ case kTypedDataFloat32x4ArrayCid:
+ return kUnboxedFloat32x4;
+ default:
+ UNIMPLEMENTED();
+ return kTagged;
+ }
}
@@ -1094,14 +1138,22 @@
case kTypedDataUint8ArrayCid:
case kTypedDataUint8ClampedArrayCid:
case kOneByteStringCid:
+ locs->set_in(2, Location::RegisterOrSmiConstant(value()));
+ break;
case kTypedDataInt16ArrayCid:
case kTypedDataUint16ArrayCid:
case kTypedDataInt32ArrayCid:
case kTypedDataUint32ArrayCid:
+ locs->set_in(2, Location::WritableRegister());
+ break;
case kTypedDataFloat32ArrayCid:
- case kTypedDataFloat64ArrayCid:
+ // TODO(regis): Verify.
+ // Need temp register for float-to-double conversion.
+ locs->AddTemp(Location::RequiresFpuRegister());
+ // Fall through.
+ case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
case kTypedDataFloat32x4ArrayCid:
- UNIMPLEMENTED();
+ locs->set_in(2, Location::RequiresFpuRegister());
break;
default:
UNREACHABLE();
@@ -1149,10 +1201,9 @@
default:
UNREACHABLE();
}
- __ AddImmediate(index.reg(),
+ __ addu(index.reg(), array, index.reg());
+ element_address = Address(index.reg(),
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
- __ addu(TMP1, array, index.reg());
- element_address = Address(TMP1);
}
switch (class_id()) {
@@ -1171,13 +1222,64 @@
case kTypedDataInt8ArrayCid:
case kTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ArrayCid:
+ case kOneByteStringCid: {
+ if (locs()->in(2).IsConstant()) {
+ const Smi& constant = Smi::Cast(locs()->in(2).constant());
+ __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()));
+ __ sb(TMP, element_address);
+ } else {
+ Register value = locs()->in(2).reg();
+ __ SmiUntag(value);
+ __ sb(value, element_address);
+ }
+ break;
+ }
case kTypedDataUint8ClampedArrayCid:
- case kExternalTypedDataUint8ClampedArrayCid:
- case kOneByteStringCid:
+ case kExternalTypedDataUint8ClampedArrayCid: {
+ if (locs()->in(2).IsConstant()) {
+ const Smi& constant = Smi::Cast(locs()->in(2).constant());
+ intptr_t value = constant.Value();
+ // Clamp to 0x0 or 0xFF respectively.
+ if (value > 0xFF) {
+ value = 0xFF;
+ } else if (value < 0) {
+ value = 0;
+ }
+ __ LoadImmediate(TMP, static_cast<int8_t>(value));
+ __ sb(TMP, element_address);
+ } else {
+ Register value = locs()->in(2).reg();
+ Label store_value, bigger, smaller;
+ __ SmiUntag(value);
+ __ BranchUnsignedLess(value, 0xFF + 1, &store_value);
+ __ LoadImmediate(TMP, 0xFF);
+ __ slti(CMPRES, value, Immediate(1));
+ __ movn(TMP, ZR, CMPRES);
+ __ mov(value, TMP);
+ __ Bind(&store_value);
+ __ sb(value, element_address);
+ }
+ break;
+ }
case kTypedDataInt16ArrayCid:
- case kTypedDataUint16ArrayCid:
+ case kTypedDataUint16ArrayCid: {
+ Register value = locs()->in(2).reg();
+ __ SmiUntag(value);
+ __ sh(value, element_address);
+ break;
+ }
case kTypedDataInt32ArrayCid:
- case kTypedDataUint32ArrayCid:
+ case kTypedDataUint32ArrayCid: {
+ if (value()->IsSmiValue()) {
+ ASSERT(RequiredInputRepresentation(2) == kTagged);
+ Register value = locs()->in(2).reg();
+ __ SmiUntag(value);
+ __ sw(value, element_address);
+ } else {
+ UNIMPLEMENTED();
+ }
+ break;
+ }
case kTypedDataFloat32ArrayCid:
case kTypedDataFloat64ArrayCid:
case kTypedDataFloat32x4ArrayCid:
@@ -1305,8 +1407,7 @@
if (field().is_nullable() && (field_cid != kNullCid)) {
__ beq(CMPRES, ZR, &ok);
- __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
- __ subu(CMPRES, value_reg, TMP1);
+ __ subu(CMPRES, value_reg, NULLREG);
}
if (ok_is_fall_through) {
@@ -1513,9 +1614,7 @@
Label type_arguments_instantiated;
const intptr_t len = type_arguments().Length();
if (type_arguments().IsRawInstantiatedRaw(len)) {
- __ BranchEqual(instantiator_reg,
- reinterpret_cast<intptr_t>(Object::null()),
- &type_arguments_instantiated);
+ __ beq(instantiator_reg, NULLREG, &type_arguments_instantiated);
}
// Instantiate non-null type arguments.
// A runtime call to instantiate the type arguments is required.
@@ -1570,9 +1669,7 @@
// the type arguments.
Label type_arguments_instantiated;
ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
- __ BranchEqual(instantiator_reg,
- reinterpret_cast<intptr_t>(Object::null()),
- &type_arguments_instantiated);
+ __ beq(instantiator_reg, NULLREG, &type_arguments_instantiated);
// Instantiate non-null type arguments.
// In the non-factory case, we rely on the allocation stub to
// instantiate the type arguments.
@@ -1612,8 +1709,7 @@
// the type arguments and do not pass the instantiator.
ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
Label instantiator_not_null;
- __ BranchNotEqual(instantiator_reg,
- reinterpret_cast<intptr_t>(Object::null()), &instantiator_not_null);
+ __ bne(instantiator_reg, NULLREG, &instantiator_not_null);
// Null was used in VisitExtractConstructorTypeArguments as the
// instantiated type arguments, no proper instantiator needed.
__ LoadImmediate(instantiator_reg,
@@ -1687,10 +1783,10 @@
Address(FP, stacktrace_var().index() * kWordSize));
Label next;
- __ mov(T0, RA); // Save return adress.
+ __ mov(TMP, RA); // Save return adress.
// Restore the pool pointer.
__ bal(&next); // Branch and link to next instruction to get PC in RA.
- __ delay_slot()->mov(T1, RA); // Save PC of the following mov.
+ __ delay_slot()->mov(CMPRES, RA); // Save PC of the following mov.
// Calculate offset of pool pointer from the PC.
const intptr_t object_pool_pc_dist =
@@ -1698,8 +1794,8 @@
compiler->assembler()->CodeSize();
__ Bind(&next);
- __ mov(RA, T0); // Restore return address.
- __ lw(PP, Address(T1, -object_pool_pc_dist));
+ __ mov(RA, TMP); // Restore return address.
+ __ lw(PP, Address(CMPRES, -object_pool_pc_dist));
}
@@ -1762,7 +1858,7 @@
UNIMPLEMENTED();
return NULL;
} else {
- const intptr_t kNumTemps = 0;
+ const intptr_t kNumTemps = op_kind() == Token::kADD ? 1 : 0;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
@@ -2414,8 +2510,7 @@
if (null_check()) {
Label* deopt = compiler->AddDeoptStub(deopt_id(),
kDeoptCheckClass);
- __ BranchEqual(locs()->in(0).reg(),
- reinterpret_cast<intptr_t>(Object::null()), deopt);
+ __ beq(locs()->in(0).reg(), NULLREG, deopt);
return;
}
@@ -2668,33 +2763,13 @@
if (compiler->CanFallThroughTo(false_successor())) {
// If the next block is the false successor we will fall through to it.
Label* label = compiler->GetJumpLabel(true_successor());
- switch (true_condition) {
- case EQ: __ beq(CMPRES, ZR, label); break;
- case NE: __ bne(CMPRES, ZR, label); break;
- case GT: __ bgtz(CMPRES, label); break;
- case GE: __ bgez(CMPRES, label); break;
- case LT: __ bltz(CMPRES, label); break;
- case LE: __ blez(CMPRES, label); break;
- default:
- UNREACHABLE();
- break;
- }
+ EmitBranchAfterCompare(compiler, true_condition, label);
} else {
// If the next block is the true successor we negate comparison and fall
// through to it.
Condition false_condition = NegateCondition(true_condition);
Label* label = compiler->GetJumpLabel(false_successor());
- switch (false_condition) {
- case EQ: __ beq(CMPRES, ZR, label); break;
- case NE: __ bne(CMPRES, ZR, label); break;
- case GT: __ bgtz(CMPRES, label); break;
- case GE: __ bgez(CMPRES, label); break;
- case LT: __ bltz(CMPRES, label); break;
- case LE: __ blez(CMPRES, label); break;
- default:
- UNREACHABLE();
- break;
- }
+ EmitBranchAfterCompare(compiler, false_condition, label);
// Fall through or jump to the true successor.
if (!compiler->CanFallThroughTo(true_successor())) {
__ b(compiler->GetJumpLabel(true_successor()));
@@ -2864,11 +2939,11 @@
Register dest_reg = locs()->in(1).reg();
if (value()->NeedsStoreBuffer()) {
- __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
- value_reg);
+ __ StoreIntoObject(dest_reg,
+ FieldAddress(dest_reg, offset_in_bytes()), value_reg);
} else {
- __ StoreIntoObjectNoBarrier(
- dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
+ __ StoreIntoObjectNoBarrier(dest_reg,
+ FieldAddress(dest_reg, offset_in_bytes()), value_reg);
}
}
« 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