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

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

Issue 19776007: Enables a SIMD test for ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 if (!IsExternal()) { 1197 if (!IsExternal()) {
1198 ASSERT(this->array()->definition()->representation() == kTagged); 1198 ASSERT(this->array()->definition()->representation() == kTagged);
1199 __ AddImmediate(index.reg(), 1199 __ AddImmediate(index.reg(),
1200 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1200 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1201 } 1201 }
1202 element_address = Address(array, index.reg(), LSL, 0); 1202 element_address = Address(array, index.reg(), LSL, 0);
1203 1203
1204 if ((representation() == kUnboxedDouble) || 1204 if ((representation() == kUnboxedDouble) ||
1205 (representation() == kUnboxedMint) || 1205 (representation() == kUnboxedMint) ||
1206 (representation() == kUnboxedFloat32x4)) { 1206 (representation() == kUnboxedFloat32x4)) {
1207 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 1207 QRegister result = locs()->out().fpu_reg();
1208 DRegister dresult0 = EvenDRegisterOf(result);
1209 DRegister dresult1 = OddDRegisterOf(result);
1208 switch (class_id()) { 1210 switch (class_id()) {
1209 case kTypedDataInt32ArrayCid: 1211 case kTypedDataInt32ArrayCid:
1210 UNIMPLEMENTED(); 1212 UNIMPLEMENTED();
1211 break; 1213 break;
1212 case kTypedDataUint32ArrayCid: 1214 case kTypedDataUint32ArrayCid:
1213 UNIMPLEMENTED(); 1215 UNIMPLEMENTED();
1214 break; 1216 break;
1215 case kTypedDataFloat32ArrayCid: 1217 case kTypedDataFloat32ArrayCid:
1216 // Load single precision float and promote to double. 1218 // Load single precision float and promote to double.
1217 // vldrs does not support indexed addressing. 1219 // vldrs does not support indexed addressing.
1218 __ add(index.reg(), index.reg(), ShifterOperand(array)); 1220 __ add(index.reg(), index.reg(), ShifterOperand(array));
1219 element_address = Address(index.reg(), 0); 1221 element_address = Address(index.reg(), 0);
1220 __ vldrs(STMP, element_address); 1222 __ vldrs(STMP, element_address);
1221 __ vcvtds(result, STMP); 1223 __ vcvtds(dresult0, STMP);
1222 break; 1224 break;
1223 case kTypedDataFloat64ArrayCid: 1225 case kTypedDataFloat64ArrayCid:
1224 // vldrd does not support indexed addressing. 1226 // vldrd does not support indexed addressing.
1225 __ add(index.reg(), index.reg(), ShifterOperand(array)); 1227 __ add(index.reg(), index.reg(), ShifterOperand(array));
1226 element_address = Address(index.reg(), 0); 1228 element_address = Address(index.reg(), 0);
1227 __ vldrd(result, element_address); 1229 __ vldrd(dresult0, element_address);
1228 break; 1230 break;
1229 case kTypedDataFloat32x4ArrayCid: 1231 case kTypedDataFloat32x4ArrayCid:
1230 UNIMPLEMENTED(); 1232 __ add(index.reg(), index.reg(), ShifterOperand(array));
1233 __ LoadDFromOffset(dresult0, index.reg(), 0);
1234 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize);
1231 break; 1235 break;
1232 } 1236 }
1233 return; 1237 return;
1234 } 1238 }
1235 1239
1236 Register result = locs()->out().reg(); 1240 Register result = locs()->out().reg();
1237 switch (class_id()) { 1241 switch (class_id()) {
1238 case kTypedDataInt8ArrayCid: 1242 case kTypedDataInt8ArrayCid:
1239 ASSERT(index_scale() == 1); 1243 ASSERT(index_scale() == 1);
1240 __ ldrsb(result, element_address); 1244 __ ldrsb(result, element_address);
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 __ add(index.reg(), index.reg(), ShifterOperand(array)); 1483 __ add(index.reg(), index.reg(), ShifterOperand(array));
1480 __ StoreSToOffset(STMP, index.reg(), 0); 1484 __ StoreSToOffset(STMP, index.reg(), 0);
1481 break; 1485 break;
1482 } 1486 }
1483 case kTypedDataFloat64ArrayCid: { 1487 case kTypedDataFloat64ArrayCid: {
1484 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); 1488 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg());
1485 __ add(index.reg(), index.reg(), ShifterOperand(array)); 1489 __ add(index.reg(), index.reg(), ShifterOperand(array));
1486 __ StoreDToOffset(in2, index.reg(), 0); 1490 __ StoreDToOffset(in2, index.reg(), 0);
1487 break; 1491 break;
1488 } 1492 }
1489 case kTypedDataFloat32x4ArrayCid: 1493 case kTypedDataFloat32x4ArrayCid: {
1490 UNIMPLEMENTED(); 1494 QRegister in = locs()->in(2).fpu_reg();
1495 DRegister din0 = EvenDRegisterOf(in);
1496 DRegister din1 = OddDRegisterOf(in);
1497 __ add(index.reg(), index.reg(), ShifterOperand(array));
1498 __ StoreDToOffset(din0, index.reg(), 0);
1499 __ StoreDToOffset(din1, index.reg(), 2*kWordSize);
1491 break; 1500 break;
1501 }
1492 default: 1502 default:
1493 UNREACHABLE(); 1503 UNREACHABLE();
1494 } 1504 }
1495 } 1505 }
1496 1506
1497 1507
1498 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { 1508 LocationSummary* GuardFieldInstr::MakeLocationSummary() const {
1499 const intptr_t kNumInputs = 1; 1509 const intptr_t kNumInputs = 1;
1500 LocationSummary* summary = 1510 LocationSummary* summary =
1501 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); 1511 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2662 // TODO(regis): Why do we preserve value here but not above? 2672 // TODO(regis): Why do we preserve value here but not above?
2663 __ mov(IP, ShifterOperand(value, ASR, 1)); // Copy and untag. 2673 __ mov(IP, ShifterOperand(value, ASR, 1)); // Copy and untag.
2664 __ vmovsr(STMP, IP); 2674 __ vmovsr(STMP, IP);
2665 __ vcvtdi(result, STMP); 2675 __ vcvtdi(result, STMP);
2666 __ Bind(&done); 2676 __ Bind(&done);
2667 } 2677 }
2668 } 2678 }
2669 2679
2670 2680
2671 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { 2681 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const {
2672 UNIMPLEMENTED(); 2682 const intptr_t kNumInputs = 1;
2673 return NULL; 2683 const intptr_t kNumTemps = 0;
2674 } 2684 LocationSummary* summary =
2685 new LocationSummary(kNumInputs,
2686 kNumTemps,
2687 LocationSummary::kCallOnSlowPath);
2688 summary->set_in(0, Location::RequiresFpuRegister());
2689 summary->set_out(Location::RequiresRegister());
2690 return summary;
2691 }
2692
2693
2694 class BoxFloat32x4SlowPath : public SlowPathCode {
2695 public:
2696 explicit BoxFloat32x4SlowPath(BoxFloat32x4Instr* instruction)
2697 : instruction_(instruction) { }
2698
2699 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2700 __ Comment("BoxFloat32x4SlowPath");
2701 __ Bind(entry_label());
2702 const Class& float32x4_class = compiler->float32x4_class();
2703 const Code& stub =
2704 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
2705 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
2706
2707 LocationSummary* locs = instruction_->locs();
2708 locs->live_registers()->Remove(locs->out());
2709
2710 compiler->SaveLiveRegisters(locs);
2711 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
2712 &label,
2713 PcDescriptors::kOther,
2714 locs);
2715 __ mov(locs->out().reg(), ShifterOperand(R0));
2716 compiler->RestoreLiveRegisters(locs);
2717
2718 __ b(exit_label());
2719 }
2720
2721 private:
2722 BoxFloat32x4Instr* instruction_;
2723 };
2675 2724
2676 2725
2677 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 2726 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2678 UNIMPLEMENTED(); 2727 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this);
2728 compiler->AddSlowPathCode(slow_path);
2729
2730 Register out_reg = locs()->out().reg();
2731 QRegister value = locs()->in(0).fpu_reg();
2732 DRegister value_even = EvenDRegisterOf(value);
2733 DRegister value_odd = OddDRegisterOf(value);
2734
2735 __ TryAllocate(compiler->float32x4_class(),
2736 slow_path->entry_label(),
2737 out_reg);
2738 __ Bind(slow_path->exit_label());
2739
2740 __ StoreDToOffset(value_even, out_reg,
2741 Float32x4::value_offset() - kHeapObjectTag);
2742 __ StoreDToOffset(value_odd, out_reg,
2743 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2679 } 2744 }
2680 2745
2681 2746
2682 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { 2747 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const {
2683 UNIMPLEMENTED(); 2748 const intptr_t value_cid = value()->Type()->ToCid();
2684 return NULL; 2749 const intptr_t kNumInputs = 1;
2750 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1;
2751 LocationSummary* summary =
2752 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2753 summary->set_in(0, Location::RequiresRegister());
2754 if (kNumTemps > 0) {
2755 ASSERT(kNumTemps == 1);
2756 summary->set_temp(0, Location::RequiresRegister());
2757 }
2758 summary->set_out(Location::RequiresFpuRegister());
2759 return summary;
2685 } 2760 }
2686 2761
2687 2762
2688 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 2763 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2689 UNIMPLEMENTED(); 2764 const intptr_t value_cid = value()->Type()->ToCid();
2765 const Register value = locs()->in(0).reg();
2766 const QRegister result = locs()->out().fpu_reg();
2767
2768 if (value_cid != kFloat32x4Cid) {
2769 const Register temp = locs()->temp(0).reg();
2770 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
2771 __ tst(value, ShifterOperand(kSmiTagMask));
2772 __ b(deopt, EQ);
2773 __ CompareClassId(value, kFloat32x4Cid, temp);
2774 __ b(deopt, NE);
2775 }
2776
2777 const DRegister result_even = EvenDRegisterOf(result);
2778 const DRegister result_odd = OddDRegisterOf(result);
2779 __ LoadDFromOffset(result_even, value,
2780 Float32x4::value_offset() - kHeapObjectTag);
2781 __ LoadDFromOffset(result_odd, value,
2782 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2690 } 2783 }
2691 2784
2692 2785
2693 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { 2786 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const {
2694 UNIMPLEMENTED(); 2787 const intptr_t kNumInputs = 1;
2695 return NULL; 2788 const intptr_t kNumTemps = 0;
2696 } 2789 LocationSummary* summary =
2790 new LocationSummary(kNumInputs,
2791 kNumTemps,
2792 LocationSummary::kCallOnSlowPath);
2793 summary->set_in(0, Location::RequiresFpuRegister());
2794 summary->set_out(Location::RequiresRegister());
2795 return summary;
2796 }
2797
2798
2799 class BoxUint32x4SlowPath : public SlowPathCode {
2800 public:
2801 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction)
2802 : instruction_(instruction) { }
2803
2804 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2805 __ Comment("BoxUint32x4SlowPath");
2806 __ Bind(entry_label());
2807 const Class& uint32x4_class = compiler->uint32x4_class();
2808 const Code& stub =
2809 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class));
2810 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint());
2811
2812 LocationSummary* locs = instruction_->locs();
2813 locs->live_registers()->Remove(locs->out());
2814
2815 compiler->SaveLiveRegisters(locs);
2816 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
2817 &label,
2818 PcDescriptors::kOther,
2819 locs);
2820 __ mov(locs->out().reg(), ShifterOperand(R0));
2821 compiler->RestoreLiveRegisters(locs);
2822
2823 __ b(exit_label());
2824 }
2825
2826 private:
2827 BoxUint32x4Instr* instruction_;
2828 };
2697 2829
2698 2830
2699 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 2831 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2700 UNIMPLEMENTED(); 2832 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this);
2833 compiler->AddSlowPathCode(slow_path);
2834
2835 Register out_reg = locs()->out().reg();
2836 QRegister value = locs()->in(0).fpu_reg();
2837 DRegister value_even = EvenDRegisterOf(value);
2838 DRegister value_odd = OddDRegisterOf(value);
2839
2840 __ TryAllocate(compiler->uint32x4_class(),
2841 slow_path->entry_label(),
2842 out_reg);
2843 __ Bind(slow_path->exit_label());
2844 __ StoreDToOffset(value_even, out_reg,
2845 Uint32x4::value_offset() - kHeapObjectTag);
2846 __ StoreDToOffset(value_odd, out_reg,
2847 Uint32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2701 } 2848 }
2702 2849
2703 2850
2704 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { 2851 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const {
2705 UNIMPLEMENTED(); 2852 const intptr_t value_cid = value()->Type()->ToCid();
2706 return NULL; 2853 const intptr_t kNumInputs = 1;
2854 const intptr_t kNumTemps = value_cid == kUint32x4Cid ? 0 : 1;
2855 LocationSummary* summary =
2856 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2857 summary->set_in(0, Location::RequiresRegister());
2858 if (kNumTemps > 0) {
2859 ASSERT(kNumTemps == 1);
2860 summary->set_temp(0, Location::RequiresRegister());
2861 }
2862 summary->set_out(Location::RequiresFpuRegister());
2863 return summary;
2707 } 2864 }
2708 2865
2709 2866
2710 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 2867 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2711 UNIMPLEMENTED(); 2868 const intptr_t value_cid = value()->Type()->ToCid();
2712 } 2869 const Register value = locs()->in(0).reg();
2713 2870 const QRegister result = locs()->out().fpu_reg();
2714 2871
2872 if (value_cid != kUint32x4Cid) {
2873 const Register temp = locs()->temp(0).reg();
2874 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
2875 __ tst(value, ShifterOperand(kSmiTagMask));
2876 __ b(deopt, EQ);
2877 __ CompareClassId(value, kUint32x4Cid, temp);
2878 __ b(deopt, NE);
2879 }
2880
2881 const DRegister result_even = EvenDRegisterOf(result);
2882 const DRegister result_odd = OddDRegisterOf(result);
2883 __ LoadDFromOffset(result_even, value,
2884 Uint32x4::value_offset() - kHeapObjectTag);
2885 __ LoadDFromOffset(result_odd, value,
2886 Uint32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2887 }
2888
2889
2715 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { 2890 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const {
2716 const intptr_t kNumInputs = 2; 2891 const intptr_t kNumInputs = 2;
2717 const intptr_t kNumTemps = 0; 2892 const intptr_t kNumTemps = 0;
2718 LocationSummary* summary = 2893 LocationSummary* summary =
2719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2894 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2720 summary->set_in(0, Location::RequiresFpuRegister()); 2895 summary->set_in(0, Location::RequiresFpuRegister());
2721 summary->set_in(1, Location::RequiresFpuRegister()); 2896 summary->set_in(1, Location::RequiresFpuRegister());
2722 summary->set_out(Location::RequiresFpuRegister()); 2897 summary->set_out(Location::RequiresFpuRegister());
2723 return summary; 2898 return summary;
2724 } 2899 }
2725 2900
2726 2901
2727 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2902 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2728 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); 2903 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg());
2729 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); 2904 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg());
2730 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 2905 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
2731 switch (op_kind()) { 2906 switch (op_kind()) {
2732 case Token::kADD: __ vaddd(result, left, right); break; 2907 case Token::kADD: __ vaddd(result, left, right); break;
2733 case Token::kSUB: __ vsubd(result, left, right); break; 2908 case Token::kSUB: __ vsubd(result, left, right); break;
2734 case Token::kMUL: __ vmuld(result, left, right); break; 2909 case Token::kMUL: __ vmuld(result, left, right); break;
2735 case Token::kDIV: __ vdivd(result, left, right); break; 2910 case Token::kDIV: __ vdivd(result, left, right); break;
2736 default: UNREACHABLE(); 2911 default: UNREACHABLE();
2737 } 2912 }
2738 } 2913 }
2739 2914
2740 2915
2741 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const { 2916 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const {
2742 UNIMPLEMENTED(); 2917 const intptr_t kNumInputs = 2;
2743 return NULL; 2918 const intptr_t kNumTemps = 0;
2919 LocationSummary* summary =
2920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2921 summary->set_in(0, Location::RequiresFpuRegister());
2922 summary->set_in(1, Location::RequiresFpuRegister());
2923 summary->set_out(Location::RequiresFpuRegister());
2924 return summary;
2744 } 2925 }
2745 2926
2746 2927
2747 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2928 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2748 UNIMPLEMENTED(); 2929 QRegister left = locs()->in(0).fpu_reg();
2930 QRegister right = locs()->in(1).fpu_reg();
2931 QRegister result = locs()->out().fpu_reg();
2932
2933 switch (op_kind()) {
2934 case Token::kADD: __ vaddqs(result, left, right); break;
2935 case Token::kSUB: __ vsubqs(result, left, right); break;
2936 case Token::kMUL: __ vmulqs(result, left, right); break;
2937 // TODO(zra): Two options for division. Either use vdiv piecewise, or do
2938 // vrecpeqs followed by vmulqs.
2939 case Token::kDIV: UNIMPLEMENTED(); break;
2940 default: UNREACHABLE();
2941 }
2749 } 2942 }
2750 2943
2751 2944
2752 LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const { 2945 LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
2753 UNIMPLEMENTED(); 2946 const intptr_t kNumInputs = 1;
2754 return NULL; 2947 const intptr_t kNumTemps = 0;
2948 LocationSummary* summary =
2949 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2950 summary->set_in(0, Location::RequiresFpuRegister());
2951 summary->set_out(Location::RequiresFpuRegister());
2952 return summary;
2755 } 2953 }
2756 2954
2757 2955
2758 void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2956 void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2759 UNIMPLEMENTED(); 2957 QRegister value = locs()->in(0).fpu_reg();
2958 QRegister result = locs()->out().fpu_reg();
2959 DRegister dresult0 = EvenDRegisterOf(result);
2960 SRegister sresult0 = EvenSRegisterOf(dresult0);
2961
2962 DRegister dvalue0 = EvenDRegisterOf(value);
2963 DRegister dvalue1 = OddDRegisterOf(value);
2964
2965 // For these cases the vdup instruction requires fewer
2966 // instructions. For arbitrary shuffles, vtbl will be needed.
2967 switch (op_kind()) {
2968 case MethodRecognizer::kFloat32x4ShuffleXXXX:
2969 __ vdup(kWord, result, dvalue0, 0);
2970 break;
2971 case MethodRecognizer::kFloat32x4ShuffleYYYY:
2972 __ vdup(kWord, result, dvalue0, 1);
2973 break;
2974 case MethodRecognizer::kFloat32x4ShuffleZZZZ:
2975 __ vdup(kWord, result, dvalue1, 0);
2976 break;
2977 case MethodRecognizer::kFloat32x4ShuffleWWWW:
2978 __ vdup(kWord, result, dvalue1, 1);
2979 break;
2980 case MethodRecognizer::kFloat32x4ShuffleX:
2981 __ vdup(kWord, result, dvalue0, 0);
2982 __ vcvtds(dresult0, sresult0);
2983 break;
2984 case MethodRecognizer::kFloat32x4ShuffleY:
2985 __ vdup(kWord, result, dvalue0, 1);
2986 __ vcvtds(dresult0, sresult0);
2987 break;
2988 case MethodRecognizer::kFloat32x4ShuffleZ:
2989 __ vdup(kWord, result, dvalue1, 0);
2990 __ vcvtds(dresult0, sresult0);
2991 break;
2992 case MethodRecognizer::kFloat32x4ShuffleW:
2993 __ vdup(kWord, result, dvalue1, 1);
2994 __ vcvtds(dresult0, sresult0);
2995 break;
2996 default: UNREACHABLE();
2997 }
2760 } 2998 }
2761 2999
2762 3000
2763 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { 3001 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
2764 UNIMPLEMENTED(); 3002 const intptr_t kNumInputs = 4;
2765 return NULL; 3003 const intptr_t kNumTemps = 0;
3004 LocationSummary* summary =
3005 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3006 summary->set_in(0, Location::RequiresFpuRegister());
3007 summary->set_in(1, Location::RequiresFpuRegister());
3008 summary->set_in(2, Location::RequiresFpuRegister());
3009 summary->set_in(3, Location::RequiresFpuRegister());
3010 summary->set_out(Location::RequiresFpuRegister());
3011 return summary;
2766 } 3012 }
2767 3013
2768 3014
2769 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3015 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2770 UNIMPLEMENTED(); 3016 QRegister q0 = locs()->in(0).fpu_reg();
3017 QRegister q1 = locs()->in(1).fpu_reg();
3018 QRegister q2 = locs()->in(2).fpu_reg();
3019 QRegister q3 = locs()->in(3).fpu_reg();
3020 QRegister r = locs()->out().fpu_reg();
3021
3022 DRegister dr0 = EvenDRegisterOf(r);
3023 DRegister dr1 = OddDRegisterOf(r);
3024
3025 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0));
3026 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1));
3027 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2));
3028 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3));
2771 } 3029 }
2772 3030
2773 3031
2774 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const { 3032 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const {
2775 UNIMPLEMENTED(); 3033 const intptr_t kNumInputs = 0;
2776 return NULL; 3034 const intptr_t kNumTemps = 0;
3035 LocationSummary* summary =
3036 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3037 summary->set_out(Location::RequiresFpuRegister());
3038 return summary;
2777 } 3039 }
2778 3040
2779 3041
2780 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3042 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2781 UNIMPLEMENTED(); 3043 QRegister q = locs()->out().fpu_reg();
3044 __ veorq(q, q, q);
2782 } 3045 }
2783 3046
2784 3047
2785 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const { 3048 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const {
2786 UNIMPLEMENTED(); 3049 const intptr_t kNumInputs = 1;
2787 return NULL; 3050 const intptr_t kNumTemps = 0;
3051 LocationSummary* summary =
3052 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3053 summary->set_in(0, Location::RequiresFpuRegister());
3054 summary->set_out(Location::RequiresFpuRegister());
3055 return summary;
2788 } 3056 }
2789 3057
2790 3058
2791 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3059 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2792 UNIMPLEMENTED(); 3060 QRegister value = locs()->in(0).fpu_reg();
3061 QRegister result = locs()->out().fpu_reg();
3062
3063 DRegister dvalue0 = EvenDRegisterOf(value);
3064
3065 // Convert to Float32.
3066 __ vcvtsd(STMP, dvalue0);
3067
3068 // Splat across all lanes.
3069 __ vdup(kWord, result, DTMP, 0);
2793 } 3070 }
2794 3071
2795 3072
2796 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { 3073 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const {
2797 UNIMPLEMENTED(); 3074 UNIMPLEMENTED();
2798 return NULL; 3075 return NULL;
2799 } 3076 }
2800 3077
2801 3078
2802 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3079 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
3674 compiler->GenerateCall(token_pos(), 3951 compiler->GenerateCall(token_pos(),
3675 &label, 3952 &label,
3676 PcDescriptors::kOther, 3953 PcDescriptors::kOther,
3677 locs()); 3954 locs());
3678 __ Drop(2); // Discard type arguments and receiver. 3955 __ Drop(2); // Discard type arguments and receiver.
3679 } 3956 }
3680 3957
3681 } // namespace dart 3958 } // namespace dart
3682 3959
3683 #endif // defined TARGET_ARCH_ARM 3960 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698