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

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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 17245)
+++ 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;
}
@@ -341,7 +342,7 @@
const Array& kNoArgumentNames = Array::Handle();
const int kNumArgumentsChecked = 2;
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label check_identity;
__ cmpl(Address(ESP, 0 * kWordSize), raw_null);
@@ -527,7 +528,7 @@
__ testl(left, Immediate(kSmiTagMask));
__ j(ZERO, deopt);
// 'left' is not Smi.
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label identity_compare;
__ cmpl(right, raw_null);
@@ -578,7 +579,7 @@
ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
Register left = locs->in(0).reg();
Register right = locs->in(1).reg();
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label done, identity_compare, non_null_compare;
__ cmpl(right, raw_null);
@@ -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) {
@@ -1151,7 +1152,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());
}
@@ -1165,7 +1166,7 @@
if (class_id() == kExternalUint8ArrayCid) {
Register result = locs()->out().reg();
- Address element_address = index.IsRegister()
+ const Address& element_address = index.IsRegister()
? FlowGraphCompiler::ExternalElementAddressForRegIndex(
class_id(), result, index.reg())
: FlowGraphCompiler::ExternalElementAddressForIntIndex(
@@ -1192,12 +1193,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);
@@ -1271,11 +1272,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();
@@ -1370,12 +1371,12 @@
}
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();
@@ -1585,7 +1586,7 @@
Label type_arguments_instantiated;
const intptr_t len = type_arguments().Length();
if (type_arguments().IsRawInstantiatedRaw(len)) {
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ cmpl(instantiator_reg, raw_null);
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
@@ -1648,7 +1649,7 @@
Label type_arguments_instantiated;
const intptr_t len = type_arguments().Length();
if (type_arguments().IsRawInstantiatedRaw(len)) {
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ cmpl(instantiator_reg, raw_null);
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
@@ -1662,7 +1663,7 @@
Label type_arguments_uninstantiated;
__ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
__ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
- Immediate arguments_length =
+ const Immediate& arguments_length =
Immediate(Smi::RawValue(type_arguments().Length()));
__ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
arguments_length);
@@ -1704,7 +1705,7 @@
Label done;
const intptr_t len = type_arguments().Length();
if (type_arguments().IsRawInstantiatedRaw(len)) {
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label instantiator_not_null;
__ cmpl(instantiator_reg, raw_null);
@@ -1730,7 +1731,7 @@
// instantiator will have the wrong class (Null instead of TypeArguments).
__ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
__ j(NOT_EQUAL, &done, Assembler::kNearJump);
- Immediate arguments_length =
+ const Immediate& arguments_length =
Immediate(Smi::RawValue(type_arguments().Length()));
__ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
arguments_length);
@@ -2164,7 +2165,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;
}
@@ -2207,7 +2208,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(),
@@ -2226,7 +2227,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;
}
@@ -2234,7 +2235,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()));
@@ -2244,7 +2245,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);
@@ -2257,18 +2258,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;
@@ -2285,14 +2286,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());
}
@@ -2412,7 +2413,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;
}
@@ -2421,7 +2422,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;
@@ -2438,22 +2439,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);
}
}
@@ -2646,7 +2647,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;
}
@@ -2654,7 +2655,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()));
@@ -2690,7 +2691,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.
@@ -2737,7 +2738,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.
@@ -2781,8 +2782,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;
}
@@ -2791,8 +2792,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());
@@ -2806,10 +2807,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;
@@ -2853,7 +2854,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) {
@@ -2865,9 +2866,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);
@@ -2881,7 +2882,7 @@
// shrd is undefined with count > operand size (32)
// TODO(fschneider): Support shift counts > 31 without deoptimization.
__ SmiUntag(ECX);
- const Immediate kCountLimit = Immediate(31);
+ const Immediate& kCountLimit = Immediate(31);
__ cmpl(ECX, kCountLimit);
__ j(ABOVE, deopt);
switch (op_kind()) {
@@ -2923,7 +2924,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;
}
@@ -2931,15 +2932,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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698