| Index: runtime/vm/intermediate_language_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_ia32.cc (revision 43881)
|
| +++ runtime/vm/intermediate_language_ia32.cc (working copy)
|
| @@ -5541,12 +5541,18 @@
|
| }
|
| if (kind() == MergedMathInstr::kSinCos) {
|
| const intptr_t kNumInputs = 1;
|
| - const intptr_t kNumTemps = 0;
|
| + const intptr_t kNumTemps = 2;
|
| LocationSummary* summary = new(zone) LocationSummary(
|
| - zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| - summary->set_in(0, Location::RequiresFpuRegister());
|
| - summary->set_out(0, Location::Pair(Location::RequiresFpuRegister(),
|
| - Location::RequiresFpuRegister()));
|
| + zone, 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));
|
| + // EDI 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(EDI));
|
| + summary->set_temp(1, Location::RegisterLocation(EBX));
|
| + summary->set_out(0, Location::Pair(Location::FpuRegisterLocation(XMM2),
|
| + Location::FpuRegisterLocation(XMM3)));
|
| return summary;
|
| }
|
| UNIMPLEMENTED();
|
| @@ -5631,27 +5637,47 @@
|
| }
|
|
|
| if (kind() == MergedMathInstr::kSinCos) {
|
| - XmmRegister in = locs()->in(0).fpu_reg();
|
| 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();
|
|
|
| - // Do x87 sincos, since the ia32 compilers may not fuse sin/cos into
|
| - // sincos.
|
| - __ pushl(EAX);
|
| - __ pushl(EAX);
|
| - __ movsd(Address(ESP, 0), in);
|
| - __ fldl(Address(ESP, 0));
|
| - __ fsincos();
|
| - __ fstpl(Address(ESP, 0));
|
| - __ movsd(out1, Address(ESP, 0));
|
| - __ fstpl(Address(ESP, 0));
|
| - __ movsd(out2, Address(ESP, 0));
|
| - __ addl(ESP, Immediate(2 * kWordSize));
|
| + // Save ESP.
|
| + __ movl(locs()->temp(0).reg(), ESP);
|
| + // +-------------------------------+
|
| + // | double-argument | <- TOS
|
| + // +-------------------------------+
|
| + // | address-cos-result | +8
|
| + // +-------------------------------+
|
| + // | address-sin-result | +12
|
| + // +-------------------------------+
|
| + // | double-storage-for-cos-result | +16
|
| + // +-------------------------------+
|
| + // | double-storage-for-sin-result | +24
|
| + // +-------------------------------+
|
| + // ....
|
| + __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2);
|
| + __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg());
|
| +
|
| + Address cos_result(ESP, 2 * kWordSize + kDoubleSize);
|
| + Address sin_result(ESP, 2 * kWordSize + 2 * kDoubleSize);
|
| +
|
| + // 'cos' result storage address.
|
| + __ leal(locs()->temp(1).reg(), cos_result);
|
| + __ movl(Address(ESP, kDoubleSize), locs()->temp(1).reg());
|
| +
|
| + // 'sin' result storage address.
|
| + __ leal(locs()->temp(1).reg(), sin_result);
|
| + __ movl(Address(ESP, kDoubleSize + kWordSize), locs()->temp(1).reg());
|
| +
|
| + __ CallRuntime(kSinCosRuntimeEntry, InputCount());
|
| + __ movsd(out2, sin_result); // sin.
|
| + __ movsd(out1, cos_result); // cos.
|
| + // Restore RSP.
|
| + __ movl(ESP, locs()->temp(0).reg());
|
| +
|
| return;
|
| }
|
| -
|
| UNIMPLEMENTED();
|
| }
|
|
|
|
|