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

Unified Diff: runtime/vm/intermediate_language_x64.cc

Issue 10533053: Implement inlined version of binary arithmetic operations for doubles. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 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
« runtime/vm/intermediate_language.h ('K') | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_x64.cc
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 5002021852cf6bb1b6dc129ab8f4e81bffc75d9c..39ea8b2ff2a6bd752f3897a2048346faded0af4d 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -750,6 +750,19 @@ void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) {
LocationSummary* BinaryOpComp::MakeLocationSummary() const {
const intptr_t kNumInputs = 2;
+
+ if (operands_type() == kDoubleOperands) {
+ const intptr_t kNumTemps = 1;
+ LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
+ summary->set_in(0, Location::RequiresRegister());
+ summary->set_in(1, Location::RequiresRegister());
+ summary->set_out(Location::RegisterLocation(RAX));
+ summary->set_temp(0, Location::RequiresRegister());
+ return summary;
+ }
+
+ ASSERT(operands_type() == kSmiOperands);
+
if (op_kind() == Token::kTRUNCDIV) {
const intptr_t kNumTemps = 3;
LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
@@ -791,22 +804,7 @@ LocationSummary* BinaryOpComp::MakeLocationSummary() const {
// TODO(srdjan): Implement variations.
-static bool TryEmitSmiBinaryOp(FlowGraphCompiler* compiler,
- BinaryOpComp* comp) {
- ASSERT((comp->ic_data() != NULL));
- const ICData& ic_data = *comp->ic_data();
- if (ic_data.IsNull()) return false;
- if (ic_data.num_args_tested() != 2) return false;
- if (ic_data.NumberOfChecks() != 1) return false;
- Function& target = Function::Handle();
- GrowableArray<const Class*> classes;
- ic_data.GetCheckAt(0, &classes, &target);
- const Class& smi_class =
- Class::Handle(Isolate::Current()->object_store()->smi_class());
- if ((classes[0]->raw() != smi_class.raw()) ||
- (classes[1]->raw() != smi_class.raw())) {
- return false;
- }
+static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
// TODO(srdjan): need to allocate a temporary register (now using r10)
Register left = comp->locs()->in(0).reg();
Register right = comp->locs()->in(1).reg();
@@ -882,11 +880,13 @@ static bool TryEmitSmiBinaryOp(FlowGraphCompiler* compiler,
case Token::kDIV: {
// Dispatches to 'Double./'.
// TODO(srdjan): Implement as conversion to double and double division.
- return false;
+ UNREACHABLE();
+ return;
Mads Ager (google) 2012/06/08 09:15:53 Why 'return' here and 'break' below?
Vyacheslav Egorov (Google) 2012/06/08 11:11:13 Done.
}
case Token::kMOD: {
// TODO(srdjan): Implement.
- return false;
+ UNREACHABLE();
+ return;
}
case Token::kSHR: {
const Immediate kCountLimit = Immediate(0x1F);
@@ -927,30 +927,96 @@ static bool TryEmitSmiBinaryOp(FlowGraphCompiler* compiler,
// Flow graph builder has dissected this operation to guarantee correct
// behavior (short-circuit evaluation).
UNREACHABLE();
- return false;
+ break;
}
default:
UNREACHABLE();
- return false;
+ break;
}
- return true;
+ return;
Mads Ager (google) 2012/06/08 09:15:53 Why the explicit return?
Vyacheslav Egorov (Google) 2012/06/08 11:11:13 Done.
}
-void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (TryEmitSmiBinaryOp(compiler, this)) {
- // Operation inlined.
- return;
- }
- // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted
- // for all intended operations.
- Register left = locs()->in(0).reg();
- Register right = locs()->in(1).reg();
+
+static void LoadDoubleOrSmi(FlowGraphCompiler* compiler,
srdjan 2012/06/08 05:18:22 LoadDoubleOrSmiToXMM?
srdjan 2012/06/08 05:18:22 WHy not move it into FlowGraphCompiler and elimina
Vyacheslav Egorov (Google) 2012/06/08 11:11:13 Done.
Vyacheslav Egorov (Google) 2012/06/08 11:11:13 Done.
+ XmmRegister result,
+ Register reg,
+ Register temp,
+ Label* not_double_or_smi) {
+ Label is_smi, done;
+ __ testq(reg, Immediate(kSmiTagMask));
+ __ j(ZERO, &is_smi);
+ __ CompareClassId(reg, kDouble);
+ __ j(NOT_EQUAL, not_double_or_smi);
+ __ movsd(result, FieldAddress(reg, Double::value_offset()));
+ __ jmp(&done);
+ __ Bind(&is_smi);
+ __ movq(temp, reg);
+ __ SmiUntag(temp);
+ __ cvtsi2sd(result, temp);
+ __ Bind(&done);
+}
+
+
+
+static bool EmitDoubleBinaryOp(FlowGraphCompiler* compiler,
+ BinaryOpComp* comp) {
+ Register left = comp->locs()->in(0).reg();
+ Register right = comp->locs()->in(1).reg();
+ Register temp = comp->locs()->temp(0).reg();
+ Register result = comp->locs()->out().reg();
+
+
+ const Class& double_class =
+ Class::ZoneHandle(Isolate::Current()->object_store()->double_class());
+ const Code& stub =
+ Code::Handle(StubCode::GetAllocationStubForClass(double_class));
+ const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
__ pushq(left);
__ pushq(right);
- InstanceCallComp* instance_call_comp = instance_call();
- instance_call_comp->EmitNativeCode(compiler);
- if (locs()->out().reg() != RAX) {
- __ movq(locs()->out().reg(), RAX);
+ compiler->GenerateCall(comp->instance_call()->token_index(),
+ comp->instance_call()->try_index(),
+ &label,
+ PcDescriptors::kOther);
+ // Newly allocated object is now in result register (RAX).
+ ASSERT(result == RAX);
+ __ popq(right);
+ __ popq(left);
+
+ Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
+ comp->instance_call()->token_index(),
+ comp->instance_call()->try_index(),
+ kDeoptDoubleBinaryOp,
+ left,
+ right);
+
+ LoadDoubleOrSmi(compiler, XMM0, left, temp, deopt);
+ LoadDoubleOrSmi(compiler, XMM1, right, temp, deopt);
+
+ switch (comp->op_kind()) {
+ case Token::kADD: __ addsd(XMM0, XMM1); break;
+ case Token::kSUB: __ subsd(XMM0, XMM1); break;
+ case Token::kMUL: __ mulsd(XMM0, XMM1); break;
+ case Token::kDIV: __ divsd(XMM0, XMM1); break;
+ default: UNREACHABLE();
+ }
+
+ __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
+ return true;
+}
+
+
+void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
+ switch (operands_type()) {
+ case kSmiOperands:
+ EmitSmiBinaryOp(compiler, this);
+ break;
+
+ case kDoubleOperands:
+ EmitDoubleBinaryOp(compiler, this);
+ break;
+
+ default:
+ UNREACHABLE();
}
}
« runtime/vm/intermediate_language.h ('K') | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698