Chromium Code Reviews| Index: runtime/vm/intermediate_language_arm.cc |
| diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc |
| index a0449e31c0237ad8fa8cfbbb6e2b1244782c75ab..969af36c6a6b4930ea3dcd90b9918c298d0e9a10 100644 |
| --- a/runtime/vm/intermediate_language_arm.cc |
| +++ b/runtime/vm/intermediate_language_arm.cc |
| @@ -829,6 +829,8 @@ CompileType LoadIndexedInstr::ComputeType() const { |
| return CompileType::FromCid(kFloat32x4Cid); |
| case kTypedDataInt32x4ArrayCid: |
| return CompileType::FromCid(kInt32x4Cid); |
| + case kTypedDataFloat64x2ArrayCid: |
| + return CompileType::FromCid(kFloat64x2Cid); |
| case kTypedDataInt8ArrayCid: |
| case kTypedDataUint8ArrayCid: |
| @@ -882,6 +884,8 @@ Representation LoadIndexedInstr::representation() const { |
| return kUnboxedInt32x4; |
| case kTypedDataFloat32x4ArrayCid: |
| return kUnboxedFloat32x4; |
| + case kTypedDataFloat64x2ArrayCid: |
| + return kUnboxedFloat64x2; |
| default: |
| UNREACHABLE(); |
| return kTagged; |
| @@ -899,9 +903,10 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { |
| // tagged (for all element sizes > 1). |
| // TODO(regis): Revisit and see if the index can be immediate. |
| locs->set_in(1, Location::WritableRegister()); |
| - if ((representation() == kUnboxedDouble) || |
| + if ((representation() == kUnboxedDouble) || |
| (representation() == kUnboxedFloat32x4) || |
| - (representation() == kUnboxedInt32x4)) { |
| + (representation() == kUnboxedInt32x4) || |
| + (representation() == kUnboxedFloat64x2)) { |
| locs->set_out(Location::RequiresFpuRegister()); |
| } else { |
| locs->set_out(Location::RequiresRegister()); |
| @@ -951,10 +956,11 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| } |
| element_address = Address(array, index.reg(), LSL, 0); |
| - if ((representation() == kUnboxedDouble) || |
| - (representation() == kUnboxedMint) || |
| + if ((representation() == kUnboxedDouble) || |
| + (representation() == kUnboxedMint) || |
| (representation() == kUnboxedFloat32x4) || |
| - (representation() == kUnboxedInt32x4)) { |
| + (representation() == kUnboxedInt32x4) || |
| + (representation() == kUnboxedFloat64x2)) { |
| QRegister result = locs()->out().fpu_reg(); |
| DRegister dresult0 = EvenDRegisterOf(result); |
| DRegister dresult1 = OddDRegisterOf(result); |
| @@ -979,6 +985,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| element_address = Address(index.reg(), 0); |
| __ vldrd(dresult0, element_address); |
| break; |
| + case kTypedDataFloat64x2ArrayCid: |
| case kTypedDataInt32x4ArrayCid: |
| case kTypedDataFloat32x4ArrayCid: |
| __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| @@ -1067,6 +1074,8 @@ Representation StoreIndexedInstr::RequiredInputRepresentation( |
| return kUnboxedFloat32x4; |
| case kTypedDataInt32x4ArrayCid: |
| return kUnboxedInt32x4; |
| + case kTypedDataFloat64x2ArrayCid: |
| + return kUnboxedFloat64x2; |
| default: |
| UNREACHABLE(); |
| return kTagged; |
| @@ -1106,6 +1115,7 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { |
| case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
| case kTypedDataInt32x4ArrayCid: |
| case kTypedDataFloat32x4ArrayCid: |
| + case kTypedDataFloat64x2ArrayCid: |
| locs->set_in(2, Location::RequiresFpuRegister()); |
| break; |
| default: |
| @@ -1245,6 +1255,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| __ StoreDToOffset(in2, index.reg(), 0); |
| break; |
| } |
| + case kTypedDataFloat64x2ArrayCid: |
| case kTypedDataInt32x4ArrayCid: |
| case kTypedDataFloat32x4ArrayCid: { |
| QRegister in = locs()->in(2).fpu_reg(); |
| @@ -1995,6 +2006,38 @@ class BoxFloat32x4SlowPath : public SlowPathCode { |
| }; |
| +class BoxFloat64x2SlowPath : public SlowPathCode { |
| + public: |
| + explicit BoxFloat64x2SlowPath(Instruction* instruction) |
| + : instruction_(instruction) { } |
| + |
| + virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| + __ Comment("BoxFloat64x2SlowPath"); |
| + __ Bind(entry_label()); |
| + const Class& float64x2_class = compiler->float64x2_class(); |
| + const Code& stub = |
| + Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class)); |
| + const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint()); |
| + |
| + LocationSummary* locs = instruction_->locs(); |
| + locs->live_registers()->Remove(locs->out()); |
| + |
| + compiler->SaveLiveRegisters(locs); |
| + compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| + &label, |
| + PcDescriptors::kOther, |
| + locs); |
| + __ mov(locs->out().reg(), ShifterOperand(R0)); |
| + compiler->RestoreLiveRegisters(locs); |
| + |
| + __ b(exit_label()); |
| + } |
| + |
| + private: |
| + Instruction* instruction_; |
| +}; |
| + |
| + |
| LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { |
| const intptr_t kNumInputs = 1; |
| const intptr_t kNumTemps = 0; |
| @@ -3018,6 +3061,81 @@ void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| } |
| +LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| + const intptr_t kNumInputs = 1; |
| + const intptr_t kNumTemps = 1; |
| + LocationSummary* summary = |
| + new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCallOnSlowPath); |
| + summary->set_in(0, Location::RequiresFpuRegister()); |
| + summary->set_temp(0, Location::RequiresRegister()); |
| + summary->set_out(Location::RequiresRegister()); |
| + return summary; |
| +} |
| + |
| + |
| +void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| + BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| + compiler->AddSlowPathCode(slow_path); |
| + |
| + Register out_reg = locs()->out().reg(); |
| + QRegister value = locs()->in(0).fpu_reg(); |
| + DRegister value_even = EvenDRegisterOf(value); |
| + DRegister value_odd = OddDRegisterOf(value); |
| + |
| + __ TryAllocate(compiler->float64x2_class(), |
| + slow_path->entry_label(), |
| + out_reg, |
| + locs()->temp(0).reg()); |
| + __ Bind(slow_path->exit_label()); |
| + |
| + __ StoreDToOffset(value_even, out_reg, |
|
Florian Schneider
2014/02/20 15:54:44
Use one store-multiple instead of two store instru
|
| + Float32x4::value_offset() - kHeapObjectTag); |
|
zra
2014/02/20 22:46:40
Is this supposed to be Float64x2::value_offset()?
|
| + __ StoreDToOffset(value_odd, out_reg, |
| + Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
|
Florian Schneider
2014/02/20 15:54:44
spaces around *
Cutch
2014/02/20 19:33:11
Done here and elsewhere.
|
| +} |
| + |
| + |
| +LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| + const intptr_t value_cid = value()->Type()->ToCid(); |
| + const intptr_t kNumInputs = 1; |
| + const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; |
| + LocationSummary* summary = |
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| + summary->set_in(0, Location::RequiresRegister()); |
| + if (kNumTemps > 0) { |
| + ASSERT(kNumTemps == 1); |
| + summary->set_temp(0, Location::RequiresRegister()); |
| + } |
| + summary->set_out(Location::RequiresFpuRegister()); |
| + return summary; |
| +} |
| + |
| + |
| +void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| + const intptr_t value_cid = value()->Type()->ToCid(); |
| + const Register value = locs()->in(0).reg(); |
| + const QRegister result = locs()->out().fpu_reg(); |
| + |
| + if (value_cid != kFloat64x2Cid) { |
| + const Register temp = locs()->temp(0).reg(); |
| + Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| + __ tst(value, ShifterOperand(kSmiTagMask)); |
| + __ b(deopt, EQ); |
| + __ CompareClassId(value, kFloat64x2Cid, temp); |
| + __ b(deopt, NE); |
| + } |
| + |
| + const DRegister result_even = EvenDRegisterOf(result); |
| + const DRegister result_odd = OddDRegisterOf(result); |
| + __ LoadDFromOffset(result_even, value, |
|
Florian Schneider
2014/02/20 15:54:44
Load-multiple (vldmd) instead of 2 vldr? This woul
Cutch
2014/02/20 19:33:11
vldmd can't be used with an offset.
|
| + Float64x2::value_offset() - kHeapObjectTag); |
| + __ LoadDFromOffset(result_odd, value, |
| + Float64x2::value_offset() + 2*kWordSize - kHeapObjectTag); |
| +} |
| + |
| + |
| LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| const intptr_t kNumInputs = 1; |
| const intptr_t kNumTemps = 1; |