Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(807)

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 215363004: Support for multiple register values (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..7699adb41eb78a550ab919e445885d0206b50f01 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -4844,8 +4844,57 @@ void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
-LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
- if (kind() == MergedMathInstr::kTruncDivMod) {
+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* MergedMath2Instr::MakeLocationSummary(bool opt) const {
+ if (kind() == MergedMath2Instr::kTruncDivMod) {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 1;
LocationSummary* summary =
@@ -4853,18 +4902,21 @@ 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(),
+ Location::RequiresRegister()));
// Will be used for sign extension and division.
summary->set_temp(0, Location::RegisterLocation(EDX));
return summary;
}
- if (kind() == MergedMathInstr::kSinCos) {
+ if (kind() == MergedMath2Instr::kSinCos) {
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();
@@ -4879,6 +4931,132 @@ extern const RuntimeEntry kSinCosRuntimeEntry(
static_cast<SinCosCFunction>(&SinCos)), 1, true, true);
+void MergedMath2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Label* deopt = NULL;
+ if (CanDeoptimize()) {
+ deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
+ }
+
+ if (kind() == MergedMath2Instr::kTruncDivMod) {
+ Register left = locs()->in(0).reg();
+ Register right = locs()->in(1).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.
+ __ testl(right, right);
+ __ j(ZERO, deopt);
+ }
+ ASSERT(left == EAX);
+ ASSERT((right != EDX) && (right != EAX));
+ ASSERT(locs()->temp(0).reg() == EDX);
+ ASSERT((result1 != EDX) && (result1 != EAX));
+ ASSERT((result2 != EDX) && (result2 != EAX));
+ __ SmiUntag(left);
+ __ SmiUntag(right);
+ __ cdq(); // Sign extend EAX -> EDX:EAX.
+ __ idivl(right); // EAX: quotient, EDX: remainder.
+ // Check the corner case of dividing the 'MIN_SMI' with -1, in which
+ // case we cannot tag the result.
+ // TODO(srdjan): We could store instead untagged intermediate results in a
+ // typed array, but then the load indexed instructions would need to be
+ // able to deoptimize.
+ __ cmpl(EAX, Immediate(0x40000000));
+ __ j(EQUAL, deopt);
+ // Modulo result (EDX) correction:
+ // res = left % right;
+ // if (res < 0) {
+ // if (right < 0) {
+ // res = res - right;
+ // } else {
+ // res = res + right;
+ // }
+ // }
+ Label done;
+ __ cmpl(EDX, Immediate(0));
+ __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
+ // Result is negative, adjust it.
+ if ((right_range == NULL) || right_range->Overlaps(-1, 1)) {
+ Label subtract;
+ __ cmpl(right, Immediate(0));
+ __ j(LESS, &subtract, Assembler::kNearJump);
+ __ addl(EDX, right);
+ __ jmp(&done, Assembler::kNearJump);
+ __ Bind(&subtract);
+ __ subl(EDX, right);
+ } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
+ // Right is positive.
+ __ addl(EDX, right);
+ } else {
+ // Right is negative.
+ __ subl(EDX, right);
+ }
+ __ Bind(&done);
+
+ __ SmiTag(EAX);
+ __ SmiTag(EDX);
+ __ movl(result1, EAX);
+ __ movl(result2, EDX);
+ return;
+ }
+
+ if (kind() == MergedMath2Instr::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));
+ return;
+ }
+
+ UNIMPLEMENTED();
+}
+
+
+LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
+ if (kind() == MergedMathInstr::kTruncDivMod) {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 1;
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ // 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());
+ // Will be used for sign extension and division.
+ summary->set_temp(0, Location::RegisterLocation(EDX));
+ return summary;
+ }
+ if (kind() == MergedMathInstr::kSinCos) {
Florian Schneider 2014/04/04 11:52:46 I wonder how much code is actually shared between
Cutch 2014/04/04 16:34:46 Note that this is a clone of MergedMathInstr that
+ 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));
+ return summary;
+ }
+ UNIMPLEMENTED();
+ return NULL;
+}
+
+
void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Label* deopt = NULL;
if (CanDeoptimize()) {

Powered by Google App Engine
This is Rietveld 408576698