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) { |