| 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 3960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3971 } | 3971 } |
| 3972 __ Bind(&do_call); | 3972 __ Bind(&do_call); |
| 3973 __ CallRuntime(TargetFunction(), InputCount()); | 3973 __ CallRuntime(TargetFunction(), InputCount()); |
| 3974 __ fstpl(Address(ESP, 0)); | 3974 __ fstpl(Address(ESP, 0)); |
| 3975 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); | 3975 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); |
| 3976 __ Bind(&skip_call); | 3976 __ Bind(&skip_call); |
| 3977 __ leave(); | 3977 __ leave(); |
| 3978 } | 3978 } |
| 3979 | 3979 |
| 3980 | 3980 |
| 3981 LocationSummary* MergedMathInstr::MakeLocationSummary() const { |
| 3982 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 3983 const intptr_t kNumInputs = 2; |
| 3984 const intptr_t kNumTemps = 1; |
| 3985 LocationSummary* summary = |
| 3986 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3987 // Both inputs must be writable because they will be untagged. |
| 3988 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 3989 summary->set_in(1, Location::WritableRegister()); |
| 3990 summary->set_out(Location::RequiresRegister()); |
| 3991 // Will be used for sign extension and division. |
| 3992 summary->set_temp(0, Location::RegisterLocation(EDX)); |
| 3993 return summary; |
| 3994 } |
| 3995 UNIMPLEMENTED(); |
| 3996 return NULL; |
| 3997 } |
| 3998 |
| 3999 |
| 4000 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4001 Label* deopt = NULL; |
| 4002 if (CanDeoptimize()) { |
| 4003 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); |
| 4004 } |
| 4005 |
| 4006 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 4007 Register left = locs()->in(0).reg(); |
| 4008 Register right = locs()->in(1).reg(); |
| 4009 Register result = locs()->out().reg(); |
| 4010 // Handle divide by zero in runtime. |
| 4011 __ testl(right, right); |
| 4012 __ j(ZERO, deopt); |
| 4013 ASSERT(left == EAX); |
| 4014 ASSERT((right != EDX) && (right != EAX)); |
| 4015 ASSERT(locs()->temp(0).reg() == EDX); |
| 4016 ASSERT((result != EDX) && (result != EAX)); |
| 4017 __ SmiUntag(left); |
| 4018 __ SmiUntag(right); |
| 4019 __ cdq(); // Sign extend EAX -> EDX:EAX. |
| 4020 __ idivl(right); // EAX: quotient, EDX: remainder. |
| 4021 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 4022 // case we cannot tag the result. |
| 4023 // TODO(srdjan): We could store instead untagged intermediate results in a |
| 4024 // typed array, but then the load indexed instructions would need to be |
| 4025 // able to deoptimize. |
| 4026 __ cmpl(EAX, Immediate(0x40000000)); |
| 4027 __ j(EQUAL, deopt); |
| 4028 // Modulo result (EDX) correction: |
| 4029 // res = left % right; |
| 4030 // if (res < 0) { |
| 4031 // if (right < 0) { |
| 4032 // res = res - right; |
| 4033 // } else { |
| 4034 // res = res + right; |
| 4035 // } |
| 4036 // } |
| 4037 Label subtract, done; |
| 4038 __ cmpl(EDX, Immediate(0)); |
| 4039 __ j(GREATER_EQUAL, &done, Assembler::kNearJump); |
| 4040 // Result is negative, adjust it. |
| 4041 __ cmpl(right, Immediate(0)); |
| 4042 __ j(LESS, &subtract, Assembler::kNearJump); |
| 4043 __ addl(EDX, right); |
| 4044 __ jmp(&done, Assembler::kNearJump); |
| 4045 __ Bind(&subtract); |
| 4046 __ subl(EDX, right); |
| 4047 __ Bind(&done); |
| 4048 |
| 4049 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld))); |
| 4050 const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(kArrayCid); |
| 4051 Address trunc_div_address( |
| 4052 FlowGraphCompiler::ElementAddressForIntIndex(kArrayCid, |
| 4053 index_scale, |
| 4054 result, |
| 4055 0)); |
| 4056 Address mod_address( |
| 4057 FlowGraphCompiler::ElementAddressForIntIndex(kArrayCid, |
| 4058 index_scale, |
| 4059 result, |
| 4060 1)); |
| 4061 __ SmiTag(EAX); |
| 4062 __ SmiTag(EDX); |
| 4063 __ StoreIntoObjectNoBarrier(result, trunc_div_address, EAX); |
| 4064 __ StoreIntoObjectNoBarrier(result, mod_address, EDX); |
| 4065 return; |
| 4066 } |
| 4067 |
| 4068 UNIMPLEMENTED(); |
| 4069 } |
| 4070 |
| 4071 |
| 3981 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4072 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 3982 return MakeCallSummary(); | 4073 return MakeCallSummary(); |
| 3983 } | 4074 } |
| 3984 | 4075 |
| 3985 | 4076 |
| 3986 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4077 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3987 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4078 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3988 kDeoptPolymorphicInstanceCallTestFail); | 4079 kDeoptPolymorphicInstanceCallTestFail); |
| 3989 if (ic_data().NumberOfChecks() == 0) { | 4080 if (ic_data().NumberOfChecks() == 0) { |
| 3990 __ jmp(deopt); | 4081 __ jmp(deopt); |
| (...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4876 PcDescriptors::kOther, | 4967 PcDescriptors::kOther, |
| 4877 locs()); | 4968 locs()); |
| 4878 __ Drop(2); // Discard type arguments and receiver. | 4969 __ Drop(2); // Discard type arguments and receiver. |
| 4879 } | 4970 } |
| 4880 | 4971 |
| 4881 } // namespace dart | 4972 } // namespace dart |
| 4882 | 4973 |
| 4883 #undef __ | 4974 #undef __ |
| 4884 | 4975 |
| 4885 #endif // defined TARGET_ARCH_IA32 | 4976 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |