Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc |
| index dd7cf89227fee0f72b81ab85a7df2297aae343d6..349a4eb2a4ac1409d0dcc0c0280364ac8862a62e 100644 |
| --- a/runtime/vm/intermediate_language_ia32.cc |
| +++ b/runtime/vm/intermediate_language_ia32.cc |
| @@ -4844,6 +4844,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(); |
| + __ movl(out, in); |
| + } |
| +} |
| + |
| + |
| LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| if (kind() == MergedMathInstr::kTruncDivMod) { |
| const intptr_t kNumInputs = 2; |
| @@ -4853,7 +4902,9 @@ LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| // Both inputs must be writable because they will be untagged. |
| summary->set_in(0, Location::RegisterLocation(EAX)); |
| summary->set_in(1, Location::WritableRegister()); |
| - summary->set_out(0, Location::RequiresRegister()); |
| + // Output is a pair of registers. |
| + summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
|
Florian Schneider
2014/04/08 09:48:45
How about making the output a pair EDX:EAX instead
Cutch
2014/04/08 15:56:16
Done.
|
| + Location::RequiresRegister())); |
| // Will be used for sign extension and division. |
| summary->set_temp(0, Location::RegisterLocation(EDX)); |
| return summary; |
| @@ -4862,9 +4913,10 @@ LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| const intptr_t kNumInputs = 1; |
| const intptr_t kNumTemps = 0; |
| LocationSummary* summary = |
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| - summary->set_in(0, Location::FpuRegisterLocation(XMM1)); |
| - summary->set_out(0, Location::RegisterLocation(EAX)); |
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| + summary->set_in(0, Location::RequiresFpuRegister()); |
| + summary->set_out(0, Location::Pair(Location::RequiresFpuRegister(), |
| + Location::RequiresFpuRegister())); |
| return summary; |
| } |
| UNIMPLEMENTED(); |
| @@ -4888,7 +4940,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 result1 = pair->At(0).reg(); |
| + Register result2 = 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. |
| @@ -4898,7 +4953,8 @@ void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| ASSERT(left == EAX); |
| ASSERT((right != EDX) && (right != EAX)); |
| ASSERT(locs()->temp(0).reg() == EDX); |
| - ASSERT((result != EDX) && (result != EAX)); |
| + ASSERT((result1 != EDX) && (result1 != EAX)); |
| + ASSERT((result2 != EDX) && (result2 != EAX)); |
| __ SmiUntag(left); |
| __ SmiUntag(right); |
| __ cdq(); // Sign extend EAX -> EDX:EAX. |
| @@ -4940,53 +4996,32 @@ void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| } |
| __ Bind(&done); |
| - __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld))); |
| - 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(EAX); |
| __ SmiTag(EDX); |
| - __ StoreIntoObjectNoBarrier(result, trunc_div_address, EAX); |
| - __ StoreIntoObjectNoBarrier(result, mod_address, EDX); |
| + __ movl(result1, EAX); |
| + __ movl(result2, EDX); |
| return; |
| } |
| 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), locs()->in(0).fpu_reg()); |
| + __ movsd(Address(ESP, 0), in); |
| __ fldl(Address(ESP, 0)); |
| __ fsincos(); |
| __ fstpl(Address(ESP, 0)); |
| - __ movsd(XMM1, Address(ESP, 0)); |
| + __ movsd(out1, Address(ESP, 0)); |
| __ fstpl(Address(ESP, 0)); |
| - __ movsd(XMM0, Address(ESP, 0)); |
| + __ movsd(out2, Address(ESP, 0)); |
| __ addl(ESP, Immediate(2 * kWordSize)); |
| - |
| - Register result = locs()->out(0).reg(); |
| - const TypedData& res_array = TypedData::ZoneHandle( |
| - TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld)); |
| - __ LoadObject(result, res_array); |
| - 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; |
| } |