Index: runtime/vm/intermediate_language_mips.cc |
=================================================================== |
--- runtime/vm/intermediate_language_mips.cc (revision 21951) |
+++ runtime/vm/intermediate_language_mips.cc (working copy) |
@@ -99,13 +99,11 @@ |
__ Bind(&stack_ok); |
} |
#endif |
+ // This sequence is patched by a debugger breakpoint. There is no need for |
+ // extra NOP instructions here because the sequence patched in for a |
+ // breakpoint is shorter than the sequence here. |
__ LeaveDartFrame(); |
__ Ret(); |
- |
- // Generate 2 NOP instructions so that the debugger can patch the return |
- // pattern (1 instruction) with a call to the debug stub (3 instructions). |
- __ nop(); |
- __ nop(); |
compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
Isolate::kNoDeoptId, |
token_pos()); |
@@ -1682,16 +1680,27 @@ |
case Token::kMUL: { |
// Keep left value tagged and untag right value. |
const intptr_t value = Smi::Cast(constant).Value(); |
- if (value == 2) { |
- __ sll(result, left, 1); |
+ if (deopt == NULL) { |
+ if (value == 2) { |
+ __ sll(result, left, 1); |
+ } else { |
+ __ LoadImmediate(TMP1, value); |
+ __ mult(left, TMP1); |
+ __ mflo(result); |
+ } |
} else { |
- __ LoadImmediate(TMP1, value); |
- __ mult(left, TMP1); |
- __ mflo(result); |
+ if (value == 2) { |
+ __ sra(TMP1, left, 31); // TMP1 = sign of left. |
+ __ sll(result, left, 1); |
+ } else { |
+ __ LoadImmediate(TMP1, value); |
+ __ mult(left, TMP1); |
+ __ mflo(result); |
+ __ mfhi(TMP1); |
+ } |
+ __ sra(TMP2, result, 31); |
+ __ bne(TMP1, TMP2, deopt); |
} |
- if (deopt != NULL) { |
- UNIMPLEMENTED(); |
- } |
break; |
} |
case Token::kTRUNCDIV: { |
@@ -2379,24 +2388,47 @@ |
LocationSummary* ChainContextInstr::MakeLocationSummary() const { |
- UNIMPLEMENTED(); |
- return NULL; |
+ return LocationSummary::Make(1, |
+ Location::NoLocation(), |
+ LocationSummary::kNoCall); |
} |
void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- UNIMPLEMENTED(); |
+ Register context_value = locs()->in(0).reg(); |
+ |
+ // Chain the new context in context_value to its parent in CTX. |
+ __ StoreIntoObject(context_value, |
+ FieldAddress(context_value, Context::parent_offset()), |
+ CTX); |
+ // Set new context as current context. |
+ __ mov(CTX, context_value); |
} |
LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { |
- UNIMPLEMENTED(); |
- return NULL; |
+ const intptr_t kNumInputs = 2; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* locs = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
+ : Location::RequiresRegister()); |
+ locs->set_in(1, Location::RequiresRegister()); |
+ return locs; |
} |
void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- UNIMPLEMENTED(); |
+ Register value_reg = locs()->in(0).reg(); |
+ Register dest_reg = locs()->in(1).reg(); |
+ |
+ if (value()->NeedsStoreBuffer()) { |
+ __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
+ value_reg); |
+ } else { |
+ __ StoreIntoObjectNoBarrier( |
+ dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
+ } |
} |