Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 20148) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -1094,25 +1094,34 @@ |
| } |
| +LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { |
| + const intptr_t kNumInputs = 1; |
| + const intptr_t kNumTemps = 0; |
| + LocationSummary* locs = |
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| + locs->set_in(0, Location::RequiresRegister()); |
| + locs->set_out(Location::SameAsFirstInput()); |
| + return locs; |
| +} |
| + |
| + |
| +void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| + Register object = locs()->in(0).reg(); |
| + ASSERT(locs()->out().reg() == object); |
| + __ movl(object, FieldAddress(object, offset())); |
| +} |
| + |
| + |
| CompileType LoadIndexedInstr::ComputeType() const { |
| switch (class_id_) { |
| case kArrayCid: |
| case kImmutableArrayCid: |
| return CompileType::Dynamic(); |
| - case kFloat32ArrayCid : |
| - case kFloat64ArrayCid : |
| case kTypedDataFloat32ArrayCid: |
| case kTypedDataFloat64ArrayCid: |
| return CompileType::FromCid(kDoubleCid); |
| - case kInt8ArrayCid: |
| - case kUint8ArrayCid: |
| - case kUint8ClampedArrayCid: |
| - case kExternalUint8ArrayCid: |
| - case kExternalUint8ClampedArrayCid: |
| - case kInt16ArrayCid: |
| - case kUint16ArrayCid: |
| case kTypedDataInt8ArrayCid: |
| case kTypedDataUint8ArrayCid: |
| case kTypedDataUint8ClampedArrayCid: |
| @@ -1124,8 +1133,6 @@ |
| case kTwoByteStringCid: |
| return CompileType::FromCid(kSmiCid); |
| - case kInt32ArrayCid: |
| - case kUint32ArrayCid: |
| case kTypedDataInt32ArrayCid: |
| case kTypedDataUint32ArrayCid: |
| // Result can be Smi or Mint when boxed. |
| @@ -1145,13 +1152,6 @@ |
| switch (class_id_) { |
| case kArrayCid: |
| case kImmutableArrayCid: |
| - case kInt8ArrayCid: |
| - case kUint8ArrayCid: |
| - case kUint8ClampedArrayCid: |
| - case kExternalUint8ArrayCid: |
| - case kExternalUint8ClampedArrayCid: |
| - case kInt16ArrayCid: |
| - case kUint16ArrayCid: |
| case kTypedDataInt8ArrayCid: |
| case kTypedDataUint8ArrayCid: |
| case kTypedDataUint8ClampedArrayCid: |
| @@ -1162,15 +1162,11 @@ |
| case kOneByteStringCid: |
| case kTwoByteStringCid: |
| return kTagged; |
| - case kInt32ArrayCid: |
| - case kUint32ArrayCid: |
| case kTypedDataInt32ArrayCid: |
| case kTypedDataUint32ArrayCid: |
| // Instruction can deoptimize if we optimistically assumed that the result |
| // fits into Smi. |
| return CanDeoptimize() ? kTagged : kUnboxedMint; |
| - case kFloat32ArrayCid : |
| - case kFloat64ArrayCid : |
| case kTypedDataFloat32ArrayCid: |
| case kTypedDataFloat64ArrayCid: |
| return kUnboxedDouble; |
| @@ -1213,34 +1209,25 @@ |
| Register array = locs()->in(0).reg(); |
| Location index = locs()->in(1); |
| - if ((class_id() == kExternalUint8ArrayCid) || |
| - (class_id() == kExternalUint8ClampedArrayCid) || |
| - (class_id() == kExternalTypedDataUint8ArrayCid) || |
| - (class_id() == kExternalTypedDataUint8ClampedArrayCid)) { |
| - Register result = locs()->out().reg(); |
| - const Address& element_address = index.IsRegister() |
| + const bool is_external = |
| + (this->array()->definition()->representation() == kUntagged); |
| + Address element_address(kNoRegister, 0); |
| + if (is_external) { |
| + element_address = index.IsRegister() |
| ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| - index_scale(), result, index.reg()) |
| + index_scale(), array, index.reg()) |
| : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| - index_scale(), result, Smi::Cast(index.constant()).Value()); |
| - ASSERT(index_scale() == 1); |
| - if (index.IsRegister()) { |
| - __ SmiUntag(index.reg()); |
| - } |
| - __ movl(result, |
| - FieldAddress(array, ExternalUint8Array::data_offset())); |
| - __ movzxb(result, element_address); |
| - __ SmiTag(result); |
| - return; |
| + index_scale(), array, Smi::Cast(index.constant()).Value()); |
| + } else { |
| + ASSERT(this->array()->definition()->representation() == kTagged); |
| + element_address = index.IsRegister() |
| + ? FlowGraphCompiler::ElementAddressForRegIndex( |
| + class_id(), index_scale(), array, index.reg()) |
| + : FlowGraphCompiler::ElementAddressForIntIndex( |
| + class_id(), index_scale(), array, |
| + Smi::Cast(index.constant()).Value()); |
| } |
| - FieldAddress element_address = index.IsRegister() |
| - ? FlowGraphCompiler::ElementAddressForRegIndex( |
| - class_id(), index_scale(), array, index.reg()) |
| - : FlowGraphCompiler::ElementAddressForIntIndex( |
| - class_id(), index_scale(), array, |
| - Smi::Cast(index.constant()).Value()); |
| - |
| if ((representation() == kUnboxedDouble) || |
| (representation() == kUnboxedMint)) { |
| XmmRegister result = locs()->out().fpu_reg(); |
| @@ -1248,23 +1235,19 @@ |
| __ SmiUntag(index.reg()); |
| } |
| switch (class_id()) { |
| - case kInt32ArrayCid: |
| case kTypedDataInt32ArrayCid: |
| __ movss(result, element_address); |
| __ pmovsxdq(result, result); |
| break; |
| - case kUint32ArrayCid: |
| case kTypedDataUint32ArrayCid: |
| __ xorpd(result, result); |
| __ movss(result, element_address); |
| break; |
| - case kFloat32ArrayCid: |
| case kTypedDataFloat32ArrayCid: |
| // Load single precision float and promote to double. |
| __ movss(result, element_address); |
| __ cvtss2sd(result, locs()->out().fpu_reg()); |
| break; |
| - case kFloat64ArrayCid: |
| case kTypedDataFloat64ArrayCid: |
| __ movsd(result, element_address); |
| break; |
| @@ -1277,33 +1260,29 @@ |
| __ SmiUntag(index.reg()); |
| } |
| switch (class_id()) { |
| - case kInt8ArrayCid: |
| case kTypedDataInt8ArrayCid: |
| ASSERT(index_scale() == 1); |
| __ movsxb(result, element_address); |
| __ SmiTag(result); |
| break; |
| - case kUint8ArrayCid: |
| - case kUint8ClampedArrayCid: |
| case kTypedDataUint8ArrayCid: |
| case kTypedDataUint8ClampedArrayCid: |
| + case kExternalTypedDataUint8ArrayCid: |
| + case kExternalTypedDataUint8ClampedArrayCid: |
| case kOneByteStringCid: |
| ASSERT(index_scale() == 1); |
| __ movzxb(result, element_address); |
| __ SmiTag(result); |
| break; |
| - case kInt16ArrayCid: |
| case kTypedDataInt16ArrayCid: |
| __ movsxw(result, element_address); |
| __ SmiTag(result); |
| break; |
| - case kUint16ArrayCid: |
| case kTypedDataUint16ArrayCid: |
| case kTwoByteStringCid: |
| __ movzxw(result, element_address); |
| __ SmiTag(result); |
| break; |
| - case kInt32ArrayCid: |
| case kTypedDataInt32ArrayCid: { |
| Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); |
| __ movl(result, element_address); |
| @@ -1313,7 +1292,6 @@ |
| __ SmiTag(result); |
| } |
| break; |
| - case kUint32ArrayCid: |
| case kTypedDataUint32ArrayCid: { |
| Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); |
| __ movl(result, element_address); |
| @@ -1333,17 +1311,11 @@ |
| Representation StoreIndexedInstr::RequiredInputRepresentation( |
| intptr_t idx) const { |
| - if ((idx == 0) || (idx == 1)) return kTagged; |
| + if (idx == 0) return kNoRepresentation; // Array can be tagged or untagged. |
|
Vyacheslav Egorov (Google)
2013/03/18 18:42:29
Comment is somewhat confusing. Array can be either
Florian Schneider
2013/03/19 11:48:57
Done.
|
| + if (idx == 1) return kTagged; // Index is a smi. |
| ASSERT(idx == 2); |
| switch (class_id_) { |
| case kArrayCid: |
| - case kInt8ArrayCid: |
| - case kUint8ArrayCid: |
| - case kExternalUint8ArrayCid: |
| - case kUint8ClampedArrayCid: |
| - case kExternalUint8ClampedArrayCid: |
| - case kInt16ArrayCid: |
| - case kUint16ArrayCid: |
| case kTypedDataInt8ArrayCid: |
| case kTypedDataUint8ArrayCid: |
| case kExternalTypedDataUint8ArrayCid: |
| @@ -1352,15 +1324,11 @@ |
| case kTypedDataInt16ArrayCid: |
| case kTypedDataUint16ArrayCid: |
| return kTagged; |
| - case kInt32ArrayCid: |
| - case kUint32ArrayCid: |
| case kTypedDataInt32ArrayCid: |
| case kTypedDataUint32ArrayCid: |
| return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| - case kFloat32ArrayCid : |
| - case kFloat64ArrayCid : |
| - case kTypedDataFloat32ArrayCid : |
| - case kTypedDataFloat64ArrayCid : |
| + case kTypedDataFloat32ArrayCid: |
| + case kTypedDataFloat64ArrayCid: |
| return kUnboxedDouble; |
| default: |
| UNIMPLEMENTED(); |
| @@ -1394,16 +1362,8 @@ |
| ? Location::WritableRegister() |
| : Location::RegisterOrConstant(value())); |
| break; |
| - case kExternalUint8ArrayCid: |
| - case kExternalUint8ClampedArrayCid: |
| case kExternalTypedDataUint8ArrayCid: |
| case kExternalTypedDataUint8ClampedArrayCid: |
| - // Need temp register to load the external array's data array. |
| - locs->AddTemp(Location::RequiresRegister()); |
| - // Fall through. |
| - case kInt8ArrayCid: |
| - case kUint8ArrayCid: |
| - case kUint8ClampedArrayCid: |
| case kTypedDataInt8ArrayCid: |
| case kTypedDataUint8ArrayCid: |
| case kTypedDataUint8ClampedArrayCid: |
| @@ -1411,15 +1371,11 @@ |
| // EBX, ECX, EDX) instead of using a fixed register. |
| locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); |
| break; |
| - case kInt16ArrayCid: |
| - case kUint16ArrayCid: |
| case kTypedDataInt16ArrayCid: |
| case kTypedDataUint16ArrayCid: |
| // Writable register because the value must be untagged before storing. |
| locs->set_in(2, Location::WritableRegister()); |
| break; |
| - case kInt32ArrayCid: |
| - case kUint32ArrayCid: |
| case kTypedDataInt32ArrayCid: |
| case kTypedDataUint32ArrayCid: |
| // Mints are stored in XMM registers. For smis, use a writable register |
| @@ -1428,12 +1384,10 @@ |
| ? Location::WritableRegister() |
| : Location::RequiresFpuRegister()); |
| break; |
| - case kFloat32ArrayCid: |
| case kTypedDataFloat32ArrayCid: |
| // Need temp register for float-to-double conversion. |
| locs->AddTemp(Location::RequiresFpuRegister()); |
| // Fall through. |
| - case kFloat64ArrayCid: |
| case kTypedDataFloat64ArrayCid: |
| // TODO(srdjan): Support Float64 constants. |
| locs->set_in(2, Location::RequiresFpuRegister()); |
| @@ -1451,19 +1405,16 @@ |
| Location index = locs()->in(1); |
| Address element_address(kNoRegister, 0); |
| - if ((class_id() == kExternalUint8ArrayCid) || |
| - (class_id() == kExternalUint8ClampedArrayCid) || |
| - (class_id() == kExternalTypedDataUint8ArrayCid) || |
| - (class_id() == kExternalTypedDataUint8ClampedArrayCid)) { |
| - Register temp = locs()->temp(0).reg(); |
| + const bool is_external = |
|
Vyacheslav Egorov (Google)
2013/03/18 18:42:29
consider creating helper method {Store,Load}Indexe
Florian Schneider
2013/03/19 11:48:57
Done.
|
| + (this->array()->definition()->representation() == kUntagged); |
| + if (is_external) { |
| element_address = index.IsRegister() |
| ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| - index_scale(), temp, index.reg()) |
| + index_scale(), array, index.reg()) |
| : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| - index_scale(), temp, Smi::Cast(index.constant()).Value()); |
| - __ movl(temp, |
| - FieldAddress(array, ExternalUint8Array::data_offset())); |
| + index_scale(), array, Smi::Cast(index.constant()).Value()); |
| } else { |
| + ASSERT(this->array()->definition()->representation() == kTagged); |
| element_address = index.IsRegister() |
| ? FlowGraphCompiler::ElementAddressForRegIndex( |
| class_id(), index_scale(), array, index.reg()) |
| @@ -1488,9 +1439,6 @@ |
| __ StoreIntoObjectNoBarrier(array, element_address, value); |
| } |
| break; |
| - case kInt8ArrayCid: |
| - case kUint8ArrayCid: |
| - case kExternalUint8ArrayCid: |
| case kTypedDataInt8ArrayCid: |
| case kTypedDataUint8ArrayCid: |
| case kExternalTypedDataUint8ArrayCid: |
| @@ -1504,8 +1452,6 @@ |
| __ movb(element_address, AL); |
| } |
| break; |
| - case kUint8ClampedArrayCid: |
| - case kExternalUint8ClampedArrayCid: |
| case kTypedDataUint8ClampedArrayCid: |
| case kExternalTypedDataUint8ClampedArrayCid: { |
| if (locs()->in(2).IsConstant()) { |
| @@ -1536,8 +1482,6 @@ |
| } |
| break; |
| } |
| - case kInt16ArrayCid: |
| - case kUint16ArrayCid: |
| case kTypedDataInt16ArrayCid: |
| case kTypedDataUint16ArrayCid: { |
| Register value = locs()->in(2).reg(); |
| @@ -1545,8 +1489,6 @@ |
| __ movw(element_address, value); |
| break; |
| } |
| - case kInt32ArrayCid: |
| - case kUint32ArrayCid: |
| case kTypedDataInt32ArrayCid: |
| case kTypedDataUint32ArrayCid: |
| if (value()->IsSmiValue()) { |
| @@ -1559,14 +1501,12 @@ |
| __ movss(element_address, locs()->in(2).fpu_reg()); |
| } |
| break; |
| - case kFloat32ArrayCid: |
| case kTypedDataFloat32ArrayCid: |
| // Convert to single precision. |
| __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| // Store. |
| __ movss(element_address, locs()->temp(0).fpu_reg()); |
| break; |
| - case kFloat64ArrayCid: |
| case kTypedDataFloat64ArrayCid: |
| __ movsd(element_address, locs()->in(2).fpu_reg()); |
| break; |
| @@ -2809,11 +2749,11 @@ |
| const intptr_t kNumTemps = 0; |
| LocationSummary* result = |
| new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| - result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble)); |
| + result->set_in(0, Location::FpuRegisterLocation(XMM1, kUnboxedDouble)); |
| if (InputCount() == 2) { |
| - result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble)); |
| + result->set_in(1, Location::FpuRegisterLocation(XMM2, kUnboxedDouble)); |
| } |
| - result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble)); |
| + result->set_out(Location::FpuRegisterLocation(XMM1, kUnboxedDouble)); |
| return result; |
| } |