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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 Label done; | 190 Label done; |
191 __ CompareObject(reg, Bool::True()); | 191 __ CompareObject(reg, Bool::True()); |
192 __ j(EQUAL, &done, Assembler::kNearJump); | 192 __ j(EQUAL, &done, Assembler::kNearJump); |
193 __ CompareObject(reg, Bool::False()); | 193 __ CompareObject(reg, Bool::False()); |
194 __ j(EQUAL, &done, Assembler::kNearJump); | 194 __ j(EQUAL, &done, Assembler::kNearJump); |
195 | 195 |
196 __ pushl(reg); // Push the source object. | 196 __ pushl(reg); // Push the source object. |
197 compiler->GenerateCallRuntime(token_pos, | 197 compiler->GenerateCallRuntime(token_pos, |
198 deopt_id, | 198 deopt_id, |
199 kConditionTypeErrorRuntimeEntry, | 199 kConditionTypeErrorRuntimeEntry, |
| 200 1, |
200 locs); | 201 locs); |
201 // We should never return here. | 202 // We should never return here. |
202 __ int3(); | 203 __ int3(); |
203 __ Bind(&done); | 204 __ Bind(&done); |
204 } | 205 } |
205 | 206 |
206 | 207 |
207 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 208 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
208 Register obj = locs()->in(0).reg(); | 209 Register obj = locs()->in(0).reg(); |
209 Register result = locs()->out().reg(); | 210 Register result = locs()->out().reg(); |
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1880 if (deopt == NULL) { | 1881 if (deopt == NULL) { |
1881 ASSERT(!compiler->is_optimizing()); | 1882 ASSERT(!compiler->is_optimizing()); |
1882 __ Bind(fail); | 1883 __ Bind(fail); |
1883 | 1884 |
1884 __ cmpl(FieldAddress(field_reg, Field::guarded_cid_offset()), | 1885 __ cmpl(FieldAddress(field_reg, Field::guarded_cid_offset()), |
1885 Immediate(kDynamicCid)); | 1886 Immediate(kDynamicCid)); |
1886 __ j(EQUAL, &ok); | 1887 __ j(EQUAL, &ok); |
1887 | 1888 |
1888 __ pushl(field_reg); | 1889 __ pushl(field_reg); |
1889 __ pushl(value_reg); | 1890 __ pushl(value_reg); |
1890 __ CallRuntime(kUpdateFieldCidRuntimeEntry); | 1891 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); |
1891 __ Drop(2); // Drop the field and the value. | 1892 __ Drop(2); // Drop the field and the value. |
1892 } | 1893 } |
1893 | 1894 |
1894 __ Bind(&ok); | 1895 __ Bind(&ok); |
1895 } | 1896 } |
1896 | 1897 |
1897 | 1898 |
1898 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1899 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
1899 const intptr_t kNumInputs = 2; | 1900 const intptr_t kNumInputs = 2; |
1900 const intptr_t kNumTemps = 0; | 1901 const intptr_t kNumTemps = 0; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2034 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 2035 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { |
2035 return MakeCallSummary(); | 2036 return MakeCallSummary(); |
2036 } | 2037 } |
2037 | 2038 |
2038 | 2039 |
2039 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 2040 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( |
2040 FlowGraphCompiler* compiler) { | 2041 FlowGraphCompiler* compiler) { |
2041 compiler->GenerateCallRuntime(token_pos(), | 2042 compiler->GenerateCallRuntime(token_pos(), |
2042 deopt_id(), | 2043 deopt_id(), |
2043 kAllocateObjectWithBoundsCheckRuntimeEntry, | 2044 kAllocateObjectWithBoundsCheckRuntimeEntry, |
| 2045 3, |
2044 locs()); | 2046 locs()); |
2045 __ Drop(3); | 2047 __ Drop(3); |
2046 ASSERT(locs()->out().reg() == EAX); | 2048 ASSERT(locs()->out().reg() == EAX); |
2047 __ popl(EAX); // Pop new instance. | 2049 __ popl(EAX); // Pop new instance. |
2048 } | 2050 } |
2049 | 2051 |
2050 | 2052 |
2051 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { | 2053 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { |
2052 return LocationSummary::Make(1, | 2054 return LocationSummary::Make(1, |
2053 Location::RequiresRegister(), | 2055 Location::RequiresRegister(), |
(...skipping 26 matching lines...) Expand all Loading... |
2080 | 2082 |
2081 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 2083 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
2082 // (or null). | 2084 // (or null). |
2083 // A runtime call to instantiate the type is required. | 2085 // A runtime call to instantiate the type is required. |
2084 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2086 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
2085 __ PushObject(type()); | 2087 __ PushObject(type()); |
2086 __ pushl(instantiator_reg); // Push instantiator type arguments. | 2088 __ pushl(instantiator_reg); // Push instantiator type arguments. |
2087 compiler->GenerateCallRuntime(token_pos(), | 2089 compiler->GenerateCallRuntime(token_pos(), |
2088 deopt_id(), | 2090 deopt_id(), |
2089 kInstantiateTypeRuntimeEntry, | 2091 kInstantiateTypeRuntimeEntry, |
| 2092 2, |
2090 locs()); | 2093 locs()); |
2091 __ Drop(2); // Drop instantiator and uninstantiated type. | 2094 __ Drop(2); // Drop instantiator and uninstantiated type. |
2092 __ popl(result_reg); // Pop instantiated type. | 2095 __ popl(result_reg); // Pop instantiated type. |
2093 ASSERT(instantiator_reg == result_reg); | 2096 ASSERT(instantiator_reg == result_reg); |
2094 } | 2097 } |
2095 | 2098 |
2096 | 2099 |
2097 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 2100 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { |
2098 const intptr_t kNumInputs = 1; | 2101 const intptr_t kNumInputs = 1; |
2099 const intptr_t kNumTemps = 0; | 2102 const intptr_t kNumTemps = 0; |
(...skipping 27 matching lines...) Expand all Loading... |
2127 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | 2130 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
2128 } | 2131 } |
2129 // Instantiate non-null type arguments. | 2132 // Instantiate non-null type arguments. |
2130 // A runtime call to instantiate the type arguments is required. | 2133 // A runtime call to instantiate the type arguments is required. |
2131 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2134 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
2132 __ PushObject(type_arguments()); | 2135 __ PushObject(type_arguments()); |
2133 __ pushl(instantiator_reg); // Push instantiator type arguments. | 2136 __ pushl(instantiator_reg); // Push instantiator type arguments. |
2134 compiler->GenerateCallRuntime(token_pos(), | 2137 compiler->GenerateCallRuntime(token_pos(), |
2135 deopt_id(), | 2138 deopt_id(), |
2136 kInstantiateTypeArgumentsRuntimeEntry, | 2139 kInstantiateTypeArgumentsRuntimeEntry, |
| 2140 2, |
2137 locs()); | 2141 locs()); |
2138 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2142 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
2139 __ popl(result_reg); // Pop instantiated type arguments. | 2143 __ popl(result_reg); // Pop instantiated type arguments. |
2140 __ Bind(&type_arguments_instantiated); | 2144 __ Bind(&type_arguments_instantiated); |
2141 ASSERT(instantiator_reg == result_reg); | 2145 ASSERT(instantiator_reg == result_reg); |
2142 } | 2146 } |
2143 | 2147 |
2144 | 2148 |
2145 LocationSummary* | 2149 LocationSummary* |
2146 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 2150 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2264 | 2268 |
2265 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2269 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2266 Register context_value = locs()->in(0).reg(); | 2270 Register context_value = locs()->in(0).reg(); |
2267 Register result = locs()->out().reg(); | 2271 Register result = locs()->out().reg(); |
2268 | 2272 |
2269 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2273 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
2270 __ pushl(context_value); | 2274 __ pushl(context_value); |
2271 compiler->GenerateCallRuntime(token_pos(), | 2275 compiler->GenerateCallRuntime(token_pos(), |
2272 deopt_id(), | 2276 deopt_id(), |
2273 kCloneContextRuntimeEntry, | 2277 kCloneContextRuntimeEntry, |
| 2278 1, |
2274 locs()); | 2279 locs()); |
2275 __ popl(result); // Remove argument. | 2280 __ popl(result); // Remove argument. |
2276 __ popl(result); // Get result (cloned context). | 2281 __ popl(result); // Get result (cloned context). |
2277 } | 2282 } |
2278 | 2283 |
2279 | 2284 |
2280 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { | 2285 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { |
2281 UNREACHABLE(); | 2286 UNREACHABLE(); |
2282 return NULL; | 2287 return NULL; |
2283 } | 2288 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2330 __ Comment("CheckStackOverflowSlowPath"); | 2335 __ Comment("CheckStackOverflowSlowPath"); |
2331 __ Bind(entry_label()); | 2336 __ Bind(entry_label()); |
2332 compiler->SaveLiveRegisters(instruction_->locs()); | 2337 compiler->SaveLiveRegisters(instruction_->locs()); |
2333 // pending_deoptimization_env_ is needed to generate a runtime call that | 2338 // pending_deoptimization_env_ is needed to generate a runtime call that |
2334 // may throw an exception. | 2339 // may throw an exception. |
2335 ASSERT(compiler->pending_deoptimization_env_ == NULL); | 2340 ASSERT(compiler->pending_deoptimization_env_ == NULL); |
2336 compiler->pending_deoptimization_env_ = instruction_->env(); | 2341 compiler->pending_deoptimization_env_ = instruction_->env(); |
2337 compiler->GenerateCallRuntime(instruction_->token_pos(), | 2342 compiler->GenerateCallRuntime(instruction_->token_pos(), |
2338 instruction_->deopt_id(), | 2343 instruction_->deopt_id(), |
2339 kStackOverflowRuntimeEntry, | 2344 kStackOverflowRuntimeEntry, |
| 2345 0, |
2340 instruction_->locs()); | 2346 instruction_->locs()); |
2341 | 2347 |
2342 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { | 2348 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { |
2343 // In unoptimized code, record loop stack checks as possible OSR entries. | 2349 // In unoptimized code, record loop stack checks as possible OSR entries. |
2344 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, | 2350 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, |
2345 instruction_->deopt_id(), | 2351 instruction_->deopt_id(), |
2346 0); // No token position. | 2352 0); // No token position. |
2347 } | 2353 } |
2348 compiler->pending_deoptimization_env_ = NULL; | 2354 compiler->pending_deoptimization_env_ = NULL; |
2349 compiler->RestoreLiveRegisters(instruction_->locs()); | 2355 compiler->RestoreLiveRegisters(instruction_->locs()); |
(...skipping 1886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4236 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 | 4242 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 |
4237 __ jmp(&do_call, Assembler::kNearJump); | 4243 __ jmp(&do_call, Assembler::kNearJump); |
4238 | 4244 |
4239 __ Bind(&base_is_nan); | 4245 __ Bind(&base_is_nan); |
4240 // Returns NaN. | 4246 // Returns NaN. |
4241 __ movsd(result, base); | 4247 __ movsd(result, base); |
4242 __ jmp(&skip_call, Assembler::kNearJump); | 4248 __ jmp(&skip_call, Assembler::kNearJump); |
4243 // exp is Nan case is handled correctly in the C-library. | 4249 // exp is Nan case is handled correctly in the C-library. |
4244 } | 4250 } |
4245 __ Bind(&do_call); | 4251 __ Bind(&do_call); |
4246 __ CallRuntime(TargetFunction()); | 4252 __ CallRuntime(TargetFunction(), InputCount()); |
4247 __ fstpl(Address(ESP, 0)); | 4253 __ fstpl(Address(ESP, 0)); |
4248 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); | 4254 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); |
4249 __ Bind(&skip_call); | 4255 __ Bind(&skip_call); |
4250 __ leave(); | 4256 __ leave(); |
4251 } | 4257 } |
4252 | 4258 |
4253 | 4259 |
4254 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4260 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
4255 return MakeCallSummary(); | 4261 return MakeCallSummary(); |
4256 } | 4262 } |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4773 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 4779 LocationSummary* ThrowInstr::MakeLocationSummary() const { |
4774 return new LocationSummary(0, 0, LocationSummary::kCall); | 4780 return new LocationSummary(0, 0, LocationSummary::kCall); |
4775 } | 4781 } |
4776 | 4782 |
4777 | 4783 |
4778 | 4784 |
4779 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4785 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4780 compiler->GenerateCallRuntime(token_pos(), | 4786 compiler->GenerateCallRuntime(token_pos(), |
4781 deopt_id(), | 4787 deopt_id(), |
4782 kThrowRuntimeEntry, | 4788 kThrowRuntimeEntry, |
| 4789 1, |
4783 locs()); | 4790 locs()); |
4784 __ int3(); | 4791 __ int3(); |
4785 } | 4792 } |
4786 | 4793 |
4787 | 4794 |
4788 LocationSummary* ReThrowInstr::MakeLocationSummary() const { | 4795 LocationSummary* ReThrowInstr::MakeLocationSummary() const { |
4789 return new LocationSummary(0, 0, LocationSummary::kCall); | 4796 return new LocationSummary(0, 0, LocationSummary::kCall); |
4790 } | 4797 } |
4791 | 4798 |
4792 | 4799 |
4793 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4800 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4794 compiler->GenerateCallRuntime(token_pos(), | 4801 compiler->GenerateCallRuntime(token_pos(), |
4795 deopt_id(), | 4802 deopt_id(), |
4796 kReThrowRuntimeEntry, | 4803 kReThrowRuntimeEntry, |
| 4804 2, |
4797 locs()); | 4805 locs()); |
4798 __ int3(); | 4806 __ int3(); |
4799 } | 4807 } |
4800 | 4808 |
4801 | 4809 |
4802 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4810 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4803 __ Bind(compiler->GetJumpLabel(this)); | 4811 __ Bind(compiler->GetJumpLabel(this)); |
4804 if (!compiler->is_optimizing()) { | 4812 if (!compiler->is_optimizing()) { |
4805 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 4813 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
4806 deopt_id_, | 4814 deopt_id_, |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5256 PcDescriptors::kOther, | 5264 PcDescriptors::kOther, |
5257 locs()); | 5265 locs()); |
5258 __ Drop(2); // Discard type arguments and receiver. | 5266 __ Drop(2); // Discard type arguments and receiver. |
5259 } | 5267 } |
5260 | 5268 |
5261 } // namespace dart | 5269 } // namespace dart |
5262 | 5270 |
5263 #undef __ | 5271 #undef __ |
5264 | 5272 |
5265 #endif // defined TARGET_ARCH_IA32 | 5273 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |