| Index: runtime/vm/intermediate_language_dbc.cc
|
| diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
|
| index 3d8fee77bf098a1afcd62d350a6418e834834885..0dda8e1f41979c5293c2376848d8a18402adec07 100644
|
| --- a/runtime/vm/intermediate_language_dbc.cc
|
| +++ b/runtime/vm/intermediate_language_dbc.cc
|
| @@ -40,7 +40,6 @@ DECLARE_FLAG(int, optimization_counter_threshold);
|
| M(DoubleToFloat) \
|
| M(FloatToDouble) \
|
| M(BoxInt64) \
|
| - M(InvokeMathCFunction) \
|
| M(MergedMath) \
|
| M(GuardFieldClass) \
|
| M(GuardFieldLength) \
|
| @@ -107,14 +106,17 @@ static LocationSummary* CreateLocationSummary(
|
| Zone* zone,
|
| intptr_t num_inputs,
|
| Location output = Location::NoLocation(),
|
| - LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall) {
|
| - const intptr_t kNumTemps = 0;
|
| + LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall,
|
| + intptr_t num_temps = 0) {
|
| LocationSummary* locs = new(zone) LocationSummary(
|
| - zone, num_inputs, kNumTemps, contains_call);
|
| + zone, num_inputs, num_temps, contains_call);
|
| for (intptr_t i = 0; i < num_inputs; i++) {
|
| locs->set_in(i, (contains_call == LocationSummary::kNoCall) ?
|
| Location::RequiresRegister() : Location::RegisterLocation(i));
|
| }
|
| + for (intptr_t i = 0; i < num_temps; i++) {
|
| + locs->set_temp(i, Location::RequiresRegister());
|
| + }
|
| if (!output.IsInvalid()) {
|
| // For instructions that call we default to returning result in R0.
|
| locs->set_out(0, output);
|
| @@ -673,15 +675,38 @@ EMIT_NATIVE_CODE(CreateArray,
|
| }
|
|
|
|
|
| -EMIT_NATIVE_CODE(StoreIndexed, 3) {
|
| +EMIT_NATIVE_CODE(StoreIndexed, 3, Location::NoLocation(),
|
| + LocationSummary::kNoCall, 1) {
|
| if (compiler->is_optimizing()) {
|
| - if (class_id() != kArrayCid) {
|
| + if (IsExternal()) {
|
| Unsupported(compiler);
|
| UNREACHABLE();
|
| }
|
| - __ StoreIndexed(locs()->in(kArrayPos).reg(),
|
| - locs()->in(kIndexPos).reg(),
|
| - locs()->in(kValuePos).reg());
|
| + const Register array = locs()->in(kArrayPos).reg();
|
| + const Register index = locs()->in(kIndexPos).reg();
|
| + const Register value = locs()->in(kValuePos).reg();
|
| + const Register temp = locs()->temp(0).reg();
|
| + switch (class_id()) {
|
| + case kArrayCid:
|
| + __ StoreIndexed(array, index, value);
|
| + break;
|
| + case kTypedDataFloat64ArrayCid:
|
| + if ((index_scale() != 8) && (index_scale() != 1)) {
|
| + Unsupported(compiler);
|
| + UNREACHABLE();
|
| + }
|
| + if (index_scale() == 1) {
|
| + __ ShrImm(temp, index, 3);
|
| + } else {
|
| + __ Move(temp, index);
|
| + }
|
| + __ StoreFloat64Indexed(array, temp, value);
|
| + break;
|
| + default:
|
| + Unsupported(compiler);
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| } else {
|
| ASSERT(class_id() == kArrayCid);
|
| __ StoreIndexedTOS();
|
| @@ -691,15 +716,44 @@ EMIT_NATIVE_CODE(StoreIndexed, 3) {
|
|
|
| EMIT_NATIVE_CODE(LoadIndexed, 2, Location::RequiresRegister()) {
|
| ASSERT(compiler->is_optimizing());
|
| - if (class_id() != kArrayCid) {
|
| + if (IsExternal()) {
|
| Unsupported(compiler);
|
| UNREACHABLE();
|
| }
|
| const Register array = locs()->in(0).reg();
|
| const Register index = locs()->in(1).reg();
|
| const Register result = locs()->out(0).reg();
|
| -
|
| - __ LoadIndexed(result, array, index);
|
| + switch (class_id()) {
|
| + case kArrayCid:
|
| + __ LoadIndexed(result, array, index);
|
| + break;
|
| + case kTypedDataFloat64ArrayCid:
|
| + if ((index_scale() != 8) && (index_scale() != 1)) {
|
| + Unsupported(compiler);
|
| + UNREACHABLE();
|
| + }
|
| + if (index_scale() == 1) {
|
| + __ ShrImm(index, index, 3);
|
| + }
|
| + __ LoadFloat64Indexed(result, array, index);
|
| + break;
|
| + case kOneByteStringCid:
|
| + ASSERT(index_scale() == 1);
|
| + __ LoadOneByteStringIndexed(result, array, index);
|
| + break;
|
| + case kTwoByteStringCid:
|
| + if (index_scale() != 2) {
|
| + // TODO(zra): Fix-up index.
|
| + Unsupported(compiler);
|
| + UNREACHABLE();
|
| + }
|
| + __ LoadTwoByteStringIndexed(result, array, index);
|
| + break;
|
| + default:
|
| + Unsupported(compiler);
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| }
|
|
|
|
|
| @@ -1319,14 +1373,33 @@ EMIT_NATIVE_CODE(UnaryDoubleOp, 1, Location::RequiresRegister()) {
|
|
|
|
|
| EMIT_NATIVE_CODE(MathUnary, 1, Location::RequiresRegister()) {
|
| + const Register value = locs()->in(0).reg();
|
| + const Register result = locs()->out(0).reg();
|
| if (kind() == MathUnaryInstr::kSqrt) {
|
| - const Register value = locs()->in(0).reg();
|
| - const Register result = locs()->out(0).reg();
|
| __ DSqrt(result, value);
|
| } else if (kind() == MathUnaryInstr::kDoubleSquare) {
|
| - const Register value = locs()->in(0).reg();
|
| - const Register result = locs()->out(0).reg();
|
| __ DMul(result, value, value);
|
| + } else if (kind() == MathUnaryInstr::kSin) {
|
| + __ DSin(result, value);
|
| + } else if (kind() == MathUnaryInstr::kCos) {
|
| + __ DCos(result, value);
|
| + } else {
|
| + Unsupported(compiler);
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +
|
| +EMIT_NATIVE_CODE(InvokeMathCFunction,
|
| + InputCount(), Location::RequiresRegister()) {
|
| + const Register left = locs()->in(0).reg();
|
| + const Register result = locs()->out(0).reg();
|
| + if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
|
| + const Register right = locs()->in(1).reg();
|
| + __ DPow(result, left, right);
|
| + } else if (recognized_kind() == MethodRecognizer::kDoubleMod) {
|
| + const Register right = locs()->in(1).reg();
|
| + __ DMod(result, left, right);
|
| } else {
|
| Unsupported(compiler);
|
| UNREACHABLE();
|
|
|