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

Unified Diff: runtime/vm/intermediate_language_arm.cc

Issue 401683003: Specialize mint shift code on arm for a constant shift amount. (Closed) Base URL: http://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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_arm.cc
===================================================================
--- runtime/vm/intermediate_language_arm.cc (revision 38346)
+++ runtime/vm/intermediate_language_arm.cc (working copy)
@@ -6143,13 +6143,12 @@
LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
bool opt) const {
const intptr_t kNumInputs = 2;
- const intptr_t kNumTemps = 1;
+ const intptr_t kNumTemps = 0;
LocationSummary* summary = new(isolate) LocationSummary(
isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::Pair(Location::RequiresRegister(),
Location::RequiresRegister()));
- summary->set_in(1, Location::WritableRegister());
- summary->set_temp(0, Location::RequiresRegister());
+ summary->set_in(1, Location::WritableRegisterOrSmiConstant(right()));
summary->set_out(0, Location::Pair(Location::RequiresRegister(),
Location::RequiresRegister()));
return summary;
@@ -6168,66 +6167,123 @@
PairLocation* left_pair = locs()->in(0).AsPairLocation();
Register left_lo = left_pair->At(0).reg();
Register left_hi = left_pair->At(1).reg();
- Register shift = locs()->in(1).reg();
PairLocation* out_pair = locs()->out(0).AsPairLocation();
Register out_lo = out_pair->At(0).reg();
Register out_hi = out_pair->At(1).reg();
- Register temp = locs()->temp(0).reg();
Label* deopt = NULL;
if (CanDeoptimize()) {
deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
}
- __ mov(out_lo, Operand(left_lo));
- __ mov(out_hi, Operand(left_hi));
+ if (locs()->in(1).IsConstant()) {
+ // Code for a constant shift amount.
+ ASSERT(locs()->in(1).constant().IsSmi());
+ const int32_t shift =
+ reinterpret_cast<int32_t>(locs()->in(1).constant().raw()) >> 1;
+ if ((shift < 0) || (shift > kMintShiftCountLimit)) {
+ __ b(deopt);
+ return;
+ } else if (shift == 0) {
+ // Nothing to do for zero shift amount.
+ __ mov(out_lo, Operand(left_lo));
+ __ mov(out_hi, Operand(left_hi));
+ return;
+ }
+ switch (op_kind()) {
+ case Token::kSHR: {
+ if (shift < 32) {
+ __ Lsl(out_lo, left_hi, 32 - shift);
+ __ orr(out_lo, out_lo, Operand(left_lo, LSR, shift));
+ __ Asr(out_hi, left_hi, shift);
+ } else {
+ if (shift == 32) {
+ __ mov(out_lo, Operand(left_hi));
+ } else {
+ __ Asr(out_lo, left_hi, shift - 32);
+ }
+ __ Asr(out_hi, left_hi, 31);
+ }
+ break;
+ }
+ case Token::kSHL: {
+ if (shift < 32) {
+ __ Lsr(out_hi, left_lo, 32 - shift);
+ __ orr(out_hi, out_hi, Operand(left_hi, LSL, shift));
+ __ Lsl(out_lo, left_lo, shift);
+ } else {
+ if (shift == 32) {
+ __ mov(out_hi, Operand(left_lo));
+ } else {
+ __ Lsl(out_hi, left_lo, shift - 32);
+ }
+ __ mov(out_lo, Operand(0));
+ }
+ // Check for overflow.
+ if (can_overflow()) {
+ // Compare high word from input with shifted high word from output.
+ if (shift > 31) {
+ __ cmp(left_hi, Operand(out_hi));
+ } else {
+ __ cmp(left_hi, Operand(out_hi, ASR, shift));
+ }
+ // Overflow if they aren't equal.
+ __ b(deopt, NE);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ // Code for a variable shift amount.
+ Register shift = locs()->in(1).reg();
- // Untag shift count.
- __ SmiUntag(shift);
+ // Untag shift count.
+ __ SmiUntag(shift);
- // Deopt if shift is larger than 63 or less than 0.
- if (has_shift_count_check()) {
- __ CompareImmediate(shift, kMintShiftCountLimit);
- __ b(deopt, HI);
- }
+ // Deopt if shift is larger than 63 or less than 0.
+ if (has_shift_count_check()) {
+ __ CompareImmediate(shift, kMintShiftCountLimit);
+ __ b(deopt, HI);
+ }
- switch (op_kind()) {
- case Token::kSHR: {
- __ cmp(shift, Operand(32));
+ __ mov(out_lo, Operand(left_lo));
+ __ mov(out_hi, Operand(left_hi));
- __ mov(out_lo, Operand(out_hi), HI);
- __ Asr(out_hi, out_hi, 31, HI);
- __ sub(shift, shift, Operand(32), HI);
+ switch (op_kind()) {
+ case Token::kSHR: {
+ __ cmp(shift, Operand(32));
- __ rsb(temp, shift, Operand(32));
- __ mov(temp, Operand(out_hi, LSL, temp));
- __ orr(out_lo, temp, Operand(out_lo, LSR, shift));
- __ Asr(out_hi, out_hi, shift);
- break;
- }
- case Token::kSHL: {
- __ rsbs(temp, shift, Operand(32));
- __ sub(temp, shift, Operand(32), MI);
- __ mov(out_hi, Operand(out_lo, LSL, temp), MI);
- __ mov(out_hi, Operand(out_hi, LSL, shift), PL);
- __ orr(out_hi, out_hi, Operand(out_lo, LSR, temp), PL);
- __ mov(out_lo, Operand(out_lo, LSL, shift));
+ __ mov(out_lo, Operand(out_hi), HI);
+ __ Asr(out_hi, out_hi, 31, HI);
+ __ sub(shift, shift, Operand(32), HI);
- // Check for overflow.
- if (can_overflow()) {
- // Copy high word from output.
- __ mov(temp, Operand(out_hi));
- // Shift copy right.
- __ Asr(temp, temp, shift);
- // Compare with high word from input.
- __ cmp(temp, Operand(left_hi));
- // Overflow if they aren't equal.
- __ b(deopt, NE);
+ __ rsb(IP, shift, Operand(32));
+ __ mov(IP, Operand(out_hi, LSL, IP));
+ __ orr(out_lo, IP, Operand(out_lo, LSR, shift));
+ __ Asr(out_hi, out_hi, shift);
+ break;
}
- break;
+ case Token::kSHL: {
+ __ rsbs(IP, shift, Operand(32));
+ __ sub(IP, shift, Operand(32), MI);
+ __ mov(out_hi, Operand(out_lo, LSL, IP), MI);
+ __ mov(out_hi, Operand(out_hi, LSL, shift), PL);
+ __ orr(out_hi, out_hi, Operand(out_lo, LSR, IP), PL);
+ __ mov(out_lo, Operand(out_lo, LSL, shift));
+
+ // Check for overflow.
+ if (can_overflow()) {
+ // Compare high word from input with shifted high word from output.
+ __ cmp(left_hi, Operand(out_hi, ASR, shift));
+ // Overflow if they aren't equal.
+ __ b(deopt, NE);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
}
- default:
- UNREACHABLE();
- break;
}
if (FLAG_throw_on_javascript_int_overflow) {
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698