Index: runtime/vm/intermediate_language_arm.cc |
=================================================================== |
--- runtime/vm/intermediate_language_arm.cc (revision 21886) |
+++ runtime/vm/intermediate_language_arm.cc (working copy) |
@@ -95,10 +95,9 @@ |
__ 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(); |
+ // No need to generate NOP instructions so that the debugger can patch the |
+ // return pattern (3 instructions) with a call to the debug stub (also 3 |
+ // instructions). |
compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
Isolate::kNoDeoptId, |
token_pos()); |
@@ -1630,15 +1629,25 @@ |
case Token::kMUL: { |
// Keep left value tagged and untag right value. |
const intptr_t value = Smi::Cast(constant).Value(); |
- if (value == 2) { |
- __ mov(result, ShifterOperand(left, LSL, 1)); |
+ if (deopt == NULL) { |
+ if (value == 2) { |
+ __ mov(result, ShifterOperand(left, LSL, 1)); |
+ } else { |
+ __ LoadImmediate(IP, value); |
+ __ mul(result, left, IP); |
+ } |
} else { |
- __ LoadImmediate(IP, value); |
- __ mul(result, left, IP); |
+ if (value == 2) { |
+ __ mov(IP, ShifterOperand(left, ASR, 31)); // IP = sign of left. |
+ __ mov(result, ShifterOperand(left, LSL, 1)); |
+ } else { |
+ __ LoadImmediate(IP, value); |
+ __ smull(result, IP, left, IP); |
+ } |
+ // IP: result bits 32..63. |
+ __ cmp(IP, ShifterOperand(result, ASR, 31)); |
+ __ b(deopt, NE); |
} |
- if (deopt != NULL) { |
- UNIMPLEMENTED(); |
- } |
break; |
} |
case Token::kTRUNCDIV: { |
@@ -2262,24 +2271,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, ShifterOperand(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); |
+ } |
} |