diff options
Diffstat (limited to '0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch')
-rw-r--r-- | 0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch | 968 |
1 files changed, 968 insertions, 0 deletions
diff --git a/0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch b/0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch new file mode 100644 index 0000000..9ad166c --- /dev/null +++ b/0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch @@ -0,0 +1,968 @@ +From 81a4b464d01cf00f8b355115588e67bf2c021acd Mon Sep 17 00:00:00 2001 +From: Richard Sandiford <richard.sandiford@arm.com> +Date: Wed, 7 Sep 2022 10:52:04 +0100 +Subject: [PATCH 029/157] [Backport][SME] aarch64: Fix +nosimd handling of FPR + moves + +Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=d6106132907f6bd01109f2616d20a87edecc6fc6 + +8-bit and 16-bit FPR moves would ICE for +nosimd+fp, and some other +moves would handle FPR<-zero inefficiently. This is very much a +niche case at the moment, but something like it becomes more +important with SME streaming mode. + +The si, di and vector tests already passed, they're just included for +completeness. + +We're a bit inconsistent about whether alternatives involving FPRs +are marked with arch==fp or arch=* (i.e. default). E.g. FPR loads +and stores are sometimes * and sometimes fp. + +IMO * makes more sense. FPRs should not be used at all without +TARGET_FLOAT, so TARGET_FLOAT represents the base architecture +when FPRs are enabled. I think it's more useful if non-default +arches represent a genuine restriction. + +gcc/ + * config/aarch64/aarch64.md (*mov<SHORT:mode>_aarch64): Extend + w<-w, r<-w and w<-r alternatives to !simd, using 32-bit moves + in that case. Extend w<-r to w<-Z. + (*mov<HFBF:mode>_aarch64): Likewise, but with Y instead of Z. + (*movti_aarch64): Use an FMOV from XZR for w<-Z if MOVI is not + available. + (define_split): Do not apply the floating-point immediate-to-register + split to zeros, even if MOVI is not available. + +gcc/testsuite/ + * gcc.target/aarch64/movqi_1.c: New test. + * gcc.target/aarch64/movhi_1.c: Likewise. + * gcc.target/aarch64/movsi_1.c: Likewise. + * gcc.target/aarch64/movdi_2.c: Likewise. + * gcc.target/aarch64/movti_2.c: Likewise. + * gcc.target/aarch64/movhf_1.c: Likewise. + * gcc.target/aarch64/movsf_1.c: Likewise. + * gcc.target/aarch64/movdf_1.c: Likewise. + * gcc.target/aarch64/movtf_2.c: Likewise. + * gcc.target/aarch64/movv8qi_1.c: Likewise. + * gcc.target/aarch64/movv16qi_1.c: Likewise. +--- + gcc/config/aarch64/aarch64.md | 38 ++++---- + gcc/testsuite/gcc.target/aarch64/movdf_1.c | 53 ++++++++++++ + gcc/testsuite/gcc.target/aarch64/movdi_2.c | 61 +++++++++++++ + gcc/testsuite/gcc.target/aarch64/movhf_1.c | 53 ++++++++++++ + gcc/testsuite/gcc.target/aarch64/movhi_1.c | 61 +++++++++++++ + gcc/testsuite/gcc.target/aarch64/movqi_1.c | 61 +++++++++++++ + gcc/testsuite/gcc.target/aarch64/movsf_1.c | 53 ++++++++++++ + gcc/testsuite/gcc.target/aarch64/movsi_1.c | 61 +++++++++++++ + gcc/testsuite/gcc.target/aarch64/movtf_2.c | 81 +++++++++++++++++ + gcc/testsuite/gcc.target/aarch64/movti_2.c | 86 +++++++++++++++++++ + gcc/testsuite/gcc.target/aarch64/movv16qi_1.c | 82 ++++++++++++++++++ + gcc/testsuite/gcc.target/aarch64/movv8qi_1.c | 55 ++++++++++++ + 12 files changed, 729 insertions(+), 16 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/aarch64/movdf_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movdi_2.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movhf_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movhi_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movqi_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movsf_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movsi_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movtf_2.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movti_2.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movv16qi_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/movv8qi_1.c + +diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md +index 7ee26284d..7267a74d6 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -1201,7 +1201,7 @@ + + (define_insn "*mov<mode>_aarch64" + [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, w,r ,r,w, m,m,r,w,w") +- (match_operand:SHORT 1 "aarch64_mov_operand" " r,M,D<hq>,Usv,m,m,rZ,w,w,r,w"))] ++ (match_operand:SHORT 1 "aarch64_mov_operand" " r,M,D<hq>,Usv,m,m,rZ,w,w,rZ,w"))] + "(register_operand (operands[0], <MODE>mode) + || aarch64_reg_or_zero (operands[1], <MODE>mode))" + { +@@ -1225,11 +1225,11 @@ + case 7: + return "str\t%<size>1, %0"; + case 8: +- return "umov\t%w0, %1.<v>[0]"; ++ return TARGET_SIMD ? "umov\t%w0, %1.<v>[0]" : "fmov\t%w0, %s1"; + case 9: +- return "dup\t%0.<Vallxd>, %w1"; ++ return TARGET_SIMD ? "dup\t%0.<Vallxd>, %w1" : "fmov\t%s0, %w1"; + case 10: +- return "dup\t%<Vetype>0, %1.<v>[0]"; ++ return TARGET_SIMD ? "dup\t%<Vetype>0, %1.<v>[0]" : "fmov\t%s0, %s1"; + default: + gcc_unreachable (); + } +@@ -1237,7 +1237,7 @@ + ;; The "mov_imm" type for CNT is just a placeholder. + [(set_attr "type" "mov_reg,mov_imm,neon_move,mov_imm,load_4,load_4,store_4, + store_4,neon_to_gp<q>,neon_from_gp<q>,neon_dup") +- (set_attr "arch" "*,*,simd,sve,*,*,*,*,simd,simd,simd")] ++ (set_attr "arch" "*,*,simd,sve,*,*,*,*,*,*,*")] + ) + + (define_expand "mov<mode>" +@@ -1399,14 +1399,15 @@ + + (define_insn "*movti_aarch64" + [(set (match_operand:TI 0 +- "nonimmediate_operand" "= r,w,w, r,w,r,m,m,w,m") ++ "nonimmediate_operand" "= r,w,w,w, r,w,r,m,m,w,m") + (match_operand:TI 1 +- "aarch64_movti_operand" " rUti,Z,r, w,w,m,r,Z,m,w"))] ++ "aarch64_movti_operand" " rUti,Z,Z,r, w,w,m,r,Z,m,w"))] + "(register_operand (operands[0], TImode) + || aarch64_reg_or_zero (operands[1], TImode))" + "@ + # + movi\\t%0.2d, #0 ++ fmov\t%d0, xzr + # + # + mov\\t%0.16b, %1.16b +@@ -1415,11 +1416,11 @@ + stp\\txzr, xzr, %0 + ldr\\t%q0, %1 + str\\t%q1, %0" +- [(set_attr "type" "multiple,neon_move,f_mcr,f_mrc,neon_logic_q, \ ++ [(set_attr "type" "multiple,neon_move,f_mcr,f_mcr,f_mrc,neon_logic_q, \ + load_16,store_16,store_16,\ + load_16,store_16") +- (set_attr "length" "8,4,8,8,4,4,4,4,4,4") +- (set_attr "arch" "*,simd,*,*,simd,*,*,*,fp,fp")] ++ (set_attr "length" "8,4,4,8,8,4,4,4,4,4,4") ++ (set_attr "arch" "*,simd,*,*,*,simd,*,*,*,fp,fp")] + ) + + ;; Split a TImode register-register or register-immediate move into +@@ -1458,16 +1459,19 @@ + ) + + (define_insn "*mov<mode>_aarch64" +- [(set (match_operand:HFBF 0 "nonimmediate_operand" "=w,w , w,?r,w,w ,w ,w,m,r,m ,r") +- (match_operand:HFBF 1 "general_operand" "Y ,?rY,?r, w,w,Ufc,Uvi,m,w,m,rY,r"))] ++ [(set (match_operand:HFBF 0 "nonimmediate_operand" "=w,w ,w ,w ,?r,?r,w,w,w ,w ,w,m,r,m ,r") ++ (match_operand:HFBF 1 "general_operand" "Y ,?rY,?r,?rY, w, w,w,w,Ufc,Uvi,m,w,m,rY,r"))] + "TARGET_FLOAT && (register_operand (operands[0], <MODE>mode) + || aarch64_reg_or_fp_zero (operands[1], <MODE>mode))" + "@ + movi\\t%0.4h, #0 + fmov\\t%h0, %w1 + dup\\t%w0.4h, %w1 ++ fmov\\t%s0, %w1 + umov\\t%w0, %1.h[0] ++ fmov\\t%w0, %s1 + mov\\t%0.h[0], %1.h[0] ++ fmov\\t%s0, %s1 + fmov\\t%h0, %1 + * return aarch64_output_scalar_simd_mov_immediate (operands[1], HImode); + ldr\\t%h0, %1 +@@ -1475,9 +1479,10 @@ + ldrh\\t%w0, %1 + strh\\t%w1, %0 + mov\\t%w0, %w1" +- [(set_attr "type" "neon_move,f_mcr,neon_move,neon_to_gp, neon_move,fconsts, \ +- neon_move,f_loads,f_stores,load_4,store_4,mov_reg") +- (set_attr "arch" "simd,fp16,simd,simd,simd,fp16,simd,*,*,*,*,*")] ++ [(set_attr "type" "neon_move,f_mcr,neon_move,f_mcr,neon_to_gp,f_mrc, ++ neon_move,fmov,fconsts,neon_move,f_loads,f_stores, ++ load_4,store_4,mov_reg") ++ (set_attr "arch" "simd,fp16,simd,*,simd,*,simd,*,fp16,simd,*,*,*,*,*")] + ) + + (define_insn "*movsf_aarch64" +@@ -1530,10 +1535,11 @@ + + (define_split + [(set (match_operand:GPF_HF 0 "nonimmediate_operand") +- (match_operand:GPF_HF 1 "general_operand"))] ++ (match_operand:GPF_HF 1 "const_double_operand"))] + "can_create_pseudo_p () + && !aarch64_can_const_movi_rtx_p (operands[1], <MODE>mode) + && !aarch64_float_const_representable_p (operands[1]) ++ && !aarch64_float_const_zero_rtx_p (operands[1]) + && aarch64_float_const_rtx_p (operands[1])" + [(const_int 0)] + { +diff --git a/gcc/testsuite/gcc.target/aarch64/movdf_1.c b/gcc/testsuite/gcc.target/aarch64/movdf_1.c +new file mode 100644 +index 000000000..a51ded1d6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movdf_1.c +@@ -0,0 +1,53 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++/* ++** fpr_to_fpr: ++** fmov d0, d1 ++** ret ++*/ ++double ++fpr_to_fpr (double q0, double q1) ++{ ++ return q1; ++} ++ ++/* ++** gpr_to_fpr: ++** fmov d0, x0 ++** ret ++*/ ++double ++gpr_to_fpr () ++{ ++ register double x0 asm ("x0"); ++ asm volatile ("" : "=r" (x0)); ++ return x0; ++} ++ ++/* ++** zero_to_fpr: ++** fmov d0, xzr ++** ret ++*/ ++double ++zero_to_fpr () ++{ ++ return 0; ++} ++ ++/* ++** fpr_to_gpr: ++** fmov x0, d0 ++** ret ++*/ ++void ++fpr_to_gpr (double q0) ++{ ++ register double x0 asm ("x0"); ++ x0 = q0; ++ asm volatile ("" :: "r" (x0)); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movdi_2.c b/gcc/testsuite/gcc.target/aarch64/movdi_2.c +new file mode 100644 +index 000000000..dd3fc3e8a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movdi_2.c +@@ -0,0 +1,61 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++#include <stdint.h> ++ ++/* ++** fpr_to_fpr: ++** fmov d0, d1 ++** ret ++*/ ++void ++fpr_to_fpr (void) ++{ ++ register uint64_t q0 asm ("q0"); ++ register uint64_t q1 asm ("q1"); ++ asm volatile ("" : "=w" (q1)); ++ q0 = q1; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** gpr_to_fpr: ++** fmov d0, x0 ++** ret ++*/ ++void ++gpr_to_fpr (uint64_t x0) ++{ ++ register uint64_t q0 asm ("q0"); ++ q0 = x0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** zero_to_fpr: ++** fmov d0, xzr ++** ret ++*/ ++void ++zero_to_fpr () ++{ ++ register uint64_t q0 asm ("q0"); ++ q0 = 0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** fpr_to_gpr: ++** fmov x0, d0 ++** ret ++*/ ++uint64_t ++fpr_to_gpr () ++{ ++ register uint64_t q0 asm ("q0"); ++ asm volatile ("" : "=w" (q0)); ++ return q0; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movhf_1.c b/gcc/testsuite/gcc.target/aarch64/movhf_1.c +new file mode 100644 +index 000000000..cae25d4e5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movhf_1.c +@@ -0,0 +1,53 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++/* ++** fpr_to_fpr: ++** fmov s0, s1 ++** ret ++*/ ++_Float16 ++fpr_to_fpr (_Float16 q0, _Float16 q1) ++{ ++ return q1; ++} ++ ++/* ++** gpr_to_fpr: ++** fmov s0, w0 ++** ret ++*/ ++_Float16 ++gpr_to_fpr () ++{ ++ register _Float16 w0 asm ("w0"); ++ asm volatile ("" : "=r" (w0)); ++ return w0; ++} ++ ++/* ++** zero_to_fpr: ++** fmov s0, wzr ++** ret ++*/ ++_Float16 ++zero_to_fpr () ++{ ++ return 0; ++} ++ ++/* ++** fpr_to_gpr: ++** fmov w0, s0 ++** ret ++*/ ++void ++fpr_to_gpr (_Float16 q0) ++{ ++ register _Float16 w0 asm ("w0"); ++ w0 = q0; ++ asm volatile ("" :: "r" (w0)); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movhi_1.c b/gcc/testsuite/gcc.target/aarch64/movhi_1.c +new file mode 100644 +index 000000000..8017abc5f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movhi_1.c +@@ -0,0 +1,61 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++#include <stdint.h> ++ ++/* ++** fpr_to_fpr: ++** fmov s0, s1 ++** ret ++*/ ++void ++fpr_to_fpr (void) ++{ ++ register uint16_t q0 asm ("q0"); ++ register uint16_t q1 asm ("q1"); ++ asm volatile ("" : "=w" (q1)); ++ q0 = q1; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** gpr_to_fpr: ++** fmov s0, w0 ++** ret ++*/ ++void ++gpr_to_fpr (uint16_t w0) ++{ ++ register uint16_t q0 asm ("q0"); ++ q0 = w0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** zero_to_fpr: ++** fmov s0, wzr ++** ret ++*/ ++void ++zero_to_fpr () ++{ ++ register uint16_t q0 asm ("q0"); ++ q0 = 0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** fpr_to_gpr: ++** fmov w0, s0 ++** ret ++*/ ++uint16_t ++fpr_to_gpr () ++{ ++ register uint16_t q0 asm ("q0"); ++ asm volatile ("" : "=w" (q0)); ++ return q0; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movqi_1.c b/gcc/testsuite/gcc.target/aarch64/movqi_1.c +new file mode 100644 +index 000000000..401a79630 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movqi_1.c +@@ -0,0 +1,61 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++#include <stdint.h> ++ ++/* ++** fpr_to_fpr: ++** fmov s0, s1 ++** ret ++*/ ++void ++fpr_to_fpr (void) ++{ ++ register uint8_t q0 asm ("q0"); ++ register uint8_t q1 asm ("q1"); ++ asm volatile ("" : "=w" (q1)); ++ q0 = q1; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** gpr_to_fpr: ++** fmov s0, w0 ++** ret ++*/ ++void ++gpr_to_fpr (uint8_t w0) ++{ ++ register uint8_t q0 asm ("q0"); ++ q0 = w0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** zero_to_fpr: ++** fmov s0, wzr ++** ret ++*/ ++void ++zero_to_fpr () ++{ ++ register uint8_t q0 asm ("q0"); ++ q0 = 0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** fpr_to_gpr: ++** fmov w0, s0 ++** ret ++*/ ++uint8_t ++fpr_to_gpr () ++{ ++ register uint8_t q0 asm ("q0"); ++ asm volatile ("" : "=w" (q0)); ++ return q0; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movsf_1.c b/gcc/testsuite/gcc.target/aarch64/movsf_1.c +new file mode 100644 +index 000000000..09715aa4f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movsf_1.c +@@ -0,0 +1,53 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++/* ++** fpr_to_fpr: ++** fmov s0, s1 ++** ret ++*/ ++float ++fpr_to_fpr (float q0, float q1) ++{ ++ return q1; ++} ++ ++/* ++** gpr_to_fpr: ++** fmov s0, w0 ++** ret ++*/ ++float ++gpr_to_fpr () ++{ ++ register float w0 asm ("w0"); ++ asm volatile ("" : "=r" (w0)); ++ return w0; ++} ++ ++/* ++** zero_to_fpr: ++** fmov s0, wzr ++** ret ++*/ ++float ++zero_to_fpr () ++{ ++ return 0; ++} ++ ++/* ++** fpr_to_gpr: ++** fmov w0, s0 ++** ret ++*/ ++void ++fpr_to_gpr (float q0) ++{ ++ register float w0 asm ("w0"); ++ w0 = q0; ++ asm volatile ("" :: "r" (w0)); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movsi_1.c b/gcc/testsuite/gcc.target/aarch64/movsi_1.c +new file mode 100644 +index 000000000..5314139aa +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movsi_1.c +@@ -0,0 +1,61 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++#include <stdint.h> ++ ++/* ++** fpr_to_fpr: ++** fmov s0, s1 ++** ret ++*/ ++void ++fpr_to_fpr (void) ++{ ++ register uint32_t q0 asm ("q0"); ++ register uint32_t q1 asm ("q1"); ++ asm volatile ("" : "=w" (q1)); ++ q0 = q1; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** gpr_to_fpr: ++** fmov s0, w0 ++** ret ++*/ ++void ++gpr_to_fpr (uint32_t w0) ++{ ++ register uint32_t q0 asm ("q0"); ++ q0 = w0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** zero_to_fpr: ++** fmov s0, wzr ++** ret ++*/ ++void ++zero_to_fpr () ++{ ++ register uint32_t q0 asm ("q0"); ++ q0 = 0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** fpr_to_gpr: ++** fmov w0, s0 ++** ret ++*/ ++uint32_t ++fpr_to_gpr () ++{ ++ register uint32_t q0 asm ("q0"); ++ asm volatile ("" : "=w" (q0)); ++ return q0; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movtf_2.c b/gcc/testsuite/gcc.target/aarch64/movtf_2.c +new file mode 100644 +index 000000000..38b16358d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movtf_2.c +@@ -0,0 +1,81 @@ ++/* { dg-do assemble } */ ++/* { dg-require-effective-target large_long_double } */ ++/* { dg-options "-O -mtune=neoverse-v1 --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++/* ++** fpr_to_fpr: ++** sub sp, sp, #16 ++** str q1, \[sp\] ++** ldr q0, \[sp\] ++** add sp, sp, #?16 ++** ret ++*/ ++long double ++fpr_to_fpr (long double q0, long double q1) ++{ ++ return q1; ++} ++ ++/* ++** gpr_to_fpr: { target aarch64_little_endian } ++** fmov d0, x0 ++** fmov v0.d\[1\], x1 ++** ret ++*/ ++/* ++** gpr_to_fpr: { target aarch64_big_endian } ++** fmov d0, x1 ++** fmov v0.d\[1\], x0 ++** ret ++*/ ++long double ++gpr_to_fpr () ++{ ++ register long double x0 asm ("x0"); ++ asm volatile ("" : "=r" (x0)); ++ return x0; ++} ++ ++/* ++** zero_to_fpr: ++** fmov s0, wzr ++** ret ++*/ ++long double ++zero_to_fpr () ++{ ++ return 0; ++} ++ ++/* ++** fpr_to_gpr: { target aarch64_little_endian } ++** ( ++** fmov x0, d0 ++** fmov x1, v0.d\[1\] ++** | ++** fmov x1, v0.d\[1\] ++** fmov x0, d0 ++** ) ++** ret ++*/ ++/* ++** fpr_to_gpr: { target aarch64_big_endian } ++** ( ++** fmov x1, d0 ++** fmov x0, v0.d\[1\] ++** | ++** fmov x0, v0.d\[1\] ++** fmov x1, d0 ++** ) ++** ret ++*/ ++void ++fpr_to_gpr (long double q0) ++{ ++ register long double x0 asm ("x0"); ++ x0 = q0; ++ asm volatile ("" :: "r" (x0)); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movti_2.c b/gcc/testsuite/gcc.target/aarch64/movti_2.c +new file mode 100644 +index 000000000..c393b1220 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movti_2.c +@@ -0,0 +1,86 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O -mtune=neoverse-v1 --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++/* ++** fpr_to_fpr: ++** sub sp, sp, #16 ++** str q1, \[sp\] ++** ldr q0, \[sp\] ++** add sp, sp, #?16 ++** ret ++*/ ++void ++fpr_to_fpr (void) ++{ ++ register __int128_t q0 asm ("q0"); ++ register __int128_t q1 asm ("q1"); ++ asm volatile ("" : "=w" (q1)); ++ q0 = q1; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** gpr_to_fpr: { target aarch64_little_endian } ++** fmov d0, x0 ++** fmov v0.d\[1\], x1 ++** ret ++*/ ++/* ++** gpr_to_fpr: { target aarch64_big_endian } ++** fmov d0, x1 ++** fmov v0.d\[1\], x0 ++** ret ++*/ ++void ++gpr_to_fpr (__int128_t x0) ++{ ++ register __int128_t q0 asm ("q0"); ++ q0 = x0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** zero_to_fpr: ++** fmov d0, xzr ++** ret ++*/ ++void ++zero_to_fpr () ++{ ++ register __int128_t q0 asm ("q0"); ++ q0 = 0; ++ asm volatile ("" :: "w" (q0)); ++} ++ ++/* ++** fpr_to_gpr: { target aarch64_little_endian } ++** ( ++** fmov x0, d0 ++** fmov x1, v0.d\[1\] ++** | ++** fmov x1, v0.d\[1\] ++** fmov x0, d0 ++** ) ++** ret ++*/ ++/* ++** fpr_to_gpr: { target aarch64_big_endian } ++** ( ++** fmov x1, d0 ++** fmov x0, v0.d\[1\] ++** | ++** fmov x0, v0.d\[1\] ++** fmov x1, d0 ++** ) ++** ret ++*/ ++__int128_t ++fpr_to_gpr () ++{ ++ register __int128_t q0 asm ("q0"); ++ asm volatile ("" : "=w" (q0)); ++ return q0; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movv16qi_1.c b/gcc/testsuite/gcc.target/aarch64/movv16qi_1.c +new file mode 100644 +index 000000000..8a6afb13b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movv16qi_1.c +@@ -0,0 +1,82 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O -mtune=neoverse-v1 --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++typedef unsigned char v16qi __attribute__((vector_size(16))); ++ ++/* ++** fpr_to_fpr: ++** sub sp, sp, #16 ++** str q1, \[sp\] ++** ldr q0, \[sp\] ++** add sp, sp, #?16 ++** ret ++*/ ++v16qi ++fpr_to_fpr (v16qi q0, v16qi q1) ++{ ++ return q1; ++} ++ ++/* ++** gpr_to_fpr: { target aarch64_little_endian } ++** fmov d0, x0 ++** fmov v0.d\[1\], x1 ++** ret ++*/ ++/* ++** gpr_to_fpr: { target aarch64_big_endian } ++** fmov d0, x1 ++** fmov v0.d\[1\], x0 ++** ret ++*/ ++v16qi ++gpr_to_fpr () ++{ ++ register v16qi x0 asm ("x0"); ++ asm volatile ("" : "=r" (x0)); ++ return x0; ++} ++ ++/* ++** zero_to_fpr: ++** fmov d0, xzr ++** ret ++*/ ++v16qi ++zero_to_fpr () ++{ ++ return (v16qi) {}; ++} ++ ++/* ++** fpr_to_gpr: { target aarch64_little_endian } ++** ( ++** fmov x0, d0 ++** fmov x1, v0.d\[1\] ++** | ++** fmov x1, v0.d\[1\] ++** fmov x0, d0 ++** ) ++** ret ++*/ ++/* ++** fpr_to_gpr: { target aarch64_big_endian } ++** ( ++** fmov x1, d0 ++** fmov x0, v0.d\[1\] ++** | ++** fmov x0, v0.d\[1\] ++** fmov x1, d0 ++** ) ++** ret ++*/ ++void ++fpr_to_gpr (v16qi q0) ++{ ++ register v16qi x0 asm ("x0"); ++ x0 = q0; ++ asm volatile ("" :: "r" (x0)); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/movv8qi_1.c b/gcc/testsuite/gcc.target/aarch64/movv8qi_1.c +new file mode 100644 +index 000000000..4c97e6fbc +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/movv8qi_1.c +@@ -0,0 +1,55 @@ ++/* { dg-do assemble } */ ++/* { dg-options "-O -mtune=neoverse-v1 --save-temps" } */ ++/* { dg-final { check-function-bodies "**" "" "" } } */ ++ ++#pragma GCC target "+nothing+nosimd+fp" ++ ++typedef unsigned char v8qi __attribute__((vector_size(8))); ++ ++/* ++** fpr_to_fpr: ++** fmov d0, d1 ++** ret ++*/ ++v8qi ++fpr_to_fpr (v8qi q0, v8qi q1) ++{ ++ return q1; ++} ++ ++/* ++** gpr_to_fpr: ++** fmov d0, x0 ++** ret ++*/ ++v8qi ++gpr_to_fpr () ++{ ++ register v8qi x0 asm ("x0"); ++ asm volatile ("" : "=r" (x0)); ++ return x0; ++} ++ ++/* ++** zero_to_fpr: ++** fmov d0, xzr ++** ret ++*/ ++v8qi ++zero_to_fpr () ++{ ++ return (v8qi) {}; ++} ++ ++/* ++** fpr_to_gpr: ++** fmov x0, d0 ++** ret ++*/ ++void ++fpr_to_gpr (v8qi q0) ++{ ++ register v8qi x0 asm ("x0"); ++ x0 = q0; ++ asm volatile ("" :: "r" (x0)); ++} +-- +2.33.0 + |