OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 5664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5675 if (!is_smi()) { | 5675 if (!is_smi()) { |
5676 summary->set_temp(0, Location::RequiresRegister()); | 5676 summary->set_temp(0, Location::RequiresRegister()); |
5677 } | 5677 } |
5678 summary->set_out(0, Location::RequiresRegister()); | 5678 summary->set_out(0, Location::RequiresRegister()); |
5679 return summary; | 5679 return summary; |
5680 } | 5680 } |
5681 | 5681 |
5682 | 5682 |
5683 class BoxIntegerSlowPath : public SlowPathCode { | 5683 class BoxIntegerSlowPath : public SlowPathCode { |
5684 public: | 5684 public: |
5685 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) | 5685 explicit BoxIntegerSlowPath(Definition* instruction) |
5686 : instruction_(instruction) { } | 5686 : instruction_(instruction) { } |
5687 | 5687 |
5688 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 5688 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
5689 __ Comment("BoxIntegerSlowPath"); | 5689 __ Comment("BoxIntegerSlowPath"); |
5690 __ Bind(entry_label()); | 5690 __ Bind(entry_label()); |
5691 const Class& mint_class = | 5691 const Class& mint_class = |
5692 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()); | 5692 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()); |
5693 const Code& stub = | 5693 const Code& stub = |
5694 Code::Handle(StubCode::GetAllocationStubForClass(mint_class)); | 5694 Code::Handle(StubCode::GetAllocationStubForClass(mint_class)); |
5695 const ExternalLabel label(stub.EntryPoint()); | 5695 const ExternalLabel label(stub.EntryPoint()); |
5696 | 5696 |
5697 LocationSummary* locs = instruction_->locs(); | 5697 LocationSummary* locs = instruction_->locs(); |
5698 locs->live_registers()->Remove(locs->out(0)); | 5698 locs->live_registers()->Remove(locs->out(0)); |
5699 | 5699 |
5700 compiler->SaveLiveRegisters(locs); | 5700 compiler->SaveLiveRegisters(locs); |
5701 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 5701 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
5702 &label, | 5702 &label, |
5703 PcDescriptors::kOther, | 5703 PcDescriptors::kOther, |
5704 locs); | 5704 locs); |
5705 __ MoveRegister(locs->out(0).reg(), EAX); | 5705 __ MoveRegister(locs->out(0).reg(), EAX); |
5706 compiler->RestoreLiveRegisters(locs); | 5706 compiler->RestoreLiveRegisters(locs); |
5707 | 5707 |
5708 __ jmp(exit_label()); | 5708 __ jmp(exit_label()); |
5709 } | 5709 } |
5710 | 5710 |
5711 private: | 5711 private: |
5712 BoxIntegerInstr* instruction_; | 5712 Definition* instruction_; |
5713 }; | 5713 }; |
5714 | 5714 |
5715 | 5715 |
5716 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5716 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5717 if (is_smi()) { | 5717 if (is_smi()) { |
5718 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | 5718 PairLocation* value_pair = locs()->in(0).AsPairLocation(); |
5719 Register value_lo = value_pair->At(0).reg(); | 5719 Register value_lo = value_pair->At(0).reg(); |
5720 Register out_reg = locs()->out(0).reg(); | 5720 Register out_reg = locs()->out(0).reg(); |
5721 __ movl(out_reg, value_lo); | 5721 __ movl(out_reg, value_lo); |
5722 __ SmiTag(out_reg); | 5722 __ SmiTag(out_reg); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5978 | 5978 |
5979 __ notl(left_lo); | 5979 __ notl(left_lo); |
5980 __ notl(left_hi); | 5980 __ notl(left_hi); |
5981 | 5981 |
5982 if (FLAG_throw_on_javascript_int_overflow) { | 5982 if (FLAG_throw_on_javascript_int_overflow) { |
5983 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 5983 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
5984 } | 5984 } |
5985 } | 5985 } |
5986 | 5986 |
5987 | 5987 |
5988 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
5989 bool opt) const { | |
5990 const intptr_t kNumInputs = 2; | |
5991 const intptr_t kNumTemps = 0; | |
5992 LocationSummary* summary = new(isolate) LocationSummary( | |
5993 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
5994 summary->set_in(0, Location::RequiresRegister()); | |
5995 summary->set_in(1, Location::RequiresRegister()); | |
5996 summary->set_out(0, Location::SameAsFirstInput()); | |
5997 return summary; | |
5998 } | |
5999 | |
6000 | |
6001 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6002 Register left = locs()->in(0).reg(); | |
6003 Register right = locs()->in(1).reg(); | |
6004 Register out = locs()->out(0).reg(); | |
6005 ASSERT(out == left); | |
6006 switch (op_kind()) { | |
6007 case Token::kBIT_AND: | |
6008 __ andl(out, right); | |
6009 break; | |
6010 case Token::kBIT_OR: | |
6011 __ orl(out, right); | |
6012 break; | |
6013 case Token::kBIT_XOR: | |
6014 __ xorl(out, right); | |
6015 break; | |
6016 case Token::kADD: | |
6017 __ addl(out, right); | |
6018 break; | |
6019 case Token::kSUB: | |
6020 __ subl(out, right); | |
6021 break; | |
6022 default: | |
6023 UNREACHABLE(); | |
6024 } | |
6025 } | |
6026 | |
6027 | |
6028 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
6029 bool opt) const { | |
6030 const intptr_t kNumInputs = 2; | |
6031 const intptr_t kNumTemps = 0; | |
6032 LocationSummary* summary = new(isolate) LocationSummary( | |
6033 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6034 summary->set_in(0, Location::RequiresRegister()); | |
6035 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.
| |
6036 summary->set_out(0, Location::SameAsFirstInput()); | |
6037 return summary; | |
6038 } | |
6039 | |
6040 | |
6041 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6042 Register left = locs()->in(0).reg(); | |
6043 Register shifter = locs()->in(1).reg(); | |
6044 Register out = locs()->out(0).reg(); | |
6045 ASSERT(left == out); | |
6046 ASSERT(shifter == ECX); | |
6047 | |
6048 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); | |
6049 const Immediate& kCountLimit = Immediate(31); | |
6050 __ SmiUntag(shifter); | |
6051 __ cmpl(shifter, kCountLimit); | |
6052 __ 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.
| |
6053 | |
6054 switch (op_kind()) { | |
6055 case Token::kSHR: | |
6056 __ shrl(left, shifter); | |
6057 break; | |
6058 case Token::kSHL: | |
6059 __ shll(left, shifter); | |
6060 break; | |
6061 default: | |
6062 UNREACHABLE(); | |
6063 } | |
6064 } | |
6065 | |
6066 | |
6067 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
6068 bool opt) const { | |
6069 const intptr_t kNumInputs = 1; | |
6070 const intptr_t kNumTemps = 0; | |
6071 LocationSummary* summary = new(isolate) LocationSummary( | |
6072 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6073 summary->set_in(0, Location::RequiresRegister()); | |
6074 summary->set_out(0, Location::SameAsFirstInput()); | |
6075 return summary; | |
6076 } | |
6077 | |
6078 | |
6079 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6080 Register out = locs()->out(0).reg(); | |
6081 ASSERT(locs()->in(0).reg() == out); | |
6082 | |
6083 ASSERT(op_kind() == Token::kBIT_NOT); | |
6084 | |
6085 __ notl(out); | |
6086 } | |
6087 | |
6088 | |
6089 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, | |
6090 bool opt) const { | |
6091 const intptr_t kNumInputs = 1; | |
6092 const intptr_t kNumTemps = 0; | |
6093 LocationSummary* summary = new(isolate) LocationSummary( | |
6094 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
6095 summary->set_in(0, Location::RequiresRegister()); | |
6096 summary->set_out(0, Location::RequiresRegister()); | |
6097 return summary; | |
6098 } | |
6099 | |
6100 | |
6101 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6102 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); | |
6103 compiler->AddSlowPathCode(slow_path); | |
6104 Register value = locs()->in(0).reg(); | |
6105 Register out = locs()->out(0).reg(); | |
6106 ASSERT(value != out); | |
6107 | |
6108 Label not_smi, done; | |
6109 | |
6110 // Test if this value is <= kSmiMax. | |
6111 __ cmpl(value, Immediate(kSmiMax)); | |
6112 __ j(ABOVE, ¬_smi); | |
6113 // Smi. | |
6114 __ movl(out, value); | |
6115 __ SmiTag(out); | |
6116 __ jmp(&done); | |
6117 __ Bind(¬_smi); | |
6118 // Allocate a mint. | |
6119 __ TryAllocate( | |
6120 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), | |
6121 slow_path->entry_label(), | |
6122 Assembler::kFarJump, | |
6123 out, | |
6124 kNoRegister); | |
6125 __ Bind(slow_path->exit_label()); | |
6126 // Copy low word into mint. | |
6127 __ movl(FieldAddress(out, Mint::value_offset()), value); | |
6128 // Zero high word. | |
6129 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); | |
6130 __ Bind(&done); | |
6131 } | |
6132 | |
6133 | |
6134 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | |
6135 bool opt) const { | |
6136 const intptr_t value_cid = value()->Type()->ToCid(); | |
6137 const intptr_t kNumInputs = 1; | |
6138 const intptr_t kNumTemps = | |
6139 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; | |
6140 LocationSummary* summary = new(isolate) LocationSummary( | |
6141 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6142 summary->set_in(0, Location::RequiresRegister()); | |
6143 if (kNumTemps > 0) { | |
6144 summary->set_temp(0, Location::RequiresRegister()); | |
6145 } | |
6146 summary->set_out(0, Location::SameAsFirstInput()); | |
6147 return summary; | |
6148 } | |
6149 | |
6150 | |
6151 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6152 const intptr_t value_cid = value()->Type()->ToCid(); | |
6153 const Register value = locs()->in(0).reg(); | |
6154 ASSERT(value == locs()->out(0).reg()); | |
6155 | |
6156 // TODO(johnmccutchan): Emit better code for constant inputs. | |
6157 if (value_cid == kMintCid) { | |
6158 __ movl(value, FieldAddress(value, Mint::value_offset())); | |
6159 } else if (value_cid == kSmiCid) { | |
6160 __ SmiUntag(value); | |
6161 } else { | |
6162 Register temp = locs()->temp(0).reg(); | |
6163 Label* deopt = compiler->AddDeoptStub(deopt_id_, | |
6164 ICData::kDeoptUnboxInteger); | |
6165 Label is_smi, done; | |
6166 __ testl(value, Immediate(kSmiTagMask)); | |
6167 __ j(ZERO, &is_smi); | |
6168 __ CompareClassId(value, kMintCid, temp); | |
6169 __ j(NOT_EQUAL, deopt); | |
6170 __ movl(value, FieldAddress(value, Mint::value_offset())); | |
6171 __ jmp(&done); | |
6172 __ Bind(&is_smi); | |
6173 __ SmiUntag(value); | |
6174 __ Bind(&done); | |
6175 } | |
6176 } | |
6177 | |
6178 | |
6179 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | |
6180 bool opt) const { | |
6181 const intptr_t kNumInputs = 1; | |
6182 const intptr_t kNumTemps = 0; | |
6183 LocationSummary* summary = new(isolate) LocationSummary( | |
6184 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6185 if (from() == kUnboxedMint) { | |
6186 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | |
6187 Location::RequiresRegister())); | |
6188 summary->set_out(0, Location::RequiresRegister()); | |
6189 } else { | |
6190 ASSERT(from() == kUnboxedUint32); | |
6191 summary->set_in(0, Location::RequiresRegister()); | |
6192 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | |
6193 Location::RequiresRegister())); | |
6194 } | |
6195 return summary; | |
6196 } | |
6197 | |
6198 | |
6199 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6200 if (from() == kUnboxedMint) { | |
6201 PairLocation* in_pair = locs()->in(0).AsPairLocation(); | |
6202 Register in_lo = in_pair->At(0).reg(); | |
6203 Register out = locs()->out(0).reg(); | |
6204 // Copy low word. | |
6205 __ movl(out, in_lo); | |
6206 } else { | |
6207 ASSERT(from() == kUnboxedUint32); | |
6208 Register in = locs()->in(0).reg(); | |
6209 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | |
6210 Register out_lo = out_pair->At(0).reg(); | |
6211 Register out_hi = out_pair->At(1).reg(); | |
6212 // Copy low word. | |
6213 __ movl(out_lo, in); | |
6214 // Zero upper word. | |
6215 __ xorl(out_hi, out_hi); | |
6216 } | |
6217 } | |
6218 | |
6219 | |
5988 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, | 6220 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, |
5989 bool opt) const { | 6221 bool opt) const { |
5990 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); | 6222 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); |
5991 } | 6223 } |
5992 | 6224 |
5993 | 6225 |
5994 | 6226 |
5995 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6227 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5996 compiler->GenerateRuntimeCall(token_pos(), | 6228 compiler->GenerateRuntimeCall(token_pos(), |
5997 deopt_id(), | 6229 deopt_id(), |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6335 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6567 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6336 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6568 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6337 #endif | 6569 #endif |
6338 } | 6570 } |
6339 | 6571 |
6340 } // namespace dart | 6572 } // namespace dart |
6341 | 6573 |
6342 #undef __ | 6574 #undef __ |
6343 | 6575 |
6344 #endif // defined TARGET_ARCH_IA32 | 6576 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |