| Index: runtime/vm/intermediate_language_ia32.cc
|
| diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
|
| index dd951763cf70351c0d15ea71d0082c6c5939069e..d28974fa1e74cd8e3acad52cea3bd8be856956b4 100644
|
| --- a/runtime/vm/intermediate_language_ia32.cc
|
| +++ b/runtime/vm/intermediate_language_ia32.cc
|
| @@ -1295,6 +1295,73 @@ void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
|
|
| +LocationSummary* ToDoubleComp::MakeLocationSummary() const {
|
| + const intptr_t kNumInputs = 1;
|
| + const intptr_t kNumTemps = 1;
|
| + if (from() == kDouble) {
|
| + LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
|
| + locs->set_in(0, Location::RequiresRegister());
|
| + locs->set_out(Location::SameAsFirstInput());
|
| + return locs;
|
| + } else {
|
| + ASSERT(from() == kSmi);
|
| + return LocationSummary::Make(kNumInputs, Location::RegisterLocation(EAX));
|
| + }
|
| +}
|
| +
|
| +
|
| +void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + Register value = locs()->in(0).reg();
|
| + Register result = locs()->out().reg();
|
| +
|
| + const DeoptReasonId deopt_reason = (from() == kDouble) ?
|
| + kDeoptDoubleToDouble : kDeoptIntegerToDouble;
|
| + Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
|
| + instance_call()->token_index(),
|
| + instance_call()->try_index(),
|
| + deopt_reason,
|
| + value,
|
| + kNoRegister);
|
| +
|
| + if (from() == kDouble) {
|
| + Register temp = locs()->temp(0).reg();
|
| + __ testl(value, Immediate(kSmiTagMask));
|
| + __ j(ZERO, deopt); // Deoptimize if Smi.
|
| + __ CompareClassId(value, kDouble, temp);
|
| + __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
|
| + ASSERT(value == result);
|
| + return;
|
| + }
|
| +
|
| + ASSERT(from() == kSmi);
|
| +
|
| + // TODO(vegorov): allocate a single ZoneHandle in FlowGraphCompiler for
|
| + // double class.
|
| + const Class& double_class =
|
| + Class::ZoneHandle(Isolate::Current()->object_store()->double_class());
|
| +
|
| + const Code& stub =
|
| + Code::Handle(StubCode::GetAllocationStubForClass(double_class));
|
| +
|
| + const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
|
| +
|
| + // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping.
|
| + __ pushl(value);
|
| + compiler->GenerateCall(instance_call()->token_index(),
|
| + instance_call()->try_index(),
|
| + &label,
|
| + PcDescriptors::kOther);
|
| + ASSERT(result == EAX);
|
| + __ popl(value);
|
| +
|
| + __ testl(value, Immediate(kSmiTagMask));
|
| + __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
|
| + __ SmiUntag(value);
|
| + __ cvtsi2sd(XMM0, value);
|
| + __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
|
| +}
|
| +
|
| +
|
| } // namespace dart
|
|
|
| #undef __
|
|
|