| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 2951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2962 __ notl(value); | 2962 __ notl(value); |
| 2963 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. | 2963 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. |
| 2964 break; | 2964 break; |
| 2965 default: | 2965 default: |
| 2966 UNREACHABLE(); | 2966 UNREACHABLE(); |
| 2967 } | 2967 } |
| 2968 } | 2968 } |
| 2969 | 2969 |
| 2970 | 2970 |
| 2971 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { | 2971 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { |
| 2972 return MakeCallSummary(); // Calls a stub to allocate result. | 2972 const intptr_t kNumInputs = 1; |
| 2973 const intptr_t kNumTemps = 0; |
| 2974 LocationSummary* result = |
| 2975 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2976 result->set_in(0, Location::WritableRegister()); |
| 2977 result->set_out(Location::RequiresFpuRegister()); |
| 2978 return result; |
| 2973 } | 2979 } |
| 2974 | 2980 |
| 2975 | 2981 |
| 2976 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2982 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2977 Register result = locs()->out().reg(); | 2983 Register value = locs()->in(0).reg(); |
| 2978 | 2984 FpuRegister result = locs()->out().fpu_reg(); |
| 2979 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | |
| 2980 kDeoptIntegerToDouble); | |
| 2981 | |
| 2982 const Class& double_class = compiler->double_class(); | |
| 2983 const Code& stub = | |
| 2984 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | |
| 2985 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | |
| 2986 | |
| 2987 // TODO(vegorov): allocate box in the driver loop to avoid spilling. | |
| 2988 compiler->GenerateCall(instance_call()->token_pos(), | |
| 2989 &label, | |
| 2990 PcDescriptors::kOther, | |
| 2991 locs()); | |
| 2992 ASSERT(result == EAX); | |
| 2993 Register value = EBX; | |
| 2994 // Preserve argument on the stack until after the deoptimization point. | |
| 2995 __ movl(value, Address(ESP, 0)); | |
| 2996 | |
| 2997 __ testl(value, Immediate(kSmiTagMask)); | |
| 2998 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. | |
| 2999 __ SmiUntag(value); | 2985 __ SmiUntag(value); |
| 3000 __ cvtsi2sd(XMM0, value); | 2986 __ cvtsi2sd(result, value); |
| 3001 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | |
| 3002 __ Drop(1); | |
| 3003 } | 2987 } |
| 3004 | 2988 |
| 3005 | 2989 |
| 3006 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { | 2990 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { |
| 3007 const intptr_t kNumInputs = 1; | 2991 const intptr_t kNumInputs = 1; |
| 3008 const intptr_t kNumTemps = 0; | 2992 const intptr_t kNumTemps = 0; |
| 3009 LocationSummary* result = | 2993 LocationSummary* result = |
| 3010 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2994 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3011 result->set_in(0, Location::RegisterLocation(ECX)); | 2995 result->set_in(0, Location::RegisterLocation(ECX)); |
| 3012 result->set_out(Location::RegisterLocation(EAX)); | 2996 result->set_out(Location::RegisterLocation(EAX)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3056 result->set_out(Location::RequiresRegister()); | 3040 result->set_out(Location::RequiresRegister()); |
| 3057 return result; | 3041 return result; |
| 3058 } | 3042 } |
| 3059 | 3043 |
| 3060 | 3044 |
| 3061 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3045 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3062 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 3046 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); |
| 3063 Register result = locs()->out().reg(); | 3047 Register result = locs()->out().reg(); |
| 3064 XmmRegister value = locs()->in(0).fpu_reg(); | 3048 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3065 __ cvttsd2si(result, value); | 3049 __ cvttsd2si(result, value); |
| 3066 // Overflow is signalled with minint. | |
| 3067 Label do_call, done; | |
| 3068 // Check for overflow and that it fits into Smi. | 3050 // Check for overflow and that it fits into Smi. |
| 3069 __ cmpl(result, Immediate(0xC0000000)); | 3051 __ cmpl(result, Immediate(0xC0000000)); |
| 3070 __ j(NEGATIVE, deopt); | 3052 __ j(NEGATIVE, deopt); |
| 3071 __ SmiTag(result); | 3053 __ SmiTag(result); |
| 3072 } | 3054 } |
| 3073 | 3055 |
| 3074 | 3056 |
| 3075 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 3057 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { |
| 3076 const intptr_t kNumInputs = 1; | 3058 const intptr_t kNumInputs = 1; |
| 3077 const intptr_t kNumTemps = 0; | 3059 const intptr_t kNumTemps = 0; |
| (...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4048 PcDescriptors::kOther, | 4030 PcDescriptors::kOther, |
| 4049 locs()); | 4031 locs()); |
| 4050 __ Drop(2); // Discard type arguments and receiver. | 4032 __ Drop(2); // Discard type arguments and receiver. |
| 4051 } | 4033 } |
| 4052 | 4034 |
| 4053 } // namespace dart | 4035 } // namespace dart |
| 4054 | 4036 |
| 4055 #undef __ | 4037 #undef __ |
| 4056 | 4038 |
| 4057 #endif // defined TARGET_ARCH_IA32 | 4039 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |