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

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 16951018: Fix left shift with constant on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 Register char_code = locs()->in(0).reg(); 1047 Register char_code = locs()->in(0).reg();
1048 Register result = locs()->out().reg(); 1048 Register result = locs()->out().reg();
1049 __ LoadImmediate(result, 1049 __ LoadImmediate(result,
1050 reinterpret_cast<uword>(Symbols::PredefinedAddress())); 1050 reinterpret_cast<uword>(Symbols::PredefinedAddress()));
1051 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); 1051 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1052 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. 1052 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi.
1053 } 1053 }
1054 1054
1055 1055
1056 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { 1056 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const {
1057 UNIMPLEMENTED(); 1057 const intptr_t kNumInputs = 1;
1058 return NULL; 1058 return LocationSummary::Make(kNumInputs,
1059 Location::RequiresRegister(),
1060 LocationSummary::kNoCall);
1059 } 1061 }
1060 1062
1061 1063
1062 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1064 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1063 UNIMPLEMENTED(); 1065 Register object = locs()->in(0).reg();
1066 Register result = locs()->out().reg();
1067 __ LoadFromOffset(kLoadWord, result, object, offset() - kHeapObjectTag);
1064 } 1068 }
1065 1069
1066 1070
1067 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { 1071 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const {
1068 const intptr_t kNumInputs = 1; 1072 const intptr_t kNumInputs = 1;
1069 return LocationSummary::Make(kNumInputs, 1073 return LocationSummary::Make(kNumInputs,
1070 Location::RequiresRegister(), 1074 Location::RequiresRegister(),
1071 LocationSummary::kNoCall); 1075 LocationSummary::kNoCall);
1072 } 1076 }
1073 1077
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 case kOneByteStringCid: 1360 case kOneByteStringCid:
1357 locs->set_in(2, Location::RegisterOrSmiConstant(value())); 1361 locs->set_in(2, Location::RegisterOrSmiConstant(value()));
1358 break; 1362 break;
1359 case kTypedDataInt16ArrayCid: 1363 case kTypedDataInt16ArrayCid:
1360 case kTypedDataUint16ArrayCid: 1364 case kTypedDataUint16ArrayCid:
1361 case kTypedDataInt32ArrayCid: 1365 case kTypedDataInt32ArrayCid:
1362 case kTypedDataUint32ArrayCid: 1366 case kTypedDataUint32ArrayCid:
1363 locs->set_in(2, Location::WritableRegister()); 1367 locs->set_in(2, Location::WritableRegister());
1364 break; 1368 break;
1365 case kTypedDataFloat32ArrayCid: 1369 case kTypedDataFloat32ArrayCid:
1366 // TODO(regis): Verify.
1367 // Need temp register for float-to-double conversion.
1368 locs->AddTemp(Location::RequiresFpuRegister());
1369 // Fall through.
1370 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. 1370 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
1371 case kTypedDataFloat32x4ArrayCid: 1371 case kTypedDataFloat32x4ArrayCid:
1372 locs->set_in(2, Location::RequiresFpuRegister()); 1372 locs->set_in(2, Location::RequiresFpuRegister());
1373 break; 1373 break;
1374 default: 1374 default:
1375 UNREACHABLE(); 1375 UNREACHABLE();
1376 return NULL; 1376 return NULL;
1377 } 1377 }
1378 return locs; 1378 return locs;
1379 } 1379 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 ASSERT(RequiredInputRepresentation(2) == kTagged); 1489 ASSERT(RequiredInputRepresentation(2) == kTagged);
1490 Register value = locs()->in(2).reg(); 1490 Register value = locs()->in(2).reg();
1491 __ SmiUntag(value); 1491 __ SmiUntag(value);
1492 __ str(value, element_address); 1492 __ str(value, element_address);
1493 } else { 1493 } else {
1494 UNIMPLEMENTED(); 1494 UNIMPLEMENTED();
1495 } 1495 }
1496 break; 1496 break;
1497 } 1497 }
1498 case kTypedDataFloat32ArrayCid: 1498 case kTypedDataFloat32ArrayCid:
1499 // Convert to single precision.
1500 __ vcvtsd(STMP, locs()->in(2).fpu_reg());
1501 // Store.
1502 __ add(index.reg(), index.reg(), ShifterOperand(array));
1503 __ StoreSToOffset(STMP, index.reg(), 0);
1504 break;
1499 case kTypedDataFloat64ArrayCid: 1505 case kTypedDataFloat64ArrayCid:
1506 __ add(index.reg(), index.reg(), ShifterOperand(array));
1507 __ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(), 0);
1508 break;
1500 case kTypedDataFloat32x4ArrayCid: 1509 case kTypedDataFloat32x4ArrayCid:
1501 UNIMPLEMENTED(); 1510 UNIMPLEMENTED();
1502 break; 1511 break;
1503 default: 1512 default:
1504 UNREACHABLE(); 1513 UNREACHABLE();
1505 } 1514 }
1506 } 1515 }
1507 1516
1508 1517
1509 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { 1518 LocationSummary* GuardFieldInstr::MakeLocationSummary() const {
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 Range* right_range = shift_left->right()->definition()->range(); 2128 Range* right_range = shift_left->right()->definition()->range();
2120 if (shift_left->left()->BindsToConstant() && !is_truncating) { 2129 if (shift_left->left()->BindsToConstant() && !is_truncating) {
2121 // TODO(srdjan): Implement code below for is_truncating(). 2130 // TODO(srdjan): Implement code below for is_truncating().
2122 // If left is constant, we know the maximal allowed size for right. 2131 // If left is constant, we know the maximal allowed size for right.
2123 const Object& obj = shift_left->left()->BoundConstant(); 2132 const Object& obj = shift_left->left()->BoundConstant();
2124 if (obj.IsSmi()) { 2133 if (obj.IsSmi()) {
2125 const intptr_t left_int = Smi::Cast(obj).Value(); 2134 const intptr_t left_int = Smi::Cast(obj).Value();
2126 if (left_int == 0) { 2135 if (left_int == 0) {
2127 __ cmp(right, ShifterOperand(0)); 2136 __ cmp(right, ShifterOperand(0));
2128 __ b(deopt, MI); 2137 __ b(deopt, MI);
2138 __ mov(result, ShifterOperand(0));
2129 return; 2139 return;
2130 } 2140 }
2131 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); 2141 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
2132 const bool right_needs_check = 2142 const bool right_needs_check =
2133 (right_range == NULL) || 2143 (right_range == NULL) ||
2134 !right_range->IsWithin(0, max_right - 1); 2144 !right_range->IsWithin(0, max_right - 1);
2135 if (right_needs_check) { 2145 if (right_needs_check) {
2136 __ cmp(right, 2146 __ cmp(right,
2137 ShifterOperand(reinterpret_cast<int32_t>(Smi::New(max_right)))); 2147 ShifterOperand(reinterpret_cast<int32_t>(Smi::New(max_right))));
2138 __ b(deopt, CS); 2148 __ b(deopt, CS);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2332 } 2342 }
2333 break; 2343 break;
2334 } 2344 }
2335 case Token::kSHR: { 2345 case Token::kSHR: {
2336 // sarl operation masks the count to 5 bits. 2346 // sarl operation masks the count to 5 bits.
2337 const intptr_t kCountLimit = 0x1F; 2347 const intptr_t kCountLimit = 0x1F;
2338 intptr_t value = Smi::Cast(constant).Value(); 2348 intptr_t value = Smi::Cast(constant).Value();
2339 2349
2340 if (value == 0) { 2350 if (value == 0) {
2341 // TODO(vegorov): should be handled outside. 2351 // TODO(vegorov): should be handled outside.
2352 __ MoveRegister(result, left);
2342 break; 2353 break;
2343 } else if (value < 0) { 2354 } else if (value < 0) {
2344 // TODO(vegorov): should be handled outside. 2355 // TODO(vegorov): should be handled outside.
2345 __ b(deopt); 2356 __ b(deopt);
2346 break; 2357 break;
2347 } 2358 }
2348 2359
2349 value = value + kSmiTagSize; 2360 value = value + kSmiTagSize;
2350 if (value >= kCountLimit) value = kCountLimit; 2361 if (value >= kCountLimit) value = kCountLimit;
2351 2362
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 } 2430 }
2420 __ sdiv(result, left, right); 2431 __ sdiv(result, left, right);
2421 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 2432 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2422 // case we cannot tag the result. 2433 // case we cannot tag the result.
2423 __ CompareImmediate(result, 0x40000000); 2434 __ CompareImmediate(result, 0x40000000);
2424 __ b(deopt, EQ); 2435 __ b(deopt, EQ);
2425 __ SmiTag(result); 2436 __ SmiTag(result);
2426 break; 2437 break;
2427 } 2438 }
2428 case Token::kSHR: { 2439 case Token::kSHR: {
2429 UNIMPLEMENTED(); 2440 if (CanDeoptimize()) {
2441 __ CompareImmediate(right, 0);
2442 __ b(deopt, LT);
2443 }
2444 __ SmiUntag(right);
2445 // sarl operation masks the count to 5 bits.
2446 const intptr_t kCountLimit = 0x1F;
2447 Range* right_range = this->right()->definition()->range();
2448 if ((right_range == NULL) ||
2449 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
2450 __ CompareImmediate(right, kCountLimit);
2451 __ LoadImmediate(right, kCountLimit, GT);
2452 }
2453 __ SmiUntag(left);
2454 __ Asr(result, left, right);
2455 __ SmiTag(result);
2430 break; 2456 break;
2431 } 2457 }
2432 case Token::kDIV: { 2458 case Token::kDIV: {
2433 // Dispatches to 'Double./'. 2459 // Dispatches to 'Double./'.
2434 // TODO(srdjan): Implement as conversion to double and double division. 2460 // TODO(srdjan): Implement as conversion to double and double division.
2435 UNREACHABLE(); 2461 UNREACHABLE();
2436 break; 2462 break;
2437 } 2463 }
2438 case Token::kMOD: { 2464 case Token::kMOD: {
2439 // TODO(srdjan): Implement. 2465 // TODO(srdjan): Implement.
(...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after
3579 compiler->GenerateCall(token_pos(), 3605 compiler->GenerateCall(token_pos(),
3580 &label, 3606 &label,
3581 PcDescriptors::kOther, 3607 PcDescriptors::kOther,
3582 locs()); 3608 locs());
3583 __ Drop(2); // Discard type arguments and receiver. 3609 __ Drop(2); // Discard type arguments and receiver.
3584 } 3610 }
3585 3611
3586 } // namespace dart 3612 } // namespace dart
3587 3613
3588 #endif // defined TARGET_ARCH_ARM 3614 #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