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

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

Issue 579243003: Fixes a bug in CheckClassInstr on arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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/assembler_arm64.h ('k') | runtime/vm/intrinsifier_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) 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } else { 172 } else {
173 true_condition = NegateCondition(true_condition); 173 true_condition = NegateCondition(true_condition);
174 } 174 }
175 } 175 }
176 176
177 __ cset(result, true_condition); 177 __ cset(result, true_condition);
178 178
179 if (is_power_of_two_kind) { 179 if (is_power_of_two_kind) {
180 const intptr_t shift = 180 const intptr_t shift =
181 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); 181 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
182 __ Lsl(result, result, shift + kSmiTagSize); 182 __ LslImmediate(result, result, shift + kSmiTagSize);
183 } else { 183 } else {
184 __ sub(result, result, Operand(1)); 184 __ sub(result, result, Operand(1));
185 const int64_t val = 185 const int64_t val =
186 Smi::RawValue(true_value) - Smi::RawValue(false_value); 186 Smi::RawValue(true_value) - Smi::RawValue(false_value);
187 __ AndImmediate(result, result, val, PP); 187 __ AndImmediate(result, result, val, PP);
188 if (false_value != 0) { 188 if (false_value != 0) {
189 __ AddImmediate(result, result, Smi::RawValue(false_value), PP); 189 __ AddImmediate(result, result, Smi::RawValue(false_value), PP);
190 } 190 }
191 } 191 }
192 } 192 }
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 } 841 }
842 842
843 843
844 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 844 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
845 const Register char_code = locs()->in(0).reg(); 845 const Register char_code = locs()->in(0).reg();
846 const Register result = locs()->out(0).reg(); 846 const Register result = locs()->out(0).reg();
847 __ LoadImmediate( 847 __ LoadImmediate(
848 result, reinterpret_cast<uword>(Symbols::PredefinedAddress()), PP); 848 result, reinterpret_cast<uword>(Symbols::PredefinedAddress()), PP);
849 __ AddImmediate( 849 __ AddImmediate(
850 result, result, Symbols::kNullCharCodeSymbolOffset * kWordSize, PP); 850 result, result, Symbols::kNullCharCodeSymbolOffset * kWordSize, PP);
851 __ Asr(TMP, char_code, kSmiTagShift); // Untag to use scaled adress mode. 851 __ SmiUntag(TMP, char_code); // Untag to use scaled adress mode.
852 __ ldr(result, Address(result, TMP, UXTX, Address::Scaled)); 852 __ ldr(result, Address(result, TMP, UXTX, Address::Scaled));
853 } 853 }
854 854
855 855
856 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Isolate* isolate, 856 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Isolate* isolate,
857 bool opt) const { 857 bool opt) const {
858 const intptr_t kNumInputs = 1; 858 const intptr_t kNumInputs = 1;
859 return LocationSummary::Make(isolate, 859 return LocationSummary::Make(isolate,
860 kNumInputs, 860 kNumInputs,
861 Location::RequiresRegister(), 861 Location::RequiresRegister(),
(...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 : NULL; 2540 : NULL;
2541 if (locs.in(1).IsConstant()) { 2541 if (locs.in(1).IsConstant()) {
2542 const Object& constant = locs.in(1).constant(); 2542 const Object& constant = locs.in(1).constant();
2543 ASSERT(constant.IsSmi()); 2543 ASSERT(constant.IsSmi());
2544 // Immediate shift operation takes 6 bits for the count. 2544 // Immediate shift operation takes 6 bits for the count.
2545 const intptr_t kCountLimit = 0x3F; 2545 const intptr_t kCountLimit = 0x3F;
2546 const intptr_t value = Smi::Cast(constant).Value(); 2546 const intptr_t value = Smi::Cast(constant).Value();
2547 ASSERT((0 < value) && (value < kCountLimit)); 2547 ASSERT((0 < value) && (value < kCountLimit));
2548 if (shift_left->can_overflow()) { 2548 if (shift_left->can_overflow()) {
2549 // Check for overflow (preserve left). 2549 // Check for overflow (preserve left).
2550 __ Lsl(TMP, left, value); 2550 __ LslImmediate(TMP, left, value);
2551 __ cmp(left, Operand(TMP, ASR, value)); 2551 __ cmp(left, Operand(TMP, ASR, value));
2552 __ b(deopt, NE); // Overflow. 2552 __ b(deopt, NE); // Overflow.
2553 } 2553 }
2554 // Shift for result now we know there is no overflow. 2554 // Shift for result now we know there is no overflow.
2555 __ Lsl(result, left, value); 2555 __ LslImmediate(result, left, value);
2556 if (FLAG_throw_on_javascript_int_overflow) { 2556 if (FLAG_throw_on_javascript_int_overflow) {
2557 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result); 2557 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2558 } 2558 }
2559 return; 2559 return;
2560 } 2560 }
2561 2561
2562 // Right (locs.in(1)) is not constant. 2562 // Right (locs.in(1)) is not constant.
2563 const Register right = locs.in(1).reg(); 2563 const Register right = locs.in(1).reg();
2564 Range* right_range = shift_left->right()->definition()->range(); 2564 Range* right_range = shift_left->right()->definition()->range();
2565 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) { 2565 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2726 __ b(deopt, NE); 2726 __ b(deopt, NE);
2727 } 2727 }
2728 break; 2728 break;
2729 } 2729 }
2730 case Token::kTRUNCDIV: { 2730 case Token::kTRUNCDIV: {
2731 const intptr_t value = Smi::Cast(constant).Value(); 2731 const intptr_t value = Smi::Cast(constant).Value();
2732 ASSERT(Utils::IsPowerOfTwo(Utils::Abs(value))); 2732 ASSERT(Utils::IsPowerOfTwo(Utils::Abs(value)));
2733 const intptr_t shift_count = 2733 const intptr_t shift_count =
2734 Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize; 2734 Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize;
2735 ASSERT(kSmiTagSize == 1); 2735 ASSERT(kSmiTagSize == 1);
2736 __ Asr(TMP, left, 63); 2736 __ AsrImmediate(TMP, left, 63);
2737 ASSERT(shift_count > 1); // 1, -1 case handled above. 2737 ASSERT(shift_count > 1); // 1, -1 case handled above.
2738 const Register temp = TMP2; 2738 const Register temp = TMP2;
2739 __ add(temp, left, Operand(TMP, LSR, 64 - shift_count)); 2739 __ add(temp, left, Operand(TMP, LSR, 64 - shift_count));
2740 ASSERT(shift_count > 0); 2740 ASSERT(shift_count > 0);
2741 __ Asr(result, temp, shift_count); 2741 __ AsrImmediate(result, temp, shift_count);
2742 if (value < 0) { 2742 if (value < 0) {
2743 __ sub(result, ZR, Operand(result)); 2743 __ sub(result, ZR, Operand(result));
2744 } 2744 }
2745 __ SmiTag(result); 2745 __ SmiTag(result);
2746 break; 2746 break;
2747 } 2747 }
2748 case Token::kBIT_AND: 2748 case Token::kBIT_AND:
2749 // No overflow check. 2749 // No overflow check.
2750 __ AndImmediate(result, left, imm, PP); 2750 __ AndImmediate(result, left, imm, PP);
2751 break; 2751 break;
2752 case Token::kBIT_OR: 2752 case Token::kBIT_OR:
2753 // No overflow check. 2753 // No overflow check.
2754 __ OrImmediate(result, left, imm, PP); 2754 __ OrImmediate(result, left, imm, PP);
2755 break; 2755 break;
2756 case Token::kBIT_XOR: 2756 case Token::kBIT_XOR:
2757 // No overflow check. 2757 // No overflow check.
2758 __ XorImmediate(result, left, imm, PP); 2758 __ XorImmediate(result, left, imm, PP);
2759 break; 2759 break;
2760 case Token::kSHR: { 2760 case Token::kSHR: {
2761 // Asr operation masks the count to 6 bits. 2761 // Asr operation masks the count to 6 bits.
2762 const intptr_t kCountLimit = 0x3F; 2762 const intptr_t kCountLimit = 0x3F;
2763 intptr_t value = Smi::Cast(constant).Value(); 2763 intptr_t value = Smi::Cast(constant).Value();
2764 __ Asr(result, left, Utils::Minimum(value + kSmiTagSize, kCountLimit)); 2764 __ AsrImmediate(
2765 result, left, Utils::Minimum(value + kSmiTagSize, kCountLimit));
2765 __ SmiTag(result); 2766 __ SmiTag(result);
2766 break; 2767 break;
2767 } 2768 }
2768 default: 2769 default:
2769 UNREACHABLE(); 2770 UNREACHABLE();
2770 break; 2771 break;
2771 } 2772 }
2772 if (FLAG_throw_on_javascript_int_overflow) { 2773 if (FLAG_throw_on_javascript_int_overflow) {
2773 EmitJavascriptOverflowCheck(compiler, range(), deopt, result); 2774 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
2774 } 2775 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 2993
2993 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2994 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2994 CompileType* value_type = value()->Type(); 2995 CompileType* value_type = value()->Type();
2995 const intptr_t value_cid = value_type->ToCid(); 2996 const intptr_t value_cid = value_type->ToCid();
2996 const Register value = locs()->in(0).reg(); 2997 const Register value = locs()->in(0).reg();
2997 const VRegister result = locs()->out(0).fpu_reg(); 2998 const VRegister result = locs()->out(0).fpu_reg();
2998 2999
2999 if (value_cid == kDoubleCid) { 3000 if (value_cid == kDoubleCid) {
3000 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP); 3001 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP);
3001 } else if (value_cid == kSmiCid) { 3002 } else if (value_cid == kSmiCid) {
3002 __ Asr(TMP, value, kSmiTagSize); // Untag input before conversion. 3003 __ SmiUntag(TMP, value); // Untag input before conversion.
3003 __ scvtfd(result, TMP); 3004 __ scvtfd(result, TMP);
3004 } else { 3005 } else {
3005 Label* deopt = compiler->AddDeoptStub(deopt_id_, 3006 Label* deopt = compiler->AddDeoptStub(deopt_id_,
3006 ICData::kDeoptBinaryDoubleOp); 3007 ICData::kDeoptBinaryDoubleOp);
3007 if (value_type->is_nullable() && 3008 if (value_type->is_nullable() &&
3008 (value_type->ToNullableCid() == kDoubleCid)) { 3009 (value_type->ToNullableCid() == kDoubleCid)) {
3009 __ CompareObject(value, Object::null_object(), PP); 3010 __ CompareObject(value, Object::null_object(), PP);
3010 __ b(deopt, EQ); 3011 __ b(deopt, EQ);
3011 // It must be double now. 3012 // It must be double now.
3012 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP); 3013 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP);
3013 } else { 3014 } else {
3014 Label is_smi, done; 3015 Label is_smi, done;
3015 __ tsti(value, kSmiTagMask); 3016 __ tsti(value, kSmiTagMask);
3016 __ b(&is_smi, EQ); 3017 __ b(&is_smi, EQ);
3017 __ CompareClassId(value, kDoubleCid, PP); 3018 __ CompareClassId(value, kDoubleCid, PP);
3018 __ b(deopt, NE); 3019 __ b(deopt, NE);
3019 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP); 3020 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP);
3020 __ b(&done); 3021 __ b(&done);
3021 __ Bind(&is_smi); 3022 __ Bind(&is_smi);
3022 __ Asr(TMP, value, kSmiTagSize); // Copy and untag. 3023 __ SmiUntag(TMP, value); // Copy and untag.
3023 __ scvtfd(result, TMP); 3024 __ scvtfd(result, TMP);
3024 __ Bind(&done); 3025 __ Bind(&done);
3025 } 3026 }
3026 } 3027 }
3027 } 3028 }
3028 3029
3029 3030
3030 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, 3031 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
3031 bool opt) const { 3032 bool opt) const {
3032 const intptr_t kNumInputs = 1; 3033 const intptr_t kNumInputs = 1;
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
3367 } 3368 }
3368 3369
3369 3370
3370 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3371 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3371 const VRegister value = locs()->in(0).fpu_reg(); 3372 const VRegister value = locs()->in(0).fpu_reg();
3372 const Register out = locs()->out(0).reg(); 3373 const Register out = locs()->out(0).reg();
3373 const Register temp = locs()->temp(0).reg(); 3374 const Register temp = locs()->temp(0).reg();
3374 3375
3375 // X lane. 3376 // X lane.
3376 __ vmovrs(out, value, 0); 3377 __ vmovrs(out, value, 0);
3377 __ Lsr(out, out, 31); 3378 __ LsrImmediate(out, out, 31);
3378 // Y lane. 3379 // Y lane.
3379 __ vmovrs(temp, value, 1); 3380 __ vmovrs(temp, value, 1);
3380 __ Lsr(temp, temp, 31); 3381 __ LsrImmediate(temp, temp, 31);
3381 __ orr(out, out, Operand(temp, LSL, 1)); 3382 __ orr(out, out, Operand(temp, LSL, 1));
3382 // Z lane. 3383 // Z lane.
3383 __ vmovrs(temp, value, 2); 3384 __ vmovrs(temp, value, 2);
3384 __ Lsr(temp, temp, 31); 3385 __ LsrImmediate(temp, temp, 31);
3385 __ orr(out, out, Operand(temp, LSL, 2)); 3386 __ orr(out, out, Operand(temp, LSL, 2));
3386 // W lane. 3387 // W lane.
3387 __ vmovrs(temp, value, 3); 3388 __ vmovrs(temp, value, 3);
3388 __ Lsr(temp, temp, 31); 3389 __ LsrImmediate(temp, temp, 31);
3389 __ orr(out, out, Operand(temp, LSL, 3)); 3390 __ orr(out, out, Operand(temp, LSL, 3));
3390 // Tag. 3391 // Tag.
3391 __ SmiTag(out); 3392 __ SmiTag(out);
3392 } 3393 }
3393 3394
3394 3395
3395 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( 3396 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary(
3396 Isolate* isolate, bool opt) const { 3397 Isolate* isolate, bool opt) const {
3397 const intptr_t kNumInputs = 4; 3398 const intptr_t kNumInputs = 4;
3398 const intptr_t kNumTemps = 0; 3399 const intptr_t kNumTemps = 0;
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
3878 3879
3879 3880
3880 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3881 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3881 const VRegister value = locs()->in(0).fpu_reg(); 3882 const VRegister value = locs()->in(0).fpu_reg();
3882 3883
3883 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { 3884 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) {
3884 const Register out = locs()->out(0).reg(); 3885 const Register out = locs()->out(0).reg();
3885 3886
3886 // Bits of X lane. 3887 // Bits of X lane.
3887 __ vmovrd(out, value, 0); 3888 __ vmovrd(out, value, 0);
3888 __ Lsr(out, out, 63); 3889 __ LsrImmediate(out, out, 63);
3889 // Bits of Y lane. 3890 // Bits of Y lane.
3890 __ vmovrd(TMP, value, 1); 3891 __ vmovrd(TMP, value, 1);
3891 __ Lsr(TMP, TMP, 63); 3892 __ LsrImmediate(TMP, TMP, 63);
3892 __ orr(out, out, Operand(TMP, LSL, 1)); 3893 __ orr(out, out, Operand(TMP, LSL, 1));
3893 // Tag. 3894 // Tag.
3894 __ SmiTag(out); 3895 __ SmiTag(out);
3895 return; 3896 return;
3896 } 3897 }
3897 ASSERT(representation() == kUnboxedFloat64x2); 3898 ASSERT(representation() == kUnboxedFloat64x2);
3898 const VRegister result = locs()->out(0).fpu_reg(); 3899 const VRegister result = locs()->out(0).fpu_reg();
3899 3900
3900 switch (op_kind()) { 3901 switch (op_kind()) {
3901 case MethodRecognizer::kFloat64x2Negate: 3902 case MethodRecognizer::kFloat64x2Negate:
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
4920 __ AddImmediate(temp, temp, -cids_[0], PP); 4921 __ AddImmediate(temp, temp, -cids_[0], PP);
4921 __ CompareImmediate(temp, cids_[cids_.length() - 1] - cids_[0], PP); 4922 __ CompareImmediate(temp, cids_[cids_.length() - 1] - cids_[0], PP);
4922 __ b(deopt, HI); 4923 __ b(deopt, HI);
4923 4924
4924 intptr_t mask = ComputeCidMask(); 4925 intptr_t mask = ComputeCidMask();
4925 if (!IsDenseMask(mask)) { 4926 if (!IsDenseMask(mask)) {
4926 // Only need mask if there are missing numbers in the range. 4927 // Only need mask if there are missing numbers in the range.
4927 ASSERT(cids_.length() > 2); 4928 ASSERT(cids_.length() > 2);
4928 Register mask_reg = locs()->temp(1).reg(); 4929 Register mask_reg = locs()->temp(1).reg();
4929 __ LoadImmediate(mask_reg, 1, PP); 4930 __ LoadImmediate(mask_reg, 1, PP);
4930 __ Lsl(mask_reg, mask_reg, temp); 4931 __ lslv(mask_reg, mask_reg, temp);
zra 2014/09/18 16:07:52 This was the bug.
4931 __ TestImmediate(mask_reg, mask, PP); 4932 __ TestImmediate(mask_reg, mask, PP);
4932 __ b(deopt, EQ); 4933 __ b(deopt, EQ);
4933 } 4934 }
4934 4935
4935 } else { 4936 } else {
4936 const intptr_t num_checks = unary_checks().NumberOfChecks(); 4937 const intptr_t num_checks = unary_checks().NumberOfChecks();
4937 for (intptr_t i = cix; i < num_checks; i++) { 4938 for (intptr_t i = cix; i < num_checks; i++) {
4938 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); 4939 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid);
4939 __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i), PP); 4940 __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i), PP);
4940 if (i == (num_checks - 1)) { 4941 if (i == (num_checks - 1)) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
5189 } 5190 }
5190 5191
5191 5192
5192 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5193 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5193 Register value = locs()->in(0).reg(); 5194 Register value = locs()->in(0).reg();
5194 Register out = locs()->out(0).reg(); 5195 Register out = locs()->out(0).reg();
5195 ASSERT(value != out); 5196 ASSERT(value != out);
5196 5197
5197 ASSERT(kSmiTagSize == 1); 5198 ASSERT(kSmiTagSize == 1);
5198 // TODO(vegorov) implement and use UBFM/SBFM for this. 5199 // TODO(vegorov) implement and use UBFM/SBFM for this.
5199 __ Lsl(out, value, 32); 5200 __ LslImmediate(out, value, 32);
5200 if (from_representation() == kUnboxedInt32) { 5201 if (from_representation() == kUnboxedInt32) {
5201 __ Asr(out, out, 32 - kSmiTagSize); 5202 __ AsrImmediate(out, out, 32 - kSmiTagSize);
5202 } else { 5203 } else {
5203 ASSERT(from_representation() == kUnboxedUint32); 5204 ASSERT(from_representation() == kUnboxedUint32);
5204 __ Lsr(out, out, 32 - kSmiTagSize); 5205 __ LsrImmediate(out, out, 32 - kSmiTagSize);
5205 } 5206 }
5206 } 5207 }
5207 5208
5208 5209
5209 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, 5210 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
5210 bool opt) const { 5211 bool opt) const {
5211 const intptr_t kNumInputs = 1; 5212 const intptr_t kNumInputs = 1;
5212 const intptr_t kNumTemps = 0; 5213 const intptr_t kNumTemps = 0;
5213 LocationSummary* summary = new(isolate) LocationSummary( 5214 LocationSummary* summary = new(isolate) LocationSummary(
5214 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5215 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 13 matching lines...) Expand all
5228 5229
5229 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5230 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5230 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) { 5231 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) {
5231 const Register value = locs()->in(0).reg(); 5232 const Register value = locs()->in(0).reg();
5232 const Register out = locs()->out(0).reg(); 5233 const Register out = locs()->out(0).reg();
5233 // Representations are bitwise equivalent but we want to normalize 5234 // Representations are bitwise equivalent but we want to normalize
5234 // upperbits for safety reasons. 5235 // upperbits for safety reasons.
5235 // TODO(vegorov) if we ensure that we never use kDoubleWord size 5236 // TODO(vegorov) if we ensure that we never use kDoubleWord size
5236 // with it then we could avoid this. 5237 // with it then we could avoid this.
5237 // TODO(vegorov) implement and use UBFM for zero extension. 5238 // TODO(vegorov) implement and use UBFM for zero extension.
5238 __ Lsl(out, value, 32); 5239 __ LslImmediate(out, value, 32);
5239 __ Lsr(out, out, 32); 5240 __ LsrImmediate(out, out, 32);
5240 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { 5241 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) {
5241 // Representations are bitwise equivalent. 5242 // Representations are bitwise equivalent.
5242 // TODO(vegorov) if we ensure that we never use kDoubleWord size 5243 // TODO(vegorov) if we ensure that we never use kDoubleWord size
5243 // with it then we could avoid this. 5244 // with it then we could avoid this.
5244 // TODO(vegorov) implement and use SBFM for sign extension. 5245 // TODO(vegorov) implement and use SBFM for sign extension.
5245 const Register value = locs()->in(0).reg(); 5246 const Register value = locs()->in(0).reg();
5246 const Register out = locs()->out(0).reg(); 5247 const Register out = locs()->out(0).reg();
5247 __ Lsl(out, value, 32); 5248 __ LslImmediate(out, value, 32);
5248 __ Asr(out, out, 32); 5249 __ AsrImmediate(out, out, 32);
5249 if (CanDeoptimize()) { 5250 if (CanDeoptimize()) {
5250 Label* deopt = 5251 Label* deopt =
5251 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); 5252 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
5252 __ cmp(out, Operand(value, UXTW, 0)); 5253 __ cmp(out, Operand(value, UXTW, 0));
5253 __ b(deopt, NE); 5254 __ b(deopt, NE);
5254 } 5255 }
5255 } else if (from() == kUnboxedMint) { 5256 } else if (from() == kUnboxedMint) {
5256 UNREACHABLE(); 5257 UNREACHABLE();
5257 } else if (to() == kUnboxedMint) { 5258 } else if (to() == kUnboxedMint) {
5258 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 5259 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
5477 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 5478 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
5478 #if defined(DEBUG) 5479 #if defined(DEBUG)
5479 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); 5480 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP);
5480 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); 5481 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP);
5481 #endif 5482 #endif
5482 } 5483 }
5483 5484
5484 } // namespace dart 5485 } // namespace dart
5485 5486
5486 #endif // defined TARGET_ARCH_ARM64 5487 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/intrinsifier_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698