Index: runtime/vm/intermediate_language_ia32.cc |
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc |
index ea956eec3eb8799aaa4cb445fa2601223f1feb3a..3babd5ea39e9275682ba78fb41cc7939ecb903d0 100644 |
--- a/runtime/vm/intermediate_language_ia32.cc |
+++ b/runtime/vm/intermediate_language_ia32.cc |
@@ -5682,7 +5682,7 @@ LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, |
class BoxIntegerSlowPath : public SlowPathCode { |
public: |
- explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) |
+ explicit BoxIntegerSlowPath(Definition* instruction) |
: instruction_(instruction) { } |
virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
@@ -5709,7 +5709,7 @@ class BoxIntegerSlowPath : public SlowPathCode { |
} |
private: |
- BoxIntegerInstr* instruction_; |
+ Definition* instruction_; |
}; |
@@ -5985,6 +5985,238 @@ void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
+LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
+ bool opt) const { |
+ const intptr_t kNumInputs = 2; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = new(isolate) LocationSummary( |
+ isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_in(1, Location::RequiresRegister()); |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ return summary; |
+} |
+ |
+ |
+void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ Register left = locs()->in(0).reg(); |
+ Register right = locs()->in(1).reg(); |
+ Register out = locs()->out(0).reg(); |
+ ASSERT(out == left); |
+ switch (op_kind()) { |
+ case Token::kBIT_AND: |
+ __ andl(out, right); |
+ break; |
+ case Token::kBIT_OR: |
+ __ orl(out, right); |
+ break; |
+ case Token::kBIT_XOR: |
+ __ xorl(out, right); |
+ break; |
+ case Token::kADD: |
+ __ addl(out, right); |
+ break; |
+ case Token::kSUB: |
+ __ subl(out, right); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
+LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
+ bool opt) const { |
+ const intptr_t kNumInputs = 2; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = new(isolate) LocationSummary( |
+ isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_in(1, Location::RegisterLocation(ECX)); |
Vyacheslav Egorov (Google)
2014/07/07 16:16:03
Please support constant operand as well. They are
Cutch
2014/07/07 22:34:28
Done.
|
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ return summary; |
+} |
+ |
+ |
+void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ Register left = locs()->in(0).reg(); |
+ Register shifter = locs()->in(1).reg(); |
+ Register out = locs()->out(0).reg(); |
+ ASSERT(left == out); |
+ ASSERT(shifter == ECX); |
+ |
+ Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); |
+ const Immediate& kCountLimit = Immediate(31); |
+ __ SmiUntag(shifter); |
+ __ cmpl(shifter, kCountLimit); |
+ __ j(ABOVE, deopt); |
Vyacheslav Egorov (Google)
2014/07/07 16:16:04
is there any reason to deopt on shifts that are: 3
Cutch
2014/07/07 22:34:28
Done.
|
+ |
+ switch (op_kind()) { |
+ case Token::kSHR: |
+ __ shrl(left, shifter); |
+ break; |
+ case Token::kSHL: |
+ __ shll(left, shifter); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
+LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
+ bool opt) const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = new(isolate) LocationSummary( |
+ isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ return summary; |
+} |
+ |
+ |
+void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ Register out = locs()->out(0).reg(); |
+ ASSERT(locs()->in(0).reg() == out); |
+ |
+ ASSERT(op_kind() == Token::kBIT_NOT); |
+ |
+ __ notl(out); |
+} |
+ |
+ |
+LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, |
+ bool opt) const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = new(isolate) LocationSummary( |
+ isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_out(0, Location::RequiresRegister()); |
+ return summary; |
+} |
+ |
+ |
+void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); |
+ compiler->AddSlowPathCode(slow_path); |
+ Register value = locs()->in(0).reg(); |
+ Register out = locs()->out(0).reg(); |
+ ASSERT(value != out); |
+ |
+ Label not_smi, done; |
+ |
+ // Test if this value is <= kSmiMax. |
+ __ cmpl(value, Immediate(kSmiMax)); |
+ __ j(ABOVE, ¬_smi); |
+ // Smi. |
+ __ movl(out, value); |
+ __ SmiTag(out); |
+ __ jmp(&done); |
+ __ Bind(¬_smi); |
+ // Allocate a mint. |
+ __ TryAllocate( |
+ Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), |
+ slow_path->entry_label(), |
+ Assembler::kFarJump, |
+ out, |
+ kNoRegister); |
+ __ Bind(slow_path->exit_label()); |
+ // Copy low word into mint. |
+ __ movl(FieldAddress(out, Mint::value_offset()), value); |
+ // Zero high word. |
+ __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); |
+ __ Bind(&done); |
+} |
+ |
+ |
+LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, |
+ bool opt) const { |
+ const intptr_t value_cid = value()->Type()->ToCid(); |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = |
+ ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; |
+ LocationSummary* summary = new(isolate) LocationSummary( |
+ isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ if (kNumTemps > 0) { |
+ summary->set_temp(0, Location::RequiresRegister()); |
+ } |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ return summary; |
+} |
+ |
+ |
+void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ const intptr_t value_cid = value()->Type()->ToCid(); |
+ const Register value = locs()->in(0).reg(); |
+ ASSERT(value == locs()->out(0).reg()); |
+ |
+ // TODO(johnmccutchan): Emit better code for constant inputs. |
+ if (value_cid == kMintCid) { |
+ __ movl(value, FieldAddress(value, Mint::value_offset())); |
+ } else if (value_cid == kSmiCid) { |
+ __ SmiUntag(value); |
+ } else { |
+ Register temp = locs()->temp(0).reg(); |
+ Label* deopt = compiler->AddDeoptStub(deopt_id_, |
+ ICData::kDeoptUnboxInteger); |
+ Label is_smi, done; |
+ __ testl(value, Immediate(kSmiTagMask)); |
+ __ j(ZERO, &is_smi); |
+ __ CompareClassId(value, kMintCid, temp); |
+ __ j(NOT_EQUAL, deopt); |
+ __ movl(value, FieldAddress(value, Mint::value_offset())); |
+ __ jmp(&done); |
+ __ Bind(&is_smi); |
+ __ SmiUntag(value); |
+ __ Bind(&done); |
+ } |
+} |
+ |
+ |
+LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
+ bool opt) const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = new(isolate) LocationSummary( |
+ isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ if (from() == kUnboxedMint) { |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ summary->set_out(0, Location::RequiresRegister()); |
+ } else { |
+ ASSERT(from() == kUnboxedUint32); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ return summary; |
+} |
+ |
+ |
+void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ if (from() == kUnboxedMint) { |
+ PairLocation* in_pair = locs()->in(0).AsPairLocation(); |
+ Register in_lo = in_pair->At(0).reg(); |
+ Register out = locs()->out(0).reg(); |
+ // Copy low word. |
+ __ movl(out, in_lo); |
+ } else { |
+ ASSERT(from() == kUnboxedUint32); |
+ Register in = locs()->in(0).reg(); |
+ PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
+ Register out_lo = out_pair->At(0).reg(); |
+ Register out_hi = out_pair->At(1).reg(); |
+ // Copy low word. |
+ __ movl(out_lo, in); |
+ // Zero upper word. |
+ __ xorl(out_hi, out_hi); |
+ } |
+} |
+ |
+ |
LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, |
bool opt) const { |
return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); |