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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 11956004: Fix vm code base so that it can be built for --arch=simarm (no snapshot yet). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 17107)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -8,6 +8,7 @@
#include "vm/intermediate_language.h"
#include "lib/error.h"
+#include "vm/dart_entry.h"
#include "vm/flow_graph_compiler.h"
#include "vm/locations.h"
#include "vm/object_store.h"
@@ -267,8 +268,8 @@
const intptr_t kNumTemps = 1;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RequiresXmmRegister());
- locs->set_in(1, Location::RequiresXmmRegister());
+ locs->set_in(0, Location::RequiresFpuRegister());
+ locs->set_in(1, Location::RequiresFpuRegister());
locs->set_temp(0, Location::RequiresRegister());
locs->set_out(Location::RequiresRegister());
return locs;
@@ -277,8 +278,8 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RequiresXmmRegister());
- locs->set_in(1, Location::RequiresXmmRegister());
+ locs->set_in(0, Location::RequiresFpuRegister());
+ locs->set_in(1, Location::RequiresFpuRegister());
locs->set_out(Location::RequiresRegister());
return locs;
}
@@ -664,8 +665,8 @@
Token::Kind kind,
BranchInstr* branch) {
ASSERT(Token::IsEqualityOperator(kind));
- XmmRegister left = locs.in(0).xmm_reg();
- XmmRegister right = locs.in(1).xmm_reg();
+ XmmRegister left = locs.in(0).fpu_reg();
+ XmmRegister right = locs.in(1).fpu_reg();
Register temp = locs.temp(0).reg();
__ movaps(XMM0, left);
__ pcmpeqq(XMM0, right);
@@ -693,8 +694,8 @@
const LocationSummary& locs,
Token::Kind kind,
BranchInstr* branch) {
- XmmRegister left = locs.in(0).xmm_reg();
- XmmRegister right = locs.in(1).xmm_reg();
+ XmmRegister left = locs.in(0).fpu_reg();
+ XmmRegister right = locs.in(1).fpu_reg();
Register left_tmp = locs.temp(0).reg();
Register right_tmp = locs.temp(1).reg();
Register result = branch == NULL ? locs.out().reg() : kNoRegister;
@@ -773,8 +774,8 @@
const LocationSummary& locs,
Token::Kind kind,
BranchInstr* branch) {
- XmmRegister left = locs.in(0).xmm_reg();
- XmmRegister right = locs.in(1).xmm_reg();
+ XmmRegister left = locs.in(0).fpu_reg();
+ XmmRegister right = locs.in(1).fpu_reg();
Condition true_condition = TokenKindToDoubleCondition(kind);
if (branch != NULL) {
@@ -883,8 +884,8 @@
const intptr_t kNumTemps = 2;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RequiresXmmRegister());
- locs->set_in(1, Location::RequiresXmmRegister());
+ locs->set_in(0, Location::RequiresFpuRegister());
+ locs->set_in(1, Location::RequiresFpuRegister());
locs->set_temp(0, Location::RequiresRegister());
locs->set_temp(1, Location::RequiresRegister());
locs->set_out(Location::RequiresRegister());
@@ -893,8 +894,8 @@
if (operands_class_id() == kDoubleCid) {
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresXmmRegister());
- summary->set_in(1, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
summary->set_out(Location::RequiresRegister());
return summary;
} else if (operands_class_id() == kSmiCid) {
@@ -1145,7 +1146,7 @@
? Location::RegisterOrSmiConstant(index())
: Location::RequiresRegister());
if (representation() == kUnboxedDouble) {
- locs->set_out(Location::RequiresXmmRegister());
+ locs->set_out(Location::RequiresFpuRegister());
} else {
locs->set_out(Location::RequiresRegister());
}
@@ -1184,12 +1185,12 @@
class_id(), array, Smi::Cast(index.constant()).Value());
if (representation() == kUnboxedDouble) {
- XmmRegister result = locs()->out().xmm_reg();
+ XmmRegister result = locs()->out().fpu_reg();
if (class_id() == kFloat32ArrayCid) {
// Load single precision float.
__ movss(result, element_address);
// Promote to double.
- __ cvtss2sd(result, locs()->out().xmm_reg());
+ __ cvtss2sd(result, locs()->out().fpu_reg());
} else {
ASSERT(class_id() == kFloat64ArrayCid);
__ movsd(result, element_address);
@@ -1238,11 +1239,11 @@
break;
case kFloat32ArrayCid:
// Need temp register for float-to-double conversion.
- locs->AddTemp(Location::RequiresXmmRegister());
+ locs->AddTemp(Location::RequiresFpuRegister());
// Fall through.
case kFloat64ArrayCid:
// TODO(srdjan): Support Float64 constants.
- locs->set_in(2, Location::RequiresXmmRegister());
+ locs->set_in(2, Location::RequiresFpuRegister());
break;
default:
UNREACHABLE();
@@ -1294,12 +1295,12 @@
break;
case kFloat32ArrayCid:
// Convert to single precision.
- __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg());
+ __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
// Store.
- __ movss(element_address, locs()->temp(0).xmm_reg());
+ __ movss(element_address, locs()->temp(0).fpu_reg());
break;
case kFloat64ArrayCid:
- __ movsd(element_address, locs()->in(2).xmm_reg());
+ __ movsd(element_address, locs()->in(2).fpu_reg());
break;
default:
UNREACHABLE();
@@ -2088,7 +2089,7 @@
new LocationSummary(kNumInputs,
kNumTemps,
LocationSummary::kCallOnSlowPath);
- summary->set_in(0, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
summary->set_out(Location::RequiresRegister());
return summary;
}
@@ -2131,7 +2132,7 @@
compiler->AddSlowPathCode(slow_path);
Register out_reg = locs()->out().reg();
- XmmRegister value = locs()->in(0).xmm_reg();
+ XmmRegister value = locs()->in(0).fpu_reg();
AssemblerMacros::TryAllocate(compiler->assembler(),
compiler->double_class(),
@@ -2150,7 +2151,7 @@
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister());
- summary->set_out(Location::RequiresXmmRegister());
+ summary->set_out(Location::RequiresFpuRegister());
return summary;
}
@@ -2158,7 +2159,7 @@
void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const intptr_t value_cid = value()->ResultCid();
const Register value = locs()->in(0).reg();
- const XmmRegister result = locs()->out().xmm_reg();
+ const XmmRegister result = locs()->out().fpu_reg();
if (value_cid == kDoubleCid) {
__ movsd(result, FieldAddress(value, Double::value_offset()));
@@ -2168,7 +2169,7 @@
__ SmiTag(value); // Restore input register.
} else {
Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
- compiler->LoadDoubleOrSmiToXmm(result,
+ compiler->LoadDoubleOrSmiToFpu(result,
value,
locs()->temp(0).reg(),
deopt);
@@ -2181,18 +2182,18 @@
const intptr_t kNumTemps = 0;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresXmmRegister());
- summary->set_in(1, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
summary->set_out(Location::SameAsFirstInput());
return summary;
}
void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister left = locs()->in(0).xmm_reg();
- XmmRegister right = locs()->in(1).xmm_reg();
+ XmmRegister left = locs()->in(0).fpu_reg();
+ XmmRegister right = locs()->in(1).fpu_reg();
- ASSERT(locs()->out().xmm_reg() == left);
+ ASSERT(locs()->out().fpu_reg() == left);
switch (op_kind()) {
case Token::kADD: __ addsd(left, right); break;
@@ -2209,14 +2210,14 @@
const intptr_t kNumTemps = 0;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresXmmRegister());
- summary->set_out(Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_out(Location::RequiresFpuRegister());
return summary;
}
void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- __ sqrtsd(locs()->out().xmm_reg(), locs()->in(0).xmm_reg());
+ __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
}
@@ -2336,7 +2337,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* result = new LocationSummary(
kNumInputs, kNumTemps, LocationSummary::kNoCall);
- result->set_in(0, Location::RequiresXmmRegister());
+ result->set_in(0, Location::RequiresFpuRegister());
result->set_out(Location::RequiresRegister());
return result;
}
@@ -2345,7 +2346,7 @@
void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
Register result = locs()->out().reg();
- XmmRegister value = locs()->in(0).xmm_reg();
+ XmmRegister value = locs()->in(0).fpu_reg();
__ cvttsd2si(result, value);
// Overflow is signalled with minint.
Label do_call, done;
@@ -2362,22 +2363,22 @@
(recognized_kind() == MethodRecognizer::kDoubleRound) ? 1 : 0;
LocationSummary* result =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- result->set_in(0, Location::RequiresXmmRegister());
- result->set_out(Location::RequiresXmmRegister());
+ result->set_in(0, Location::RequiresFpuRegister());
+ result->set_out(Location::RequiresFpuRegister());
if (recognized_kind() == MethodRecognizer::kDoubleRound) {
- result->set_temp(0, Location::RequiresXmmRegister());
+ result->set_temp(0, Location::RequiresFpuRegister());
}
return result;
}
void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister value = locs()->in(0).xmm_reg();
- XmmRegister result = locs()->out().xmm_reg();
+ XmmRegister value = locs()->in(0).fpu_reg();
+ XmmRegister result = locs()->out().fpu_reg();
if (recognized_kind() == MethodRecognizer::kDoubleTruncate) {
__ roundsd(result, value, Assembler::kRoundToZero);
} else {
- XmmRegister temp = locs()->temp(0).xmm_reg();
+ XmmRegister temp = locs()->temp(0).fpu_reg();
__ DoubleRound(result, value, temp);
}
}
@@ -2570,7 +2571,7 @@
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister());
- summary->set_out(Location::RequiresXmmRegister());
+ summary->set_out(Location::RequiresFpuRegister());
return summary;
}
@@ -2578,7 +2579,7 @@
void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const intptr_t value_cid = value()->ResultCid();
const Register value = locs()->in(0).reg();
- const XmmRegister result = locs()->out().xmm_reg();
+ const XmmRegister result = locs()->out().fpu_reg();
if (value_cid == kMintCid) {
__ movsd(result, FieldAddress(value, Mint::value_offset()));
@@ -2614,7 +2615,7 @@
new LocationSummary(kNumInputs,
kNumTemps,
LocationSummary::kCallOnSlowPath);
- summary->set_in(0, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
summary->set_temp(0, Location::RegisterLocation(EAX));
summary->set_temp(1, Location::RegisterLocation(EDX));
// TODO(fschneider): Save one temp by using result register as a temp.
@@ -2661,7 +2662,7 @@
compiler->AddSlowPathCode(slow_path);
Register out_reg = locs()->out().reg();
- XmmRegister value = locs()->in(0).xmm_reg();
+ XmmRegister value = locs()->in(0).fpu_reg();
// Unboxed operations produce smis or mint-sized values.
// Check if value fits into a smi.
@@ -2705,8 +2706,8 @@
const intptr_t kNumTemps = 0;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresXmmRegister());
- summary->set_in(1, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
summary->set_out(Location::SameAsFirstInput());
return summary;
}
@@ -2715,8 +2716,8 @@
const intptr_t kNumTemps = 2;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresXmmRegister());
- summary->set_in(1, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
summary->set_temp(0, Location::RequiresRegister());
summary->set_temp(1, Location::RequiresRegister());
summary->set_out(Location::SameAsFirstInput());
@@ -2730,10 +2731,10 @@
void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister left = locs()->in(0).xmm_reg();
- XmmRegister right = locs()->in(1).xmm_reg();
+ XmmRegister left = locs()->in(0).fpu_reg();
+ XmmRegister right = locs()->in(1).fpu_reg();
- ASSERT(locs()->out().xmm_reg() == left);
+ ASSERT(locs()->out().fpu_reg() == left);
switch (op_kind()) {
case Token::kBIT_AND: __ andpd(left, right); break;
@@ -2777,7 +2778,7 @@
const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
summary->set_in(1, Location::RegisterLocation(ECX));
summary->set_temp(0, Location::RequiresRegister());
if (op_kind() == Token::kSHL) {
@@ -2789,9 +2790,9 @@
void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister left = locs()->in(0).xmm_reg();
+ XmmRegister left = locs()->in(0).fpu_reg();
ASSERT(locs()->in(1).reg() == ECX);
- ASSERT(locs()->out().xmm_reg() == left);
+ ASSERT(locs()->out().fpu_reg() == left);
Label* deopt = compiler->AddDeoptStub(deopt_id(),
kDeoptShiftMintOp);
@@ -2847,7 +2848,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresXmmRegister());
+ summary->set_in(0, Location::RequiresFpuRegister());
summary->set_out(Location::SameAsFirstInput());
return summary;
}
@@ -2855,15 +2856,326 @@
void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(op_kind() == Token::kBIT_NOT);
- XmmRegister value = locs()->in(0).xmm_reg();
- ASSERT(value == locs()->out().xmm_reg());
+ XmmRegister value = locs()->in(0).fpu_reg();
+ ASSERT(value == locs()->out().fpu_reg());
__ pcmpeqq(XMM0, XMM0); // Generate all 1's.
__ pxor(value, XMM0);
}
+LocationSummary* ThrowInstr::MakeLocationSummary() const {
+ return new LocationSummary(0, 0, LocationSummary::kCall);
+}
+
+
+
+void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ compiler->GenerateCallRuntime(token_pos(),
+ kThrowRuntimeEntry,
+ locs());
+ __ int3();
+}
+
+
+LocationSummary* ReThrowInstr::MakeLocationSummary() const {
+ return new LocationSummary(0, 0, LocationSummary::kCall);
+}
+
+
+void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ compiler->GenerateCallRuntime(token_pos(),
+ kReThrowRuntimeEntry,
+ locs());
+ __ int3();
+}
+
+
+LocationSummary* GotoInstr::MakeLocationSummary() const {
+ return new LocationSummary(0, 0, LocationSummary::kNoCall);
+}
+
+
+void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ // Add deoptimization descriptor for deoptimizing instructions
+ // that may be inserted before this instruction.
+ if (!compiler->is_optimizing()) {
+ compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
+ GetDeoptId(),
+ 0); // No token position.
+ }
+
+ if (HasParallelMove()) {
+ compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
+ }
+
+ // We can fall through if the successor is the next block in the list.
+ // Otherwise, we need a jump.
+ if (!compiler->IsNextBlock(successor())) {
+ __ jmp(compiler->GetBlockLabel(successor()));
+ }
+}
+
+
+static Condition NegateCondition(Condition condition) {
+ switch (condition) {
+ case EQUAL: return NOT_EQUAL;
+ case NOT_EQUAL: return EQUAL;
+ case LESS: return GREATER_EQUAL;
+ case LESS_EQUAL: return GREATER;
+ case GREATER: return LESS_EQUAL;
+ case GREATER_EQUAL: return LESS;
+ case BELOW: return ABOVE_EQUAL;
+ case BELOW_EQUAL: return ABOVE;
+ case ABOVE: return BELOW_EQUAL;
+ case ABOVE_EQUAL: return BELOW;
+ default:
+ OS::Print("Error %d\n", condition);
+ UNIMPLEMENTED();
+ return EQUAL;
+ }
+}
+
+
+void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
+ bool value) {
+ if (value && compiler->IsNextBlock(false_successor())) {
+ __ jmp(compiler->GetBlockLabel(true_successor()));
+ } else if (!value && compiler->IsNextBlock(true_successor())) {
+ __ jmp(compiler->GetBlockLabel(false_successor()));
+ }
+}
+
+
+void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
+ Condition true_condition) {
+ if (compiler->IsNextBlock(false_successor())) {
+ // If the next block is the false successor we will fall through to it.
+ __ j(true_condition, compiler->GetBlockLabel(true_successor()));
+ } else {
+ // If the next block is the true successor we negate comparison and fall
+ // through to it.
+ ASSERT(compiler->IsNextBlock(true_successor()));
+ Condition false_condition = NegateCondition(true_condition);
+ __ j(false_condition, compiler->GetBlockLabel(false_successor()));
+ }
+}
+
+
+LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
+ return LocationSummary::Make(0,
+ Location::RequiresRegister(),
+ LocationSummary::kNoCall);
+}
+
+
+void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ __ MoveRegister(locs()->out().reg(), CTX);
+}
+
+
+LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* locs =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(1, Location::RegisterOrConstant(right()));
+ locs->set_out(Location::RequiresRegister());
+ return locs;
+}
+
+
+// Special code for numbers (compare values instead of references.)
+void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
+ Location left = locs()->in(0);
+ Location right = locs()->in(1);
+ if (left.IsConstant() && right.IsConstant()) {
+ // TODO(vegorov): should be eliminated earlier by constant propagation.
+ const bool result = (kind() == Token::kEQ_STRICT) ?
+ left.constant().raw() == right.constant().raw() :
+ left.constant().raw() != right.constant().raw();
+ __ LoadObject(locs()->out().reg(), result ? Bool::True() : Bool::False());
+ return;
+ }
+ if (left.IsConstant()) {
+ compiler->EmitEqualityRegConstCompare(right.reg(),
+ left.constant(),
+ needs_number_check());
+ } else if (right.IsConstant()) {
+ compiler->EmitEqualityRegConstCompare(left.reg(),
+ right.constant(),
+ needs_number_check());
+ } else {
+ compiler->EmitEqualityRegRegCompare(left.reg(),
+ right.reg(),
+ needs_number_check());
+ }
+
+ Register result = locs()->out().reg();
+ Label load_true, done;
+ Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+ __ j(true_condition, &load_true, Assembler::kNearJump);
+ __ LoadObject(result, Bool::False());
+ __ jmp(&done, Assembler::kNearJump);
+ __ Bind(&load_true);
+ __ LoadObject(result, Bool::True());
+ __ Bind(&done);
+}
+
+
+void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+ BranchInstr* branch) {
+ ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
+ Location left = locs()->in(0);
+ Location right = locs()->in(1);
+ if (left.IsConstant() && right.IsConstant()) {
+ // TODO(vegorov): should be eliminated earlier by constant propagation.
+ const bool result = (kind() == Token::kEQ_STRICT) ?
+ left.constant().raw() == right.constant().raw() :
+ left.constant().raw() != right.constant().raw();
+ branch->EmitBranchOnValue(compiler, result);
+ return;
+ }
+ if (left.IsConstant()) {
+ compiler->EmitEqualityRegConstCompare(right.reg(),
+ left.constant(),
+ needs_number_check());
+ } else if (right.IsConstant()) {
+ compiler->EmitEqualityRegConstCompare(left.reg(),
+ right.constant(),
+ needs_number_check());
+ } else {
+ compiler->EmitEqualityRegRegCompare(left.reg(),
+ right.reg(),
+ needs_number_check());
+ }
+
+ Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+ branch->EmitBranchOnCondition(compiler, true_condition);
+}
+
+
+void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ // The arguments to the stub include the closure, as does the arguments
+ // descriptor.
+ Register temp_reg = locs()->temp(0).reg();
+ int argument_count = ArgumentCount();
+ const Array& arguments_descriptor =
+ Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
+ argument_names()));
+ __ LoadObject(temp_reg, arguments_descriptor);
+ compiler->GenerateDartCall(deopt_id(),
+ token_pos(),
+ &StubCode::CallClosureFunctionLabel(),
+ PcDescriptors::kOther,
+ locs());
+ __ Drop(argument_count);
+}
+
+
+LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
+ return LocationSummary::Make(1,
+ Location::RequiresRegister(),
+ LocationSummary::kNoCall);
+}
+
+
+void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Register value = locs()->in(0).reg();
+ Register result = locs()->out().reg();
+
+ Label done;
+ __ LoadObject(result, Bool::True());
+ __ CompareRegisters(result, value);
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+ __ LoadObject(result, Bool::False());
+ __ Bind(&done);
+}
+
+
+LocationSummary* ChainContextInstr::MakeLocationSummary() const {
+ return LocationSummary::Make(1,
+ Location::NoLocation(),
+ LocationSummary::kNoCall);
+}
+
+
+void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Register context_value = locs()->in(0).reg();
+
+ // Chain the new context in context_value to its parent in CTX.
+ __ StoreIntoObject(context_value,
+ FieldAddress(context_value, Context::parent_offset()),
+ CTX);
+ // Set new context as current context.
+ __ MoveRegister(CTX, context_value);
+}
+
+
+LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* locs =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
+ : Location::RequiresRegister());
+ locs->set_in(1, Location::RequiresRegister());
+ return locs;
+}
+
+
+void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Register value_reg = locs()->in(0).reg();
+ Register dest_reg = locs()->in(1).reg();
+
+ if (value()->NeedsStoreBuffer()) {
+ __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
+ value_reg);
+ } else {
+ __ StoreIntoObjectNoBarrier(
+ dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
+ }
+}
+
+
+LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
+ return MakeCallSummary();
+}
+
+
+void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ const Class& cls = Class::ZoneHandle(constructor().Owner());
+ const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
+ const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
+ compiler->GenerateCall(token_pos(),
+ &label,
+ PcDescriptors::kOther,
+ locs());
+ __ Drop(ArgumentCount()); // Discard arguments.
+}
+
+
+LocationSummary* CreateClosureInstr::MakeLocationSummary() const {
+ return MakeCallSummary();
+}
+
+
+void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ const Function& closure_function = function();
+ ASSERT(!closure_function.IsImplicitStaticClosureFunction());
+ const Code& stub = Code::Handle(
+ StubCode::GetAllocationStubForClosure(closure_function));
+ const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
+ compiler->GenerateCall(token_pos(),
+ &label,
+ PcDescriptors::kOther,
+ locs());
+ __ Drop(2); // Discard type arguments and receiver.
+}
+
} // namespace dart
#undef __
-#endif // defined TARGET_ARCH_X64
+#endif // defined TARGET_ARCH_IA32

Powered by Google App Engine
This is Rietveld 408576698