| Index: runtime/vm/intermediate_language_arm.cc
|
| diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
|
| index 34255e95c088f3181156ea36743523036acfc384..1ae7daaad5d64b741e428f04e5cbc89f81182585 100644
|
| --- a/runtime/vm/intermediate_language_arm.cc
|
| +++ b/runtime/vm/intermediate_language_arm.cc
|
| @@ -5024,19 +5024,68 @@ void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
|
|
| +LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const {
|
| + // Only use this instruction in optimized code.
|
| + ASSERT(opt);
|
| + const intptr_t kNumInputs = 1;
|
| + LocationSummary* summary =
|
| + new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
|
| + if (representation() == kUnboxedDouble) {
|
| + if (index() == 0) {
|
| + summary->set_in(0, Location::Pair(Location::RequiresFpuRegister(),
|
| + Location::Any()));
|
| + } else {
|
| + ASSERT(index() == 1);
|
| + summary->set_in(0, Location::Pair(Location::Any(),
|
| + Location::RequiresFpuRegister()));
|
| + }
|
| + summary->set_out(0, Location::RequiresFpuRegister());
|
| + } else {
|
| + ASSERT(representation() == kTagged);
|
| + if (index() == 0) {
|
| + summary->set_in(0, Location::Pair(Location::RequiresRegister(),
|
| + Location::Any()));
|
| + } else {
|
| + ASSERT(index() == 1);
|
| + summary->set_in(0, Location::Pair(Location::Any(),
|
| + Location::RequiresRegister()));
|
| + }
|
| + summary->set_out(0, Location::RequiresRegister());
|
| + }
|
| + return summary;
|
| +}
|
| +
|
| +
|
| +void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + ASSERT(locs()->in(0).IsPairLocation());
|
| + PairLocation* pair = locs()->in(0).AsPairLocation();
|
| + Location in_loc = pair->At(index());
|
| + if (representation() == kUnboxedDouble) {
|
| + QRegister out = locs()->out(0).fpu_reg();
|
| + QRegister in = in_loc.fpu_reg();
|
| + __ vmovq(out, in);
|
| + } else {
|
| + ASSERT(representation() == kTagged);
|
| + Register out = locs()->out(0).reg();
|
| + Register in = in_loc.reg();
|
| + __ mov(out, ShifterOperand(in));
|
| + }
|
| +}
|
| +
|
| +
|
| LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
|
| if (kind() == MergedMathInstr::kTruncDivMod) {
|
| const intptr_t kNumInputs = 2;
|
| - const intptr_t kNumTemps = 4;
|
| + const intptr_t kNumTemps = 2;
|
| LocationSummary* summary =
|
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| summary->set_in(0, Location::RequiresRegister());
|
| summary->set_in(1, Location::RequiresRegister());
|
| summary->set_temp(0, Location::RequiresRegister());
|
| summary->set_temp(1, Location::RequiresFpuRegister());
|
| - summary->set_temp(2, Location::RequiresRegister()); // result_div.
|
| - summary->set_temp(3, Location::RequiresRegister()); // result_mod.
|
| - summary->set_out(0, Location::RequiresRegister());
|
| + // Output is a pair of registers.
|
| + summary->set_out(0, Location::Pair(Location::RequiresRegister(),
|
| + Location::RequiresRegister()));
|
| return summary;
|
| }
|
| UNIMPLEMENTED();
|
| @@ -5052,7 +5101,10 @@ void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| if (kind() == MergedMathInstr::kTruncDivMod) {
|
| Register left = locs()->in(0).reg();
|
| Register right = locs()->in(1).reg();
|
| - Register result = locs()->out(0).reg();
|
| + ASSERT(locs()->out(0).IsPairLocation());
|
| + PairLocation* pair = locs()->out(0).AsPairLocation();
|
| + Register result_div = pair->At(0).reg();
|
| + Register result_mod = pair->At(1).reg();
|
| Range* right_range = InputAt(1)->definition()->range();
|
| if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
|
| // Handle divide by zero in runtime.
|
| @@ -5061,8 +5113,7 @@ void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
| Register temp = locs()->temp(0).reg();
|
| DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
|
| - Register result_div = locs()->temp(2).reg();
|
| - Register result_mod = locs()->temp(3).reg();
|
| +
|
| __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
|
| __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
|
|
|
| @@ -5095,15 +5146,6 @@ void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| __ add(result_mod, result_mod, ShifterOperand(right), GE);
|
| __ Bind(&done);
|
|
|
| - __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld)));
|
| - // Note that index is expected smi-tagged, (i.e, times 2) for all arrays.
|
| - // [0]: divide resut, [1]: mod result.
|
| - __ mov(temp, ShifterOperand(0 +
|
| - FlowGraphCompiler::DataOffsetFor(kArrayCid) - kHeapObjectTag));
|
| - Address store_address(result, temp, LSL, 0);
|
| - __ StoreIntoObjectNoBarrier(result, store_address, result_div);
|
| - __ add(temp, temp, ShifterOperand(kWordSize));
|
| - __ StoreIntoObjectNoBarrier(result, store_address, result_mod);
|
| return;
|
| }
|
| if (kind() == MergedMathInstr::kSinCos) {
|
|
|