| 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::RequiresRegister());
|
| + return locs;
|
| +}
|
| +
|
| +
|
| +void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + Register object = locs()->in(0).reg();
|
| + Register result = locs()->out().reg();
|
| + __ movl(result, 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,23 @@
|
| 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()
|
| + Address element_address(kNoRegister, 0);
|
| + if (IsExternal()) {
|
| + 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 +1233,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 +1258,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 +1290,6 @@
|
| __ SmiTag(result);
|
| }
|
| break;
|
| - case kUint32ArrayCid:
|
| case kTypedDataUint32ArrayCid: {
|
| Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
|
| __ movl(result, element_address);
|
| @@ -1333,17 +1309,12 @@
|
|
|
| Representation StoreIndexedInstr::RequiredInputRepresentation(
|
| intptr_t idx) const {
|
| - if ((idx == 0) || (idx == 1)) return kTagged;
|
| + // Array can be a Dart object or a pointer to external data.
|
| + if (idx == 0) return kNoRepresentation; // Flexible input representation.
|
| + 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 +1323,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 +1361,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 +1370,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 +1383,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 +1404,14 @@
|
| 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();
|
| + if (IsExternal()) {
|
| 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 +1436,6 @@
|
| __ StoreIntoObjectNoBarrier(array, element_address, value);
|
| }
|
| break;
|
| - case kInt8ArrayCid:
|
| - case kUint8ArrayCid:
|
| - case kExternalUint8ArrayCid:
|
| case kTypedDataInt8ArrayCid:
|
| case kTypedDataUint8ArrayCid:
|
| case kExternalTypedDataUint8ArrayCid:
|
| @@ -1504,8 +1449,6 @@
|
| __ movb(element_address, AL);
|
| }
|
| break;
|
| - case kUint8ClampedArrayCid:
|
| - case kExternalUint8ClampedArrayCid:
|
| case kTypedDataUint8ClampedArrayCid:
|
| case kExternalTypedDataUint8ClampedArrayCid: {
|
| if (locs()->in(2).IsConstant()) {
|
| @@ -1536,8 +1479,6 @@
|
| }
|
| break;
|
| }
|
| - case kInt16ArrayCid:
|
| - case kUint16ArrayCid:
|
| case kTypedDataInt16ArrayCid:
|
| case kTypedDataUint16ArrayCid: {
|
| Register value = locs()->in(2).reg();
|
| @@ -1545,8 +1486,6 @@
|
| __ movw(element_address, value);
|
| break;
|
| }
|
| - case kInt32ArrayCid:
|
| - case kUint32ArrayCid:
|
| case kTypedDataInt32ArrayCid:
|
| case kTypedDataUint32ArrayCid:
|
| if (value()->IsSmiValue()) {
|
| @@ -1559,14 +1498,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 +2746,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;
|
| }
|
|
|
|
|