OLD | NEW |
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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 (kFirstLocalSlotIndex + 1 - compiler->StackSize()) * kWordSize; | 88 (kFirstLocalSlotIndex + 1 - compiler->StackSize()) * kWordSize; |
89 ASSERT(fp_sp_dist <= 0); | 89 ASSERT(fp_sp_dist <= 0); |
90 __ sub(R2, SP, ShifterOperand(FP)); | 90 __ sub(R2, SP, ShifterOperand(FP)); |
91 __ CompareImmediate(R2, fp_sp_dist); | 91 __ CompareImmediate(R2, fp_sp_dist); |
92 __ bkpt(0, NE); | 92 __ bkpt(0, NE); |
93 } | 93 } |
94 #endif | 94 #endif |
95 __ LeaveDartFrame(); | 95 __ LeaveDartFrame(); |
96 __ Ret(); | 96 __ Ret(); |
97 | 97 |
98 // Generate 2 NOP instructions so that the debugger can patch the return | 98 // No need to generate NOP instructions so that the debugger can patch the |
99 // pattern (1 instruction) with a call to the debug stub (3 instructions). | 99 // return pattern (3 instructions) with a call to the debug stub (also 3 |
100 __ nop(); | 100 // instructions). |
101 __ nop(); | |
102 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, | 101 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
103 Isolate::kNoDeoptId, | 102 Isolate::kNoDeoptId, |
104 token_pos()); | 103 token_pos()); |
105 } | 104 } |
106 | 105 |
107 | 106 |
108 bool IfThenElseInstr::IsSupported() { | 107 bool IfThenElseInstr::IsSupported() { |
109 return false; | 108 return false; |
110 } | 109 } |
111 | 110 |
(...skipping 1511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1623 __ AddImmediate(result, left, imm); | 1622 __ AddImmediate(result, left, imm); |
1624 } else { | 1623 } else { |
1625 __ AddImmediateSetFlags(result, left, imm); | 1624 __ AddImmediateSetFlags(result, left, imm); |
1626 __ b(deopt, VS); | 1625 __ b(deopt, VS); |
1627 } | 1626 } |
1628 break; | 1627 break; |
1629 } | 1628 } |
1630 case Token::kMUL: { | 1629 case Token::kMUL: { |
1631 // Keep left value tagged and untag right value. | 1630 // Keep left value tagged and untag right value. |
1632 const intptr_t value = Smi::Cast(constant).Value(); | 1631 const intptr_t value = Smi::Cast(constant).Value(); |
1633 if (value == 2) { | 1632 if (deopt == NULL) { |
1634 __ mov(result, ShifterOperand(left, LSL, 1)); | 1633 if (value == 2) { |
| 1634 __ mov(result, ShifterOperand(left, LSL, 1)); |
| 1635 } else { |
| 1636 __ LoadImmediate(IP, value); |
| 1637 __ mul(result, left, IP); |
| 1638 } |
1635 } else { | 1639 } else { |
1636 __ LoadImmediate(IP, value); | 1640 if (value == 2) { |
1637 __ mul(result, left, IP); | 1641 __ mov(IP, ShifterOperand(left, ASR, 31)); // IP = sign of left. |
1638 } | 1642 __ mov(result, ShifterOperand(left, LSL, 1)); |
1639 if (deopt != NULL) { | 1643 } else { |
1640 UNIMPLEMENTED(); | 1644 __ LoadImmediate(IP, value); |
| 1645 __ smull(result, IP, left, IP); |
| 1646 } |
| 1647 // IP: result bits 32..63. |
| 1648 __ cmp(IP, ShifterOperand(result, ASR, 31)); |
| 1649 __ b(deopt, NE); |
1641 } | 1650 } |
1642 break; | 1651 break; |
1643 } | 1652 } |
1644 case Token::kTRUNCDIV: { | 1653 case Token::kTRUNCDIV: { |
1645 UNIMPLEMENTED(); | 1654 UNIMPLEMENTED(); |
1646 break; | 1655 break; |
1647 } | 1656 } |
1648 case Token::kBIT_AND: { | 1657 case Token::kBIT_AND: { |
1649 // No overflow check. | 1658 // No overflow check. |
1650 ShifterOperand shifter_op; | 1659 ShifterOperand shifter_op; |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2255 Register value = locs()->in(0).reg(); | 2264 Register value = locs()->in(0).reg(); |
2256 Register result = locs()->out().reg(); | 2265 Register result = locs()->out().reg(); |
2257 | 2266 |
2258 __ LoadObject(result, Bool::True()); | 2267 __ LoadObject(result, Bool::True()); |
2259 __ cmp(result, ShifterOperand(value)); | 2268 __ cmp(result, ShifterOperand(value)); |
2260 __ LoadObject(result, Bool::False(), EQ); | 2269 __ LoadObject(result, Bool::False(), EQ); |
2261 } | 2270 } |
2262 | 2271 |
2263 | 2272 |
2264 LocationSummary* ChainContextInstr::MakeLocationSummary() const { | 2273 LocationSummary* ChainContextInstr::MakeLocationSummary() const { |
2265 UNIMPLEMENTED(); | 2274 return LocationSummary::Make(1, |
2266 return NULL; | 2275 Location::NoLocation(), |
| 2276 LocationSummary::kNoCall); |
2267 } | 2277 } |
2268 | 2278 |
2269 | 2279 |
2270 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2280 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2271 UNIMPLEMENTED(); | 2281 Register context_value = locs()->in(0).reg(); |
| 2282 |
| 2283 // Chain the new context in context_value to its parent in CTX. |
| 2284 __ StoreIntoObject(context_value, |
| 2285 FieldAddress(context_value, Context::parent_offset()), |
| 2286 CTX); |
| 2287 // Set new context as current context. |
| 2288 __ mov(CTX, ShifterOperand(context_value)); |
2272 } | 2289 } |
2273 | 2290 |
2274 | 2291 |
2275 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { | 2292 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { |
2276 UNIMPLEMENTED(); | 2293 const intptr_t kNumInputs = 2; |
2277 return NULL; | 2294 const intptr_t kNumTemps = 0; |
| 2295 LocationSummary* locs = |
| 2296 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2297 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
| 2298 : Location::RequiresRegister()); |
| 2299 locs->set_in(1, Location::RequiresRegister()); |
| 2300 return locs; |
2278 } | 2301 } |
2279 | 2302 |
2280 | 2303 |
2281 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2304 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2282 UNIMPLEMENTED(); | 2305 Register value_reg = locs()->in(0).reg(); |
| 2306 Register dest_reg = locs()->in(1).reg(); |
| 2307 |
| 2308 if (value()->NeedsStoreBuffer()) { |
| 2309 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
| 2310 value_reg); |
| 2311 } else { |
| 2312 __ StoreIntoObjectNoBarrier( |
| 2313 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
| 2314 } |
2283 } | 2315 } |
2284 | 2316 |
2285 | 2317 |
2286 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { | 2318 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { |
2287 return MakeCallSummary(); | 2319 return MakeCallSummary(); |
2288 } | 2320 } |
2289 | 2321 |
2290 | 2322 |
2291 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2323 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2292 const Class& cls = Class::ZoneHandle(constructor().Owner()); | 2324 const Class& cls = Class::ZoneHandle(constructor().Owner()); |
(...skipping 22 matching lines...) Expand all Loading... |
2315 &label, | 2347 &label, |
2316 PcDescriptors::kOther, | 2348 PcDescriptors::kOther, |
2317 locs()); | 2349 locs()); |
2318 __ Drop(2); // Discard type arguments and receiver. | 2350 __ Drop(2); // Discard type arguments and receiver. |
2319 } | 2351 } |
2320 | 2352 |
2321 } // namespace dart | 2353 } // namespace dart |
2322 | 2354 |
2323 #endif // defined TARGET_ARCH_ARM | 2355 #endif // defined TARGET_ARCH_ARM |
2324 | 2356 |
OLD | NEW |