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

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

Issue 300003015: Reduce register pressure on ARM, ARM64, and MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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 | « runtime/vm/intermediate_language_arm.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 1191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 : Location::RegisterOrConstant(value())); 1202 : Location::RegisterOrConstant(value()));
1203 break; 1203 break;
1204 case kExternalTypedDataUint8ArrayCid: 1204 case kExternalTypedDataUint8ArrayCid:
1205 case kExternalTypedDataUint8ClampedArrayCid: 1205 case kExternalTypedDataUint8ClampedArrayCid:
1206 case kTypedDataInt8ArrayCid: 1206 case kTypedDataInt8ArrayCid:
1207 case kTypedDataUint8ArrayCid: 1207 case kTypedDataUint8ArrayCid:
1208 case kTypedDataUint8ClampedArrayCid: 1208 case kTypedDataUint8ClampedArrayCid:
1209 case kOneByteStringCid: 1209 case kOneByteStringCid:
1210 case kTypedDataInt16ArrayCid: 1210 case kTypedDataInt16ArrayCid:
1211 case kTypedDataUint16ArrayCid: 1211 case kTypedDataUint16ArrayCid:
1212 locs->set_in(2, Location::WritableRegister());
1213 break;
1214 case kTypedDataInt32ArrayCid: 1212 case kTypedDataInt32ArrayCid:
1215 case kTypedDataUint32ArrayCid: 1213 case kTypedDataUint32ArrayCid:
1216 locs->set_in(2, Location::WritableRegister()); 1214 locs->set_in(2, Location::RequiresRegister());
1217 break; 1215 break;
1218 case kTypedDataFloat32ArrayCid: 1216 case kTypedDataFloat32ArrayCid:
1219 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. 1217 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
1220 locs->set_in(2, Location::RequiresFpuRegister()); 1218 locs->set_in(2, Location::RequiresFpuRegister());
1221 break; 1219 break;
1222 case kTypedDataInt32x4ArrayCid: 1220 case kTypedDataInt32x4ArrayCid:
1223 case kTypedDataFloat32x4ArrayCid: 1221 case kTypedDataFloat32x4ArrayCid:
1224 case kTypedDataFloat64x2ArrayCid: 1222 case kTypedDataFloat64x2ArrayCid:
1225 locs->set_in(2, Location::RequiresFpuRegister()); 1223 locs->set_in(2, Location::RequiresFpuRegister());
1226 break; 1224 break;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 case kTypedDataInt8ArrayCid: 1259 case kTypedDataInt8ArrayCid:
1262 case kTypedDataUint8ArrayCid: 1260 case kTypedDataUint8ArrayCid:
1263 case kExternalTypedDataUint8ArrayCid: 1261 case kExternalTypedDataUint8ArrayCid:
1264 case kOneByteStringCid: { 1262 case kOneByteStringCid: {
1265 if (locs()->in(2).IsConstant()) { 1263 if (locs()->in(2).IsConstant()) {
1266 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1264 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1267 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()), PP); 1265 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()), PP);
1268 __ str(TMP, element_address, kUnsignedByte); 1266 __ str(TMP, element_address, kUnsignedByte);
1269 } else { 1267 } else {
1270 const Register value = locs()->in(2).reg(); 1268 const Register value = locs()->in(2).reg();
1271 __ SmiUntag(value); 1269 __ SmiUntag(TMP, value);
1272 __ str(value, element_address, kUnsignedByte); 1270 __ str(TMP, element_address, kUnsignedByte);
1273 } 1271 }
1274 break; 1272 break;
1275 } 1273 }
1276 case kTypedDataUint8ClampedArrayCid: 1274 case kTypedDataUint8ClampedArrayCid:
1277 case kExternalTypedDataUint8ClampedArrayCid: { 1275 case kExternalTypedDataUint8ClampedArrayCid: {
1278 if (locs()->in(2).IsConstant()) { 1276 if (locs()->in(2).IsConstant()) {
1279 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1277 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1280 intptr_t value = constant.Value(); 1278 intptr_t value = constant.Value();
1281 // Clamp to 0x0 or 0xFF respectively. 1279 // Clamp to 0x0 or 0xFF respectively.
1282 if (value > 0xFF) { 1280 if (value > 0xFF) {
1283 value = 0xFF; 1281 value = 0xFF;
1284 } else if (value < 0) { 1282 } else if (value < 0) {
1285 value = 0; 1283 value = 0;
1286 } 1284 }
1287 __ LoadImmediate(TMP, static_cast<int8_t>(value), PP); 1285 __ LoadImmediate(TMP, static_cast<int8_t>(value), PP);
1288 __ str(TMP, element_address, kUnsignedByte); 1286 __ str(TMP, element_address, kUnsignedByte);
1289 } else { 1287 } else {
1290 const Register value = locs()->in(2).reg(); 1288 const Register value = locs()->in(2).reg();
1291 Label store_value; 1289 __ CompareImmediate(value, 0x1FE, PP); // Smi value and smi 0xFF.
1292 __ SmiUntag(value);
1293 __ CompareImmediate(value, 0xFF, PP);
1294 // Clamp to 0x00 or 0xFF respectively. 1290 // Clamp to 0x00 or 0xFF respectively.
1295 __ b(&store_value, LS); 1291 __ csetm(TMP, GT); // TMP = value > 0x1FE ? -1 : 0.
1296 __ LoadImmediate(TMP, 0x00, PP); 1292 __ csel(TMP, value, TMP, LS); // TMP = value in range ? value : TMP.
1297 __ LoadImmediate(TMP2, 0xFF, PP); 1293 __ SmiUntag(TMP);
1298 __ csel(value, TMP, value, LE); 1294 __ str(TMP, element_address, kUnsignedByte);
1299 __ csel(value, TMP2, value, GT);
1300 __ Bind(&store_value);
1301 __ str(value, element_address, kUnsignedByte);
1302 } 1295 }
1303 break; 1296 break;
1304 } 1297 }
1305 case kTypedDataInt16ArrayCid: 1298 case kTypedDataInt16ArrayCid:
1306 case kTypedDataUint16ArrayCid: { 1299 case kTypedDataUint16ArrayCid: {
1307 const Register value = locs()->in(2).reg(); 1300 const Register value = locs()->in(2).reg();
1308 __ SmiUntag(value); 1301 __ SmiUntag(TMP, value);
1309 __ str(value, element_address, kUnsignedHalfword); 1302 __ str(TMP, element_address, kUnsignedHalfword);
1310 break; 1303 break;
1311 } 1304 }
1312 case kTypedDataInt32ArrayCid: 1305 case kTypedDataInt32ArrayCid:
1313 case kTypedDataUint32ArrayCid: { 1306 case kTypedDataUint32ArrayCid: {
1314 const Register value = locs()->in(2).reg(); 1307 const Register value = locs()->in(2).reg();
1315 __ SmiUntag(value); 1308 __ SmiUntag(TMP, value);
1316 __ str(value, element_address, kUnsignedWord); 1309 __ str(TMP, element_address, kUnsignedWord);
1317 break; 1310 break;
1318 } 1311 }
1319 case kTypedDataFloat32ArrayCid: { 1312 case kTypedDataFloat32ArrayCid: {
1320 const VRegister value_reg = locs()->in(2).fpu_reg(); 1313 const VRegister value_reg = locs()->in(2).fpu_reg();
1321 __ fstrs(value_reg, element_address); 1314 __ fstrs(value_reg, element_address);
1322 break; 1315 break;
1323 } 1316 }
1324 case kTypedDataFloat64ArrayCid: { 1317 case kTypedDataFloat64ArrayCid: {
1325 const VRegister value_reg = locs()->in(2).fpu_reg(); 1318 const VRegister value_reg = locs()->in(2).fpu_reg();
1326 __ fstrd(value_reg, element_address); 1319 __ fstrd(value_reg, element_address);
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2636 } 2629 }
2637 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); 2630 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
2638 const bool right_needs_check = 2631 const bool right_needs_check =
2639 (right_range == NULL) || 2632 (right_range == NULL) ||
2640 !right_range->IsWithin(0, max_right - 1); 2633 !right_range->IsWithin(0, max_right - 1);
2641 if (right_needs_check) { 2634 if (right_needs_check) {
2642 __ CompareImmediate(right, 2635 __ CompareImmediate(right,
2643 reinterpret_cast<int64_t>(Smi::New(max_right)), PP); 2636 reinterpret_cast<int64_t>(Smi::New(max_right)), PP);
2644 __ b(deopt, CS); 2637 __ b(deopt, CS);
2645 } 2638 }
2646 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 2639 __ SmiUntag(TMP, right);
2647 __ lslv(result, left, TMP); 2640 __ lslv(result, left, TMP);
2648 } 2641 }
2649 if (FLAG_throw_on_javascript_int_overflow) { 2642 if (FLAG_throw_on_javascript_int_overflow) {
2650 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result); 2643 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2651 } 2644 }
2652 return; 2645 return;
2653 } 2646 }
2654 2647
2655 const bool right_needs_check = 2648 const bool right_needs_check =
2656 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1)); 2649 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1));
2657 if (is_truncating) { 2650 if (is_truncating) {
2658 if (right_needs_check) { 2651 if (right_needs_check) {
2659 const bool right_may_be_negative = 2652 const bool right_may_be_negative =
2660 (right_range == NULL) || 2653 (right_range == NULL) ||
2661 !right_range->IsWithin(0, RangeBoundary::kPlusInfinity); 2654 !right_range->IsWithin(0, RangeBoundary::kPlusInfinity);
2662 if (right_may_be_negative) { 2655 if (right_may_be_negative) {
2663 ASSERT(shift_left->CanDeoptimize()); 2656 ASSERT(shift_left->CanDeoptimize());
2664 __ CompareRegisters(right, ZR); 2657 __ CompareRegisters(right, ZR);
2665 __ b(deopt, MI); 2658 __ b(deopt, MI);
2666 } 2659 }
2667 2660
2668 __ CompareImmediate( 2661 __ CompareImmediate(
2669 right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)), PP); 2662 right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)), PP);
2670 __ csel(result, ZR, result, CS); 2663 __ csel(result, ZR, result, CS);
2671 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 2664 __ SmiUntag(TMP, right);
2672 __ lslv(TMP, left, TMP); 2665 __ lslv(TMP, left, TMP);
2673 __ csel(result, TMP, result, CC); 2666 __ csel(result, TMP, result, CC);
2674 } else { 2667 } else {
2675 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 2668 __ SmiUntag(TMP, right);
2676 __ lslv(result, left, TMP); 2669 __ lslv(result, left, TMP);
2677 } 2670 }
2678 } else { 2671 } else {
2679 if (right_needs_check) { 2672 if (right_needs_check) {
2680 ASSERT(shift_left->CanDeoptimize()); 2673 ASSERT(shift_left->CanDeoptimize());
2681 __ CompareImmediate( 2674 __ CompareImmediate(
2682 right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)), PP); 2675 right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)), PP);
2683 __ b(deopt, CS); 2676 __ b(deopt, CS);
2684 } 2677 }
2685 // Left is not a constant. 2678 // Left is not a constant.
2686 // Check if count too large for handling it inlined. 2679 // Check if count too large for handling it inlined.
2687 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 2680 __ SmiUntag(TMP, right);
2688 // Overflow test (preserve left, right, and TMP); 2681 // Overflow test (preserve left, right, and TMP);
2689 const Register temp = locs.temp(0).reg(); 2682 const Register temp = locs.temp(0).reg();
2690 __ lslv(temp, left, TMP); 2683 __ lslv(temp, left, TMP);
2691 __ asrv(TMP2, temp, TMP); 2684 __ asrv(TMP2, temp, TMP);
2692 __ CompareRegisters(left, TMP2); 2685 __ CompareRegisters(left, TMP2);
2693 __ b(deopt, NE); // Overflow. 2686 __ b(deopt, NE); // Overflow.
2694 // Shift for result now we know there is no overflow. 2687 // Shift for result now we know there is no overflow.
2695 __ lslv(result, left, TMP); 2688 __ lslv(result, left, TMP);
2696 } 2689 }
2697 if (FLAG_throw_on_javascript_int_overflow) { 2690 if (FLAG_throw_on_javascript_int_overflow) {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2893 case Token::kSUB: { 2886 case Token::kSUB: {
2894 if (deopt == NULL) { 2887 if (deopt == NULL) {
2895 __ sub(result, left, Operand(right)); 2888 __ sub(result, left, Operand(right));
2896 } else { 2889 } else {
2897 __ subs(result, left, Operand(right)); 2890 __ subs(result, left, Operand(right));
2898 __ b(deopt, VS); 2891 __ b(deopt, VS);
2899 } 2892 }
2900 break; 2893 break;
2901 } 2894 }
2902 case Token::kMUL: { 2895 case Token::kMUL: {
2903 __ Asr(TMP, left, kSmiTagSize); // SmiUntag left into TMP. 2896 __ SmiUntag(TMP, left);
2904 if (deopt == NULL) { 2897 if (deopt == NULL) {
2905 __ mul(result, TMP, right); 2898 __ mul(result, TMP, right);
2906 } else { 2899 } else {
2907 __ mul(result, TMP, right); 2900 __ mul(result, TMP, right);
2908 __ smulh(TMP, TMP, right); 2901 __ smulh(TMP, TMP, right);
2909 // TMP: result bits 64..127. 2902 // TMP: result bits 64..127.
2910 __ cmp(TMP, Operand(result, ASR, 63)); 2903 __ cmp(TMP, Operand(result, ASR, 63));
2911 __ b(deopt, NE); 2904 __ b(deopt, NE);
2912 } 2905 }
2913 break; 2906 break;
(...skipping 13 matching lines...) Expand all
2927 __ eor(result, left, Operand(right)); 2920 __ eor(result, left, Operand(right));
2928 break; 2921 break;
2929 } 2922 }
2930 case Token::kTRUNCDIV: { 2923 case Token::kTRUNCDIV: {
2931 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 2924 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
2932 // Handle divide by zero in runtime. 2925 // Handle divide by zero in runtime.
2933 __ CompareRegisters(right, ZR); 2926 __ CompareRegisters(right, ZR);
2934 __ b(deopt, EQ); 2927 __ b(deopt, EQ);
2935 } 2928 }
2936 const Register temp = TMP2; 2929 const Register temp = TMP2;
2937 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2930 __ SmiUntag(temp, left);
2938 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into IP. 2931 __ SmiUntag(TMP, right);
2939 2932
2940 __ sdiv(result, temp, TMP); 2933 __ sdiv(result, temp, TMP);
2941 2934
2942 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 2935 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2943 // case we cannot tag the result. 2936 // case we cannot tag the result.
2944 __ CompareImmediate(result, 0x4000000000000000LL, kNoPP); 2937 __ CompareImmediate(result, 0x4000000000000000LL, kNoPP);
2945 __ b(deopt, EQ); 2938 __ b(deopt, EQ);
2946 __ SmiTag(result); 2939 __ SmiTag(result);
2947 break; 2940 break;
2948 } 2941 }
2949 case Token::kMOD: { 2942 case Token::kMOD: {
2950 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 2943 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
2951 // Handle divide by zero in runtime. 2944 // Handle divide by zero in runtime.
2952 __ CompareRegisters(right, ZR); 2945 __ CompareRegisters(right, ZR);
2953 __ b(deopt, EQ); 2946 __ b(deopt, EQ);
2954 } 2947 }
2955 const Register temp = TMP2; 2948 const Register temp = TMP2;
2956 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2949 __ SmiUntag(temp, left);
2957 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into IP. 2950 __ SmiUntag(TMP, right);
2958 2951
2959 __ sdiv(result, temp, TMP); 2952 __ sdiv(result, temp, TMP);
2960 2953
2961 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into IP. 2954 __ SmiUntag(TMP, right);
2962 __ msub(result, TMP, result, temp); // result <- left - right * result 2955 __ msub(result, TMP, result, temp); // result <- left - right * result
2963 __ SmiTag(result); 2956 __ SmiTag(result);
2964 // res = left % right; 2957 // res = left % right;
2965 // if (res < 0) { 2958 // if (res < 0) {
2966 // if (right < 0) { 2959 // if (right < 0) {
2967 // res = res - right; 2960 // res = res - right;
2968 // } else { 2961 // } else {
2969 // res = res + right; 2962 // res = res + right;
2970 // } 2963 // }
2971 // } 2964 // }
2972 Label done; 2965 Label done;
2973 __ CompareRegisters(result, ZR); 2966 __ CompareRegisters(result, ZR);
2974 __ b(&done, GE); 2967 __ b(&done, GE);
2975 // Result is negative, adjust it. 2968 // Result is negative, adjust it.
2976 __ CompareRegisters(right, ZR); 2969 __ CompareRegisters(right, ZR);
2977 __ sub(TMP, result, Operand(right)); 2970 __ sub(TMP, result, Operand(right));
2978 __ add(result, result, Operand(right)); 2971 __ add(result, result, Operand(right));
2979 __ csel(result, TMP, result, LT); 2972 __ csel(result, TMP, result, LT);
2980 __ Bind(&done); 2973 __ Bind(&done);
2981 break; 2974 break;
2982 } 2975 }
2983 case Token::kSHR: { 2976 case Token::kSHR: {
2984 if (CanDeoptimize()) { 2977 if (CanDeoptimize()) {
2985 __ CompareRegisters(right, ZR); 2978 __ CompareRegisters(right, ZR);
2986 __ b(deopt, LT); 2979 __ b(deopt, LT);
2987 } 2980 }
2988 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 2981 __ SmiUntag(TMP, right);
2989 // sarl operation masks the count to 6 bits. 2982 // sarl operation masks the count to 6 bits.
2990 const intptr_t kCountLimit = 0x3F; 2983 const intptr_t kCountLimit = 0x3F;
2991 if ((right_range == NULL) || 2984 if ((right_range == NULL) ||
2992 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { 2985 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
2993 __ LoadImmediate(TMP2, kCountLimit, PP); 2986 __ LoadImmediate(TMP2, kCountLimit, PP);
2994 __ CompareRegisters(TMP, TMP2); 2987 __ CompareRegisters(TMP, TMP2);
2995 __ csel(TMP, TMP2, TMP, GT); 2988 __ csel(TMP, TMP2, TMP, GT);
2996 } 2989 }
2997 const Register temp = locs()->temp(0).reg(); 2990 const Register temp = locs()->temp(0).reg();
2998 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2991 __ SmiUntag(temp, left);
2999 __ asrv(result, temp, TMP); 2992 __ asrv(result, temp, TMP);
3000 __ SmiTag(result); 2993 __ SmiTag(result);
3001 break; 2994 break;
3002 } 2995 }
3003 case Token::kDIV: { 2996 case Token::kDIV: {
3004 // Dispatches to 'Double./'. 2997 // Dispatches to 'Double./'.
3005 // TODO(srdjan): Implement as conversion to double and double division. 2998 // TODO(srdjan): Implement as conversion to double and double division.
3006 UNREACHABLE(); 2999 UNREACHABLE();
3007 break; 3000 break;
3008 } 3001 }
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after
4507 __ fnegd(result, value); 4500 __ fnegd(result, value);
4508 } 4501 }
4509 4502
4510 4503
4511 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, 4504 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate,
4512 bool opt) const { 4505 bool opt) const {
4513 const intptr_t kNumInputs = 1; 4506 const intptr_t kNumInputs = 1;
4514 const intptr_t kNumTemps = 0; 4507 const intptr_t kNumTemps = 0;
4515 LocationSummary* result = new(isolate) LocationSummary( 4508 LocationSummary* result = new(isolate) LocationSummary(
4516 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4509 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4517 result->set_in(0, Location::WritableRegister()); 4510 result->set_in(0, Location::RequiresRegister());
4518 result->set_out(0, Location::RequiresFpuRegister()); 4511 result->set_out(0, Location::RequiresFpuRegister());
4519 return result; 4512 return result;
4520 } 4513 }
4521 4514
4522 4515
4523 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4516 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4524 const Register value = locs()->in(0).reg(); 4517 const Register value = locs()->in(0).reg();
4525 const VRegister result = locs()->out(0).fpu_reg(); 4518 const VRegister result = locs()->out(0).fpu_reg();
4526 __ SmiUntag(value); 4519 __ SmiUntag(TMP, value);
4527 __ scvtfd(result, value); 4520 __ scvtfd(result, TMP);
4528 } 4521 }
4529 4522
4530 4523
4531 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Isolate* isolate, 4524 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Isolate* isolate,
4532 bool opt) const { 4525 bool opt) const {
4533 const intptr_t kNumInputs = 1; 4526 const intptr_t kNumInputs = 1;
4534 const intptr_t kNumTemps = 0; 4527 const intptr_t kNumTemps = 0;
4535 LocationSummary* result = new(isolate) LocationSummary( 4528 LocationSummary* result = new(isolate) LocationSummary(
4536 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); 4529 isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
4537 result->set_in(0, Location::RegisterLocation(R1)); 4530 result->set_in(0, Location::RegisterLocation(R1));
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
4886 const PairLocation* pair = locs()->out(0).AsPairLocation(); 4879 const PairLocation* pair = locs()->out(0).AsPairLocation();
4887 const Register result_div = pair->At(0).reg(); 4880 const Register result_div = pair->At(0).reg();
4888 const Register result_mod = pair->At(1).reg(); 4881 const Register result_mod = pair->At(1).reg();
4889 const Range* right_range = InputAt(1)->definition()->range(); 4882 const Range* right_range = InputAt(1)->definition()->range();
4890 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4883 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4891 // Handle divide by zero in runtime. 4884 // Handle divide by zero in runtime.
4892 __ CompareRegisters(right, ZR); 4885 __ CompareRegisters(right, ZR);
4893 __ b(deopt, EQ); 4886 __ b(deopt, EQ);
4894 } 4887 }
4895 4888
4896 __ Asr(result_mod, left, kSmiTagSize); // SmiUntag left. 4889 __ SmiUntag(result_mod, left);
4897 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right. 4890 __ SmiUntag(TMP, right);
4898 4891
4899 __ sdiv(result_div, result_mod, TMP); 4892 __ sdiv(result_div, result_mod, TMP);
4900 4893
4901 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 4894 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
4902 // case we cannot tag the result. 4895 // case we cannot tag the result.
4903 __ CompareImmediate(result_div, 0x4000000000000000, PP); 4896 __ CompareImmediate(result_div, 0x4000000000000000, PP);
4904 __ b(deopt, EQ); 4897 __ b(deopt, EQ);
4905 // result_mod <- left - right * result_div. 4898 // result_mod <- left - right * result_div.
4906 __ msub(result_mod, TMP, result_div, result_mod); 4899 __ msub(result_mod, TMP, result_div, result_mod);
4907 __ SmiTag(result_div); 4900 __ SmiTag(result_div);
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
5401 compiler->GenerateCall(token_pos(), 5394 compiler->GenerateCall(token_pos(),
5402 &label, 5395 &label,
5403 PcDescriptors::kOther, 5396 PcDescriptors::kOther,
5404 locs()); 5397 locs());
5405 __ Drop(ArgumentCount()); // Discard arguments. 5398 __ Drop(ArgumentCount()); // Discard arguments.
5406 } 5399 }
5407 5400
5408 } // namespace dart 5401 } // namespace dart
5409 5402
5410 #endif // defined TARGET_ARCH_ARM64 5403 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698