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

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
« no previous file with comments | « runtime/vm/intermediate_language_arm64.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 5735 matching lines...) Expand 10 before | Expand all | Expand 10 after
5746 if (!is_smi()) { 5746 if (!is_smi()) {
5747 summary->set_temp(0, Location::RequiresRegister()); 5747 summary->set_temp(0, Location::RequiresRegister());
5748 } 5748 }
5749 summary->set_out(0, Location::RequiresRegister()); 5749 summary->set_out(0, Location::RequiresRegister());
5750 return summary; 5750 return summary;
5751 } 5751 }
5752 5752
5753 5753
5754 class BoxIntegerSlowPath : public SlowPathCode { 5754 class BoxIntegerSlowPath : public SlowPathCode {
5755 public: 5755 public:
5756 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) 5756 explicit BoxIntegerSlowPath(Definition* instruction)
5757 : instruction_(instruction) { } 5757 : instruction_(instruction) { }
5758 5758
5759 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5759 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5760 __ Comment("BoxIntegerSlowPath"); 5760 __ Comment("BoxIntegerSlowPath");
5761 __ Bind(entry_label()); 5761 __ Bind(entry_label());
5762 Isolate* isolate = compiler->isolate(); 5762 Isolate* isolate = compiler->isolate();
5763 StubCode* stub_code = isolate->stub_code(); 5763 StubCode* stub_code = isolate->stub_code();
5764 const Class& mint_class = 5764 const Class& mint_class =
5765 Class::ZoneHandle(isolate, isolate->object_store()->mint_class()); 5765 Class::ZoneHandle(isolate, isolate->object_store()->mint_class());
5766 const Code& stub = 5766 const Code& stub =
5767 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); 5767 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class));
5768 const ExternalLabel label(stub.EntryPoint()); 5768 const ExternalLabel label(stub.EntryPoint());
5769 5769
5770 LocationSummary* locs = instruction_->locs(); 5770 LocationSummary* locs = instruction_->locs();
5771 ASSERT(!locs->live_registers()->Contains(locs->out(0))); 5771 ASSERT(!locs->live_registers()->Contains(locs->out(0)));
5772 5772
5773 compiler->SaveLiveRegisters(locs); 5773 compiler->SaveLiveRegisters(locs);
5774 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 5774 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
5775 &label, 5775 &label,
5776 RawPcDescriptors::kOther, 5776 RawPcDescriptors::kOther,
5777 locs); 5777 locs);
5778 __ MoveRegister(locs->out(0).reg(), EAX); 5778 __ MoveRegister(locs->out(0).reg(), EAX);
5779 compiler->RestoreLiveRegisters(locs); 5779 compiler->RestoreLiveRegisters(locs);
5780 5780
5781 __ jmp(exit_label()); 5781 __ jmp(exit_label());
5782 } 5782 }
5783 5783
5784 private: 5784 private:
5785 BoxIntegerInstr* instruction_; 5785 Definition* instruction_;
5786 }; 5786 };
5787 5787
5788 5788
5789 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5789 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5790 if (is_smi()) { 5790 if (is_smi()) {
5791 PairLocation* value_pair = locs()->in(0).AsPairLocation(); 5791 PairLocation* value_pair = locs()->in(0).AsPairLocation();
5792 Register value_lo = value_pair->At(0).reg(); 5792 Register value_lo = value_pair->At(0).reg();
5793 Register out_reg = locs()->out(0).reg(); 5793 Register out_reg = locs()->out(0).reg();
5794 __ movl(out_reg, value_lo); 5794 __ movl(out_reg, value_lo);
5795 __ SmiTag(out_reg); 5795 __ SmiTag(out_reg);
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
6158 6158
6159 __ notl(left_lo); 6159 __ notl(left_lo);
6160 __ notl(left_hi); 6160 __ notl(left_hi);
6161 6161
6162 if (FLAG_throw_on_javascript_int_overflow) { 6162 if (FLAG_throw_on_javascript_int_overflow) {
6163 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6163 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
6164 } 6164 }
6165 } 6165 }
6166 6166
6167 6167
6168 CompileType BinaryUint32OpInstr::ComputeType() const {
6169 return CompileType::Int();
6170 }
6171
6172
6173 CompileType ShiftUint32OpInstr::ComputeType() const {
6174 return CompileType::Int();
6175 }
6176
6177
6178 CompileType UnaryUint32OpInstr::ComputeType() const {
6179 return CompileType::Int();
6180 }
6181
6182
6183 CompileType BoxUint32Instr::ComputeType() const {
6184 return CompileType::Int();
6185 }
6186
6187
6188 CompileType UnboxUint32Instr::ComputeType() const {
6189 return CompileType::Int();
6190 }
6191
6192
6193 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6194 bool opt) const {
6195 const intptr_t kNumInputs = 2;
6196 const intptr_t kNumTemps = 0;
6197 LocationSummary* summary = new(isolate) LocationSummary(
6198 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6199 summary->set_in(0, Location::RequiresRegister());
6200 summary->set_in(1, Location::RequiresRegister());
6201 summary->set_out(0, Location::SameAsFirstInput());
6202 return summary;
6203 }
6204
6205
6206 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6207 Register left = locs()->in(0).reg();
6208 Register right = locs()->in(1).reg();
6209 Register out = locs()->out(0).reg();
6210 ASSERT(out == left);
6211 switch (op_kind()) {
6212 case Token::kBIT_AND:
6213 __ andl(out, right);
6214 break;
6215 case Token::kBIT_OR:
6216 __ orl(out, right);
6217 break;
6218 case Token::kBIT_XOR:
6219 __ xorl(out, right);
6220 break;
6221 case Token::kADD:
6222 __ addl(out, right);
6223 break;
6224 case Token::kSUB:
6225 __ subl(out, right);
6226 break;
6227 default:
6228 UNREACHABLE();
6229 }
6230 }
6231
6232
6233 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6234 bool opt) const {
6235 const intptr_t kNumInputs = 2;
6236 const intptr_t kNumTemps = 0;
6237 LocationSummary* summary = new(isolate) LocationSummary(
6238 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6239 summary->set_in(0, Location::RequiresRegister());
6240 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
6241 summary->set_out(0, Location::SameAsFirstInput());
6242 return summary;
6243 }
6244
6245
6246 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6247 const intptr_t kShifterLimit = 31;
6248
6249 Register left = locs()->in(0).reg();
6250 Register out = locs()->out(0).reg();
6251 ASSERT(left == out);
6252
6253
6254 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
6255
6256 if (locs()->in(1).IsConstant()) {
6257 // Shifter is constant.
6258
6259 const Object& constant = locs()->in(1).constant();
6260 ASSERT(constant.IsSmi());
6261 const intptr_t shift_value = Smi::Cast(constant).Value();
6262
6263 // Check constant shift value.
6264 if (shift_value == 0) {
6265 // Nothing to do.
6266 } else if (shift_value < 0) {
6267 // Invalid shift value.
6268 __ jmp(deopt);
6269 } else if (shift_value > kShifterLimit) {
6270 // Result is 0.
6271 __ xorl(left, left);
6272 } else {
6273 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6274 switch (op_kind()) {
6275 case Token::kSHR:
6276 __ shrl(left, Immediate(shift_value));
6277 break;
6278 case Token::kSHL:
6279 __ shll(left, Immediate(shift_value));
6280 break;
6281 default:
6282 UNREACHABLE();
6283 }
6284 }
6285 return;
6286 }
6287
6288 // Non constant shift value.
6289
6290 Register shifter = locs()->in(1).reg();
6291 ASSERT(shifter == ECX);
6292
6293 Label done;
6294 Label zero;
6295
6296 // TODO(johnmccutchan): Use range information to avoid these checks.
6297 __ SmiUntag(shifter);
6298 __ cmpl(shifter, Immediate(0));
6299 // If shift value is < 0, deoptimize.
6300 __ j(NEGATIVE, deopt);
6301 __ cmpl(shifter, Immediate(kShifterLimit));
6302 // If shift value is >= 32, return zero.
6303 __ j(ABOVE, &zero);
6304
6305 // Do the shift.
6306 switch (op_kind()) {
6307 case Token::kSHR:
6308 __ shrl(left, shifter);
6309 __ jmp(&done);
6310 break;
6311 case Token::kSHL:
6312 __ shll(left, shifter);
6313 __ jmp(&done);
6314 break;
6315 default:
6316 UNREACHABLE();
6317 }
6318
6319 __ Bind(&zero);
6320 // Shift was greater than 31 bits, just return zero.
6321 __ xorl(left, left);
6322
6323 // Exit path.
6324 __ Bind(&done);
6325 }
6326
6327
6328 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6329 bool opt) const {
6330 const intptr_t kNumInputs = 1;
6331 const intptr_t kNumTemps = 0;
6332 LocationSummary* summary = new(isolate) LocationSummary(
6333 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6334 summary->set_in(0, Location::RequiresRegister());
6335 summary->set_out(0, Location::SameAsFirstInput());
6336 return summary;
6337 }
6338
6339
6340 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6341 Register out = locs()->out(0).reg();
6342 ASSERT(locs()->in(0).reg() == out);
6343
6344 ASSERT(op_kind() == Token::kBIT_NOT);
6345
6346 __ notl(out);
6347 }
6348
6349
6350 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate,
6351 bool opt) const {
6352 const intptr_t kNumInputs = 1;
6353 const intptr_t kNumTemps = 0;
6354 LocationSummary* summary = new(isolate) LocationSummary(
6355 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
6356 summary->set_in(0, Location::RequiresRegister());
6357 summary->set_out(0, Location::RequiresRegister());
6358 return summary;
6359 }
6360
6361
6362 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6363 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
6364 compiler->AddSlowPathCode(slow_path);
6365 Register value = locs()->in(0).reg();
6366 Register out = locs()->out(0).reg();
6367 ASSERT(value != out);
6368
6369 Label not_smi, done;
6370
6371 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing.
6372 // Test if this value is <= kSmiMax.
6373 __ cmpl(value, Immediate(kSmiMax));
6374 __ j(ABOVE, &not_smi);
6375 // Smi.
6376 __ movl(out, value);
6377 __ SmiTag(out);
6378 __ jmp(&done);
6379 __ Bind(&not_smi);
6380 // Allocate a mint.
6381 __ TryAllocate(
6382 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
6383 slow_path->entry_label(),
6384 Assembler::kFarJump,
6385 out,
6386 kNoRegister);
6387 __ Bind(slow_path->exit_label());
6388 // Copy low word into mint.
6389 __ movl(FieldAddress(out, Mint::value_offset()), value);
6390 // Zero high word.
6391 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0));
6392 __ Bind(&done);
6393 }
6394
6395
6396 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate,
6397 bool opt) const {
6398 const intptr_t value_cid = value()->Type()->ToCid();
6399 const intptr_t kNumInputs = 1;
6400 const intptr_t kNumTemps =
6401 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1;
6402 LocationSummary* summary = new(isolate) LocationSummary(
6403 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6404 summary->set_in(0, Location::RequiresRegister());
6405 if (kNumTemps > 0) {
6406 summary->set_temp(0, Location::RequiresRegister());
6407 }
6408 summary->set_out(0, Location::SameAsFirstInput());
6409 return summary;
6410 }
6411
6412
6413 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6414 const intptr_t value_cid = value()->Type()->ToCid();
6415 const Register value = locs()->in(0).reg();
6416 ASSERT(value == locs()->out(0).reg());
6417
6418 // TODO(johnmccutchan): Emit better code for constant inputs.
6419 if (value_cid == kMintCid) {
6420 __ movl(value, FieldAddress(value, Mint::value_offset()));
6421 } else if (value_cid == kSmiCid) {
6422 __ SmiUntag(value);
6423 } else {
6424 Register temp = locs()->temp(0).reg();
6425 Label* deopt = compiler->AddDeoptStub(deopt_id_,
6426 ICData::kDeoptUnboxInteger);
6427 Label is_smi, done;
6428 __ testl(value, Immediate(kSmiTagMask));
6429 __ j(ZERO, &is_smi);
6430 __ CompareClassId(value, kMintCid, temp);
6431 __ j(NOT_EQUAL, deopt);
6432 __ movl(value, FieldAddress(value, Mint::value_offset()));
6433 __ jmp(&done);
6434 __ Bind(&is_smi);
6435 __ SmiUntag(value);
6436 __ Bind(&done);
6437 }
6438 }
6439
6440
6441 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
6442 bool opt) const {
6443 const intptr_t kNumInputs = 1;
6444 const intptr_t kNumTemps = 0;
6445 LocationSummary* summary = new(isolate) LocationSummary(
6446 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6447 if (from() == kUnboxedMint) {
6448 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6449 Location::RequiresRegister()));
6450 summary->set_out(0, Location::RequiresRegister());
6451 } else {
6452 ASSERT(from() == kUnboxedUint32);
6453 summary->set_in(0, Location::RequiresRegister());
6454 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6455 Location::RequiresRegister()));
6456 }
6457 return summary;
6458 }
6459
6460
6461 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6462 if (from() == kUnboxedMint) {
6463 PairLocation* in_pair = locs()->in(0).AsPairLocation();
6464 Register in_lo = in_pair->At(0).reg();
6465 Register out = locs()->out(0).reg();
6466 // Copy low word.
6467 __ movl(out, in_lo);
6468 } else {
6469 ASSERT(from() == kUnboxedUint32);
6470 Register in = locs()->in(0).reg();
6471 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6472 Register out_lo = out_pair->At(0).reg();
6473 Register out_hi = out_pair->At(1).reg();
6474 // Copy low word.
6475 __ movl(out_lo, in);
6476 // Zero upper word.
6477 __ xorl(out_hi, out_hi);
6478 }
6479 }
6480
6481
6168 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6482 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
6169 bool opt) const { 6483 bool opt) const {
6170 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6484 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
6171 } 6485 }
6172 6486
6173 6487
6174 6488
6175 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6489 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6176 compiler->GenerateRuntimeCall(token_pos(), 6490 compiler->GenerateRuntimeCall(token_pos(),
6177 deopt_id(), 6491 deopt_id(),
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
6519 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6833 __ movl(EDX, Immediate(kInvalidObjectPointer));
6520 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6834 __ movl(EDX, Immediate(kInvalidObjectPointer));
6521 #endif 6835 #endif
6522 } 6836 }
6523 6837
6524 } // namespace dart 6838 } // namespace dart
6525 6839
6526 #undef __ 6840 #undef __
6527 6841
6528 #endif // defined TARGET_ARCH_IA32 6842 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm64.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698