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

Side by Side Diff: runtime/vm/intermediate_language_arm.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.cc ('k') | runtime/vm/intermediate_language_arm64.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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 5907 matching lines...) Expand 10 before | Expand all | Expand 10 after
5918 if (!is_smi()) { 5918 if (!is_smi()) {
5919 summary->set_temp(0, Location::RequiresRegister()); 5919 summary->set_temp(0, Location::RequiresRegister());
5920 } 5920 }
5921 summary->set_out(0, Location::RequiresRegister()); 5921 summary->set_out(0, Location::RequiresRegister());
5922 return summary; 5922 return summary;
5923 } 5923 }
5924 5924
5925 5925
5926 class BoxIntegerSlowPath : public SlowPathCode { 5926 class BoxIntegerSlowPath : public SlowPathCode {
5927 public: 5927 public:
5928 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) 5928 explicit BoxIntegerSlowPath(Definition* instruction)
5929 : instruction_(instruction) { } 5929 : instruction_(instruction) { }
5930 5930
5931 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5931 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5932 __ Comment("BoxIntegerSlowPath"); 5932 __ Comment("BoxIntegerSlowPath");
5933 __ Bind(entry_label()); 5933 __ Bind(entry_label());
5934 Isolate* isolate = compiler->isolate(); 5934 Isolate* isolate = compiler->isolate();
5935 StubCode* stub_code = isolate->stub_code(); 5935 StubCode* stub_code = isolate->stub_code();
5936 const Class& mint_class = 5936 const Class& mint_class =
5937 Class::ZoneHandle(isolate->object_store()->mint_class()); 5937 Class::ZoneHandle(isolate->object_store()->mint_class());
5938 const Code& stub = 5938 const Code& stub =
5939 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); 5939 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class));
5940 const ExternalLabel label(stub.EntryPoint()); 5940 const ExternalLabel label(stub.EntryPoint());
5941 5941
5942 LocationSummary* locs = instruction_->locs(); 5942 LocationSummary* locs = instruction_->locs();
5943 ASSERT(!locs->live_registers()->Contains(locs->out(0))); 5943 ASSERT(!locs->live_registers()->Contains(locs->out(0)));
5944 5944
5945 compiler->SaveLiveRegisters(locs); 5945 compiler->SaveLiveRegisters(locs);
5946 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 5946 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
5947 &label, 5947 &label,
5948 RawPcDescriptors::kOther, 5948 RawPcDescriptors::kOther,
5949 locs); 5949 locs);
5950 __ mov(locs->out(0).reg(), Operand(R0)); 5950 __ mov(locs->out(0).reg(), Operand(R0));
5951 compiler->RestoreLiveRegisters(locs); 5951 compiler->RestoreLiveRegisters(locs);
5952 5952
5953 __ b(exit_label()); 5953 __ b(exit_label());
5954 } 5954 }
5955 5955
5956 private: 5956 private:
5957 BoxIntegerInstr* instruction_; 5957 Definition* instruction_;
5958 }; 5958 };
5959 5959
5960 5960
5961 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5961 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5962 if (is_smi()) { 5962 if (is_smi()) {
5963 PairLocation* value_pair = locs()->in(0).AsPairLocation(); 5963 PairLocation* value_pair = locs()->in(0).AsPairLocation();
5964 Register value_lo = value_pair->At(0).reg(); 5964 Register value_lo = value_pair->At(0).reg();
5965 Register out_reg = locs()->out(0).reg(); 5965 Register out_reg = locs()->out(0).reg();
5966 __ mov(out_reg, Operand(value_lo)); 5966 __ mov(out_reg, Operand(value_lo));
5967 __ SmiTag(out_reg); 5967 __ SmiTag(out_reg);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
6224 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); 6224 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
6225 } 6225 }
6226 __ mvn(out_lo, Operand(left_lo)); 6226 __ mvn(out_lo, Operand(left_lo));
6227 __ mvn(out_hi, Operand(left_hi)); 6227 __ mvn(out_hi, Operand(left_hi));
6228 if (FLAG_throw_on_javascript_int_overflow) { 6228 if (FLAG_throw_on_javascript_int_overflow) {
6229 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6229 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6230 } 6230 }
6231 } 6231 }
6232 6232
6233 6233
6234 CompileType BinaryUint32OpInstr::ComputeType() const {
6235 return CompileType::Int();
6236 }
6237
6238
6239 CompileType ShiftUint32OpInstr::ComputeType() const {
6240 return CompileType::Int();
6241 }
6242
6243
6244 CompileType UnaryUint32OpInstr::ComputeType() const {
6245 return CompileType::Int();
6246 }
6247
6248
6249 CompileType BoxUint32Instr::ComputeType() const {
6250 return CompileType::Int();
6251 }
6252
6253
6254 CompileType UnboxUint32Instr::ComputeType() const {
6255 return CompileType::Int();
6256 }
6257
6258
6259 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6260 bool opt) const {
6261 const intptr_t kNumInputs = 2;
6262 const intptr_t kNumTemps = 0;
6263 LocationSummary* summary = new(isolate) LocationSummary(
6264 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6265 summary->set_in(0, Location::RequiresRegister());
6266 summary->set_in(1, Location::RequiresRegister());
6267 summary->set_out(0, Location::RequiresRegister());
6268 return summary;
6269 }
6270
6271
6272 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6273 Register left = locs()->in(0).reg();
zra 2014/07/11 22:42:47 const Register here and below
6274 Register right = locs()->in(1).reg();
6275 Register out = locs()->out(0).reg();
6276 ASSERT(out != left);
6277 switch (op_kind()) {
6278 case Token::kBIT_AND:
6279 __ and_(out, left, Operand(right));
6280 break;
6281 case Token::kBIT_OR:
6282 __ orr(out, left, Operand(right));
6283 break;
6284 case Token::kBIT_XOR:
6285 __ eor(out, left, Operand(right));
6286 break;
6287 case Token::kADD:
6288 __ add(out, left, Operand(right));
6289 break;
6290 case Token::kSUB:
6291 __ sub(out, left, Operand(right));
6292 break;
6293 default:
6294 UNREACHABLE();
6295 }
6296 }
6297
6298
6299 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6300 bool opt) const {
6301 const intptr_t kNumInputs = 2;
6302 const intptr_t kNumTemps = 1;
6303 LocationSummary* summary = new(isolate) LocationSummary(
6304 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6305 summary->set_in(0, Location::RequiresRegister());
6306 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
6307 summary->set_temp(0, Location::RequiresRegister());
6308 summary->set_out(0, Location::RequiresRegister());
6309 return summary;
6310 }
6311
6312
6313 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6314 const intptr_t kShifterLimit = 31;
6315
6316 Register left = locs()->in(0).reg();
6317 Register out = locs()->out(0).reg();
6318 Register temp = locs()->temp(0).reg();
6319
6320 ASSERT(left != out);
6321
6322 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
6323
6324 if (locs()->in(1).IsConstant()) {
6325 // Shifter is constant.
6326
6327 const Object& constant = locs()->in(1).constant();
6328 ASSERT(constant.IsSmi());
6329 const intptr_t shift_value = Smi::Cast(constant).Value();
6330
6331 // Check constant shift value.
6332 if (shift_value == 0) {
6333 // Nothing to do.
zra 2014/07/11 22:42:46 rm comment
6334 __ mov(out, Operand(left));
6335 } else if (shift_value < 0) {
6336 // Invalid shift value.
6337 __ b(deopt);
6338 } else if (shift_value > kShifterLimit) {
6339 // Result is 0.
6340 __ eor(out, out, Operand(out));
6341 } else {
6342 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6343 switch (op_kind()) {
6344 case Token::kSHR:
6345 __ Lsr(out, left, shift_value);
6346 break;
6347 case Token::kSHL:
6348 __ Lsl(out, left, shift_value);
6349 break;
6350 default:
6351 UNREACHABLE();
6352 }
6353 }
6354 return;
6355 }
6356
6357 // Non constant shift value.
6358
6359 Register shifter = locs()->in(1).reg();
6360
6361 __ mov(temp, Operand(shifter));
6362 __ SmiUntag(temp);
6363 __ CompareImmediate(temp, 0);
6364 // If shift value is < 0, deoptimize.
6365 __ b(deopt, LT);
6366 __ CompareImmediate(temp, kShifterLimit);
6367 // > kShifterLimit, result is 0.
6368 __ eor(out, out, Operand(out), HI);
6369 // Do the shift.
6370 switch (op_kind()) {
6371 case Token::kSHR:
6372 __ Lsr(out, left, temp, LS);
6373 break;
6374 case Token::kSHL:
6375 __ Lsl(out, left, temp, LS);
6376 break;
6377 default:
6378 UNREACHABLE();
6379 }
6380 }
6381
6382
6383 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6384 bool opt) const {
6385 const intptr_t kNumInputs = 1;
6386 const intptr_t kNumTemps = 0;
6387 LocationSummary* summary = new(isolate) LocationSummary(
6388 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6389 summary->set_in(0, Location::RequiresRegister());
6390 summary->set_out(0, Location::RequiresRegister());
6391 return summary;
6392 }
6393
6394
6395 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6396 Register left = locs()->in(0).reg();
6397 Register out = locs()->out(0).reg();
6398 ASSERT(left != out);
6399
6400 ASSERT(op_kind() == Token::kBIT_NOT);
6401
6402 __ mvn(out, Operand(left));
6403 }
6404
6405
6406 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate,
6407 bool opt) const {
6408 const intptr_t kNumInputs = 1;
6409 const intptr_t kNumTemps = 1;
6410 LocationSummary* summary = new(isolate) LocationSummary(
6411 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
6412 summary->set_in(0, Location::RequiresRegister());
6413 summary->set_temp(0, Location::RequiresRegister());
6414 summary->set_out(0, Location::RequiresRegister());
6415 return summary;
6416 }
6417
6418
6419 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6420 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
6421 compiler->AddSlowPathCode(slow_path);
6422 Register value = locs()->in(0).reg();
6423 Register out = locs()->out(0).reg();
6424 Register temp = locs()->temp(0).reg();
6425 ASSERT(value != out);
6426
6427 Label not_smi, done;
6428
6429 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing.
6430
6431 // Test if this value is <= kSmiMax.
6432 __ CompareImmediate(value, kSmiMax);
6433 __ b(&not_smi, HI);
6434 // Smi.
6435 __ mov(out, Operand(value));
6436 __ SmiTag(out);
6437 __ b(&done);
6438 __ Bind(&not_smi);
6439 // Allocate a mint.
6440 __ TryAllocate(
6441 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
6442 slow_path->entry_label(),
6443 out,
6444 temp);
6445 __ Bind(slow_path->exit_label());
6446 // Copy low word into mint.
6447 __ StoreToOffset(kWord,
6448 value,
6449 out,
6450 Mint::value_offset() - kHeapObjectTag);
6451 // Zero high word.
6452 __ eor(temp, temp, Operand(temp));
6453 __ StoreToOffset(kWord,
6454 temp,
6455 out,
6456 Mint::value_offset() - kHeapObjectTag + kWordSize);
6457 __ Bind(&done);
6458 }
6459
6460
6461
6462 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate,
6463 bool opt) const {
6464 const intptr_t value_cid = value()->Type()->ToCid();
6465 const intptr_t kNumInputs = 1;
6466 const intptr_t kNumTemps =
6467 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1;
6468 LocationSummary* summary = new(isolate) LocationSummary(
6469 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6470 summary->set_in(0, Location::RequiresRegister());
6471 if (kNumTemps > 0) {
6472 summary->set_temp(0, Location::RequiresRegister());
6473 }
6474 summary->set_out(0, Location::RequiresRegister());
6475 return summary;
6476 }
6477
6478
6479 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6480 const intptr_t value_cid = value()->Type()->ToCid();
6481 const Register value = locs()->in(0).reg();
6482 const Register out = locs()->out(0).reg();
6483 ASSERT(value != out);
6484
6485 // TODO(johnmccutchan): Emit better code for constant inputs.
6486 if (value_cid == kMintCid) {
6487 __ LoadFromOffset(kWord, out, value, Mint::value_offset() - kHeapObjectTag);
6488 } else if (value_cid == kSmiCid) {
6489 __ mov(out, Operand(value));
6490 __ SmiUntag(out);
6491 } else {
6492 Register temp = locs()->temp(0).reg();
6493 Label* deopt = compiler->AddDeoptStub(deopt_id_,
6494 ICData::kDeoptUnboxInteger);
6495 Label is_smi, done;
6496 __ tst(value, Operand(kSmiTagMask));
zra 2014/07/11 22:42:47 Sorry I missed this one before. You can eliminate
Cutch 2014/07/14 14:57:33 Done.
6497 __ b(&is_smi, EQ);
6498 __ CompareClassId(value, kMintCid, temp);
6499 __ b(deopt, NE);
6500 __ LoadFromOffset(kWord, out, value, Mint::value_offset() - kHeapObjectTag);
6501 __ b(&done);
6502 __ Bind(&is_smi);
6503 __ mov(out, Operand(value));
6504 __ SmiUntag(out);
6505 __ Bind(&done);
6506 }
6507 }
6508
6509
6510 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
6511 bool opt) const {
6512 const intptr_t kNumInputs = 1;
6513 const intptr_t kNumTemps = 0;
6514 LocationSummary* summary = new(isolate) LocationSummary(
6515 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6516 if (from() == kUnboxedMint) {
6517 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6518 Location::RequiresRegister()));
6519 summary->set_out(0, Location::RequiresRegister());
6520 } else {
6521 ASSERT(from() == kUnboxedUint32);
6522 summary->set_in(0, Location::RequiresRegister());
6523 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6524 Location::RequiresRegister()));
6525 }
6526 return summary;
6527 }
6528
6529
6530 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6531 if (from() == kUnboxedMint) {
6532 PairLocation* in_pair = locs()->in(0).AsPairLocation();
6533 Register in_lo = in_pair->At(0).reg();
6534 Register out = locs()->out(0).reg();
6535 // Copy low word.
6536 __ mov(out, Operand(in_lo));
6537 } else {
6538 ASSERT(from() == kUnboxedUint32);
6539 Register in = locs()->in(0).reg();
6540 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6541 Register out_lo = out_pair->At(0).reg();
6542 Register out_hi = out_pair->At(1).reg();
6543 // Copy low word.
6544 __ mov(out_lo, Operand(in));
6545 // Zero upper word.
6546 __ eor(out_hi, out_hi, Operand(out_hi));
6547 }
6548 }
6549
6550
6234 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6551 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
6235 bool opt) const { 6552 bool opt) const {
6236 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6553 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
6237 } 6554 }
6238 6555
6239 6556
6240 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6557 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6241 compiler->GenerateRuntimeCall(token_pos(), 6558 compiler->GenerateRuntimeCall(token_pos(),
6242 deopt_id(), 6559 deopt_id(),
6243 kThrowRuntimeEntry, 6560 kThrowRuntimeEntry,
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
6459 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 6776 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6460 #if defined(DEBUG) 6777 #if defined(DEBUG)
6461 __ LoadImmediate(R4, kInvalidObjectPointer); 6778 __ LoadImmediate(R4, kInvalidObjectPointer);
6462 __ LoadImmediate(R5, kInvalidObjectPointer); 6779 __ LoadImmediate(R5, kInvalidObjectPointer);
6463 #endif 6780 #endif
6464 } 6781 }
6465 6782
6466 } // namespace dart 6783 } // namespace dart
6467 6784
6468 #endif // defined TARGET_ARCH_ARM 6785 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698