Chromium Code Reviews| Index: runtime/vm/intermediate_language_x64.cc |
| diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc |
| index 310a16ac86239ce3f24adf01af96bb30d3cf062b..882e7ef530eca44f45ffb4bf55cee8799db4a70e 100644 |
| --- a/runtime/vm/intermediate_language_x64.cc |
| +++ b/runtime/vm/intermediate_language_x64.cc |
| @@ -4752,6 +4752,55 @@ 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) { |
| + XmmRegister out = locs()->out(0).fpu_reg(); |
| + XmmRegister in = in_loc.fpu_reg(); |
| + __ movaps(out, in); |
| + } else { |
| + ASSERT(representation() == kTagged); |
| + Register out = locs()->out(0).reg(); |
| + Register in = in_loc.reg(); |
| + __ movq(out, in); |
| + } |
| +} |
| + |
| + |
| LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| if (kind() == MergedMathInstr::kTruncDivMod) { |
| const intptr_t kNumInputs = 2; |
| @@ -4761,7 +4810,8 @@ LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| // Both inputs must be writable because they will be untagged. |
| summary->set_in(0, Location::RegisterLocation(RAX)); |
| summary->set_in(1, Location::WritableRegister()); |
| - summary->set_out(0, Location::RequiresRegister()); |
| + summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
|
Florian Schneider
2014/04/08 09:48:45
Same here: It should be possible to have the outpu
Cutch
2014/04/08 15:56:16
Done.
|
| + Location::RequiresRegister())); |
| // Will be used for sign extension and division. |
| summary->set_temp(0, Location::RegisterLocation(RDX)); |
| return summary; |
| @@ -4771,11 +4821,14 @@ LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| const intptr_t kNumTemps = 1; |
| LocationSummary* summary = |
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| + // Because we always call into the runtime (LocationSummary::kCall) we |
| + // must specify each input, temp, and output register explicitly. |
| summary->set_in(0, Location::FpuRegisterLocation(XMM1)); |
| // R13 is chosen because it is callee saved so we do not need to back it |
| // up before calling into the runtime. |
| summary->set_temp(0, Location::RegisterLocation(R13)); |
| - summary->set_out(0, Location::RegisterLocation(RAX)); |
| + summary->set_out(0, Location::Pair(Location::FpuRegisterLocation(XMM2), |
| + Location::FpuRegisterLocation(XMM3))); |
| return summary; |
| } |
| UNIMPLEMENTED(); |
| @@ -4799,13 +4852,17 @@ 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 result1 = pair->At(0).reg(); |
| + Register result2 = pair->At(1).reg(); |
| Label not_32bit, done; |
| Register temp = locs()->temp(0).reg(); |
| ASSERT(left == RAX); |
| ASSERT((right != RDX) && (right != RAX)); |
| ASSERT(temp == RDX); |
| - ASSERT((result != RDX) && (result != RAX)); |
| + ASSERT((result1 != RDX) && (result1 != RAX)); |
| + ASSERT((result2 != RDX) && (result2 != RAX)); |
| Range* right_range = InputAt(1)->definition()->range(); |
| if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
| @@ -4875,28 +4932,23 @@ void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| __ subq(RDX, right); |
| } |
| __ Bind(&all_done); |
| - __ SmiTag(result); |
| - |
| - __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld)), PP); |
| - const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(kArrayCid); |
| - Address trunc_div_address( |
| - FlowGraphCompiler::ElementAddressForIntIndex( |
| - kArrayCid, index_scale, result, |
| - MergedMathInstr::ResultIndexOf(Token::kTRUNCDIV))); |
| - Address mod_address( |
| - FlowGraphCompiler::ElementAddressForIntIndex( |
| - kArrayCid, index_scale, result, |
| - MergedMathInstr::ResultIndexOf(Token::kMOD))); |
| + |
| __ SmiTag(RAX); |
| __ SmiTag(RDX); |
| - __ StoreIntoObjectNoBarrier(result, trunc_div_address, RAX); |
| - __ StoreIntoObjectNoBarrier(result, mod_address, RDX); |
| + |
| + __ movq(result1, RAX); |
| + __ movq(result2, RDX); |
| // FLAG_throw_on_javascript_int_overflow: not needed. |
| // Note that the result of an integer division/modulo of two |
| // in-range arguments, cannot create out-of-range result. |
| return; |
| } |
| if (kind() == MergedMathInstr::kSinCos) { |
| + ASSERT(locs()->out(0).IsPairLocation()); |
| + PairLocation* pair = locs()->out(0).AsPairLocation(); |
| + XmmRegister out1 = pair->At(0).fpu_reg(); |
| + XmmRegister out2 = pair->At(1).fpu_reg(); |
| + |
| // Save RSP. |
| __ movq(locs()->temp(0).reg(), RSP); |
| // +-------------------------------+ |
| @@ -4919,27 +4971,11 @@ void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| __ movaps(XMM0, locs()->in(0).fpu_reg()); |
| __ CallRuntime(kSinCosRuntimeEntry, InputCount()); |
| - __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin. |
| - __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos. |
| + __ movsd(out2, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin. |
| + __ movsd(out1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos. |
| // Restore RSP. |
| __ movq(RSP, locs()->temp(0).reg()); |
| - Register result = locs()->out(0).reg(); |
| - const TypedData& res_array = TypedData::ZoneHandle( |
| - TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld)); |
| - __ LoadObject(result, res_array, PP); |
| - const intptr_t index_scale = |
| - FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid); |
| - Address sin_address( |
| - FlowGraphCompiler::ElementAddressForIntIndex( |
| - kTypedDataFloat64ArrayCid, index_scale, result, |
| - MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathSin))); |
| - Address cos_address( |
| - FlowGraphCompiler::ElementAddressForIntIndex( |
| - kTypedDataFloat64ArrayCid, index_scale, result, |
| - MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathCos))); |
| - __ movsd(sin_address, XMM0); |
| - __ movsd(cos_address, XMM1); |
| return; |
| } |
| UNIMPLEMENTED(); |