| 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..f5d8fc8bd7485d056d8d61017117ae6a6abcb958 100644
|
| --- a/runtime/vm/intermediate_language_x64.cc
|
| +++ b/runtime/vm/intermediate_language_x64.cc
|
| @@ -4752,18 +4752,66 @@ 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;
|
| - const intptr_t kNumTemps = 1;
|
| + const intptr_t kNumTemps = 0;
|
| LocationSummary* summary =
|
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| // 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());
|
| - // Will be used for sign extension and division.
|
| - summary->set_temp(0, Location::RegisterLocation(RDX));
|
| + summary->set_out(0, Location::Pair(Location::RegisterLocation(RAX),
|
| + Location::RegisterLocation(RDX)));
|
| return summary;
|
| }
|
| if (kind() == MergedMathInstr::kSinCos) {
|
| @@ -4771,11 +4819,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,14 +4850,16 @@ 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();
|
| + Register temp = RDX;
|
| ASSERT(left == RAX);
|
| ASSERT((right != RDX) && (right != RAX));
|
| - ASSERT(temp == RDX);
|
| - ASSERT((result != RDX) && (result != RAX));
|
| -
|
| + ASSERT(result1 == RAX);
|
| + ASSERT(result2 == RDX);
|
| Range* right_range = InputAt(1)->definition()->range();
|
| if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
|
| // Handle divide by zero in runtime.
|
| @@ -4875,28 +4928,20 @@ 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);
|
| // 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 +4964,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();
|
|
|