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 86d9c5a07095de27b6034f33ca34020e06921dbd..c097fef251a19765166ae035b5a3bfcce877c32c 100644 |
| --- a/runtime/vm/intermediate_language_arm.cc |
| +++ b/runtime/vm/intermediate_language_arm.cc |
| @@ -1,4 +1,3 @@ |
| - |
| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| @@ -1239,7 +1238,13 @@ static bool CanBeImmediateIndex(Value* value, |
| LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, |
| bool opt) const { |
| const intptr_t kNumInputs = 2; |
| - const intptr_t kNumTemps = aligned() ? 0 : 1; |
| + intptr_t kNumTemps = 0; |
| + if (!aligned()) { |
| + kNumTemps += 1; |
| + if (representation() == kUnboxedDouble) { |
| + kNumTemps += 2; |
| + } |
| + } |
| LocationSummary* locs = new (zone) |
| LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| locs->set_in(0, Location::RequiresRegister()); |
| @@ -1276,6 +1281,10 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, |
| } |
| if (!aligned()) { |
| locs->set_temp(0, Location::RequiresRegister()); |
| + if (representation() == kUnboxedDouble) { |
| + locs->set_temp(1, Location::RequiresRegister()); |
| + locs->set_temp(2, Location::RequiresRegister()); |
| + } |
| } |
| return locs; |
| } |
| @@ -1325,16 +1334,32 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| case kTypedDataFloat32ArrayCid: |
| // Load single precision float. |
| // vldrs does not support indexed addressing. |
| - __ vldrs(EvenSRegisterOf(dresult0), element_address); |
| + if (aligned()) { |
| + __ vldrs(EvenSRegisterOf(dresult0), element_address); |
| + } else { |
| + const Register value = locs()->temp(1).reg(); |
| + __ LoadWordUnaligned(value, address, TMP); |
| + __ vmovsr(EvenSRegisterOf(dresult0), value); |
| + } |
| break; |
| case kTypedDataFloat64ArrayCid: |
| // vldrd does not support indexed addressing. |
| - __ vldrd(dresult0, element_address); |
| + if (aligned()) { |
| + __ vldrd(dresult0, element_address); |
| + } else { |
| + const Register value1 = locs()->temp(1).reg(); |
|
zra
2017/06/19 15:02:48
You can save a temporary register here by using vm
rmacnak
2017/06/19 17:18:32
Done.
|
| + const Register value2 = locs()->temp(2).reg(); |
| + __ LoadWordUnaligned(value1, address, TMP); |
| + __ AddImmediate(address, address, 4); |
| + __ LoadWordUnaligned(value2, address, TMP); |
| + __ vmovdrr(dresult0, value1, value2); |
| + } |
| break; |
| case kTypedDataFloat64x2ArrayCid: |
| case kTypedDataInt32x4ArrayCid: |
| case kTypedDataFloat32x4ArrayCid: |
| ASSERT(element_address.Equals(Address(IP))); |
| + ASSERT(aligned()); |
| __ vldmd(IA, IP, dresult0, 2); |
| break; |
| default: |
| @@ -1459,34 +1484,41 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, |
| LocationSummary* locs; |
| bool needs_base = false; |
| + intptr_t kNumTemps = 0; |
| if (CanBeImmediateIndex(index(), class_id(), IsExternal(), |
| false, // Store. |
| &needs_base)) { |
| - const intptr_t kNumTemps = aligned() ? (needs_base ? 1 : 0) : 2; |
| + if (!aligned()) { |
| + kNumTemps += 2; |
| + if (class_id() == kTypedDataFloat64ArrayCid) { |
| + kNumTemps += 1; |
| + } |
| + } else if (needs_base) { |
| + kNumTemps += 1; |
| + } |
| + |
| locs = new (zone) |
| LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| // CanBeImmediateIndex must return false for unsafe smis. |
| locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); |
| - if (needs_base) { |
| - locs->set_temp(0, Location::RequiresRegister()); |
| - } |
| + } else { |
| if (!aligned()) { |
| - locs->set_temp(0, Location::RequiresRegister()); |
| - locs->set_temp(1, Location::RequiresRegister()); |
| + kNumTemps += 2; |
| + if (class_id() == kTypedDataFloat64ArrayCid) { |
| + kNumTemps += 1; |
| + } |
| } |
| - } else { |
| - const intptr_t kNumTemps = aligned() ? 0 : 2; |
| + |
| locs = new (zone) |
| LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| locs->set_in(1, Location::WritableRegister()); |
| - if (!aligned()) { |
| - locs->set_temp(0, Location::RequiresRegister()); |
| - locs->set_temp(1, Location::RequiresRegister()); |
| - } |
| } |
| locs->set_in(0, Location::RequiresRegister()); |
| + for (intptr_t i = 0; i < kNumTemps; i++) { |
| + locs->set_temp(i, Location::RequiresRegister()); |
| + } |
| switch (class_id()) { |
| case kArrayCid: |
| @@ -1532,6 +1564,8 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (locs()->temp_count() > 0) ? locs()->temp(0).reg() : kNoRegister; |
| const Register temp2 = |
| (locs()->temp_count() > 1) ? locs()->temp(1).reg() : kNoRegister; |
| + const Register temp3 = |
| + (locs()->temp_count() > 2) ? locs()->temp(2).reg() : kNoRegister; |
| Address element_address(kNoRegister); |
| if (aligned()) { |
| @@ -1636,18 +1670,36 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| case kTypedDataFloat32ArrayCid: { |
| const SRegister value_reg = |
| EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg())); |
| - __ vstrs(value_reg, element_address); |
| + if (aligned()) { |
| + __ vstrs(value_reg, element_address); |
| + } else { |
| + const Register& address = temp; |
|
zra
2017/06/19 15:02:48
Is & needed?
rmacnak
2017/06/19 17:18:32
No, removed.
|
| + const Register& value = temp2; |
| + __ vmovrs(value, value_reg); |
| + __ StoreWordUnaligned(value, address, TMP); |
| + } |
| break; |
| } |
| case kTypedDataFloat64ArrayCid: { |
| const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
| - __ vstrd(value_reg, element_address); |
| + if (aligned()) { |
| + __ vstrd(value_reg, element_address); |
| + } else { |
| + const Register& address = temp; |
| + const Register& value1 = temp2; |
| + const Register& value2 = temp3; |
| + __ vmovrrd(value1, value2, value_reg); |
|
zra
2017/06/19 15:02:48
Same idea here for saving a temporary by using vmo
|
| + __ StoreWordUnaligned(value1, address, TMP); |
| + __ AddImmediate(address, address, 4); |
| + __ StoreWordUnaligned(value2, address, TMP); |
| + } |
| break; |
| } |
| case kTypedDataFloat64x2ArrayCid: |
| case kTypedDataInt32x4ArrayCid: |
| case kTypedDataFloat32x4ArrayCid: { |
| ASSERT(element_address.Equals(Address(index.reg()))); |
| + ASSERT(aligned()); |
| const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
| __ vstmd(IA, index.reg(), value_reg, 2); |
| break; |