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

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 345563007: Add Uint32 representation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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, &not_smi);
6113 // Smi.
6114 __ movl(out, value);
6115 __ SmiTag(out);
6116 __ jmp(&done);
6117 __ Bind(&not_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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698