Chromium Code Reviews| Index: runtime/vm/intermediate_language_arm64.cc |
| diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc |
| index 3503a991b702d8f84a328d78d3ff4809f4b816ef..dc1cf7af48dc4e1a69c9e46d41eb11782fafd8a6 100644 |
| --- a/runtime/vm/intermediate_language_arm64.cc |
| +++ b/runtime/vm/intermediate_language_arm64.cc |
| @@ -1043,7 +1043,7 @@ static bool CanBeImmediateIndex(Value* value, intptr_t cid, bool is_external) { |
| LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, |
| bool opt) const { |
| const intptr_t kNumInputs = 2; |
| - const intptr_t kNumTemps = 0; |
| + const intptr_t kNumTemps = aligned() ? 0 : 1; |
| LocationSummary* locs = new(zone) LocationSummary( |
| zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| locs->set_in(0, Location::RequiresRegister()); |
| @@ -1060,6 +1060,9 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, |
| } else { |
| locs->set_out(0, Location::RequiresRegister()); |
| } |
| + if (!aligned()) { |
| + locs->set_temp(0, Location::RequiresRegister()); |
| + } |
| return locs; |
| } |
| @@ -1068,15 +1071,31 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| // The array register points to the backing store for external arrays. |
| const Register array = locs()->in(0).reg(); |
| const Location index = locs()->in(1); |
| - |
| - Address element_address = index.IsRegister() |
| - ? __ ElementAddressForRegIndex(true, // Load. |
| - IsExternal(), class_id(), index_scale(), |
| - array, index.reg()) |
| - : __ ElementAddressForIntIndex( |
| - IsExternal(), class_id(), index_scale(), |
| - array, Smi::Cast(index.constant()).Value()); |
| - // Warning: element_address may use register TMP as base. |
| + const Register address = aligned() ? kNoRegister : locs()->temp(0).reg(); |
| + |
| + Address element_address(TMP); |
|
zra
2016/10/26 06:59:41
ditto
|
| + if (aligned()) { |
| + element_address = index.IsRegister() |
| + ? __ ElementAddressForRegIndex(true, // Load. |
| + IsExternal(), class_id(), index_scale(), |
| + array, index.reg()) |
| + : __ ElementAddressForIntIndex( |
| + IsExternal(), class_id(), index_scale(), |
| + array, Smi::Cast(index.constant()).Value()); |
| + // Warning: element_address may use register TMP as base. |
| + } else { |
| + if (index.IsRegister()) { |
| + __ LoadElementAddressForRegIndex(address, |
| + true, // Load. |
| + IsExternal(), class_id(), index_scale(), |
| + array, index.reg()); |
| + } else { |
| + __ LoadElementAddressForIntIndex(address, |
| + IsExternal(), class_id(), index_scale(), |
| + array, |
| + Smi::Cast(index.constant()).Value()); |
| + } |
| + } |
| if ((representation() == kUnboxedDouble) || |
| (representation() == kUnboxedFloat32x4) || |
| @@ -1084,6 +1103,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (representation() == kUnboxedFloat64x2)) { |
| const VRegister result = locs()->out(0).fpu_reg(); |
| switch (class_id()) { |
| + ASSERT(aligned()); |
| case kTypedDataFloat32ArrayCid: |
| // Load single precision float. |
| __ fldrs(result, element_address); |
| @@ -1109,11 +1129,19 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| switch (class_id()) { |
| case kTypedDataInt32ArrayCid: |
| ASSERT(representation() == kUnboxedInt32); |
| - __ ldr(result, element_address, kWord); |
| + if (aligned()) { |
| + __ ldr(result, element_address, kWord); |
| + } else { |
| + __ LoadUnaligned(result, address, TMP, kWord); |
| + } |
| break; |
| case kTypedDataUint32ArrayCid: |
| ASSERT(representation() == kUnboxedUint32); |
| - __ ldr(result, element_address, kUnsignedWord); |
| + if (aligned()) { |
| + __ ldr(result, element_address, kUnsignedWord); |
| + } else { |
| + __ LoadUnaligned(result, address, TMP, kUnsignedWord); |
| + } |
| break; |
| default: |
| UNREACHABLE(); |
| @@ -1140,17 +1168,26 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| __ SmiTag(result); |
| break; |
| case kTypedDataInt16ArrayCid: |
| - __ ldr(result, element_address, kHalfword); |
| + if (aligned()) { |
| + __ ldr(result, element_address, kHalfword); |
| + } else { |
| + __ LoadUnaligned(result, address, TMP, kHalfword); |
| + } |
| __ SmiTag(result); |
| break; |
| case kTypedDataUint16ArrayCid: |
| case kTwoByteStringCid: |
| case kExternalTwoByteStringCid: |
| - __ ldr(result, element_address, kUnsignedHalfword); |
| + if (aligned()) { |
| + __ ldr(result, element_address, kUnsignedHalfword); |
| + } else { |
| + __ LoadUnaligned(result, address, TMP, kUnsignedHalfword); |
| + } |
| __ SmiTag(result); |
| break; |
| default: |
| ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| + ASSERT(aligned()); |
| __ ldr(result, element_address); |
| break; |
| } |
| @@ -1247,7 +1284,7 @@ Representation StoreIndexedInstr::RequiredInputRepresentation( |
| LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, |
| bool opt) const { |
| const intptr_t kNumInputs = 3; |
| - const intptr_t kNumTemps = 0; |
| + const intptr_t kNumTemps = aligned() ? 0 : 2; |
| LocationSummary* locs = new(zone) LocationSummary( |
| zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| locs->set_in(0, Location::RequiresRegister()); |
| @@ -1287,6 +1324,10 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, |
| UNREACHABLE(); |
| return NULL; |
| } |
| + if (!aligned()) { |
| + locs->set_temp(0, Location::RequiresRegister()); |
| + locs->set_temp(1, Location::RequiresRegister()); |
| + } |
| return locs; |
| } |
| @@ -1295,17 +1336,35 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| // The array register points to the backing store for external arrays. |
| const Register array = locs()->in(0).reg(); |
| const Location index = locs()->in(1); |
| + const Register address = aligned() ? kNoRegister : locs()->temp(0).reg(); |
| + const Register scratch = aligned() ? kNoRegister : locs()->temp(1).reg(); |
| - Address element_address = index.IsRegister() |
| + Address element_address(TMP); |
|
zra
2016/10/26 06:59:41
ditto
|
| + if (aligned()) { |
| + element_address = index.IsRegister() |
| ? __ ElementAddressForRegIndex(false, // Store. |
| IsExternal(), class_id(), index_scale(), |
| array, index.reg()) |
| : __ ElementAddressForIntIndex( |
| IsExternal(), class_id(), index_scale(), |
| array, Smi::Cast(index.constant()).Value()); |
| + } else { |
| + if (index.IsRegister()) { |
| + __ LoadElementAddressForRegIndex(address, |
| + false, // Store. |
| + IsExternal(), class_id(), index_scale(), |
| + array, index.reg()); |
| + } else { |
| + __ LoadElementAddressForIntIndex(address, |
| + IsExternal(), class_id(), index_scale(), |
| + array, |
| + Smi::Cast(index.constant()).Value()); |
| + } |
| + } |
| switch (class_id()) { |
| case kArrayCid: |
| + ASSERT(aligned()); |
| if (ShouldEmitStoreBarrier()) { |
| const Register value = locs()->in(2).reg(); |
| __ StoreIntoObject(array, element_address, value); |
| @@ -1321,6 +1380,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| case kTypedDataUint8ArrayCid: |
| case kExternalTypedDataUint8ArrayCid: |
| case kOneByteStringCid: { |
| + ASSERT(aligned()); |
| if (locs()->in(2).IsConstant()) { |
| const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value())); |
| @@ -1334,6 +1394,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| } |
| case kTypedDataUint8ClampedArrayCid: |
| case kExternalTypedDataUint8ClampedArrayCid: { |
| + ASSERT(aligned()); |
| if (locs()->in(2).IsConstant()) { |
| const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| intptr_t value = constant.Value(); |
| @@ -1360,21 +1421,31 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| case kTypedDataUint16ArrayCid: { |
| const Register value = locs()->in(2).reg(); |
| __ SmiUntag(TMP, value); |
| - __ str(TMP, element_address, kUnsignedHalfword); |
| + if (aligned()) { |
| + __ str(TMP, element_address, kUnsignedHalfword); |
| + } else { |
| + __ StoreUnaligned(TMP, address, scratch, kUnsignedHalfword); |
| + } |
| break; |
| } |
| case kTypedDataInt32ArrayCid: |
| case kTypedDataUint32ArrayCid: { |
| const Register value = locs()->in(2).reg(); |
| - __ str(value, element_address, kUnsignedWord); |
| + if (aligned()) { |
| + __ str(value, element_address, kUnsignedWord); |
| + } else { |
| + __ StoreUnaligned(value, address, scratch, kUnsignedWord); |
| + } |
| break; |
| } |
| case kTypedDataFloat32ArrayCid: { |
| + ASSERT(aligned()); |
| const VRegister value_reg = locs()->in(2).fpu_reg(); |
| __ fstrs(value_reg, element_address); |
| break; |
| } |
| case kTypedDataFloat64ArrayCid: { |
| + ASSERT(aligned()); |
| const VRegister value_reg = locs()->in(2).fpu_reg(); |
| __ fstrd(value_reg, element_address); |
| break; |
| @@ -1382,6 +1453,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| case kTypedDataFloat64x2ArrayCid: |
| case kTypedDataInt32x4ArrayCid: |
| case kTypedDataFloat32x4ArrayCid: { |
| + ASSERT(aligned()); |
| const VRegister value_reg = locs()->in(2).fpu_reg(); |
| __ fstrq(value_reg, element_address); |
| break; |