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

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

Issue 262333007: Adds arm64 double arithmetic instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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/simulator_arm64.h » ('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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 if (true_value == 0) { 154 if (true_value == 0) {
155 // Swap values so that false_value is zero. 155 // Swap values so that false_value is zero.
156 intptr_t temp = true_value; 156 intptr_t temp = true_value;
157 true_value = false_value; 157 true_value = false_value;
158 false_value = temp; 158 false_value = temp;
159 } else { 159 } else {
160 true_condition = NegateCondition(true_condition); 160 true_condition = NegateCondition(true_condition);
161 } 161 }
162 } 162 }
163 163
164 // TODO(zra): replace with cinc(result, ZR, ZR, true_condition) 164 __ cset(result, true_condition);
165 __ LoadImmediate(TMP, 1, kNoPP);
166 __ csel(result, TMP, ZR, true_condition);
167 165
168 if (is_power_of_two_kind) { 166 if (is_power_of_two_kind) {
169 const intptr_t shift = 167 const intptr_t shift =
170 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); 168 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
171 __ Lsl(result, result, shift + kSmiTagSize); 169 __ Lsl(result, result, shift + kSmiTagSize);
172 } else { 170 } else {
173 __ sub(result, result, Operand(1)); 171 __ sub(result, result, Operand(1));
174 const int32_t val = 172 const int32_t val =
175 Smi::RawValue(true_value) - Smi::RawValue(false_value); 173 Smi::RawValue(true_value) - Smi::RawValue(false_value);
176 __ AndImmediate(result, result, val, PP); 174 __ AndImmediate(result, result, val, PP);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 275
278 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(bool opt) const { 276 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(bool opt) const {
279 const intptr_t kNumInputs = 0; 277 const intptr_t kNumInputs = 0;
280 return LocationSummary::Make(kNumInputs, 278 return LocationSummary::Make(kNumInputs,
281 Location::RequiresFpuRegister(), 279 Location::RequiresFpuRegister(),
282 LocationSummary::kNoCall); 280 LocationSummary::kNoCall);
283 } 281 }
284 282
285 283
286 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 284 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
287 UNIMPLEMENTED(); 285 if (!locs()->out(0).IsInvalid()) {
286 const VRegister dst = locs()->out(0).fpu_reg();
287 __ LoadDImmediate(dst, Double::Cast(value()).value(), PP);
288 }
288 } 289 }
289 290
290 291
291 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { 292 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const {
292 const intptr_t kNumInputs = 3; 293 const intptr_t kNumInputs = 3;
293 const intptr_t kNumTemps = 0; 294 const intptr_t kNumTemps = 0;
294 LocationSummary* summary = 295 LocationSummary* summary =
295 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 296 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
296 summary->set_in(0, Location::RegisterLocation(R0)); // Value. 297 summary->set_in(0, Location::RegisterLocation(R0)); // Value.
297 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. 298 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 ? Location::RequiresRegister() 445 ? Location::RequiresRegister()
445 : Location::RegisterOrConstant(right())); 446 : Location::RegisterOrConstant(right()));
446 locs->set_out(0, Location::RequiresRegister()); 447 locs->set_out(0, Location::RequiresRegister());
447 return locs; 448 return locs;
448 } 449 }
449 UNREACHABLE(); 450 UNREACHABLE();
450 return NULL; 451 return NULL;
451 } 452 }
452 453
453 454
455 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
456 switch (kind) {
457 case Token::kEQ: return EQ;
458 case Token::kNE: return NE;
459 case Token::kLT: return LT;
460 case Token::kGT: return GT;
461 case Token::kLTE: return LE;
462 case Token::kGTE: return GE;
463 default:
464 UNREACHABLE();
465 return VS;
466 }
467 }
468
469
470 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
471 LocationSummary* locs,
472 Token::Kind kind) {
473 VRegister left = locs->in(0).fpu_reg();
474 VRegister right = locs->in(1).fpu_reg();
475 __ fcmpd(left, right);
476 Condition true_condition = TokenKindToDoubleCondition(kind);
477 return true_condition;
478 }
479
480
454 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 481 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
455 BranchLabels labels) { 482 BranchLabels labels) {
456 if (operation_cid() == kSmiCid) { 483 if (operation_cid() == kSmiCid) {
457 return EmitSmiComparisonOp(compiler, locs(), kind()); 484 return EmitSmiComparisonOp(compiler, locs(), kind());
458 } else { 485 } else {
459 UNIMPLEMENTED(); 486 ASSERT(operation_cid() == kDoubleCid);
460 return VS; 487 return EmitDoubleComparisonOp(compiler, locs(), kind());
461 } 488 }
462 } 489 }
463 490
464 491
465 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 492 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
466 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 493 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
467 494
468 Label is_true, is_false; 495 Label is_true, is_false;
469 BranchLabels labels = { &is_true, &is_false, &is_false }; 496 BranchLabels labels = { &is_true, &is_false, &is_false };
470 Condition true_condition = EmitComparisonCode(compiler, labels); 497 Condition true_condition = EmitComparisonCode(compiler, labels);
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 case kTwoByteStringCid: 1050 case kTwoByteStringCid:
1024 __ ldr(result, element_address, kUnsignedHalfword); 1051 __ ldr(result, element_address, kUnsignedHalfword);
1025 __ SmiTag(result); 1052 __ SmiTag(result);
1026 break; 1053 break;
1027 case kTypedDataInt32ArrayCid: 1054 case kTypedDataInt32ArrayCid:
1028 __ ldr(result, element_address, kWord); 1055 __ ldr(result, element_address, kWord);
1029 __ SmiTag(result); 1056 __ SmiTag(result);
1030 break; 1057 break;
1031 case kTypedDataUint32ArrayCid: 1058 case kTypedDataUint32ArrayCid:
1032 __ ldr(result, element_address, kUnsignedWord); 1059 __ ldr(result, element_address, kUnsignedWord);
1060 __ SmiTag(result);
1033 break; 1061 break;
1034 default: 1062 default:
1035 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1063 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1036 __ ldr(result, element_address); 1064 __ ldr(result, element_address);
1037 break; 1065 break;
1038 } 1066 }
1039 } 1067 }
1040 1068
1041 1069
1042 Representation StoreIndexedInstr::RequiredInputRepresentation( 1070 Representation StoreIndexedInstr::RequiredInputRepresentation(
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 } 1278 }
1251 break; 1279 break;
1252 } 1280 }
1253 case kTypedDataFloat32ArrayCid: 1281 case kTypedDataFloat32ArrayCid:
1254 // TODO(zra): Implement when we add float store. 1282 // TODO(zra): Implement when we add float store.
1255 UNIMPLEMENTED(); 1283 UNIMPLEMENTED();
1256 break; 1284 break;
1257 case kTypedDataFloat64ArrayCid: { 1285 case kTypedDataFloat64ArrayCid: {
1258 VRegister in2 = locs()->in(2).fpu_reg(); 1286 VRegister in2 = locs()->in(2).fpu_reg();
1259 __ add(index.reg(), index.reg(), Operand(array)); 1287 __ add(index.reg(), index.reg(), Operand(array));
1260 __ StoreDFieldToOffset(in2, index.reg(), 0); 1288 __ StoreDToOffset(in2, index.reg(), 0);
1261 break; 1289 break;
1262 } 1290 }
1263 case kTypedDataFloat64x2ArrayCid: 1291 case kTypedDataFloat64x2ArrayCid:
1264 case kTypedDataInt32x4ArrayCid: 1292 case kTypedDataInt32x4ArrayCid:
1265 case kTypedDataFloat32x4ArrayCid: { 1293 case kTypedDataFloat32x4ArrayCid: {
1266 // TODO(zra): Implement when we add simd loads and stores. 1294 // TODO(zra): Implement when we add simd loads and stores.
1267 UNIMPLEMENTED(); 1295 UNIMPLEMENTED();
1268 break; 1296 break;
1269 } 1297 }
1270 default: 1298 default:
(...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after
2783 break; 2811 break;
2784 } 2812 }
2785 default: 2813 default:
2786 UNREACHABLE(); 2814 UNREACHABLE();
2787 break; 2815 break;
2788 } 2816 }
2789 } 2817 }
2790 2818
2791 2819
2792 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const { 2820 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const {
2793 UNIMPLEMENTED(); 2821 intptr_t left_cid = left()->Type()->ToCid();
2794 return NULL; 2822 intptr_t right_cid = right()->Type()->ToCid();
2823 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid));
2824 const intptr_t kNumInputs = 2;
2825 const intptr_t kNumTemps = 0;
2826 LocationSummary* summary =
2827 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2828 summary->set_in(0, Location::RequiresRegister());
2829 summary->set_in(1, Location::RequiresRegister());
2830 return summary;
2795 } 2831 }
2796 2832
2797 2833
2798 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2834 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2799 UNIMPLEMENTED(); 2835 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2836 ICData::kDeoptBinaryDoubleOp);
2837 intptr_t left_cid = left()->Type()->ToCid();
2838 intptr_t right_cid = right()->Type()->ToCid();
2839 Register left = locs()->in(0).reg();
2840 Register right = locs()->in(1).reg();
2841 if (left_cid == kSmiCid) {
2842 __ tsti(right, kSmiTagMask);
2843 } else if (right_cid == kSmiCid) {
2844 __ tsti(left, kSmiTagMask);
2845 } else {
2846 __ orr(TMP, left, Operand(right));
2847 __ tsti(TMP, kSmiTagMask);
2848 }
2849 __ b(deopt, EQ);
2800 } 2850 }
2801 2851
2802 2852
2803 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 2853 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
2804 const intptr_t kNumInputs = 1; 2854 const intptr_t kNumInputs = 1;
2805 const intptr_t kNumTemps = 1; 2855 const intptr_t kNumTemps = 1;
2806 LocationSummary* summary = 2856 LocationSummary* summary =
2807 new LocationSummary(kNumInputs, 2857 new LocationSummary(kNumInputs,
2808 kNumTemps, 2858 kNumTemps,
2809 LocationSummary::kCallOnSlowPath); 2859 LocationSummary::kCallOnSlowPath);
(...skipping 15 matching lines...) Expand all
2825 slow_path->entry_label(), 2875 slow_path->entry_label(),
2826 out_reg, 2876 out_reg,
2827 locs()->temp(0).reg(), 2877 locs()->temp(0).reg(),
2828 PP); 2878 PP);
2829 __ Bind(slow_path->exit_label()); 2879 __ Bind(slow_path->exit_label());
2830 __ StoreDFieldToOffset(value, out_reg, Double::value_offset()); 2880 __ StoreDFieldToOffset(value, out_reg, Double::value_offset());
2831 } 2881 }
2832 2882
2833 2883
2834 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { 2884 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const {
2835 UNIMPLEMENTED(); 2885 const intptr_t kNumInputs = 1;
2836 return NULL; 2886 const intptr_t kNumTemps = 0;
2887 LocationSummary* summary =
2888 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2889 summary->set_in(0, Location::RequiresRegister());
2890 summary->set_out(0, Location::RequiresFpuRegister());
2891 return summary;
2837 } 2892 }
2838 2893
2839 2894
2840 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2895 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2841 UNIMPLEMENTED(); 2896 CompileType* value_type = value()->Type();
2897 const intptr_t value_cid = value_type->ToCid();
2898 const Register value = locs()->in(0).reg();
2899 const VRegister result = locs()->out(0).fpu_reg();
2900
2901 if (value_cid == kDoubleCid) {
2902 __ LoadDFieldFromOffset(result, value, Double::value_offset());
2903 } else if (value_cid == kSmiCid) {
2904 __ Asr(TMP, value, kSmiTagSize); // Untag input before conversion.
2905 __ scvtfd(result, TMP);
2906 } else {
2907 Label* deopt = compiler->AddDeoptStub(deopt_id_,
2908 ICData::kDeoptBinaryDoubleOp);
2909 if (value_type->is_nullable() &&
2910 (value_type->ToNullableCid() == kDoubleCid)) {
2911 __ CompareObject(value, Object::null_object(), PP);
2912 __ b(deopt, EQ);
2913 // It must be double now.
2914 __ LoadDFieldFromOffset(result, value, Double::value_offset());
2915 } else {
2916 Label is_smi, done;
2917 __ tsti(value, kSmiTagMask);
2918 __ b(&is_smi, EQ);
2919 __ CompareClassId(value, kDoubleCid);
2920 __ b(deopt, NE);
2921 __ LoadDFieldFromOffset(result, value, Double::value_offset());
2922 __ b(&done);
2923 __ Bind(&is_smi);
2924 __ Asr(TMP, value, kSmiTagSize); // Copy and untag.
2925 __ scvtfd(result, TMP);
2926 __ Bind(&done);
2927 }
2928 }
2842 } 2929 }
2843 2930
2844 2931
2845 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { 2932 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
2846 UNIMPLEMENTED(); 2933 UNIMPLEMENTED();
2847 return NULL; 2934 return NULL;
2848 } 2935 }
2849 2936
2850 2937
2851 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 2938 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 return NULL; 2989 return NULL;
2903 } 2990 }
2904 2991
2905 2992
2906 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 2993 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2907 UNIMPLEMENTED(); 2994 UNIMPLEMENTED();
2908 } 2995 }
2909 2996
2910 2997
2911 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 2998 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
2912 UNIMPLEMENTED(); 2999 const intptr_t kNumInputs = 2;
2913 return NULL; 3000 const intptr_t kNumTemps = 0;
3001 LocationSummary* summary =
3002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3003 summary->set_in(0, Location::RequiresFpuRegister());
3004 summary->set_in(1, Location::RequiresFpuRegister());
3005 summary->set_out(0, Location::RequiresFpuRegister());
3006 return summary;
2914 } 3007 }
2915 3008
2916 3009
2917 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3010 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2918 UNIMPLEMENTED(); 3011 const VRegister left = locs()->in(0).fpu_reg();
3012 const VRegister right = locs()->in(1).fpu_reg();
3013 const VRegister result = locs()->out(0).fpu_reg();
3014 switch (op_kind()) {
3015 case Token::kADD: __ faddd(result, left, right); break;
3016 case Token::kSUB: __ fsubd(result, left, right); break;
3017 case Token::kMUL: __ fmuld(result, left, right); break;
3018 case Token::kDIV: __ fdivd(result, left, right); break;
3019 default: UNREACHABLE();
3020 }
2919 } 3021 }
2920 3022
2921 3023
2922 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { 3024 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const {
2923 UNIMPLEMENTED(); 3025 UNIMPLEMENTED();
2924 return NULL; 3026 return NULL;
2925 } 3027 }
2926 3028
2927 3029
2928 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3030 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after
3901 compiler->GenerateCall(token_pos(), 4003 compiler->GenerateCall(token_pos(),
3902 &label, 4004 &label,
3903 PcDescriptors::kOther, 4005 PcDescriptors::kOther,
3904 locs()); 4006 locs());
3905 __ Drop(ArgumentCount()); // Discard arguments. 4007 __ Drop(ArgumentCount()); // Discard arguments.
3906 } 4008 }
3907 4009
3908 } // namespace dart 4010 } // namespace dart
3909 4011
3910 #endif // defined TARGET_ARCH_ARM64 4012 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/simulator_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698