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_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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 3292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3303 switch (op_kind()) { | 3303 switch (op_kind()) { |
3304 case Token::kADD: __ vaddqs(result, left, right); break; | 3304 case Token::kADD: __ vaddqs(result, left, right); break; |
3305 case Token::kSUB: __ vsubqs(result, left, right); break; | 3305 case Token::kSUB: __ vsubqs(result, left, right); break; |
3306 case Token::kMUL: __ vmulqs(result, left, right); break; | 3306 case Token::kMUL: __ vmulqs(result, left, right); break; |
3307 case Token::kDIV: __ Vdivqs(result, left, right); break; | 3307 case Token::kDIV: __ Vdivqs(result, left, right); break; |
3308 default: UNREACHABLE(); | 3308 default: UNREACHABLE(); |
3309 } | 3309 } |
3310 } | 3310 } |
3311 | 3311 |
3312 | 3312 |
| 3313 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const { |
| 3314 const intptr_t kNumInputs = 2; |
| 3315 const intptr_t kNumTemps = 0; |
| 3316 LocationSummary* summary = |
| 3317 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3318 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3319 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3320 summary->set_out(Location::RequiresFpuRegister()); |
| 3321 return summary; |
| 3322 } |
| 3323 |
| 3324 |
| 3325 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3326 QRegister left = locs()->in(0).fpu_reg(); |
| 3327 QRegister right = locs()->in(1).fpu_reg(); |
| 3328 QRegister result = locs()->out().fpu_reg(); |
| 3329 |
| 3330 DRegister left0 = EvenDRegisterOf(left); |
| 3331 DRegister left1 = OddDRegisterOf(left); |
| 3332 |
| 3333 DRegister right0 = EvenDRegisterOf(right); |
| 3334 DRegister right1 = OddDRegisterOf(right); |
| 3335 |
| 3336 DRegister result0 = EvenDRegisterOf(result); |
| 3337 DRegister result1 = OddDRegisterOf(result); |
| 3338 |
| 3339 switch (op_kind()) { |
| 3340 case Token::kADD: |
| 3341 __ vaddd(result0, left0, right0); |
| 3342 __ vaddd(result1, left1, right1); |
| 3343 break; |
| 3344 case Token::kSUB: |
| 3345 __ vsubd(result0, left0, right0); |
| 3346 __ vsubd(result1, left1, right1); |
| 3347 break; |
| 3348 case Token::kMUL: |
| 3349 __ vmuld(result0, left0, right0); |
| 3350 __ vmuld(result1, left1, right1); |
| 3351 break; |
| 3352 case Token::kDIV: |
| 3353 __ vdivd(result0, left0, right0); |
| 3354 __ vdivd(result1, left1, right1); |
| 3355 break; |
| 3356 default: UNREACHABLE(); |
| 3357 } |
| 3358 } |
| 3359 |
| 3360 |
3313 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { | 3361 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { |
3314 const intptr_t kNumInputs = 1; | 3362 const intptr_t kNumInputs = 1; |
3315 const intptr_t kNumTemps = 0; | 3363 const intptr_t kNumTemps = 0; |
3316 LocationSummary* summary = | 3364 LocationSummary* summary = |
3317 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3365 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3318 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | 3366 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. |
3319 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | 3367 summary->set_in(0, Location::FpuRegisterLocation(Q5)); |
3320 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3368 summary->set_out(Location::FpuRegisterLocation(Q6)); |
3321 return summary; | 3369 return summary; |
3322 } | 3370 } |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3806 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3854 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3807 QRegister value = locs()->in(0).fpu_reg(); | 3855 QRegister value = locs()->in(0).fpu_reg(); |
3808 QRegister result = locs()->out().fpu_reg(); | 3856 QRegister result = locs()->out().fpu_reg(); |
3809 | 3857 |
3810 if (value != result) { | 3858 if (value != result) { |
3811 __ vmovq(result, value); | 3859 __ vmovq(result, value); |
3812 } | 3860 } |
3813 } | 3861 } |
3814 | 3862 |
3815 | 3863 |
| 3864 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const { |
| 3865 const intptr_t kNumInputs = 1; |
| 3866 const intptr_t kNumTemps = 0; |
| 3867 LocationSummary* summary = |
| 3868 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3869 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3870 summary->set_out(Location::RequiresFpuRegister()); |
| 3871 return summary; |
| 3872 } |
| 3873 |
| 3874 |
| 3875 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3876 QRegister value = locs()->in(0).fpu_reg(); |
| 3877 |
| 3878 DRegister dvalue0 = EvenDRegisterOf(value); |
| 3879 DRegister dvalue1 = OddDRegisterOf(value); |
| 3880 |
| 3881 QRegister result = locs()->out().fpu_reg(); |
| 3882 |
| 3883 DRegister dresult0 = EvenDRegisterOf(result); |
| 3884 |
| 3885 switch (op_kind()) { |
| 3886 case MethodRecognizer::kFloat64x2GetX: |
| 3887 __ vmovd(dresult0, dvalue0); |
| 3888 break; |
| 3889 case MethodRecognizer::kFloat64x2GetY: |
| 3890 __ vmovd(dresult0, dvalue1); |
| 3891 break; |
| 3892 default: UNREACHABLE(); |
| 3893 } |
| 3894 } |
| 3895 |
| 3896 |
| 3897 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { |
| 3898 const intptr_t kNumInputs = 0; |
| 3899 const intptr_t kNumTemps = 0; |
| 3900 LocationSummary* summary = |
| 3901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3902 summary->set_out(Location::RequiresFpuRegister()); |
| 3903 return summary; |
| 3904 } |
| 3905 |
| 3906 |
| 3907 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3908 QRegister q = locs()->out().fpu_reg(); |
| 3909 __ veorq(q, q, q); |
| 3910 } |
| 3911 |
| 3912 |
| 3913 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { |
| 3914 const intptr_t kNumInputs = 1; |
| 3915 const intptr_t kNumTemps = 0; |
| 3916 LocationSummary* summary = |
| 3917 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3918 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3919 summary->set_out(Location::RequiresFpuRegister()); |
| 3920 return summary; |
| 3921 } |
| 3922 |
| 3923 |
| 3924 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3925 QRegister value = locs()->in(0).fpu_reg(); |
| 3926 |
| 3927 DRegister dvalue = EvenDRegisterOf(value); |
| 3928 |
| 3929 QRegister result = locs()->out().fpu_reg(); |
| 3930 |
| 3931 DRegister dresult0 = EvenDRegisterOf(result); |
| 3932 DRegister dresult1 = OddDRegisterOf(result); |
| 3933 |
| 3934 // Splat across all lanes. |
| 3935 __ vmovd(dresult0, dvalue); |
| 3936 __ vmovd(dresult1, dvalue); |
| 3937 } |
| 3938 |
| 3939 |
| 3940 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( |
| 3941 bool opt) const { |
| 3942 const intptr_t kNumInputs = 2; |
| 3943 const intptr_t kNumTemps = 0; |
| 3944 LocationSummary* summary = |
| 3945 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3946 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3947 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3948 summary->set_out(Location::RequiresFpuRegister()); |
| 3949 return summary; |
| 3950 } |
| 3951 |
| 3952 |
| 3953 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3954 QRegister q0 = locs()->in(0).fpu_reg(); |
| 3955 QRegister q1 = locs()->in(1).fpu_reg(); |
| 3956 QRegister r = locs()->out().fpu_reg(); |
| 3957 |
| 3958 DRegister d0 = EvenDRegisterOf(q0); |
| 3959 DRegister d1 = EvenDRegisterOf(q1); |
| 3960 |
| 3961 DRegister dr0 = EvenDRegisterOf(r); |
| 3962 DRegister dr1 = OddDRegisterOf(r); |
| 3963 |
| 3964 __ vmovd(dr0, d0); |
| 3965 __ vmovd(dr1, d1); |
| 3966 } |
| 3967 |
| 3968 |
| 3969 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( |
| 3970 bool opt) const { |
| 3971 const intptr_t kNumInputs = 1; |
| 3972 const intptr_t kNumTemps = 0; |
| 3973 LocationSummary* summary = |
| 3974 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3975 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3976 // Low (< 7) Q registers are needed for the vcvtsd instruction. |
| 3977 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 3978 return summary; |
| 3979 } |
| 3980 |
| 3981 |
| 3982 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3983 QRegister q = locs()->in(0).fpu_reg(); |
| 3984 QRegister r = locs()->out().fpu_reg(); |
| 3985 |
| 3986 DRegister dq0 = EvenDRegisterOf(q); |
| 3987 DRegister dq1 = OddDRegisterOf(q); |
| 3988 |
| 3989 DRegister dr0 = EvenDRegisterOf(r); |
| 3990 |
| 3991 // Zero register. |
| 3992 __ veorq(r, r, r); |
| 3993 // Set X lane. |
| 3994 __ vcvtsd(EvenSRegisterOf(dr0), dq0); |
| 3995 // Set Y lane. |
| 3996 __ vcvtsd(OddSRegisterOf(dr0), dq1); |
| 3997 } |
| 3998 |
| 3999 |
| 4000 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( |
| 4001 bool opt) const { |
| 4002 const intptr_t kNumInputs = 1; |
| 4003 const intptr_t kNumTemps = 0; |
| 4004 LocationSummary* summary = |
| 4005 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4006 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4007 // Low (< 7) Q registers are needed for the vcvtsd instruction. |
| 4008 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 4009 return summary; |
| 4010 } |
| 4011 |
| 4012 |
| 4013 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4014 QRegister q = locs()->in(0).fpu_reg(); |
| 4015 QRegister r = locs()->out().fpu_reg(); |
| 4016 |
| 4017 DRegister dq0 = EvenDRegisterOf(q); |
| 4018 |
| 4019 DRegister dr0 = EvenDRegisterOf(r); |
| 4020 DRegister dr1 = OddDRegisterOf(r); |
| 4021 |
| 4022 // Set X. |
| 4023 __ vcvtds(dr0, EvenSRegisterOf(dq0)); |
| 4024 // Set Y. |
| 4025 __ vcvtds(dr1, OddSRegisterOf(dq0)); |
| 4026 } |
| 4027 |
| 4028 |
3816 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( | 4029 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
3817 bool opt) const { | 4030 bool opt) const { |
3818 const intptr_t kNumInputs = 4; | 4031 const intptr_t kNumInputs = 4; |
3819 const intptr_t kNumTemps = 1; | 4032 const intptr_t kNumTemps = 1; |
3820 LocationSummary* summary = | 4033 LocationSummary* summary = |
3821 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4034 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3822 summary->set_in(0, Location::RequiresRegister()); | 4035 summary->set_in(0, Location::RequiresRegister()); |
3823 summary->set_in(1, Location::RequiresRegister()); | 4036 summary->set_in(1, Location::RequiresRegister()); |
3824 summary->set_in(2, Location::RequiresRegister()); | 4037 summary->set_in(2, Location::RequiresRegister()); |
3825 summary->set_in(3, Location::RequiresRegister()); | 4038 summary->set_in(3, Location::RequiresRegister()); |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5000 compiler->GenerateCall(token_pos(), | 5213 compiler->GenerateCall(token_pos(), |
5001 &label, | 5214 &label, |
5002 PcDescriptors::kOther, | 5215 PcDescriptors::kOther, |
5003 locs()); | 5216 locs()); |
5004 __ Drop(ArgumentCount()); // Discard arguments. | 5217 __ Drop(ArgumentCount()); // Discard arguments. |
5005 } | 5218 } |
5006 | 5219 |
5007 } // namespace dart | 5220 } // namespace dart |
5008 | 5221 |
5009 #endif // defined TARGET_ARCH_ARM | 5222 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |