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 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | |
zra
2014/03/04 17:43:51
Looks like this isn't used here, so any Q register
Cutch
2014/03/07 21:41:29
Done.
| |
3870 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | |
3871 summary->set_out(Location::FpuRegisterLocation(Q6)); | |
3872 return summary; | |
3873 } | |
3874 | |
3875 | |
3876 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
3877 QRegister value = locs()->in(0).fpu_reg(); | |
3878 | |
3879 DRegister dvalue0 = EvenDRegisterOf(value); | |
3880 DRegister dvalue1 = OddDRegisterOf(value); | |
3881 | |
3882 QRegister result = locs()->out().fpu_reg(); | |
3883 | |
3884 DRegister dresult0 = EvenDRegisterOf(result); | |
3885 | |
3886 switch (op_kind()) { | |
3887 case MethodRecognizer::kFloat64x2GetX: | |
3888 __ vmovd(dresult0, dvalue0); | |
3889 break; | |
3890 case MethodRecognizer::kFloat64x2GetY: | |
3891 __ vmovd(dresult0, dvalue1); | |
3892 break; | |
3893 default: UNREACHABLE(); | |
3894 } | |
3895 } | |
3896 | |
3897 | |
3898 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { | |
3899 const intptr_t kNumInputs = 0; | |
3900 const intptr_t kNumTemps = 0; | |
3901 LocationSummary* summary = | |
3902 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
3903 summary->set_out(Location::RequiresFpuRegister()); | |
3904 return summary; | |
3905 } | |
3906 | |
3907 | |
3908 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
3909 QRegister q = locs()->out().fpu_reg(); | |
3910 __ veorq(q, q, q); | |
3911 } | |
3912 | |
3913 | |
3914 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { | |
3915 const intptr_t kNumInputs = 1; | |
3916 const intptr_t kNumTemps = 0; | |
3917 LocationSummary* summary = | |
3918 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
3919 summary->set_in(0, Location::RequiresFpuRegister()); | |
3920 summary->set_out(Location::RequiresFpuRegister()); | |
3921 return summary; | |
3922 } | |
3923 | |
3924 | |
3925 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
3926 QRegister value = locs()->in(0).fpu_reg(); | |
3927 | |
3928 DRegister dvalue = EvenDRegisterOf(value); | |
3929 | |
3930 QRegister result = locs()->out().fpu_reg(); | |
3931 | |
3932 DRegister dresult0 = EvenDRegisterOf(result); | |
3933 DRegister dresult1 = OddDRegisterOf(result); | |
3934 | |
3935 // Splat across all lanes. | |
3936 __ vmovd(dresult0, dvalue); | |
3937 __ vmovd(dresult1, dvalue); | |
3938 } | |
3939 | |
3940 | |
3941 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( | |
3942 bool opt) const { | |
3943 const intptr_t kNumInputs = 2; | |
3944 const intptr_t kNumTemps = 0; | |
3945 LocationSummary* summary = | |
3946 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
3947 summary->set_in(0, Location::RequiresFpuRegister()); | |
3948 summary->set_in(1, Location::RequiresFpuRegister()); | |
3949 summary->set_out(Location::RequiresFpuRegister()); | |
3950 return summary; | |
3951 } | |
3952 | |
3953 | |
3954 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
3955 QRegister q0 = locs()->in(0).fpu_reg(); | |
3956 QRegister q1 = locs()->in(1).fpu_reg(); | |
3957 QRegister r = locs()->out().fpu_reg(); | |
3958 | |
3959 DRegister d0 = EvenDRegisterOf(q0); | |
3960 DRegister d1 = EvenDRegisterOf(q1); | |
3961 | |
3962 DRegister dr0 = EvenDRegisterOf(r); | |
3963 DRegister dr1 = OddDRegisterOf(r); | |
3964 | |
3965 __ vmovd(dr0, d0); | |
3966 __ vmovd(dr1, d1); | |
3967 } | |
3968 | |
3969 | |
3970 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( | |
3971 bool opt) const { | |
3972 const intptr_t kNumInputs = 1; | |
3973 const intptr_t kNumTemps = 0; | |
3974 LocationSummary* summary = | |
3975 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
3976 summary->set_in(0, Location::RequiresFpuRegister()); | |
3977 // Low (< 7) Q registers are needed for the vcvtsd instruction. | |
3978 summary->set_out(Location::FpuRegisterLocation(Q6)); | |
3979 return summary; | |
3980 } | |
3981 | |
3982 | |
3983 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
3984 QRegister q = locs()->in(0).fpu_reg(); | |
3985 QRegister r = locs()->out().fpu_reg(); | |
3986 | |
3987 DRegister dq0 = EvenDRegisterOf(q); | |
3988 DRegister dq1 = OddDRegisterOf(q); | |
3989 | |
3990 DRegister dr0 = EvenDRegisterOf(r); | |
3991 | |
3992 // Zero register. | |
3993 __ veorq(r, r, r); | |
3994 // Set X lane. | |
3995 __ vcvtsd(EvenSRegisterOf(dr0), dq0); | |
3996 // Set Y lane. | |
3997 __ vcvtsd(OddSRegisterOf(dr0), dq1); | |
3998 } | |
3999 | |
4000 | |
4001 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( | |
4002 bool opt) const { | |
4003 const intptr_t kNumInputs = 1; | |
4004 const intptr_t kNumTemps = 0; | |
4005 LocationSummary* summary = | |
4006 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
4007 summary->set_in(0, Location::RequiresFpuRegister()); | |
4008 // Low (< 7) Q registers are needed for the vcvtsd instruction. | |
4009 summary->set_out(Location::FpuRegisterLocation(Q6)); | |
4010 return summary; | |
4011 } | |
4012 | |
4013 | |
4014 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
4015 QRegister q = locs()->in(0).fpu_reg(); | |
4016 QRegister r = locs()->out().fpu_reg(); | |
4017 | |
4018 DRegister dq0 = EvenDRegisterOf(q); | |
4019 | |
4020 DRegister dr0 = EvenDRegisterOf(r); | |
4021 DRegister dr1 = OddDRegisterOf(r); | |
4022 | |
4023 // Set X. | |
4024 __ vcvtds(dr0, EvenSRegisterOf(dq0)); | |
4025 // Set Y. | |
4026 __ vcvtds(dr1, OddSRegisterOf(dq0)); | |
4027 } | |
4028 | |
4029 | |
3816 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( | 4030 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
3817 bool opt) const { | 4031 bool opt) const { |
3818 const intptr_t kNumInputs = 4; | 4032 const intptr_t kNumInputs = 4; |
3819 const intptr_t kNumTemps = 1; | 4033 const intptr_t kNumTemps = 1; |
3820 LocationSummary* summary = | 4034 LocationSummary* summary = |
3821 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4035 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3822 summary->set_in(0, Location::RequiresRegister()); | 4036 summary->set_in(0, Location::RequiresRegister()); |
3823 summary->set_in(1, Location::RequiresRegister()); | 4037 summary->set_in(1, Location::RequiresRegister()); |
3824 summary->set_in(2, Location::RequiresRegister()); | 4038 summary->set_in(2, Location::RequiresRegister()); |
3825 summary->set_in(3, Location::RequiresRegister()); | 4039 summary->set_in(3, Location::RequiresRegister()); |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5000 compiler->GenerateCall(token_pos(), | 5214 compiler->GenerateCall(token_pos(), |
5001 &label, | 5215 &label, |
5002 PcDescriptors::kOther, | 5216 PcDescriptors::kOther, |
5003 locs()); | 5217 locs()); |
5004 __ Drop(ArgumentCount()); // Discard arguments. | 5218 __ Drop(ArgumentCount()); // Discard arguments. |
5005 } | 5219 } |
5006 | 5220 |
5007 } // namespace dart | 5221 } // namespace dart |
5008 | 5222 |
5009 #endif // defined TARGET_ARCH_ARM | 5223 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |