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

Side by Side Diff: runtime/vm/intermediate_language_mips.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_arm64.cc ('k') | runtime/vm/simulator_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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 case kExternalTypedDataUint8ArrayCid: 1337 case kExternalTypedDataUint8ArrayCid:
1338 case kExternalTypedDataUint8ClampedArrayCid: 1338 case kExternalTypedDataUint8ClampedArrayCid:
1339 case kTypedDataInt8ArrayCid: 1339 case kTypedDataInt8ArrayCid:
1340 case kTypedDataUint8ArrayCid: 1340 case kTypedDataUint8ArrayCid:
1341 case kTypedDataUint8ClampedArrayCid: 1341 case kTypedDataUint8ClampedArrayCid:
1342 case kOneByteStringCid: 1342 case kOneByteStringCid:
1343 case kTypedDataInt16ArrayCid: 1343 case kTypedDataInt16ArrayCid:
1344 case kTypedDataUint16ArrayCid: 1344 case kTypedDataUint16ArrayCid:
1345 case kTypedDataInt32ArrayCid: 1345 case kTypedDataInt32ArrayCid:
1346 case kTypedDataUint32ArrayCid: 1346 case kTypedDataUint32ArrayCid:
1347 locs->set_in(2, Location::WritableRegister()); 1347 locs->set_in(2, Location::RequiresRegister());
1348 break; 1348 break;
1349 case kTypedDataFloat32ArrayCid: 1349 case kTypedDataFloat32ArrayCid:
1350 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. 1350 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
1351 case kTypedDataInt32x4ArrayCid: 1351 case kTypedDataInt32x4ArrayCid:
1352 case kTypedDataFloat32x4ArrayCid: 1352 case kTypedDataFloat32x4ArrayCid:
1353 locs->set_in(2, Location::RequiresFpuRegister()); 1353 locs->set_in(2, Location::RequiresFpuRegister());
1354 break; 1354 break;
1355 default: 1355 default:
1356 UNREACHABLE(); 1356 UNREACHABLE();
1357 return NULL; 1357 return NULL;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 case kTypedDataInt8ArrayCid: 1390 case kTypedDataInt8ArrayCid:
1391 case kTypedDataUint8ArrayCid: 1391 case kTypedDataUint8ArrayCid:
1392 case kExternalTypedDataUint8ArrayCid: 1392 case kExternalTypedDataUint8ArrayCid:
1393 case kOneByteStringCid: { 1393 case kOneByteStringCid: {
1394 if (locs()->in(2).IsConstant()) { 1394 if (locs()->in(2).IsConstant()) {
1395 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1395 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1396 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value())); 1396 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()));
1397 __ sb(TMP, element_address); 1397 __ sb(TMP, element_address);
1398 } else { 1398 } else {
1399 Register value = locs()->in(2).reg(); 1399 Register value = locs()->in(2).reg();
1400 __ SmiUntag(value); 1400 __ SmiUntag(TMP, value);
1401 __ sb(value, element_address); 1401 __ sb(TMP, element_address);
1402 } 1402 }
1403 break; 1403 break;
1404 } 1404 }
1405 case kTypedDataUint8ClampedArrayCid: 1405 case kTypedDataUint8ClampedArrayCid:
1406 case kExternalTypedDataUint8ClampedArrayCid: { 1406 case kExternalTypedDataUint8ClampedArrayCid: {
1407 if (locs()->in(2).IsConstant()) { 1407 if (locs()->in(2).IsConstant()) {
1408 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1408 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1409 intptr_t value = constant.Value(); 1409 intptr_t value = constant.Value();
1410 // Clamp to 0x0 or 0xFF respectively. 1410 // Clamp to 0x0 or 0xFF respectively.
1411 if (value > 0xFF) { 1411 if (value > 0xFF) {
1412 value = 0xFF; 1412 value = 0xFF;
1413 } else if (value < 0) { 1413 } else if (value < 0) {
1414 value = 0; 1414 value = 0;
1415 } 1415 }
1416 __ LoadImmediate(TMP, static_cast<int8_t>(value)); 1416 __ LoadImmediate(TMP, static_cast<int8_t>(value));
1417 __ sb(TMP, element_address); 1417 __ sb(TMP, element_address);
1418 } else { 1418 } else {
1419 Register value = locs()->in(2).reg(); 1419 Register value = locs()->in(2).reg();
1420 Label store_value, bigger, smaller; 1420 Label store_value, bigger, smaller;
1421 __ SmiUntag(value); 1421 __ SmiUntag(TMP, value);
1422 __ BranchUnsignedLess(value, 0xFF + 1, &store_value); 1422 __ BranchUnsignedLess(TMP, 0xFF + 1, &store_value);
1423 __ LoadImmediate(TMP, 0xFF); 1423 __ LoadImmediate(TMP, 0xFF);
1424 __ slti(CMPRES1, value, Immediate(1)); 1424 __ slti(CMPRES1, value, Immediate(1));
1425 __ movn(TMP, ZR, CMPRES1); 1425 __ movn(TMP, ZR, CMPRES1);
1426 __ mov(value, TMP);
1427 __ Bind(&store_value); 1426 __ Bind(&store_value);
1428 __ sb(value, element_address); 1427 __ sb(TMP, element_address);
1429 } 1428 }
1430 break; 1429 break;
1431 } 1430 }
1432 case kTypedDataInt16ArrayCid: 1431 case kTypedDataInt16ArrayCid:
1433 case kTypedDataUint16ArrayCid: { 1432 case kTypedDataUint16ArrayCid: {
1434 Register value = locs()->in(2).reg(); 1433 Register value = locs()->in(2).reg();
1435 __ SmiUntag(value); 1434 __ SmiUntag(TMP, value);
1436 __ sh(value, element_address); 1435 __ sh(TMP, element_address);
1437 break; 1436 break;
1438 } 1437 }
1439 case kTypedDataInt32ArrayCid: 1438 case kTypedDataInt32ArrayCid:
1440 case kTypedDataUint32ArrayCid: { 1439 case kTypedDataUint32ArrayCid: {
1441 if (value()->IsSmiValue()) { 1440 if (value()->IsSmiValue()) {
1442 ASSERT(RequiredInputRepresentation(2) == kTagged); 1441 ASSERT(RequiredInputRepresentation(2) == kTagged);
1443 Register value = locs()->in(2).reg(); 1442 Register value = locs()->in(2).reg();
1444 __ SmiUntag(value); 1443 __ SmiUntag(TMP, value);
1445 __ sw(value, element_address); 1444 __ sw(TMP, element_address);
1446 } else { 1445 } else {
1447 UNIMPLEMENTED(); 1446 UNIMPLEMENTED();
1448 } 1447 }
1449 break; 1448 break;
1450 } 1449 }
1451 case kTypedDataFloat32ArrayCid: { 1450 case kTypedDataFloat32ArrayCid: {
1452 FRegister value = EvenFRegisterOf(locs()->in(2).fpu_reg()); 1451 FRegister value = EvenFRegisterOf(locs()->in(2).fpu_reg());
1453 __ swc1(value, element_address); 1452 __ swc1(value, element_address);
1454 break; 1453 break;
1455 } 1454 }
(...skipping 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after
2697 return; 2696 return;
2698 } 2697 }
2699 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); 2698 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
2700 const bool right_needs_check = 2699 const bool right_needs_check =
2701 (right_range == NULL) || 2700 (right_range == NULL) ||
2702 !right_range->IsWithin(0, max_right - 1); 2701 !right_range->IsWithin(0, max_right - 1);
2703 if (right_needs_check) { 2702 if (right_needs_check) {
2704 __ BranchUnsignedGreaterEqual( 2703 __ BranchUnsignedGreaterEqual(
2705 right, reinterpret_cast<int32_t>(Smi::New(max_right)), deopt); 2704 right, reinterpret_cast<int32_t>(Smi::New(max_right)), deopt);
2706 } 2705 }
2707 __ sra(TMP, right, kSmiTagMask); // SmiUntag right into TMP. 2706 __ SmiUntag(TMP, right);
2708 __ sllv(result, left, TMP); 2707 __ sllv(result, left, TMP);
2709 } 2708 }
2710 return; 2709 return;
2711 } 2710 }
2712 2711
2713 const bool right_needs_check = 2712 const bool right_needs_check =
2714 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1)); 2713 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1));
2715 if (is_truncating) { 2714 if (is_truncating) {
2716 if (right_needs_check) { 2715 if (right_needs_check) {
2717 const bool right_may_be_negative = 2716 const bool right_may_be_negative =
(...skipping 18 matching lines...) Expand all
2736 } 2735 }
2737 } else { 2736 } else {
2738 if (right_needs_check) { 2737 if (right_needs_check) {
2739 ASSERT(shift_left->CanDeoptimize()); 2738 ASSERT(shift_left->CanDeoptimize());
2740 __ BranchUnsignedGreaterEqual( 2739 __ BranchUnsignedGreaterEqual(
2741 right, reinterpret_cast<int32_t>(Smi::New(Smi::kBits)), deopt); 2740 right, reinterpret_cast<int32_t>(Smi::New(Smi::kBits)), deopt);
2742 } 2741 }
2743 // Left is not a constant. 2742 // Left is not a constant.
2744 Register temp = locs.temp(0).reg(); 2743 Register temp = locs.temp(0).reg();
2745 // Check if count too large for handling it inlined. 2744 // Check if count too large for handling it inlined.
2746 __ sra(temp, right, kSmiTagSize); // SmiUntag right into temp. 2745 __ SmiUntag(temp, right);
2747 // Overflow test (preserve left, right, and temp); 2746 // Overflow test (preserve left, right, and temp);
2748 __ sllv(CMPRES1, left, temp); 2747 __ sllv(CMPRES1, left, temp);
2749 __ srav(CMPRES1, CMPRES1, temp); 2748 __ srav(CMPRES1, CMPRES1, temp);
2750 __ bne(CMPRES1, left, deopt); // Overflow. 2749 __ bne(CMPRES1, left, deopt); // Overflow.
2751 // Shift for result now we know there is no overflow. 2750 // Shift for result now we know there is no overflow.
2752 __ sllv(result, left, temp); 2751 __ sllv(result, left, temp);
2753 } 2752 }
2754 } 2753 }
2755 2754
2756 2755
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 // No overflow check. 3006 // No overflow check.
3008 __ xor_(result, left, right); 3007 __ xor_(result, left, right);
3009 break; 3008 break;
3010 } 3009 }
3011 case Token::kTRUNCDIV: { 3010 case Token::kTRUNCDIV: {
3012 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 3011 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
3013 // Handle divide by zero in runtime. 3012 // Handle divide by zero in runtime.
3014 __ beq(right, ZR, deopt); 3013 __ beq(right, ZR, deopt);
3015 } 3014 }
3016 Register temp = locs()->temp(0).reg(); 3015 Register temp = locs()->temp(0).reg();
3017 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. 3016 __ SmiUntag(temp, left);
3018 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 3017 __ SmiUntag(TMP, right);
3019 __ div(temp, TMP); 3018 __ div(temp, TMP);
3020 __ mflo(result); 3019 __ mflo(result);
3021 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 3020 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
3022 // case we cannot tag the result. 3021 // case we cannot tag the result.
3023 __ BranchEqual(result, 0x40000000, deopt); 3022 __ BranchEqual(result, 0x40000000, deopt);
3024 __ SmiTag(result); 3023 __ SmiTag(result);
3025 break; 3024 break;
3026 } 3025 }
3027 case Token::kMOD: { 3026 case Token::kMOD: {
3028 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 3027 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
3029 // Handle divide by zero in runtime. 3028 // Handle divide by zero in runtime.
3030 __ beq(right, ZR, deopt); 3029 __ beq(right, ZR, deopt);
3031 } 3030 }
3032 Register temp = locs()->temp(0).reg(); 3031 Register temp = locs()->temp(0).reg();
3033 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. 3032 __ SmiUntag(temp, left);
3034 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 3033 __ SmiUntag(TMP, right);
3035 __ div(temp, TMP); 3034 __ div(temp, TMP);
3036 __ mfhi(result); 3035 __ mfhi(result);
3037 // res = left % right; 3036 // res = left % right;
3038 // if (res < 0) { 3037 // if (res < 0) {
3039 // if (right < 0) { 3038 // if (right < 0) {
3040 // res = res - right; 3039 // res = res - right;
3041 // } else { 3040 // } else {
3042 // res = res + right; 3041 // res = res + right;
3043 // } 3042 // }
3044 // } 3043 // }
(...skipping 15 matching lines...) Expand all
3060 } 3059 }
3061 __ Bind(&done); 3060 __ Bind(&done);
3062 __ SmiTag(result); 3061 __ SmiTag(result);
3063 break; 3062 break;
3064 } 3063 }
3065 case Token::kSHR: { 3064 case Token::kSHR: {
3066 Register temp = locs()->temp(0).reg(); 3065 Register temp = locs()->temp(0).reg();
3067 if (CanDeoptimize()) { 3066 if (CanDeoptimize()) {
3068 __ bltz(right, deopt); 3067 __ bltz(right, deopt);
3069 } 3068 }
3070 __ sra(temp, right, kSmiTagSize); // SmiUntag right into temp. 3069 __ SmiUntag(temp, right);
3071 // sra operation masks the count to 5 bits. 3070 // sra operation masks the count to 5 bits.
3072 const intptr_t kCountLimit = 0x1F; 3071 const intptr_t kCountLimit = 0x1F;
3073 if ((right_range == NULL) || 3072 if ((right_range == NULL) ||
3074 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { 3073 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
3075 Label ok; 3074 Label ok;
3076 __ BranchSignedLessEqual(temp, kCountLimit, &ok); 3075 __ BranchSignedLessEqual(temp, kCountLimit, &ok);
3077 __ LoadImmediate(temp, kCountLimit); 3076 __ LoadImmediate(temp, kCountLimit);
3078 __ Bind(&ok); 3077 __ Bind(&ok);
3079 } 3078 }
3080 3079
3081 __ sra(CMPRES1, left, kSmiTagSize); // SmiUntag left into CMPRES1. 3080 __ SmiUntag(CMPRES1, left);
3082 __ srav(result, CMPRES1, temp); 3081 __ srav(result, CMPRES1, temp);
3083 __ SmiTag(result); 3082 __ SmiTag(result);
3084 break; 3083 break;
3085 } 3084 }
3086 case Token::kDIV: { 3085 case Token::kDIV: {
3087 // Dispatches to 'Double./'. 3086 // Dispatches to 'Double./'.
3088 // TODO(srdjan): Implement as conversion to double and double division. 3087 // TODO(srdjan): Implement as conversion to double and double division.
3089 UNREACHABLE(); 3088 UNREACHABLE();
3090 break; 3089 break;
3091 } 3090 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3166 out_reg, 3165 out_reg,
3167 locs()->temp(0).reg()); 3166 locs()->temp(0).reg());
3168 __ Bind(slow_path->exit_label()); 3167 __ Bind(slow_path->exit_label());
3169 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); 3168 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag);
3170 } 3169 }
3171 3170
3172 3171
3173 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, 3172 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate,
3174 bool opt) const { 3173 bool opt) const {
3175 const intptr_t kNumInputs = 1; 3174 const intptr_t kNumInputs = 1;
3176 const intptr_t value_cid = value()->Type()->ToCid();
3177 const bool needs_writable_input = (value_cid == kSmiCid);
3178 const intptr_t kNumTemps = 0; 3175 const intptr_t kNumTemps = 0;
3179 LocationSummary* summary = new(isolate) LocationSummary( 3176 LocationSummary* summary = new(isolate) LocationSummary(
3180 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3177 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3181 summary->set_in(0, needs_writable_input 3178 summary->set_in(0, Location::RequiresRegister());
3182 ? Location::WritableRegister()
3183 : Location::RequiresRegister());
3184 summary->set_out(0, Location::RequiresFpuRegister()); 3179 summary->set_out(0, Location::RequiresFpuRegister());
3185 return summary; 3180 return summary;
3186 } 3181 }
3187 3182
3188 3183
3189 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3184 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3190 CompileType* value_type = value()->Type(); 3185 CompileType* value_type = value()->Type();
3191 const intptr_t value_cid = value_type->ToCid(); 3186 const intptr_t value_cid = value_type->ToCid();
3192 const Register value = locs()->in(0).reg(); 3187 const Register value = locs()->in(0).reg();
3193 const DRegister result = locs()->out(0).fpu_reg(); 3188 const DRegister result = locs()->out(0).fpu_reg();
3194 3189
3195 if (value_cid == kDoubleCid) { 3190 if (value_cid == kDoubleCid) {
3196 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); 3191 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
3197 } else if (value_cid == kSmiCid) { 3192 } else if (value_cid == kSmiCid) {
3198 __ SmiUntag(value); // Untag input before conversion. 3193 __ SmiUntag(TMP, value);
3199 __ mtc1(value, STMP1); 3194 __ mtc1(TMP, STMP1);
3200 __ cvtdw(result, STMP1); 3195 __ cvtdw(result, STMP1);
3201 } else { 3196 } else {
3202 Label* deopt = compiler->AddDeoptStub(deopt_id_, 3197 Label* deopt = compiler->AddDeoptStub(deopt_id_,
3203 ICData::kDeoptBinaryDoubleOp); 3198 ICData::kDeoptBinaryDoubleOp);
3204 if (value_type->is_nullable() && 3199 if (value_type->is_nullable() &&
3205 (value_type->ToNullableCid() == kDoubleCid)) { 3200 (value_type->ToNullableCid() == kDoubleCid)) {
3206 __ BranchEqual(value, reinterpret_cast<int32_t>(Object::null()), deopt); 3201 __ BranchEqual(value, reinterpret_cast<int32_t>(Object::null()), deopt);
3207 // It must be double now. 3202 // It must be double now.
3208 __ LoadDFromOffset(result, value, 3203 __ LoadDFromOffset(result, value,
3209 Double::value_offset() - kHeapObjectTag); 3204 Double::value_offset() - kHeapObjectTag);
3210 } else { 3205 } else {
3211 Label is_smi, done; 3206 Label is_smi, done;
3212 3207
3213 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); 3208 __ andi(CMPRES1, value, Immediate(kSmiTagMask));
3214 __ beq(CMPRES1, ZR, &is_smi); 3209 __ beq(CMPRES1, ZR, &is_smi);
3215 __ LoadClassId(CMPRES1, value); 3210 __ LoadClassId(CMPRES1, value);
3216 __ BranchNotEqual(CMPRES1, kDoubleCid, deopt); 3211 __ BranchNotEqual(CMPRES1, kDoubleCid, deopt);
3217 __ LoadDFromOffset(result, value, 3212 __ LoadDFromOffset(result, value,
3218 Double::value_offset() - kHeapObjectTag); 3213 Double::value_offset() - kHeapObjectTag);
3219 __ b(&done); 3214 __ b(&done);
3220 __ Bind(&is_smi); 3215 __ Bind(&is_smi);
3221 // TODO(regis): Why do we preserve value here but not above? 3216 __ SmiUntag(TMP, value);
3222 __ sra(TMP, value, 1);
3223 __ mtc1(TMP, STMP1); 3217 __ mtc1(TMP, STMP1);
3224 __ cvtdw(result, STMP1); 3218 __ cvtdw(result, STMP1);
3225 __ Bind(&done); 3219 __ Bind(&done);
3226 } 3220 }
3227 } 3221 }
3228 } 3222 }
3229 3223
3230 3224
3231 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, 3225 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
3232 bool opt) const { 3226 bool opt) const {
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 } 3869 }
3876 3870
3877 3871
3878 3872
3879 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, 3873 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate,
3880 bool opt) const { 3874 bool opt) const {
3881 const intptr_t kNumInputs = 1; 3875 const intptr_t kNumInputs = 1;
3882 const intptr_t kNumTemps = 0; 3876 const intptr_t kNumTemps = 0;
3883 LocationSummary* result = new(isolate) LocationSummary( 3877 LocationSummary* result = new(isolate) LocationSummary(
3884 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3878 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3885 result->set_in(0, Location::WritableRegister()); 3879 result->set_in(0, Location::RequiresRegister());
3886 result->set_out(0, Location::RequiresFpuRegister()); 3880 result->set_out(0, Location::RequiresFpuRegister());
3887 return result; 3881 return result;
3888 } 3882 }
3889 3883
3890 3884
3891 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3885 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3892 Register value = locs()->in(0).reg(); 3886 Register value = locs()->in(0).reg();
3893 FpuRegister result = locs()->out(0).fpu_reg(); 3887 FpuRegister result = locs()->out(0).fpu_reg();
3894 __ SmiUntag(value); 3888 __ SmiUntag(TMP, value);
3895 __ mtc1(value, STMP1); 3889 __ mtc1(TMP, STMP1);
3896 __ cvtdw(result, STMP1); 3890 __ cvtdw(result, STMP1);
3897 } 3891 }
3898 3892
3899 3893
3900 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Isolate* isolate, 3894 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Isolate* isolate,
3901 bool opt) const { 3895 bool opt) const {
3902 const intptr_t kNumInputs = 1; 3896 const intptr_t kNumInputs = 1;
3903 const intptr_t kNumTemps = 0; 3897 const intptr_t kNumTemps = 0;
3904 LocationSummary* result = new(isolate) LocationSummary( 3898 LocationSummary* result = new(isolate) LocationSummary(
3905 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); 3899 isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
4243 Register temp = locs()->temp(0).reg(); 4237 Register temp = locs()->temp(0).reg();
4244 ASSERT(locs()->out(0).IsPairLocation()); 4238 ASSERT(locs()->out(0).IsPairLocation());
4245 PairLocation* pair = locs()->out(0).AsPairLocation(); 4239 PairLocation* pair = locs()->out(0).AsPairLocation();
4246 Register result_div = pair->At(0).reg(); 4240 Register result_div = pair->At(0).reg();
4247 Register result_mod = pair->At(1).reg(); 4241 Register result_mod = pair->At(1).reg();
4248 Range* right_range = InputAt(1)->definition()->range(); 4242 Range* right_range = InputAt(1)->definition()->range();
4249 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4243 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4250 // Handle divide by zero in runtime. 4244 // Handle divide by zero in runtime.
4251 __ beq(right, ZR, deopt); 4245 __ beq(right, ZR, deopt);
4252 } 4246 }
4253 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. 4247 __ SmiUntag(temp, left);
4254 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 4248 __ SmiUntag(TMP, right);
4255 __ div(temp, TMP); 4249 __ div(temp, TMP);
4256 __ mflo(result_div); 4250 __ mflo(result_div);
4257 __ mfhi(result_mod); 4251 __ mfhi(result_mod);
4258 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 4252 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
4259 // case we cannot tag the result. 4253 // case we cannot tag the result.
4260 __ BranchEqual(result_div, 0x40000000, deopt); 4254 __ BranchEqual(result_div, 0x40000000, deopt);
4261 // res = left % right; 4255 // res = left % right;
4262 // if (res < 0) { 4256 // if (res < 0) {
4263 // if (right < 0) { 4257 // if (right < 0) {
4264 // res = res - right; 4258 // res = res - right;
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
4757 compiler->GenerateCall(token_pos(), 4751 compiler->GenerateCall(token_pos(),
4758 &label, 4752 &label,
4759 PcDescriptors::kOther, 4753 PcDescriptors::kOther,
4760 locs()); 4754 locs());
4761 __ Drop(ArgumentCount()); // Discard arguments. 4755 __ Drop(ArgumentCount()); // Discard arguments.
4762 } 4756 }
4763 4757
4764 } // namespace dart 4758 } // namespace dart
4765 4759
4766 #endif // defined TARGET_ARCH_MIPS 4760 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm64.cc ('k') | runtime/vm/simulator_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698