| 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..4252de5abcb8862121ace7a44bf87472b3bda35c 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 += 1;
|
| + }
|
| + }
|
| LocationSummary* locs = new (zone)
|
| LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| locs->set_in(0, Location::RequiresRegister());
|
| @@ -1276,6 +1281,9 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
|
| }
|
| if (!aligned()) {
|
| locs->set_temp(0, Location::RequiresRegister());
|
| + if (representation() == kUnboxedDouble) {
|
| + locs->set_temp(1, Location::RequiresRegister());
|
| + }
|
| }
|
| return locs;
|
| }
|
| @@ -1325,16 +1333,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 value = locs()->temp(1).reg();
|
| + __ LoadWordUnaligned(value, address, TMP);
|
| + __ vmovsr(EvenSRegisterOf(dresult0), value);
|
| + __ AddImmediate(address, address, 4);
|
| + __ LoadWordUnaligned(value, address, TMP);
|
| + __ vmovsr(OddSRegisterOf(dresult0), value);
|
| + }
|
| break;
|
| case kTypedDataFloat64x2ArrayCid:
|
| case kTypedDataInt32x4ArrayCid:
|
| case kTypedDataFloat32x4ArrayCid:
|
| ASSERT(element_address.Equals(Address(IP)));
|
| + ASSERT(aligned());
|
| __ vldmd(IA, IP, dresult0, 2);
|
| break;
|
| default:
|
| @@ -1459,34 +1483,35 @@ 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;
|
| + } 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;
|
| }
|
| - } 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:
|
| @@ -1636,18 +1661,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;
|
| + 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 value = temp2;
|
| + __ vmovrs(value, EvenSRegisterOf(value_reg));
|
| + __ StoreWordUnaligned(value, address, TMP);
|
| + __ AddImmediate(address, address, 4);
|
| + __ vmovrs(value, OddSRegisterOf(value_reg));
|
| + __ StoreWordUnaligned(value, 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;
|
|
|