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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 Label done; | 242 Label done; |
243 __ CompareObject(reg, Bool::True()); | 243 __ CompareObject(reg, Bool::True()); |
244 __ b(&done, EQ); | 244 __ b(&done, EQ); |
245 __ CompareObject(reg, Bool::False()); | 245 __ CompareObject(reg, Bool::False()); |
246 __ b(&done, EQ); | 246 __ b(&done, EQ); |
247 | 247 |
248 __ Push(reg); // Push the source object. | 248 __ Push(reg); // Push the source object. |
249 compiler->GenerateCallRuntime(token_pos, | 249 compiler->GenerateCallRuntime(token_pos, |
250 deopt_id, | 250 deopt_id, |
251 kConditionTypeErrorRuntimeEntry, | 251 kConditionTypeErrorRuntimeEntry, |
| 252 1, |
252 locs); | 253 locs); |
253 // We should never return here. | 254 // We should never return here. |
254 __ bkpt(0); | 255 __ bkpt(0); |
255 __ Bind(&done); | 256 __ Bind(&done); |
256 } | 257 } |
257 | 258 |
258 | 259 |
259 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 260 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
260 Register obj = locs()->in(0).reg(); | 261 Register obj = locs()->in(0).reg(); |
261 Register result = locs()->out().reg(); | 262 Register result = locs()->out().reg(); |
(...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1792 if (deopt == NULL) { | 1793 if (deopt == NULL) { |
1793 ASSERT(!compiler->is_optimizing()); | 1794 ASSERT(!compiler->is_optimizing()); |
1794 __ Bind(fail); | 1795 __ Bind(fail); |
1795 | 1796 |
1796 __ ldr(IP, FieldAddress(field_reg, Field::guarded_cid_offset())); | 1797 __ ldr(IP, FieldAddress(field_reg, Field::guarded_cid_offset())); |
1797 __ CompareImmediate(IP, kDynamicCid); | 1798 __ CompareImmediate(IP, kDynamicCid); |
1798 __ b(&ok, EQ); | 1799 __ b(&ok, EQ); |
1799 | 1800 |
1800 __ Push(field_reg); | 1801 __ Push(field_reg); |
1801 __ Push(value_reg); | 1802 __ Push(value_reg); |
1802 __ CallRuntime(kUpdateFieldCidRuntimeEntry); | 1803 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); |
1803 __ Drop(2); // Drop the field and the value. | 1804 __ Drop(2); // Drop the field and the value. |
1804 } | 1805 } |
1805 | 1806 |
1806 __ Bind(&ok); | 1807 __ Bind(&ok); |
1807 } | 1808 } |
1808 | 1809 |
1809 | 1810 |
1810 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1811 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
1811 const intptr_t kNumInputs = 2; | 1812 const intptr_t kNumInputs = 2; |
1812 const intptr_t kNumTemps = 0; | 1813 const intptr_t kNumTemps = 0; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1945 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 1946 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { |
1946 return MakeCallSummary(); | 1947 return MakeCallSummary(); |
1947 } | 1948 } |
1948 | 1949 |
1949 | 1950 |
1950 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 1951 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( |
1951 FlowGraphCompiler* compiler) { | 1952 FlowGraphCompiler* compiler) { |
1952 compiler->GenerateCallRuntime(token_pos(), | 1953 compiler->GenerateCallRuntime(token_pos(), |
1953 deopt_id(), | 1954 deopt_id(), |
1954 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1955 kAllocateObjectWithBoundsCheckRuntimeEntry, |
| 1956 3, |
1955 locs()); | 1957 locs()); |
1956 __ Drop(3); | 1958 __ Drop(3); |
1957 ASSERT(locs()->out().reg() == R0); | 1959 ASSERT(locs()->out().reg() == R0); |
1958 __ Pop(R0); // Pop new instance. | 1960 __ Pop(R0); // Pop new instance. |
1959 } | 1961 } |
1960 | 1962 |
1961 | 1963 |
1962 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { | 1964 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { |
1963 return LocationSummary::Make(1, | 1965 return LocationSummary::Make(1, |
1964 Location::RequiresRegister(), | 1966 Location::RequiresRegister(), |
(...skipping 27 matching lines...) Expand all Loading... |
1992 | 1994 |
1993 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 1995 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
1994 // (or null). | 1996 // (or null). |
1995 // A runtime call to instantiate the type is required. | 1997 // A runtime call to instantiate the type is required. |
1996 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1998 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
1997 __ PushObject(type()); | 1999 __ PushObject(type()); |
1998 __ Push(instantiator_reg); // Push instantiator type arguments. | 2000 __ Push(instantiator_reg); // Push instantiator type arguments. |
1999 compiler->GenerateCallRuntime(token_pos(), | 2001 compiler->GenerateCallRuntime(token_pos(), |
2000 deopt_id(), | 2002 deopt_id(), |
2001 kInstantiateTypeRuntimeEntry, | 2003 kInstantiateTypeRuntimeEntry, |
| 2004 2, |
2002 locs()); | 2005 locs()); |
2003 __ Drop(2); // Drop instantiator and uninstantiated type. | 2006 __ Drop(2); // Drop instantiator and uninstantiated type. |
2004 __ Pop(result_reg); // Pop instantiated type. | 2007 __ Pop(result_reg); // Pop instantiated type. |
2005 ASSERT(instantiator_reg == result_reg); | 2008 ASSERT(instantiator_reg == result_reg); |
2006 } | 2009 } |
2007 | 2010 |
2008 | 2011 |
2009 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 2012 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { |
2010 const intptr_t kNumInputs = 1; | 2013 const intptr_t kNumInputs = 1; |
2011 const intptr_t kNumTemps = 0; | 2014 const intptr_t kNumTemps = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
2038 __ b(&type_arguments_instantiated, EQ); | 2041 __ b(&type_arguments_instantiated, EQ); |
2039 } | 2042 } |
2040 // Instantiate non-null type arguments. | 2043 // Instantiate non-null type arguments. |
2041 // A runtime call to instantiate the type arguments is required. | 2044 // A runtime call to instantiate the type arguments is required. |
2042 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2045 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
2043 __ PushObject(type_arguments()); | 2046 __ PushObject(type_arguments()); |
2044 __ Push(instantiator_reg); // Push instantiator type arguments. | 2047 __ Push(instantiator_reg); // Push instantiator type arguments. |
2045 compiler->GenerateCallRuntime(token_pos(), | 2048 compiler->GenerateCallRuntime(token_pos(), |
2046 deopt_id(), | 2049 deopt_id(), |
2047 kInstantiateTypeArgumentsRuntimeEntry, | 2050 kInstantiateTypeArgumentsRuntimeEntry, |
| 2051 2, |
2048 locs()); | 2052 locs()); |
2049 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2053 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
2050 __ Pop(result_reg); // Pop instantiated type arguments. | 2054 __ Pop(result_reg); // Pop instantiated type arguments. |
2051 __ Bind(&type_arguments_instantiated); | 2055 __ Bind(&type_arguments_instantiated); |
2052 ASSERT(instantiator_reg == result_reg); | 2056 ASSERT(instantiator_reg == result_reg); |
2053 } | 2057 } |
2054 | 2058 |
2055 | 2059 |
2056 LocationSummary* | 2060 LocationSummary* |
2057 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 2061 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2173 | 2177 |
2174 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2178 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2175 Register context_value = locs()->in(0).reg(); | 2179 Register context_value = locs()->in(0).reg(); |
2176 Register result = locs()->out().reg(); | 2180 Register result = locs()->out().reg(); |
2177 | 2181 |
2178 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2182 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
2179 __ Push(context_value); | 2183 __ Push(context_value); |
2180 compiler->GenerateCallRuntime(token_pos(), | 2184 compiler->GenerateCallRuntime(token_pos(), |
2181 deopt_id(), | 2185 deopt_id(), |
2182 kCloneContextRuntimeEntry, | 2186 kCloneContextRuntimeEntry, |
| 2187 1, |
2183 locs()); | 2188 locs()); |
2184 __ Drop(1); // Remove argument. | 2189 __ Drop(1); // Remove argument. |
2185 __ Pop(result); // Get result (cloned context). | 2190 __ Pop(result); // Get result (cloned context). |
2186 } | 2191 } |
2187 | 2192 |
2188 | 2193 |
2189 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { | 2194 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { |
2190 UNREACHABLE(); | 2195 UNREACHABLE(); |
2191 return NULL; | 2196 return NULL; |
2192 } | 2197 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2244 __ Comment("CheckStackOverflowSlowPath"); | 2249 __ Comment("CheckStackOverflowSlowPath"); |
2245 __ Bind(entry_label()); | 2250 __ Bind(entry_label()); |
2246 compiler->SaveLiveRegisters(instruction_->locs()); | 2251 compiler->SaveLiveRegisters(instruction_->locs()); |
2247 // pending_deoptimization_env_ is needed to generate a runtime call that | 2252 // pending_deoptimization_env_ is needed to generate a runtime call that |
2248 // may throw an exception. | 2253 // may throw an exception. |
2249 ASSERT(compiler->pending_deoptimization_env_ == NULL); | 2254 ASSERT(compiler->pending_deoptimization_env_ == NULL); |
2250 compiler->pending_deoptimization_env_ = instruction_->env(); | 2255 compiler->pending_deoptimization_env_ = instruction_->env(); |
2251 compiler->GenerateCallRuntime(instruction_->token_pos(), | 2256 compiler->GenerateCallRuntime(instruction_->token_pos(), |
2252 instruction_->deopt_id(), | 2257 instruction_->deopt_id(), |
2253 kStackOverflowRuntimeEntry, | 2258 kStackOverflowRuntimeEntry, |
| 2259 0, |
2254 instruction_->locs()); | 2260 instruction_->locs()); |
2255 | 2261 |
2256 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { | 2262 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { |
2257 // In unoptimized code, record loop stack checks as possible OSR entries. | 2263 // In unoptimized code, record loop stack checks as possible OSR entries. |
2258 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, | 2264 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, |
2259 instruction_->deopt_id(), | 2265 instruction_->deopt_id(), |
2260 0); // No token position. | 2266 0); // No token position. |
2261 } | 2267 } |
2262 compiler->pending_deoptimization_env_ = NULL; | 2268 compiler->pending_deoptimization_env_ = NULL; |
2263 compiler->RestoreLiveRegisters(instruction_->locs()); | 2269 compiler->RestoreLiveRegisters(instruction_->locs()); |
(...skipping 1914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4178 } | 4184 } |
4179 __ Bind(&do_call); | 4185 __ Bind(&do_call); |
4180 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' | 4186 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' |
4181 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values | 4187 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values |
4182 // are passed and returned in vfp registers rather than in integer | 4188 // are passed and returned in vfp registers rather than in integer |
4183 // register pairs. | 4189 // register pairs. |
4184 if (InputCount() == 2) { | 4190 if (InputCount() == 2) { |
4185 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. | 4191 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. |
4186 __ vmovd(D1, D2); | 4192 __ vmovd(D1, D2); |
4187 } | 4193 } |
4188 __ CallRuntime(TargetFunction()); | 4194 __ CallRuntime(TargetFunction(), InputCount()); |
4189 __ Bind(&skip_call); | 4195 __ Bind(&skip_call); |
4190 } | 4196 } |
4191 | 4197 |
4192 | 4198 |
4193 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4199 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
4194 return MakeCallSummary(); | 4200 return MakeCallSummary(); |
4195 } | 4201 } |
4196 | 4202 |
4197 | 4203 |
4198 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4204 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4427 | 4433 |
4428 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 4434 LocationSummary* ThrowInstr::MakeLocationSummary() const { |
4429 return new LocationSummary(0, 0, LocationSummary::kCall); | 4435 return new LocationSummary(0, 0, LocationSummary::kCall); |
4430 } | 4436 } |
4431 | 4437 |
4432 | 4438 |
4433 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4439 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4434 compiler->GenerateCallRuntime(token_pos(), | 4440 compiler->GenerateCallRuntime(token_pos(), |
4435 deopt_id(), | 4441 deopt_id(), |
4436 kThrowRuntimeEntry, | 4442 kThrowRuntimeEntry, |
| 4443 1, |
4437 locs()); | 4444 locs()); |
4438 __ bkpt(0); | 4445 __ bkpt(0); |
4439 } | 4446 } |
4440 | 4447 |
4441 | 4448 |
4442 LocationSummary* ReThrowInstr::MakeLocationSummary() const { | 4449 LocationSummary* ReThrowInstr::MakeLocationSummary() const { |
4443 return new LocationSummary(0, 0, LocationSummary::kCall); | 4450 return new LocationSummary(0, 0, LocationSummary::kCall); |
4444 } | 4451 } |
4445 | 4452 |
4446 | 4453 |
4447 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4454 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4448 compiler->GenerateCallRuntime(token_pos(), | 4455 compiler->GenerateCallRuntime(token_pos(), |
4449 deopt_id(), | 4456 deopt_id(), |
4450 kReThrowRuntimeEntry, | 4457 kReThrowRuntimeEntry, |
| 4458 2, |
4451 locs()); | 4459 locs()); |
4452 __ bkpt(0); | 4460 __ bkpt(0); |
4453 } | 4461 } |
4454 | 4462 |
4455 | 4463 |
4456 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4464 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4457 __ Bind(compiler->GetJumpLabel(this)); | 4465 __ Bind(compiler->GetJumpLabel(this)); |
4458 if (!compiler->is_optimizing()) { | 4466 if (!compiler->is_optimizing()) { |
4459 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 4467 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
4460 deopt_id_, | 4468 deopt_id_, |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4691 compiler->GenerateCall(token_pos(), | 4699 compiler->GenerateCall(token_pos(), |
4692 &label, | 4700 &label, |
4693 PcDescriptors::kOther, | 4701 PcDescriptors::kOther, |
4694 locs()); | 4702 locs()); |
4695 __ Drop(2); // Discard type arguments and receiver. | 4703 __ Drop(2); // Discard type arguments and receiver. |
4696 } | 4704 } |
4697 | 4705 |
4698 } // namespace dart | 4706 } // namespace dart |
4699 | 4707 |
4700 #endif // defined TARGET_ARCH_ARM | 4708 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |