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

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 5686 matching lines...) Expand 10 before | Expand all | Expand 10 after
5697 if (!is_smi()) { 5697 if (!is_smi()) {
5698 summary->set_temp(0, Location::RequiresRegister()); 5698 summary->set_temp(0, Location::RequiresRegister());
5699 } 5699 }
5700 summary->set_out(0, Location::RequiresRegister()); 5700 summary->set_out(0, Location::RequiresRegister());
5701 return summary; 5701 return summary;
5702 } 5702 }
5703 5703
5704 5704
5705 class BoxIntegerSlowPath : public SlowPathCode { 5705 class BoxIntegerSlowPath : public SlowPathCode {
5706 public: 5706 public:
5707 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) 5707 explicit BoxIntegerSlowPath(Definition* instruction)
5708 : instruction_(instruction) { } 5708 : instruction_(instruction) { }
5709 5709
5710 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5710 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5711 __ Comment("BoxIntegerSlowPath"); 5711 __ Comment("BoxIntegerSlowPath");
5712 __ Bind(entry_label()); 5712 __ Bind(entry_label());
5713 Isolate* isolate = compiler->isolate(); 5713 Isolate* isolate = compiler->isolate();
5714 StubCode* stub_code = isolate->stub_code(); 5714 StubCode* stub_code = isolate->stub_code();
5715 const Class& mint_class = 5715 const Class& mint_class =
5716 Class::ZoneHandle(isolate, isolate->object_store()->mint_class()); 5716 Class::ZoneHandle(isolate, isolate->object_store()->mint_class());
5717 const Code& stub = 5717 const Code& stub =
5718 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); 5718 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class));
5719 const ExternalLabel label(stub.EntryPoint()); 5719 const ExternalLabel label(stub.EntryPoint());
5720 5720
5721 LocationSummary* locs = instruction_->locs(); 5721 LocationSummary* locs = instruction_->locs();
5722 ASSERT(!locs->live_registers()->Contains(locs->out(0))); 5722 ASSERT(!locs->live_registers()->Contains(locs->out(0)));
5723 5723
5724 compiler->SaveLiveRegisters(locs); 5724 compiler->SaveLiveRegisters(locs);
5725 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 5725 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
5726 &label, 5726 &label,
5727 RawPcDescriptors::kOther, 5727 RawPcDescriptors::kOther,
5728 locs); 5728 locs);
5729 __ MoveRegister(locs->out(0).reg(), EAX); 5729 __ MoveRegister(locs->out(0).reg(), EAX);
5730 compiler->RestoreLiveRegisters(locs); 5730 compiler->RestoreLiveRegisters(locs);
5731 5731
5732 __ jmp(exit_label()); 5732 __ jmp(exit_label());
5733 } 5733 }
5734 5734
5735 private: 5735 private:
5736 BoxIntegerInstr* instruction_; 5736 Definition* instruction_;
5737 }; 5737 };
5738 5738
5739 5739
5740 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5740 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5741 if (is_smi()) { 5741 if (is_smi()) {
5742 PairLocation* value_pair = locs()->in(0).AsPairLocation(); 5742 PairLocation* value_pair = locs()->in(0).AsPairLocation();
5743 Register value_lo = value_pair->At(0).reg(); 5743 Register value_lo = value_pair->At(0).reg();
5744 Register out_reg = locs()->out(0).reg(); 5744 Register out_reg = locs()->out(0).reg();
5745 __ movl(out_reg, value_lo); 5745 __ movl(out_reg, value_lo);
5746 __ SmiTag(out_reg); 5746 __ SmiTag(out_reg);
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
6002 6002
6003 __ notl(left_lo); 6003 __ notl(left_lo);
6004 __ notl(left_hi); 6004 __ notl(left_hi);
6005 6005
6006 if (FLAG_throw_on_javascript_int_overflow) { 6006 if (FLAG_throw_on_javascript_int_overflow) {
6007 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6007 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
6008 } 6008 }
6009 } 6009 }
6010 6010
6011 6011
6012 CompileType BinaryUint32OpInstr::ComputeType() const {
6013 return CompileType::Int();
6014 }
6015
6016
6017 CompileType ShiftUint32OpInstr::ComputeType() const {
6018 return CompileType::Int();
6019 }
6020
6021
6022 CompileType UnaryUint32OpInstr::ComputeType() const {
6023 return CompileType::Int();
6024 }
6025
6026
6027 CompileType BoxUint32Instr::ComputeType() const {
6028 return CompileType::Int();
6029 }
6030
6031
6032 CompileType UnboxUint32Instr::ComputeType() const {
6033 return CompileType::Int();
6034 }
6035
6036
6037 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6038 bool opt) const {
6039 const intptr_t kNumInputs = 2;
6040 const intptr_t kNumTemps = 0;
6041 LocationSummary* summary = new(isolate) LocationSummary(
6042 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6043 summary->set_in(0, Location::RequiresRegister());
6044 summary->set_in(1, Location::RequiresRegister());
6045 summary->set_out(0, Location::SameAsFirstInput());
6046 return summary;
6047 }
6048
6049
6050 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6051 Register left = locs()->in(0).reg();
6052 Register right = locs()->in(1).reg();
6053 Register out = locs()->out(0).reg();
6054 ASSERT(out == left);
6055 switch (op_kind()) {
6056 case Token::kBIT_AND:
6057 __ andl(out, right);
6058 break;
6059 case Token::kBIT_OR:
6060 __ orl(out, right);
6061 break;
6062 case Token::kBIT_XOR:
6063 __ xorl(out, right);
6064 break;
6065 case Token::kADD:
6066 __ addl(out, right);
6067 break;
6068 case Token::kSUB:
6069 __ subl(out, right);
6070 break;
6071 default:
6072 UNREACHABLE();
6073 }
6074 }
6075
6076
6077 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6078 bool opt) const {
6079 const intptr_t kNumInputs = 2;
6080 const intptr_t kNumTemps = 0;
6081 LocationSummary* summary = new(isolate) LocationSummary(
6082 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6083 summary->set_in(0, Location::RequiresRegister());
6084 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
6085 summary->set_out(0, Location::SameAsFirstInput());
6086 return summary;
6087 }
6088
6089
6090 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6091 const intptr_t kShifterLimit = 31;
6092
6093 Register left = locs()->in(0).reg();
6094 Register out = locs()->out(0).reg();
6095 ASSERT(left == out);
6096
6097
6098 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
6099
6100 if (locs()->in(1).IsConstant()) {
6101 // Shifter is constant.
6102
6103 const Object& constant = locs()->in(1).constant();
6104 ASSERT(constant.IsSmi());
6105 const intptr_t shift_value = Smi::Cast(constant).Value();
6106
6107 // Check constant shift value.
6108 if (shift_value == 0) {
6109 // Nothing to do.
6110 } else if (shift_value < 0) {
6111 // Invalid shift value.
6112 __ jmp(deopt);
6113 } else if (shift_value > kShifterLimit) {
6114 // Result is 0.
6115 __ xorl(left, left);
6116 } else {
6117 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6118 switch (op_kind()) {
6119 case Token::kSHR:
6120 __ shrl(left, Immediate(shift_value));
6121 break;
6122 case Token::kSHL:
6123 __ shll(left, Immediate(shift_value));
6124 break;
6125 default:
6126 UNREACHABLE();
6127 }
6128 }
6129 return;
6130 }
6131
6132 // Non constant shift value.
6133
6134 Register shifter = locs()->in(1).reg();
6135 ASSERT(shifter == ECX);
6136
6137 Label done;
6138 Label zero;
6139
6140 __ SmiUntag(shifter);
6141 __ cmpl(shifter, Immediate(0));
6142 // If shift value is < 0, deoptimize.
6143 __ j(NEGATIVE, deopt);
6144 __ cmpl(shifter, Immediate(kShifterLimit));
6145 // If shift value is >= 32, return zero.
6146 __ j(ABOVE, &zero);
Florian Schneider 2014/07/10 13:05:05 Use range information to eliminate these checkes i
Cutch 2014/07/10 17:12:53 TODO added.
6147
6148 // Do the shift.
6149 switch (op_kind()) {
6150 case Token::kSHR:
6151 __ shrl(left, shifter);
6152 __ jmp(&done);
6153 break;
6154 case Token::kSHL:
6155 __ shll(left, shifter);
6156 __ jmp(&done);
6157 break;
6158 default:
6159 UNREACHABLE();
6160 }
6161
6162 __ Bind(&zero);
6163 // Shift was greater than 31 bits, just return zero.
6164 __ xorl(left, left);
6165
6166 // Exit path.
6167 __ Bind(&done);
6168 }
6169
6170
6171 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6172 bool opt) const {
6173 const intptr_t kNumInputs = 1;
6174 const intptr_t kNumTemps = 0;
6175 LocationSummary* summary = new(isolate) LocationSummary(
6176 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6177 summary->set_in(0, Location::RequiresRegister());
6178 summary->set_out(0, Location::SameAsFirstInput());
6179 return summary;
6180 }
6181
6182
6183 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6184 Register out = locs()->out(0).reg();
6185 ASSERT(locs()->in(0).reg() == out);
6186
6187 ASSERT(op_kind() == Token::kBIT_NOT);
6188
6189 __ notl(out);
6190 }
6191
6192
6193 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate,
6194 bool opt) const {
6195 const intptr_t kNumInputs = 1;
6196 const intptr_t kNumTemps = 0;
6197 LocationSummary* summary = new(isolate) LocationSummary(
6198 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
6199 summary->set_in(0, Location::RequiresRegister());
6200 summary->set_out(0, Location::RequiresRegister());
6201 return summary;
6202 }
6203
6204
6205 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6206 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
6207 compiler->AddSlowPathCode(slow_path);
6208 Register value = locs()->in(0).reg();
6209 Register out = locs()->out(0).reg();
6210 ASSERT(value != out);
6211
6212 Label not_smi, done;
6213
6214 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing.
6215 // Test if this value is <= kSmiMax.
6216 __ cmpl(value, Immediate(kSmiMax));
6217 __ j(ABOVE, &not_smi);
6218 // Smi.
6219 __ movl(out, value);
6220 __ SmiTag(out);
6221 __ jmp(&done);
6222 __ Bind(&not_smi);
6223 // Allocate a mint.
6224 __ TryAllocate(
6225 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
6226 slow_path->entry_label(),
6227 Assembler::kFarJump,
6228 out,
6229 kNoRegister);
6230 __ Bind(slow_path->exit_label());
6231 // Copy low word into mint.
6232 __ movl(FieldAddress(out, Mint::value_offset()), value);
6233 // Zero high word.
6234 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0));
6235 __ Bind(&done);
6236 }
6237
6238
6239 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate,
6240 bool opt) const {
6241 const intptr_t value_cid = value()->Type()->ToCid();
6242 const intptr_t kNumInputs = 1;
6243 const intptr_t kNumTemps =
6244 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1;
6245 LocationSummary* summary = new(isolate) LocationSummary(
6246 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6247 summary->set_in(0, Location::RequiresRegister());
6248 if (kNumTemps > 0) {
6249 summary->set_temp(0, Location::RequiresRegister());
6250 }
6251 summary->set_out(0, Location::SameAsFirstInput());
6252 return summary;
6253 }
6254
6255
6256 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6257 const intptr_t value_cid = value()->Type()->ToCid();
6258 const Register value = locs()->in(0).reg();
6259 ASSERT(value == locs()->out(0).reg());
6260
6261 // TODO(johnmccutchan): Emit better code for constant inputs.
6262 if (value_cid == kMintCid) {
6263 __ movl(value, FieldAddress(value, Mint::value_offset()));
6264 } else if (value_cid == kSmiCid) {
6265 __ SmiUntag(value);
6266 } else {
6267 Register temp = locs()->temp(0).reg();
6268 Label* deopt = compiler->AddDeoptStub(deopt_id_,
6269 ICData::kDeoptUnboxInteger);
6270 Label is_smi, done;
6271 __ testl(value, Immediate(kSmiTagMask));
6272 __ j(ZERO, &is_smi);
6273 __ CompareClassId(value, kMintCid, temp);
6274 __ j(NOT_EQUAL, deopt);
6275 __ movl(value, FieldAddress(value, Mint::value_offset()));
6276 __ jmp(&done);
6277 __ Bind(&is_smi);
6278 __ SmiUntag(value);
6279 __ Bind(&done);
6280 }
6281 }
6282
6283
6284 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
6285 bool opt) const {
6286 const intptr_t kNumInputs = 1;
6287 const intptr_t kNumTemps = 0;
6288 LocationSummary* summary = new(isolate) LocationSummary(
6289 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6290 if (from() == kUnboxedMint) {
6291 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6292 Location::RequiresRegister()));
6293 summary->set_out(0, Location::RequiresRegister());
6294 } else {
6295 ASSERT(from() == kUnboxedUint32);
6296 summary->set_in(0, Location::RequiresRegister());
6297 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6298 Location::RequiresRegister()));
6299 }
6300 return summary;
6301 }
6302
6303
6304 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6305 if (from() == kUnboxedMint) {
6306 PairLocation* in_pair = locs()->in(0).AsPairLocation();
6307 Register in_lo = in_pair->At(0).reg();
6308 Register out = locs()->out(0).reg();
6309 // Copy low word.
6310 __ movl(out, in_lo);
6311 } else {
6312 ASSERT(from() == kUnboxedUint32);
6313 Register in = locs()->in(0).reg();
6314 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6315 Register out_lo = out_pair->At(0).reg();
6316 Register out_hi = out_pair->At(1).reg();
6317 // Copy low word.
6318 __ movl(out_lo, in);
6319 // Zero upper word.
6320 __ xorl(out_hi, out_hi);
6321 }
6322 }
6323
6324
6012 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6325 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
6013 bool opt) const { 6326 bool opt) const {
6014 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6327 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
6015 } 6328 }
6016 6329
6017 6330
6018 6331
6019 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6332 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6020 compiler->GenerateRuntimeCall(token_pos(), 6333 compiler->GenerateRuntimeCall(token_pos(),
6021 deopt_id(), 6334 deopt_id(),
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
6363 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6676 __ movl(EDX, Immediate(kInvalidObjectPointer));
6364 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6677 __ movl(EDX, Immediate(kInvalidObjectPointer));
6365 #endif 6678 #endif
6366 } 6679 }
6367 6680
6368 } // namespace dart 6681 } // namespace dart
6369 6682
6370 #undef __ 6683 #undef __
6371 6684
6372 #endif // defined TARGET_ARCH_IA32 6685 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698