| Index: runtime/vm/intermediate_language_arm64.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_arm64.cc (revision 35908)
|
| +++ runtime/vm/intermediate_language_arm64.cc (working copy)
|
| @@ -1009,8 +1009,7 @@
|
| break;
|
| case kTypedDataFloat32ArrayCid:
|
| // Load single precision float.
|
| - // TODO(zra): Add when we add single precision floats.
|
| - UNIMPLEMENTED();
|
| + __ fldrs(result, element_address);
|
| break;
|
| case kTypedDataFloat64ArrayCid:
|
| // Load double precision float.
|
| @@ -1141,9 +1140,6 @@
|
| }
|
| break;
|
| case kTypedDataFloat32ArrayCid:
|
| - // TODO(zra): Implement when we add float store.
|
| - UNIMPLEMENTED();
|
| - break;
|
| case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
|
| locs->set_in(2, Location::RequiresFpuRegister());
|
| break;
|
| @@ -1162,7 +1158,7 @@
|
|
|
|
|
| void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - Register array = locs()->in(0).reg();
|
| + const Register array = locs()->in(0).reg();
|
| Location index = locs()->in(1);
|
|
|
| Address element_address(kNoRegister, 0);
|
| @@ -1204,13 +1200,13 @@
|
| switch (class_id()) {
|
| case kArrayCid:
|
| if (ShouldEmitStoreBarrier()) {
|
| - Register value = locs()->in(2).reg();
|
| + const Register value = locs()->in(2).reg();
|
| __ StoreIntoObject(array, element_address, value);
|
| } else if (locs()->in(2).IsConstant()) {
|
| const Object& constant = locs()->in(2).constant();
|
| __ StoreIntoObjectNoBarrier(array, element_address, constant);
|
| } else {
|
| - Register value = locs()->in(2).reg();
|
| + const Register value = locs()->in(2).reg();
|
| __ StoreIntoObjectNoBarrier(array, element_address, value);
|
| }
|
| break;
|
| @@ -1223,7 +1219,7 @@
|
| __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()), PP);
|
| __ str(TMP, element_address, kUnsignedByte);
|
| } else {
|
| - Register value = locs()->in(2).reg();
|
| + const Register value = locs()->in(2).reg();
|
| __ SmiUntag(value);
|
| __ str(value, element_address, kUnsignedByte);
|
| }
|
| @@ -1243,7 +1239,7 @@
|
| __ LoadImmediate(TMP, static_cast<int8_t>(value), PP);
|
| __ str(TMP, element_address, kUnsignedByte);
|
| } else {
|
| - Register value = locs()->in(2).reg();
|
| + const Register value = locs()->in(2).reg();
|
| Label store_value;
|
| __ SmiUntag(value);
|
| __ CompareImmediate(value, 0xFF, PP);
|
| @@ -1260,7 +1256,7 @@
|
| }
|
| case kTypedDataInt16ArrayCid:
|
| case kTypedDataUint16ArrayCid: {
|
| - Register value = locs()->in(2).reg();
|
| + const Register value = locs()->in(2).reg();
|
| __ SmiUntag(value);
|
| __ str(value, element_address, kUnsignedHalfword);
|
| break;
|
| @@ -1269,21 +1265,23 @@
|
| case kTypedDataUint32ArrayCid: {
|
| if (value()->IsSmiValue()) {
|
| ASSERT(RequiredInputRepresentation(2) == kTagged);
|
| - Register value = locs()->in(2).reg();
|
| + const Register value = locs()->in(2).reg();
|
| __ SmiUntag(value);
|
| - __ str(value, element_address);
|
| + __ str(value, element_address, kUnsignedWord);
|
| } else {
|
| // TODO(zra): Implement when we add simd loads and stores.
|
| UNIMPLEMENTED();
|
| }
|
| break;
|
| }
|
| - case kTypedDataFloat32ArrayCid:
|
| - // TODO(zra): Implement when we add float store.
|
| - UNIMPLEMENTED();
|
| + case kTypedDataFloat32ArrayCid: {
|
| + const VRegister in2 = locs()->in(2).fpu_reg();
|
| + __ add(index.reg(), index.reg(), Operand(array));
|
| + __ fstrs(in2, Address(index.reg()));
|
| break;
|
| + }
|
| case kTypedDataFloat64ArrayCid: {
|
| - VRegister in2 = locs()->in(2).fpu_reg();
|
| + const VRegister in2 = locs()->in(2).fpu_reg();
|
| __ add(index.reg(), index.reg(), Operand(array));
|
| __ StoreDToOffset(in2, index.reg(), 0);
|
| break;
|
| @@ -1719,10 +1717,11 @@
|
| case kDoubleCid:
|
| cls = &compiler->double_class();
|
| break;
|
| - // TODO(zra): Implement these when we add fpu loads and stores.
|
| case kFloat32x4Cid:
|
| + cls = &compiler->float32x4_class();
|
| + break;
|
| case kFloat64x2Cid:
|
| - UNIMPLEMENTED();
|
| + cls = &compiler->float64x2_class();
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -1739,9 +1738,7 @@
|
| PP);
|
| __ Bind(slow_path->exit_label());
|
| __ mov(temp2, temp);
|
| - __ StoreIntoObject(instance_reg,
|
| - FieldAddress(instance_reg, offset_in_bytes_),
|
| - temp2);
|
| + __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
|
| } else {
|
| __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_);
|
| }
|
| @@ -1751,8 +1748,12 @@
|
| __ StoreDFieldToOffset(value, temp, Double::value_offset());
|
| break;
|
| case kFloat32x4Cid:
|
| + __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr");
|
| + __ StoreQFieldToOffset(value, temp, Float32x4::value_offset());
|
| + break;
|
| case kFloat64x2Cid:
|
| - UNIMPLEMENTED();
|
| + __ Comment("UnboxedFloat64x2StoreInstanceFieldInstr");
|
| + __ StoreQFieldToOffset(value, temp, Float64x2::value_offset());
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -1821,45 +1822,82 @@
|
| PP);
|
| __ Bind(slow_path->exit_label());
|
| __ mov(temp2, temp);
|
| - __ StoreIntoObject(instance_reg,
|
| - FieldAddress(instance_reg, offset_in_bytes_),
|
| - temp2);
|
| + __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
|
| __ Bind(©_double);
|
| __ LoadDFieldFromOffset(fpu_temp, value_reg, Double::value_offset());
|
| __ StoreDFieldToOffset(fpu_temp, temp, Double::value_offset());
|
| __ b(&skip_store);
|
| }
|
|
|
| - // TODO(zra): Implement these when we add simd loads and stores.
|
| {
|
| __ Bind(&store_float32x4);
|
| - __ Stop("Float32x4 Unimplemented");
|
| + Label copy_float32x4;
|
| + StoreInstanceFieldSlowPath* slow_path =
|
| + new StoreInstanceFieldSlowPath(this, compiler->float32x4_class());
|
| + compiler->AddSlowPathCode(slow_path);
|
| +
|
| + __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_);
|
| + __ CompareObject(temp, Object::null_object(), PP);
|
| + __ b(©_float32x4, NE);
|
| +
|
| + __ TryAllocate(compiler->float32x4_class(),
|
| + slow_path->entry_label(),
|
| + temp,
|
| + temp2,
|
| + PP);
|
| + __ Bind(slow_path->exit_label());
|
| + __ mov(temp2, temp);
|
| + __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
|
| + __ Bind(©_float32x4);
|
| + __ LoadQFieldFromOffset(fpu_temp, value_reg, Float32x4::value_offset());
|
| + __ StoreQFieldToOffset(fpu_temp, value_reg, Float32x4::value_offset());
|
| + __ b(&skip_store);
|
| }
|
|
|
| {
|
| __ Bind(&store_float64x2);
|
| - __ Stop("Float64x2 Unimplemented");
|
| + Label copy_float64x2;
|
| + StoreInstanceFieldSlowPath* slow_path =
|
| + new StoreInstanceFieldSlowPath(this, compiler->float64x2_class());
|
| + compiler->AddSlowPathCode(slow_path);
|
| +
|
| + __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_);
|
| + __ CompareObject(temp, Object::null_object(), PP);
|
| + __ b(©_float64x2, NE);
|
| +
|
| + __ TryAllocate(compiler->float64x2_class(),
|
| + slow_path->entry_label(),
|
| + temp,
|
| + temp2,
|
| + PP);
|
| + __ Bind(slow_path->exit_label());
|
| + __ mov(temp2, temp);
|
| + __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
|
| + __ Bind(©_float64x2);
|
| + __ LoadQFieldFromOffset(fpu_temp, value_reg, Float64x2::value_offset());
|
| + __ StoreQFieldToOffset(fpu_temp, value_reg, Float64x2::value_offset());
|
| + __ b(&skip_store);
|
| }
|
|
|
| __ Bind(&store_pointer);
|
| }
|
|
|
| if (ShouldEmitStoreBarrier()) {
|
| - Register value_reg = locs()->in(1).reg();
|
| - __ StoreIntoObject(instance_reg,
|
| - FieldAddress(instance_reg, offset_in_bytes_),
|
| - value_reg,
|
| - CanValueBeSmi());
|
| + const Register value_reg = locs()->in(1).reg();
|
| + __ StoreIntoObjectOffset(
|
| + instance_reg, offset_in_bytes_, value_reg, CanValueBeSmi());
|
| } else {
|
| if (locs()->in(1).IsConstant()) {
|
| - __ StoreIntoObjectNoBarrier(
|
| + __ StoreIntoObjectOffsetNoBarrier(
|
| instance_reg,
|
| - FieldAddress(instance_reg, offset_in_bytes_),
|
| + offset_in_bytes_,
|
| locs()->in(1).constant());
|
| } else {
|
| - Register value_reg = locs()->in(1).reg();
|
| - __ StoreIntoObjectNoBarrier(instance_reg,
|
| - FieldAddress(instance_reg, offset_in_bytes_), value_reg);
|
| + const Register value_reg = locs()->in(1).reg();
|
| + __ StoreIntoObjectOffsetNoBarrier(
|
| + instance_reg,
|
| + offset_in_bytes_,
|
| + value_reg);
|
| }
|
| }
|
| __ Bind(&skip_store);
|
| @@ -1904,11 +1942,10 @@
|
|
|
| __ LoadObject(temp, field(), PP);
|
| if (this->value()->NeedsStoreBuffer()) {
|
| - __ StoreIntoObject(temp,
|
| - FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi());
|
| + __ StoreIntoObjectOffset(
|
| + temp, Field::value_offset(), value, CanValueBeSmi());
|
| } else {
|
| - __ StoreIntoObjectNoBarrier(
|
| - temp, FieldAddress(temp, Field::value_offset()), value);
|
| + __ StoreIntoObjectOffsetNoBarrier(temp, Field::value_offset(), value);
|
| }
|
| }
|
|
|
| @@ -3568,24 +3605,38 @@
|
|
|
|
|
| LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + const intptr_t kNumInputs = 1;
|
| + const intptr_t kNumTemps = 0;
|
| + LocationSummary* result =
|
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| + result->set_in(0, Location::RequiresFpuRegister());
|
| + result->set_out(0, Location::RequiresFpuRegister());
|
| + return result;
|
| }
|
|
|
|
|
| void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + const VRegister value = locs()->in(0).fpu_reg();
|
| + const VRegister result = locs()->out(0).fpu_reg();
|
| + __ fcvtsd(result, value);
|
| }
|
|
|
|
|
| LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + const intptr_t kNumInputs = 1;
|
| + const intptr_t kNumTemps = 0;
|
| + LocationSummary* result =
|
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| + result->set_in(0, Location::RequiresFpuRegister());
|
| + result->set_out(0, Location::RequiresFpuRegister());
|
| + return result;
|
| }
|
|
|
|
|
| void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + const VRegister value = locs()->in(0).fpu_reg();
|
| + const VRegister result = locs()->out(0).fpu_reg();
|
| + __ fcvtds(result, value);
|
| }
|
|
|
|
|
|
|