| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |