Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 13622) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -945,24 +945,28 @@ |
| locs->set_in(1, CanBeImmediateIndex(index()) |
| ? Location::RegisterOrConstant(index()) |
| : Location::RequiresRegister()); |
| - locs->set_out(Location::RequiresRegister()); |
| + if (representation() == kUnboxedDouble) { |
| + locs->set_out(Location::RequiresXmmRegister()); |
| + } else { |
| + locs->set_out(Location::RequiresRegister()); |
| + } |
| return locs; |
| } |
| void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| Register array = locs()->in(0).reg(); |
| - Register result = locs()->out().reg(); |
| 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))); |
| + FieldAddress element_address = index.IsRegister() ? |
| + FlowGraphCompiler::ElementAddressForRegIndex( |
| + class_id(), array, index.reg()) : |
| + FlowGraphCompiler::ElementAddressForIntIndex( |
| + class_id(), array, Smi::Cast(index.constant()).Value()); |
| + |
| + if (representation() == kUnboxedDouble) { |
| + __ movsd(locs()->out().xmm_reg(), element_address); |
| } else { |
| - const int32_t disp = |
| - Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray); |
| - __ movl(result, FieldAddress(array, disp)); |
| + __ movl(locs()->out().reg(), element_address); |
| } |
| } |
| @@ -976,36 +980,45 @@ |
| locs->set_in(1, CanBeImmediateIndex(index()) |
| ? Location::RegisterOrConstant(index()) |
| : Location::RequiresRegister()); |
| - locs->set_in(2, ShouldEmitStoreBarrier() |
| - ? Location::WritableRegister() |
| - : Location::RegisterOrConstant(value())); |
| + if (RequiredInputRepresentation(2) == kUnboxedDouble) { |
| + // TODO(srdjan): Support Float64 constants. |
| + locs->set_in(2, Location::RequiresXmmRegister()); |
| + } else { |
| + locs->set_in(2, ShouldEmitStoreBarrier() |
| + ? Location::WritableRegister() |
| + : Location::RegisterOrConstant(value())); |
| + } |
| return locs; |
| } |
| void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| Register array = locs()->in(0).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)); |
| + FieldAddress element_address = index.IsRegister() ? |
| + FlowGraphCompiler::ElementAddressForRegIndex( |
| + class_id(), array, index.reg()) : |
| + FlowGraphCompiler::ElementAddressForIntIndex( |
| + class_id(), array, Smi::Cast(index.constant()).Value()); |
| + |
| + if (class_id() == kFloat64ArrayCid) { |
| + __ movsd(element_address, locs()->in(2).xmm_reg()); |
| + return; |
| + } |
| + |
| if (ShouldEmitStoreBarrier()) { |
| Register value = locs()->in(2).reg(); |
| - __ StoreIntoObject(array, field_address, value); |
| + __ StoreIntoObject(array, element_address, value); |
| + return; |
| + } |
| + |
| + if (locs()->in(2).IsConstant()) { |
| + const Object& constant = locs()->in(2).constant(); |
| + __ StoreIntoObjectNoBarrier(array, element_address, constant); |
| } else { |
| - 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); |
| - } |
| + Register value = locs()->in(2).reg(); |
| + __ StoreIntoObjectNoBarrier(array, element_address, value); |
| } |
| } |
| @@ -2194,15 +2207,21 @@ |
| void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| const DeoptReasonId deopt_reason = |
| (array_type() == kGrowableObjectArrayCid) ? |
| - kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| + kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| deopt_reason); |
| - ASSERT(array_type() == kArrayCid || |
| - array_type() == kImmutableArrayCid || |
| - array_type() == kGrowableObjectArrayCid); |
| - intptr_t length_offset = (array_type() == kGrowableObjectArrayCid) |
| - ? GrowableObjectArray::length_offset() |
| - : Array::length_offset(); |
| + ASSERT((array_type() == kArrayCid) || |
| + (array_type() == kImmutableArrayCid) || |
| + (array_type() == kGrowableObjectArrayCid) || |
| + (array_type() == kFloat64ArrayCid)); |
| + intptr_t length_offset = -1; |
| + if (array_type() == kGrowableObjectArrayCid) { |
| + length_offset = GrowableObjectArray::length_offset(); |
| + } else if (array_type() == kFloat64ArrayCid) { |
| + length_offset = ByteArray::length_offset(); |
|
Florian Schneider
2012/10/15 09:40:25
Even though length_offset is defined in the superc
srdjan
2012/10/15 16:53:13
Done.
|
| + } else { |
| + length_offset = Array::length_offset(); |
| + } |
| // This case should not have created a bound check instruction. |
| ASSERT(!(locs()->in(0).IsConstant() && locs()->in(1).IsConstant())); |