mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 04:17:30 +00:00
Add immediate operand support for indexed operations.
The value and/or the index of indexed loads/stores can be emitted as immediate operands to reduce the number of registers needed when constants are used. Review URL: https://chromiumcodereview.appspot.com//10933045 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12265 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
26a215b25a
commit
a52116f4af
|
@ -1543,6 +1543,7 @@ void Assembler::StoreObject(const Address& dst, const Object& object) {
|
|||
if (object.IsSmi() || object.IsNull()) {
|
||||
movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
|
||||
} else {
|
||||
ASSERT(object.IsOld());
|
||||
LoadObject(TMP, object);
|
||||
movq(dst, TMP);
|
||||
}
|
||||
|
|
|
@ -864,22 +864,43 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
}
|
||||
|
||||
|
||||
static bool CanBeImmediateIndex(Value* index) {
|
||||
if (!index->definition()->IsConstant()) return false;
|
||||
const Object& constant = index->definition()->AsConstant()->value();
|
||||
const Smi& smi_const = Smi::Cast(constant);
|
||||
int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray);
|
||||
return Utils::IsInt(32, disp);
|
||||
}
|
||||
|
||||
|
||||
LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
|
||||
const intptr_t kNumInputs = 2;
|
||||
return LocationSummary::Make(kNumInputs,
|
||||
Location::RequiresRegister(),
|
||||
LocationSummary::kNoCall);
|
||||
const intptr_t kNumTemps = 0;
|
||||
LocationSummary* locs =
|
||||
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
locs->set_in(0, Location::RequiresRegister());
|
||||
locs->set_in(1, CanBeImmediateIndex(index())
|
||||
? Location::RegisterOrConstant(index())
|
||||
: Location::RequiresRegister());
|
||||
locs->set_out(Location::RequiresRegister());
|
||||
return locs;
|
||||
}
|
||||
|
||||
|
||||
void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
Register array = locs()->in(0).reg();
|
||||
Register index = locs()->in(1).reg();
|
||||
Register result = locs()->out().reg();
|
||||
|
||||
// Note that index is Smi, i.e, times 2.
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
__ movl(result, FieldAddress(array, index, TIMES_2, sizeof(RawArray)));
|
||||
Location index = locs()->in(1);
|
||||
if (index.IsRegister()) {
|
||||
// Note that index is Smi, i.e, times 2.
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
__ movl(result,
|
||||
FieldAddress(array, index.reg(), TIMES_2, sizeof(RawArray)));
|
||||
} else {
|
||||
const int32_t disp =
|
||||
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray);
|
||||
__ movl(result, FieldAddress(array, disp));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -889,28 +910,39 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
|
|||
LocationSummary* locs =
|
||||
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
locs->set_in(0, Location::RequiresRegister());
|
||||
locs->set_in(1, Location::RequiresRegister());
|
||||
locs->set_in(2, value()->NeedsStoreBuffer() ? Location::WritableRegister()
|
||||
: Location::RequiresRegister());
|
||||
locs->set_in(1, CanBeImmediateIndex(index())
|
||||
? Location::RegisterOrConstant(index())
|
||||
: Location::RequiresRegister());
|
||||
locs->set_in(2, value()->NeedsStoreBuffer()
|
||||
? Location::WritableRegister()
|
||||
: Location::RegisterOrConstant(value()));
|
||||
return locs;
|
||||
}
|
||||
|
||||
|
||||
void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
Register array = locs()->in(0).reg();
|
||||
Register index = locs()->in(1).reg();
|
||||
Register value = locs()->in(2).reg();
|
||||
|
||||
// Note that index is Smi, i.e, times 2.
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
Location index = locs()->in(1);
|
||||
FieldAddress field_address = index.IsConstant()
|
||||
? FieldAddress(
|
||||
array,
|
||||
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray))
|
||||
: FieldAddress(array, index.reg(), TIMES_2, sizeof(RawArray));
|
||||
|
||||
if (this->value()->NeedsStoreBuffer()) {
|
||||
__ StoreIntoObject(array,
|
||||
FieldAddress(array, index, TIMES_2, sizeof(RawArray)),
|
||||
value);
|
||||
Register value = locs()->in(2).reg();
|
||||
__ StoreIntoObject(array, field_address, value);
|
||||
} else {
|
||||
__ StoreIntoObjectNoBarrier(array,
|
||||
FieldAddress(array, index, TIMES_2, sizeof(RawArray)),
|
||||
value);
|
||||
if (locs()->in(2).IsConstant()) {
|
||||
const Object& constant = locs()->in(2).constant();
|
||||
__ StoreIntoObjectNoBarrier(array, field_address, constant);
|
||||
} else {
|
||||
Register value = locs()->in(2).reg();
|
||||
__ StoreIntoObjectNoBarrier(array, field_address, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -880,22 +880,45 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
}
|
||||
|
||||
|
||||
static bool CanBeImmediateIndex(Value* index) {
|
||||
if (!index->definition()->IsConstant()) return false;
|
||||
const Object& constant = index->definition()->AsConstant()->value();
|
||||
const Smi& smi_const = Smi::Cast(constant);
|
||||
int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray);
|
||||
return Utils::IsInt(32, disp);
|
||||
}
|
||||
|
||||
|
||||
LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
|
||||
const intptr_t kNumInputs = 2;
|
||||
return LocationSummary::Make(kNumInputs,
|
||||
Location::RequiresRegister(),
|
||||
LocationSummary::kNoCall);
|
||||
const intptr_t kNumTemps = 0;
|
||||
LocationSummary* locs =
|
||||
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
locs->set_in(0, Location::RequiresRegister());
|
||||
locs->set_in(1, CanBeImmediateIndex(index())
|
||||
? Location::RegisterOrConstant(index())
|
||||
: Location::RequiresRegister());
|
||||
locs->set_out(Location::RequiresRegister());
|
||||
return locs;
|
||||
}
|
||||
|
||||
|
||||
void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
Register array = locs()->in(0).reg();
|
||||
Register index = locs()->in(1).reg();
|
||||
Register result = locs()->out().reg();
|
||||
|
||||
// Note that index is Smi, i.e, times 4.
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
__ movq(result, FieldAddress(array, index, TIMES_4, sizeof(RawArray)));
|
||||
Location index = locs()->in(1);
|
||||
if (index.IsRegister()) {
|
||||
// Note that index is Smi, i.e, times 4.
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
__ movq(result,
|
||||
FieldAddress(array, index.reg(), TIMES_4, sizeof(RawArray)));
|
||||
} else {
|
||||
const int64_t disp =
|
||||
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray);
|
||||
ASSERT(Utils::IsInt(32, disp));
|
||||
__ movq(result, FieldAddress(array, static_cast<int32_t>(disp)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -905,28 +928,40 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
|
|||
LocationSummary* locs =
|
||||
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
locs->set_in(0, Location::RequiresRegister());
|
||||
locs->set_in(1, Location::RequiresRegister());
|
||||
locs->set_in(2, value()->NeedsStoreBuffer() ? Location::WritableRegister()
|
||||
: Location::RequiresRegister());
|
||||
locs->set_in(1, CanBeImmediateIndex(index())
|
||||
? Location::RegisterOrConstant(index())
|
||||
: Location::RequiresRegister());
|
||||
locs->set_in(2, value()->NeedsStoreBuffer()
|
||||
? Location::WritableRegister()
|
||||
: Location::RegisterOrConstant(value()));
|
||||
return locs;
|
||||
}
|
||||
|
||||
|
||||
void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
Register array = locs()->in(0).reg();
|
||||
Register index = locs()->in(1).reg();
|
||||
Register value = locs()->in(2).reg();
|
||||
|
||||
// Note that index is Smi, i.e, times 4.
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
Location index = locs()->in(1);
|
||||
FieldAddress field_address = index.IsConstant()
|
||||
? FieldAddress(
|
||||
array,
|
||||
static_cast<int32_t>(
|
||||
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray)))
|
||||
: FieldAddress(array, index.reg(), TIMES_4, sizeof(RawArray));
|
||||
|
||||
if (this->value()->NeedsStoreBuffer()) {
|
||||
__ StoreIntoObject(array,
|
||||
FieldAddress(array, index, TIMES_4, sizeof(RawArray)),
|
||||
value);
|
||||
Register value = locs()->in(2).reg();
|
||||
__ StoreIntoObject(array, field_address, value);
|
||||
} else {
|
||||
__ StoreIntoObjectNoBarrier(array,
|
||||
FieldAddress(array, index, TIMES_4, sizeof(RawArray)),
|
||||
value);
|
||||
if (locs()->in(2).IsConstant()) {
|
||||
const Object& constant = locs()->in(2).constant();
|
||||
__ StoreObject(field_address, constant);
|
||||
} else {
|
||||
Register value = locs()->in(2).reg();
|
||||
__ StoreIntoObjectNoBarrier(array, field_address, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue