Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 17016) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -1054,13 +1054,15 @@ |
| } |
| -static bool CanBeImmediateIndex(Value* index) { |
| +static bool CanBeImmediateIndex(Value* index, intptr_t cid) { |
| if (!index->definition()->IsConstant()) return false; |
| const Object& constant = index->definition()->AsConstant()->value(); |
| if (!constant.IsSmi()) return false; |
| const Smi& smi_const = Smi::Cast(constant); |
| - int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray); |
| - return Utils::IsInt(32, disp); |
| + const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); |
| + const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); |
| + int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
| + return Utils::IsInt(31, disp); |
|
Vyacheslav Egorov (Google)
2013/01/14 16:39:56
I think this should be 32 and the same in other pl
Florian Schneider
2013/01/14 17:00:47
Done.
|
| } |
| @@ -1070,8 +1072,9 @@ |
| LocationSummary* locs = |
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| locs->set_in(0, Location::RequiresRegister()); |
| - // TODO(fschneider): Allow immediate operands for the index. |
| - locs->set_in(1, Location::RequiresRegister()); |
| + locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| + ? Location::RegisterOrSmiConstant(index()) |
| + : Location::RequiresRegister()); |
| locs->set_out(Location::RequiresRegister()); |
| return locs; |
| } |
| @@ -1079,25 +1082,30 @@ |
| void StringCharCodeAtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| Register str = locs()->in(0).reg(); |
| - Register index = locs()->in(1).reg(); |
| + Location index = locs()->in(1); |
| Register result = locs()->out().reg(); |
| ASSERT((class_id() == kOneByteStringCid) || |
| (class_id() == kTwoByteStringCid)); |
| + |
| + FieldAddress element_address = index.IsRegister() ? |
| + FlowGraphCompiler::ElementAddressForRegIndex( |
| + class_id(), str, index.reg()) : |
| + FlowGraphCompiler::ElementAddressForIntIndex( |
| + class_id(), str, Smi::Cast(index.constant()).Value()); |
| + |
| if (class_id() == kOneByteStringCid) { |
| - __ SmiUntag(index); |
| - __ movzxb(result, FieldAddress(str, |
| - index, |
| - TIMES_1, |
| - OneByteString::data_offset())); |
| - __ SmiTag(index); // Retag index. |
| + if (index.IsRegister()) { |
| + __ SmiUntag(index.reg()); |
| + } |
| + __ movzxb(result, element_address); |
| + if (index.IsRegister()) { |
| + __ SmiTag(index.reg()); // Retag index. |
| + } |
| __ SmiTag(result); |
| } else { |
| // Don't untag smi-index and use TIMES_1 for two byte strings. |
| - __ movzxw(result, FieldAddress(str, |
| - index, |
| - TIMES_1, |
| - TwoByteString::data_offset())); |
| + __ movzxw(result, element_address); |
| __ SmiTag(result); |
| } |
| } |
| @@ -1133,8 +1141,8 @@ |
| LocationSummary* locs = |
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| locs->set_in(0, Location::RequiresRegister()); |
| - locs->set_in(1, CanBeImmediateIndex(index()) |
| - ? Location::RegisterOrConstant(index()) |
| + locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| + ? Location::RegisterOrSmiConstant(index()) |
| : Location::RequiresRegister()); |
| if (representation() == kUnboxedDouble) { |
| locs->set_out(Location::RequiresXmmRegister()); |
| @@ -1214,8 +1222,8 @@ |
| LocationSummary* locs = |
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| locs->set_in(0, Location::RequiresRegister()); |
| - locs->set_in(1, CanBeImmediateIndex(index()) |
| - ? Location::RegisterOrConstant(index()) |
| + locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| + ? Location::RegisterOrSmiConstant(index()) |
| : Location::RequiresRegister()); |
| switch (class_id()) { |
| case kArrayCid: |