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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.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 6125 matching lines...) Expand 10 before | Expand all | Expand 10 after
6136 } 6136 }
6137 if (FLAG_throw_on_javascript_int_overflow) { 6137 if (FLAG_throw_on_javascript_int_overflow) {
6138 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6138 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6139 } 6139 }
6140 } 6140 }
6141 6141
6142 6142
6143 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 6143 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
6144 bool opt) const { 6144 bool opt) const {
6145 const intptr_t kNumInputs = 2; 6145 const intptr_t kNumInputs = 2;
6146 const intptr_t kNumTemps = 1; 6146 const intptr_t kNumTemps = 0;
6147 LocationSummary* summary = new(isolate) LocationSummary( 6147 LocationSummary* summary = new(isolate) LocationSummary(
6148 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6148 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6149 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 6149 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6150 Location::RequiresRegister())); 6150 Location::RequiresRegister()));
6151 summary->set_in(1, Location::WritableRegister()); 6151 summary->set_in(1, Location::WritableRegisterOrSmiConstant(right()));
6152 summary->set_temp(0, Location::RequiresRegister());
6153 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 6152 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6154 Location::RequiresRegister())); 6153 Location::RequiresRegister()));
6155 return summary; 6154 return summary;
6156 } 6155 }
6157 6156
6158 6157
6159 static const intptr_t kMintShiftCountLimit = 63; 6158 static const intptr_t kMintShiftCountLimit = 63;
6160 6159
6161 bool ShiftMintOpInstr::has_shift_count_check() const { 6160 bool ShiftMintOpInstr::has_shift_count_check() const {
6162 return (right()->definition()->range() == NULL) 6161 return (right()->definition()->range() == NULL)
6163 || !right()->definition()->range()->IsWithin(0, kMintShiftCountLimit); 6162 || !right()->definition()->range()->IsWithin(0, kMintShiftCountLimit);
6164 } 6163 }
6165 6164
6166 6165
6167 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6166 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6168 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 6167 PairLocation* left_pair = locs()->in(0).AsPairLocation();
6169 Register left_lo = left_pair->At(0).reg(); 6168 Register left_lo = left_pair->At(0).reg();
6170 Register left_hi = left_pair->At(1).reg(); 6169 Register left_hi = left_pair->At(1).reg();
6171 Register shift = locs()->in(1).reg();
6172 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 6170 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6173 Register out_lo = out_pair->At(0).reg(); 6171 Register out_lo = out_pair->At(0).reg();
6174 Register out_hi = out_pair->At(1).reg(); 6172 Register out_hi = out_pair->At(1).reg();
6175 Register temp = locs()->temp(0).reg();
6176 6173
6177 Label* deopt = NULL; 6174 Label* deopt = NULL;
6178 if (CanDeoptimize()) { 6175 if (CanDeoptimize()) {
6179 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); 6176 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
6180 } 6177 }
6181 __ mov(out_lo, Operand(left_lo)); 6178 if (locs()->in(1).IsConstant()) {
6182 __ mov(out_hi, Operand(left_hi)); 6179 // Code for a constant shift amount.
6180 ASSERT(locs()->in(1).constant().IsSmi());
6181 const int32_t shift =
6182 reinterpret_cast<int32_t>(locs()->in(1).constant().raw()) >> 1;
6183 if ((shift < 0) || (shift > kMintShiftCountLimit)) {
6184 __ b(deopt);
6185 return;
6186 } else if (shift == 0) {
6187 // Nothing to do for zero shift amount.
6188 __ mov(out_lo, Operand(left_lo));
6189 __ mov(out_hi, Operand(left_hi));
6190 return;
6191 }
6192 switch (op_kind()) {
6193 case Token::kSHR: {
6194 if (shift < 32) {
6195 __ Lsl(out_lo, left_hi, 32 - shift);
6196 __ orr(out_lo, out_lo, Operand(left_lo, LSR, shift));
6197 __ Asr(out_hi, left_hi, shift);
6198 } else {
6199 if (shift == 32) {
6200 __ mov(out_lo, Operand(left_hi));
6201 } else {
6202 __ Asr(out_lo, left_hi, shift - 32);
6203 }
6204 __ Asr(out_hi, left_hi, 31);
6205 }
6206 break;
6207 }
6208 case Token::kSHL: {
6209 if (shift < 32) {
6210 __ Lsr(out_hi, left_lo, 32 - shift);
6211 __ orr(out_hi, out_hi, Operand(left_hi, LSL, shift));
6212 __ Lsl(out_lo, left_lo, shift);
6213 } else {
6214 if (shift == 32) {
6215 __ mov(out_hi, Operand(left_lo));
6216 } else {
6217 __ Lsl(out_hi, left_lo, shift - 32);
6218 }
6219 __ mov(out_lo, Operand(0));
6220 }
6221 // Check for overflow.
6222 if (can_overflow()) {
6223 // Compare high word from input with shifted high word from output.
6224 if (shift > 31) {
6225 __ cmp(left_hi, Operand(out_hi));
6226 } else {
6227 __ cmp(left_hi, Operand(out_hi, ASR, shift));
6228 }
6229 // Overflow if they aren't equal.
6230 __ b(deopt, NE);
6231 }
6232 break;
6233 }
6234 default:
6235 UNREACHABLE();
6236 }
6237 } else {
6238 // Code for a variable shift amount.
6239 Register shift = locs()->in(1).reg();
6183 6240
6184 // Untag shift count. 6241 // Untag shift count.
6185 __ SmiUntag(shift); 6242 __ SmiUntag(shift);
6186 6243
6187 // Deopt if shift is larger than 63 or less than 0. 6244 // Deopt if shift is larger than 63 or less than 0.
6188 if (has_shift_count_check()) { 6245 if (has_shift_count_check()) {
6189 __ CompareImmediate(shift, kMintShiftCountLimit); 6246 __ CompareImmediate(shift, kMintShiftCountLimit);
6190 __ b(deopt, HI); 6247 __ b(deopt, HI);
6191 } 6248 }
6192 6249
6193 switch (op_kind()) { 6250 __ mov(out_lo, Operand(left_lo));
6194 case Token::kSHR: { 6251 __ mov(out_hi, Operand(left_hi));
6195 __ cmp(shift, Operand(32));
6196 6252
6197 __ mov(out_lo, Operand(out_hi), HI); 6253 switch (op_kind()) {
6198 __ Asr(out_hi, out_hi, 31, HI); 6254 case Token::kSHR: {
6199 __ sub(shift, shift, Operand(32), HI); 6255 __ cmp(shift, Operand(32));
6200 6256
6201 __ rsb(temp, shift, Operand(32)); 6257 __ mov(out_lo, Operand(out_hi), HI);
6202 __ mov(temp, Operand(out_hi, LSL, temp)); 6258 __ Asr(out_hi, out_hi, 31, HI);
6203 __ orr(out_lo, temp, Operand(out_lo, LSR, shift)); 6259 __ sub(shift, shift, Operand(32), HI);
6204 __ Asr(out_hi, out_hi, shift); 6260
6205 break; 6261 __ rsb(IP, shift, Operand(32));
6262 __ mov(IP, Operand(out_hi, LSL, IP));
6263 __ orr(out_lo, IP, Operand(out_lo, LSR, shift));
6264 __ Asr(out_hi, out_hi, shift);
6265 break;
6266 }
6267 case Token::kSHL: {
6268 __ rsbs(IP, shift, Operand(32));
6269 __ sub(IP, shift, Operand(32), MI);
6270 __ mov(out_hi, Operand(out_lo, LSL, IP), MI);
6271 __ mov(out_hi, Operand(out_hi, LSL, shift), PL);
6272 __ orr(out_hi, out_hi, Operand(out_lo, LSR, IP), PL);
6273 __ mov(out_lo, Operand(out_lo, LSL, shift));
6274
6275 // Check for overflow.
6276 if (can_overflow()) {
6277 // Compare high word from input with shifted high word from output.
6278 __ cmp(left_hi, Operand(out_hi, ASR, shift));
6279 // Overflow if they aren't equal.
6280 __ b(deopt, NE);
6281 }
6282 break;
6283 }
6284 default:
6285 UNREACHABLE();
6206 } 6286 }
6207 case Token::kSHL: {
6208 __ rsbs(temp, shift, Operand(32));
6209 __ sub(temp, shift, Operand(32), MI);
6210 __ mov(out_hi, Operand(out_lo, LSL, temp), MI);
6211 __ mov(out_hi, Operand(out_hi, LSL, shift), PL);
6212 __ orr(out_hi, out_hi, Operand(out_lo, LSR, temp), PL);
6213 __ mov(out_lo, Operand(out_lo, LSL, shift));
6214
6215 // Check for overflow.
6216 if (can_overflow()) {
6217 // Copy high word from output.
6218 __ mov(temp, Operand(out_hi));
6219 // Shift copy right.
6220 __ Asr(temp, temp, shift);
6221 // Compare with high word from input.
6222 __ cmp(temp, Operand(left_hi));
6223 // Overflow if they aren't equal.
6224 __ b(deopt, NE);
6225 }
6226 break;
6227 }
6228 default:
6229 UNREACHABLE();
6230 break;
6231 } 6287 }
6232 6288
6233 if (FLAG_throw_on_javascript_int_overflow) { 6289 if (FLAG_throw_on_javascript_int_overflow) {
6234 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6290 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6235 } 6291 }
6236 } 6292 }
6237 6293
6238 6294
6239 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 6295 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
6240 bool opt) const { 6296 bool opt) const {
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
6816 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 6872 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6817 #if defined(DEBUG) 6873 #if defined(DEBUG)
6818 __ LoadImmediate(R4, kInvalidObjectPointer); 6874 __ LoadImmediate(R4, kInvalidObjectPointer);
6819 __ LoadImmediate(R5, kInvalidObjectPointer); 6875 __ LoadImmediate(R5, kInvalidObjectPointer);
6820 #endif 6876 #endif
6821 } 6877 }
6822 6878
6823 } // namespace dart 6879 } // namespace dart
6824 6880
6825 #endif // defined TARGET_ARCH_ARM 6881 #endif // defined TARGET_ARCH_ARM
OLDNEW
« 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