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

Unified Diff: runtime/vm/flow_graph_compiler_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/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_x64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_compiler_ia32.cc
===================================================================
--- runtime/vm/flow_graph_compiler_ia32.cc (revision 17245)
+++ runtime/vm/flow_graph_compiler_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.
@@ -26,6 +26,16 @@
DECLARE_FLAG(bool, print_scopes);
+FlowGraphCompiler::~FlowGraphCompiler() {
+ // BlockInfos are zone-allocated, so their destructors are not called.
+ // Verify the labels explicitly here.
+ for (int i = 0; i < block_info_.length(); ++i) {
+ ASSERT(!block_info_[i]->label.IsLinked());
+ ASSERT(!block_info_[i]->label.HasNear());
+ }
+}
+
+
bool FlowGraphCompiler::SupportsUnboxedMints() {
// Support unboxed mints when SSE 4.1 is available.
return FLAG_unbox_mints && CPUFeatures::sse4_1_supported();
@@ -57,7 +67,7 @@
void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
Label* is_true,
Label* is_false) {
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label fall_through;
__ cmpl(bool_register, raw_null);
@@ -79,7 +89,7 @@
Label* is_not_instance_lbl) {
const SubtypeTestCache& type_test_cache =
SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ LoadObject(temp_reg, type_test_cache);
__ pushl(temp_reg); // Subtype test cache.
@@ -227,7 +237,7 @@
}
if (type.IsFunctionType()) {
// Check if instance is a closure.
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ LoadClassById(EDI, kClassIdReg);
__ movl(EDI, FieldAddress(EDI, Class::signature_function_offset()));
@@ -294,7 +304,7 @@
__ Comment("UninstantiatedTypeTest");
ASSERT(!type.IsInstantiated());
// Skip check if destination is a dynamic type.
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
if (type.IsTypeParameter()) {
const TypeParameter& type_param = TypeParameter::Cast(type);
@@ -454,7 +464,7 @@
LocationSummary* locs) {
ASSERT(type.IsFinalized() && !type.IsMalformed());
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label is_instance, is_not_instance;
__ pushl(ECX); // Store instantiator on stack.
@@ -543,7 +553,7 @@
__ pushl(ECX); // Store instantiator.
__ pushl(EDX); // Store instantiator type arguments.
// A null object is always assignable and is returned as result.
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label is_assignable, runtime_call;
__ cmpl(EAX, raw_null);
@@ -675,7 +685,7 @@
__ j(POSITIVE, &loop, Assembler::kNearJump);
// Copy or initialize optional named arguments.
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label all_arguments_processed;
if (num_opt_named_params > 0) {
@@ -857,7 +867,7 @@
__ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver.
__ movl(EBX, Address(ESP, 1 * kWordSize)); // Value.
__ StoreIntoObject(EAX, FieldAddress(EAX, offset), EBX);
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ movl(EAX, raw_null);
__ ret();
@@ -1012,7 +1022,7 @@
if (!is_optimizing() && (num_locals > 0)) {
__ Comment("Initialize spill slots");
const intptr_t slot_base = parsed_function().first_stack_local_index();
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ movl(EAX, raw_null);
for (intptr_t i = 0; i < num_locals; ++i) {
@@ -1267,7 +1277,7 @@
// Fallthrough calls super equality.
void FlowGraphCompiler::EmitSuperEqualityCallPrologue(Register result,
Label* skip_call) {
- const Immediate raw_null =
+ const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label check_identity, fall_through;
__ cmpl(Address(ESP, 0 * kWordSize), raw_null);
@@ -1291,7 +1301,7 @@
}
-void FlowGraphCompiler::LoadDoubleOrSmiToXmm(XmmRegister result,
+void FlowGraphCompiler::LoadDoubleOrSmiToFpu(FpuRegister result,
Register reg,
Register temp,
Label* not_double_or_smi) {
@@ -1312,7 +1322,7 @@
void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
// TODO(vegorov): consider saving only caller save (volatile) registers.
- const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
+ const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
if (xmm_regs_count > 0) {
__ subl(ESP, Immediate(xmm_regs_count * kDoubleSize));
// Store XMM registers with the lowest register number at the lowest
@@ -1320,7 +1330,7 @@
intptr_t offset = 0;
for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
- if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
+ if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) {
__ movsd(Address(ESP, offset), xmm_reg);
offset += kDoubleSize;
}
@@ -1349,13 +1359,13 @@
}
}
- const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
+ const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
if (xmm_regs_count > 0) {
// XMM registers have the lowest register number at the lowest address.
intptr_t offset = 0;
for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
- if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
+ if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) {
__ movsd(xmm_reg, Address(ESP, offset));
offset += kDoubleSize;
}
@@ -1366,6 +1376,184 @@
}
+void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
+ Register class_id_reg,
+ intptr_t arg_count,
+ const Array& arg_names,
+ Label* deopt,
+ intptr_t deopt_id,
+ intptr_t token_index,
+ LocationSummary* locs) {
+ ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
+ Label match_found;
+ const intptr_t len = ic_data.NumberOfChecks();
+ GrowableArray<CidTarget> sorted(len);
+ SortICDataByCount(ic_data, &sorted);
+ for (intptr_t i = 0; i < len; i++) {
+ const bool is_last_check = (i == (len - 1));
+ Label next_test;
+ assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid));
+ if (is_last_check) {
+ assembler()->j(NOT_EQUAL, deopt);
+ } else {
+ assembler()->j(NOT_EQUAL, &next_test);
+ }
+ GenerateStaticCall(deopt_id,
+ token_index,
+ *sorted[i].target,
+ arg_count,
+ arg_names,
+ locs);
+ if (!is_last_check) {
+ assembler()->jmp(&match_found);
+ }
+ assembler()->Bind(&next_test);
+ }
+ assembler()->Bind(&match_found);
+}
+
+
+void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition,
+ FpuRegister left,
+ FpuRegister right,
+ BranchInstr* branch) {
+ ASSERT(branch != NULL);
+ assembler()->comisd(left, right);
+ BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ?
+ branch->true_successor() : branch->false_successor();
+ assembler()->j(PARITY_EVEN, GetBlockLabel(nan_result));
+ branch->EmitBranchOnCondition(this, true_condition);
+}
+
+
+
+void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition,
+ FpuRegister left,
+ FpuRegister right,
+ Register result) {
+ assembler()->comisd(left, right);
+ Label is_false, is_true, done;
+ assembler()->j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN false;
+ assembler()->j(true_condition, &is_true, Assembler::kNearJump);
+ assembler()->Bind(&is_false);
+ assembler()->LoadObject(result, Bool::False());
+ assembler()->jmp(&done);
+ assembler()->Bind(&is_true);
+ assembler()->LoadObject(result, Bool::True());
+ assembler()->Bind(&done);
+}
+
+
+Condition FlowGraphCompiler::FlipCondition(Condition condition) {
+ switch (condition) {
+ case EQUAL: return EQUAL;
+ case NOT_EQUAL: return NOT_EQUAL;
+ case LESS: return GREATER;
+ case LESS_EQUAL: return GREATER_EQUAL;
+ case GREATER: return LESS;
+ case GREATER_EQUAL: return LESS_EQUAL;
+ case BELOW: return ABOVE;
+ case BELOW_EQUAL: return ABOVE_EQUAL;
+ case ABOVE: return BELOW;
+ case ABOVE_EQUAL: return BELOW_EQUAL;
+ default:
+ UNIMPLEMENTED();
+ return EQUAL;
+ }
+}
+
+
+bool FlowGraphCompiler::EvaluateCondition(Condition condition,
+ intptr_t left,
+ intptr_t right) {
+ const uintptr_t unsigned_left = static_cast<uintptr_t>(left);
+ const uintptr_t unsigned_right = static_cast<uintptr_t>(right);
+ switch (condition) {
+ case EQUAL: return left == right;
+ case NOT_EQUAL: return left != right;
+ case LESS: return left < right;
+ case LESS_EQUAL: return left <= right;
+ case GREATER: return left > right;
+ case GREATER_EQUAL: return left >= right;
+ case BELOW: return unsigned_left < unsigned_right;
+ case BELOW_EQUAL: return unsigned_left <= unsigned_right;
+ case ABOVE: return unsigned_left > unsigned_right;
+ case ABOVE_EQUAL: return unsigned_left >= unsigned_right;
+ default:
+ UNIMPLEMENTED();
+ return false;
+ }
+}
+
+
+FieldAddress FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
+ Register array,
+ intptr_t index) {
+ const int64_t disp =
+ static_cast<int64_t>(index) * ElementSizeFor(cid) + DataOffsetFor(cid);
+ ASSERT(Utils::IsInt(32, disp));
+ return FieldAddress(array, static_cast<int32_t>(disp));
+}
+
+
+FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
+ Register array,
+ Register index) {
+ // Note that index is smi-tagged, (i.e, times 2) for all arrays with element
+ // size > 1. For Uint8Array and OneByteString the index is expected to be
+ // untagged before accessing.
+ ASSERT(kSmiTagShift == 1);
+ switch (cid) {
+ case kArrayCid:
+ case kImmutableArrayCid:
+ return FieldAddress(
+ array, index, TIMES_HALF_WORD_SIZE, Array::data_offset());
+ case kFloat32ArrayCid:
+ return FieldAddress(array, index, TIMES_2, Float32Array::data_offset());
+ case kFloat64ArrayCid:
+ return FieldAddress(array, index, TIMES_4, Float64Array::data_offset());
+ case kInt8ArrayCid:
+ return FieldAddress(array, index, TIMES_1, Int8Array::data_offset());
+ case kUint8ArrayCid:
+ return FieldAddress(array, index, TIMES_1, Uint8Array::data_offset());
+ case kUint8ClampedArrayCid:
+ return
+ FieldAddress(array, index, TIMES_1, Uint8ClampedArray::data_offset());
+ case kInt16ArrayCid:
+ return FieldAddress(array, index, TIMES_1, Int16Array::data_offset());
+ case kUint16ArrayCid:
+ return FieldAddress(array, index, TIMES_1, Uint16Array::data_offset());
+ case kOneByteStringCid:
+ return FieldAddress(array, index, TIMES_1, OneByteString::data_offset());
+ case kTwoByteStringCid:
+ return FieldAddress(array, index, TIMES_1, TwoByteString::data_offset());
+ default:
+ UNIMPLEMENTED();
+ return FieldAddress(SPREG, 0);
+ }
+}
+
+
+Address FlowGraphCompiler::ExternalElementAddressForIntIndex(intptr_t cid,
+ Register array,
+ intptr_t index) {
+ return Address(array, index * ElementSizeFor(cid));
+}
+
+
+Address FlowGraphCompiler::ExternalElementAddressForRegIndex(intptr_t cid,
+ Register array,
+ Register index) {
+ switch (cid) {
+ case kExternalUint8ArrayCid:
+ return Address(array, index, TIMES_1, 0);
+ default:
+ UNIMPLEMENTED();
+ return Address(SPREG, 0);
+ }
+}
+
+
#undef __
#define __ compiler_->assembler()->
@@ -1390,18 +1578,18 @@
MoveMemoryToMemory(destination.ToStackSlotAddress(),
source.ToStackSlotAddress());
}
- } else if (source.IsXmmRegister()) {
- if (destination.IsXmmRegister()) {
+ } else if (source.IsFpuRegister()) {
+ if (destination.IsFpuRegister()) {
// Optimization manual recommends using MOVAPS for register
// to register moves.
- __ movaps(destination.xmm_reg(), source.xmm_reg());
+ __ movaps(destination.fpu_reg(), source.fpu_reg());
} else {
ASSERT(destination.IsDoubleStackSlot());
- __ movsd(destination.ToStackSlotAddress(), source.xmm_reg());
+ __ movsd(destination.ToStackSlotAddress(), source.fpu_reg());
}
} else if (source.IsDoubleStackSlot()) {
- if (destination.IsXmmRegister()) {
- __ movsd(destination.xmm_reg(), source.ToStackSlotAddress());
+ if (destination.IsFpuRegister()) {
+ __ movsd(destination.fpu_reg(), source.ToStackSlotAddress());
} else {
ASSERT(destination.IsDoubleStackSlot());
__ movsd(XMM0, source.ToStackSlotAddress());
@@ -1439,15 +1627,15 @@
Exchange(destination.reg(), source.ToStackSlotAddress());
} else if (source.IsStackSlot() && destination.IsStackSlot()) {
Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress());
- } else if (source.IsXmmRegister() && destination.IsXmmRegister()) {
- __ movaps(XMM0, source.xmm_reg());
- __ movaps(source.xmm_reg(), destination.xmm_reg());
- __ movaps(destination.xmm_reg(), XMM0);
- } else if (source.IsXmmRegister() || destination.IsXmmRegister()) {
+ } else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
+ __ movaps(XMM0, source.fpu_reg());
+ __ movaps(source.fpu_reg(), destination.fpu_reg());
+ __ movaps(destination.fpu_reg(), XMM0);
+ } else if (source.IsFpuRegister() || destination.IsFpuRegister()) {
ASSERT(destination.IsDoubleStackSlot() || source.IsDoubleStackSlot());
- XmmRegister reg = source.IsXmmRegister() ? source.xmm_reg()
- : destination.xmm_reg();
- Address slot_address = source.IsXmmRegister()
+ XmmRegister reg = source.IsFpuRegister() ? source.fpu_reg()
+ : destination.fpu_reg();
+ const Address& slot_address = source.IsFpuRegister()
? destination.ToStackSlotAddress()
: source.ToStackSlotAddress();
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698