diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 46 | ||||
-rw-r--r-- | gcc/config/aarch64/iterators.md | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/fmul_lane_1.c | 59 |
3 files changed, 82 insertions, 36 deletions
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 2347629..9962089 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -719,51 +719,35 @@ ) (define_insn "mul_lane<mode>3" - [(set (match_operand:VMUL 0 "register_operand" "=w") - (mult:VMUL - (vec_duplicate:VMUL + [(set (match_operand:VMULD 0 "register_operand" "=w") + (mult:VMULD + (vec_duplicate:VMULD (vec_select:<VEL> - (match_operand:VMUL 2 "register_operand" "<h_con>") + (match_operand:<VCOND> 2 "register_operand" "<h_con>") (parallel [(match_operand:SI 3 "immediate_operand" "i")]))) - (match_operand:VMUL 1 "register_operand" "w")))] + (match_operand:VMULD 1 "register_operand" "w")))] "TARGET_SIMD" { - operands[3] = aarch64_endian_lane_rtx (<MODE>mode, INTVAL (operands[3])); + operands[3] = aarch64_endian_lane_rtx (<VCOND>mode, INTVAL (operands[3])); return "<f>mul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]"; } [(set_attr "type" "neon<fp>_mul_<stype>_scalar<q>")] ) (define_insn "mul_laneq<mode>3" - [(set (match_operand:VDQSF 0 "register_operand" "=w") - (mult:VDQSF - (vec_duplicate:VDQSF - (vec_select:<VEL> - (match_operand:V4SF 2 "register_operand" "w") - (parallel [(match_operand:SI 3 "immediate_operand" "i")]))) - (match_operand:VDQSF 1 "register_operand" "w")))] - "TARGET_SIMD" - { - operands[3] = aarch64_endian_lane_rtx (V4SFmode, INTVAL (operands[3])); - return "fmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]"; - } - [(set_attr "type" "neon_fp_mul_s_scalar<q>")] -) - -(define_insn "*aarch64_mul3_elt_<vswap_width_name><mode>" - [(set (match_operand:VMUL_CHANGE_NLANES 0 "register_operand" "=w") - (mult:VMUL_CHANGE_NLANES - (vec_duplicate:VMUL_CHANGE_NLANES + [(set (match_operand:VMUL 0 "register_operand" "=w") + (mult:VMUL + (vec_duplicate:VMUL (vec_select:<VEL> - (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>") - (parallel [(match_operand:SI 2 "immediate_operand")]))) - (match_operand:VMUL_CHANGE_NLANES 3 "register_operand" "w")))] + (match_operand:<VCONQ> 2 "register_operand" "<h_con>") + (parallel [(match_operand:SI 3 "immediate_operand")]))) + (match_operand:VMUL 1 "register_operand" "w")))] "TARGET_SIMD" { - operands[2] = aarch64_endian_lane_rtx (<VSWAP_WIDTH>mode, INTVAL (operands[2])); - return "<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]"; + operands[3] = aarch64_endian_lane_rtx (<VCONQ>mode, INTVAL (operands[3])); + return "<f>mul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]"; } - [(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")] + [(set_attr "type" "neon<fp>_mul_<stype>_scalar<q>")] ) (define_insn "mul_n<mode>3" diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index c57aa6b..69d9dbe 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -312,15 +312,17 @@ (define_mode_iterator DSX [DF DI SF SI]) -;; Modes available for Advanced SIMD <f>mul lane operations. +;; Modes available for Advanced SIMD <f>mul operations. (define_mode_iterator VMUL [V4HI V8HI V2SI V4SI (V4HF "TARGET_SIMD_F16INST") (V8HF "TARGET_SIMD_F16INST") V2SF V4SF V2DF]) -;; Modes available for Advanced SIMD <f>mul lane operations changing lane -;; count. -(define_mode_iterator VMUL_CHANGE_NLANES [V4HI V8HI V2SI V4SI V2SF V4SF]) +;; The subset of VMUL for which VCOND is a vector mode. +(define_mode_iterator VMULD [V4HI V8HI V2SI V4SI + (V4HF "TARGET_SIMD_F16INST") + (V8HF "TARGET_SIMD_F16INST") + V2SF V4SF]) ;; Iterators for single modes, for "@" patterns. (define_mode_iterator VNx16QI_ONLY [VNx16QI]) @@ -1201,6 +1203,7 @@ (V4HI "V4HI") (V8HI "V4HI") (V2SI "V2SI") (V4SI "V2SI") (DI "DI") (V2DI "DI") + (V4HF "V4HF") (V8HF "V4HF") (V2SF "V2SF") (V4SF "V2SF") (V2DF "DF")]) @@ -1210,7 +1213,7 @@ (V2SI "V4SI") (V4SI "V4SI") (DI "V2DI") (V2DI "V2DI") (V4HF "V8HF") (V8HF "V8HF") - (V2SF "V2SF") (V4SF "V4SF") + (V2SF "V4SF") (V4SF "V4SF") (V2DF "V2DF") (SI "V4SI") (HI "V8HI") (QI "V16QI")]) diff --git a/gcc/testsuite/gcc.target/aarch64/fmul_lane_1.c b/gcc/testsuite/gcc.target/aarch64/fmul_lane_1.c new file mode 100644 index 0000000..a2b5758 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmul_lane_1.c @@ -0,0 +1,59 @@ +/* { dg-options "-O" } */ + +#pragma GCC target "+simd+fp16" + +__Float16x4_t +f1 (__Float16x4_t x, __Float16x4_t y) +{ + return x * y[0]; +} + +__Float16x4_t +f2 (__Float16x4_t x, __Float16x4_t y) +{ + return x * y[3]; +} + +__Float16x4_t +f3 (__Float16x4_t x, __Float16x8_t y) +{ + return x * y[0]; +} + +__Float16x4_t +f4 (__Float16x4_t x, __Float16x8_t y) +{ + return x * y[7]; +} + +__Float16x8_t +f5 (__Float16x8_t x, __Float16x4_t y) +{ + return x * y[0]; +} + +__Float16x8_t +f6 (__Float16x8_t x, __Float16x4_t y) +{ + return x * y[3]; +} + +__Float16x8_t +f7 (__Float16x8_t x, __Float16x8_t y) +{ + return x * y[0]; +} + +__Float16x8_t +f8 (__Float16x8_t x, __Float16x8_t y) +{ + return x * y[7]; +} + +/* { dg-final { scan-assembler-times {\tfmul\tv0.4h, v0.4h, v1.h\[0\]} 2 } } */ +/* { dg-final { scan-assembler-times {\tfmul\tv0.4h, v0.4h, v1.h\[3\]} 1 } } */ +/* { dg-final { scan-assembler-times {\tfmul\tv0.4h, v0.4h, v1.h\[7\]} 1 } } */ + +/* { dg-final { scan-assembler-times {\tfmul\tv0.8h, v0.8h, v1.h\[0\]} 2 } } */ +/* { dg-final { scan-assembler-times {\tfmul\tv0.8h, v0.8h, v1.h\[3\]} 1 } } */ +/* { dg-final { scan-assembler-times {\tfmul\tv0.8h, v0.8h, v1.h\[7\]} 1 } } */ |