(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
aarch64/
vmov_n_1.c
       1  /* Test vmov_n works correctly.  */
       2  /* { dg-do run } */
       3  /* { dg-options "-O3 --save-temps" } */
       4  
       5  #include <arm_neon.h>
       6  
       7  extern void abort (void);
       8  
       9  #define INHIB_OPTIMIZATION asm volatile ("" : : : "memory")
      10  
      11  #define CONCAT(a, b) a##b
      12  #define CONCAT1(a, b) CONCAT (a, b)
      13  #define REG_INFEX64 _
      14  #define REG_INFEX128 q_
      15  #define REG_INFEX(reg_len) REG_INFEX##reg_len
      16  #define POSTFIX_N(reg_len, data_len, data_type)	\
      17    CONCAT1 (REG_INFEX (reg_len), n_##data_type##data_len)
      18  #define LANE_POSTFIX(reg_len, data_len, data_type) \
      19    CONCAT1 (REG_INFEX (reg_len),lane_##data_type##data_len)
      20  
      21  /* Test values consist of bytes with following hex values.
      22     For example:
      23     TEST1 for int16_t will be 0xaaaa
      24     TEST1 for int32_t will be 0xaaaaaaaa
      25     etc.  */
      26  
      27  #define TEST1h aa
      28  #define TEST2h 55
      29  #define TEST3h ff
      30  #define TEST4h 00
      31  #define TEST5h cc
      32  #define TEST6h 33
      33  
      34  #define TESTh_8(x) TEST##x##h
      35  #define TESTh_16(x) CONCAT1 (TESTh_8 (x), TESTh_8 (x))
      36  #define TESTh_32(x) CONCAT1 (TESTh_16 (x), TESTh_16 (x))
      37  #define TESTh_64(x) CONCAT1 (TESTh_32 (x), TESTh_32 (x))
      38  
      39  #define TEST_8(x) CONCAT1 (0x, TESTh_8 (x))
      40  #define TEST_16(x) CONCAT1 (0x, TESTh_16 (x))
      41  #define TEST_32(x) CONCAT1 (0x, TESTh_32 (x))
      42  #define TEST_64(x) CONCAT1 (0x, TESTh_64 (x))
      43  
      44  #define TEST(test, data_len) \
      45    CONCAT1 (TEST, _##data_len) (test)
      46  
      47  #define GET_ELEMENT(reg_len, data_len, data_type)		\
      48    CONCAT1 (vget, LANE_POSTFIX (reg_len, data_len, data_type))
      49  
      50  #define VMOV_INST(reg_len, data_len, data_type)			\
      51    CONCAT1 (vmov, POSTFIX_N (reg_len, data_len, data_type))
      52  
      53  #define VMOV_OBSCURE_INST(reg_len, data_len, data_type)		\
      54    CONCAT1 (VMOV_INST (reg_len, data_len, data_type), _obscure)
      55  
      56  #define RUN_TEST(reg_len, data_len, data_type,				\
      57  		 test, n, a, b, c)					\
      58  {									\
      59    int i;								\
      60    INHIB_OPTIMIZATION;							\
      61    (a) = TEST (test, data_len);						\
      62    INHIB_OPTIMIZATION;							\
      63    (b) = VMOV_OBSCURE_INST (reg_len, data_len, data_type) (&(a));	\
      64    (c) = TEST (test, data_len);						\
      65    for (i = 0; i < n; i++)						\
      66      {									\
      67        INHIB_OPTIMIZATION;						\
      68        a = GET_ELEMENT (reg_len, data_len, data_type) (b, i);		\
      69        if ((a) != (c))							\
      70  	return 1;							\
      71      }									\
      72  }
      73  
      74  #define TYPE_f32 float32_t
      75  #define TYPE_64_f32 float32x2_t
      76  #define TYPE_128_f32 float32x4_t
      77  
      78  #define TYPE_f64 float64_t
      79  #define TYPE_64_f64 float64x1_t
      80  #define TYPE_128_f64 float64x2_t
      81  
      82  #define TYPE_s8 int8_t
      83  #define TYPE_64_s8 int8x8_t
      84  #define TYPE_128_s8 int8x16_t
      85  
      86  #define TYPE_s16 int16_t
      87  #define TYPE_64_s16 int16x4_t
      88  #define TYPE_128_s16 int16x8_t
      89  
      90  #define TYPE_s32 int32_t
      91  #define TYPE_64_s32 int32x2_t
      92  #define TYPE_128_s32 int32x4_t
      93  
      94  #define TYPE_s64 int64_t
      95  #define TYPE_64_s64 int64x1_t
      96  #define TYPE_128_s64 int64x2_t
      97  
      98  #define TYPE_u8 uint8_t
      99  #define TYPE_64_u8 uint8x8_t
     100  #define TYPE_128_u8 uint8x16_t
     101  
     102  #define TYPE_u16 uint16_t
     103  #define TYPE_64_u16 uint16x4_t
     104  #define TYPE_128_u16 uint16x8_t
     105  
     106  #define TYPE_u32 uint32_t
     107  #define TYPE_64_u32 uint32x2_t
     108  #define TYPE_128_u32 uint32x4_t
     109  
     110  #define TYPE_u64 uint64_t
     111  #define TYPE_64_u64 uint64x1_t
     112  #define TYPE_128_u64 uint64x2_t
     113  
     114  #define TYPE_p8 poly8_t
     115  #define TYPE_64_p8 poly8x8_t
     116  #define TYPE_128_p8 poly8x16_t
     117  
     118  #define TYPE_p16 poly16_t
     119  #define TYPE_64_p16 poly16x4_t
     120  #define TYPE_128_p16 poly16x8_t
     121  
     122  #define DIV64_8  8
     123  #define DIV64_16 4
     124  #define DIV64_32 2
     125  #define DIV64_64 1
     126  
     127  #define DIV128_8  16
     128  #define DIV128_16 8
     129  #define DIV128_32 4
     130  #define DIV128_64 2
     131  
     132  #define DIV(reg_len, data_len)			\
     133  CONCAT1 (CONCAT1 (DIV, reg_len),		\
     134  	 CONCAT1 (_, data_len))
     135  
     136  #define VECTOR_TYPE(reg_len, data_len, data_type)	\
     137  CONCAT1 (CONCAT1 (CONCAT1 (TYPE_,reg_len),		\
     138  		  CONCAT1 (_,data_type)),		\
     139  	 data_len)
     140  
     141  #define SIMPLE_TYPE(data_len, data_type)	\
     142  CONCAT1 (TYPE_,					\
     143  	 CONCAT1 (data_type,			\
     144  		  data_len))
     145  
     146  #define OBSCURE_FUNC_NAME(reg_len, data_type, data_len)		\
     147  CONCAT1 (CONCAT1 (vmov,						\
     148  		  POSTFIX_N (reg_len, data_len, data_type)),	\
     149  	 _obscure)
     150  
     151  #define OBSCURE_FUNC(reg_len, data_len, data_type)	\
     152  VECTOR_TYPE (reg_len, data_len, data_type)		\
     153  __attribute__ ((noinline))				\
     154  OBSCURE_FUNC_NAME (reg_len, data_type, data_len)	\
     155   (SIMPLE_TYPE (data_len, data_type) *ap)		\
     156  {							\
     157    SIMPLE_TYPE (data_len, data_type) register a;		\
     158    INHIB_OPTIMIZATION;					\
     159    a = *ap;						\
     160    INHIB_OPTIMIZATION;					\
     161    return VMOV_INST (reg_len, data_len, data_type) (a);	\
     162  }
     163  
     164  #define TESTFUNC_NAME(reg_len, data_type, data_len)	\
     165  CONCAT1 (test_vmov,					\
     166  	 POSTFIX_N (reg_len, data_len, data_type))
     167  
     168  #define TESTFUNC(reg_len, data_len, data_type)	\
     169  int						\
     170  TESTFUNC_NAME (reg_len, data_type, data_len) ()	\
     171  {						\
     172    SIMPLE_TYPE (data_len, data_type) a;		\
     173    VECTOR_TYPE (reg_len, data_len, data_type) b;	\
     174    SIMPLE_TYPE (data_len, data_type) c;		\
     175  						\
     176    RUN_TEST (reg_len, data_len, data_type, 1,	\
     177  	    DIV (reg_len, data_len), a, b, c);	\
     178    RUN_TEST (reg_len, data_len, data_type, 2,	\
     179  	    DIV (reg_len, data_len), a, b, c);	\
     180    RUN_TEST (reg_len, data_len, data_type, 3,	\
     181  	    DIV (reg_len, data_len), a, b, c);	\
     182    RUN_TEST (reg_len, data_len, data_type, 4,	\
     183  	    DIV (reg_len, data_len), a, b, c);	\
     184    RUN_TEST (reg_len, data_len, data_type, 5,	\
     185  	    DIV (reg_len, data_len), a, b, c);	\
     186    RUN_TEST (reg_len, data_len, data_type, 6,	\
     187  	    DIV (reg_len, data_len), a, b, c);	\
     188    return 0;					\
     189  }
     190  
     191  OBSCURE_FUNC (64, 32, f)
     192  TESTFUNC (64, 32, f)
     193  /* "dup  Vd.2s, Rn" is less preferable than "dup  Vd.2s, Vn.s[lane]".  */
     194  /* { dg-final { scan-assembler-not "dup\\tv\[0-9\]+\.2s, w\[0-9\]+" } } */
     195  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 3 } } */
     196  
     197  OBSCURE_FUNC (64, 64, f)
     198  TESTFUNC (64, 64, f)
     199  /* "fmov  Dd, Rn" is generated instead of "dup  Dd, Rn".
     200     No assembley scan included.  */
     201  
     202  OBSCURE_FUNC (64, 8, p)
     203  TESTFUNC (64, 8, p)
     204  /* Generates "dup  Vd.8b, Rn". Scan found near s8 version.  */
     205  
     206  OBSCURE_FUNC (64, 16, p)
     207  TESTFUNC (64, 16, p)
     208  /* Generates "dup  Vd.4h, Rn". Scan found near s16 version.  */
     209  
     210  OBSCURE_FUNC (64, 8, s)
     211  TESTFUNC (64, 8, s)
     212  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.8b, w\[0-9\]+" 1 } } */
     213  
     214  OBSCURE_FUNC (64, 16, s)
     215  TESTFUNC (64, 16, s)
     216  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.4h, w\[0-9\]+" 1 } } */
     217  
     218  OBSCURE_FUNC (64, 32, s)
     219  TESTFUNC (64, 32, s)
     220  /* "dup  Vd.2s, Rn" is less preferable than "dup  Vd.2s, Vn.s[lane]".  */
     221  /* { dg-final { scan-assembler-not "dup\\tv\[0-9\]+\.2s, w\[0-9\]+" } } */
     222  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 3 } } */
     223  
     224  OBSCURE_FUNC (64, 64, s)
     225  TESTFUNC (64, 64, s)
     226  /* "fmov  Dd, Rn" is generated instead of "dup  Dd, Rn".
     227     No assembley scan included.  */
     228  
     229  OBSCURE_FUNC (64, 8, u)
     230  TESTFUNC (64, 8, u)
     231  /* Generates "dup  Vd.8b, Rn". Scan found near s8 version.  */
     232  
     233  OBSCURE_FUNC (64, 16, u)
     234  TESTFUNC (64, 16, u)
     235  /* Generates "dup  Vd.4h, Rn". Scan found near s16 version.  */
     236  
     237  OBSCURE_FUNC (64, 32, u)
     238  TESTFUNC (64, 32, u)
     239  /* Generates "dup  Vd.2s, Rn". Scan found near s32 version.  */
     240  
     241  OBSCURE_FUNC (64, 64, u)
     242  TESTFUNC (64, 64, u)
     243  /* "fmov  Dd, Rn" is generated instead of "dup  Dd, Rn".
     244     No assembley scan included.  */
     245  
     246  OBSCURE_FUNC (128, 32, f)
     247  TESTFUNC (128, 32, f)
     248  /* "dup  Vd.4s, Rn" is less preferable than "dup  Vd.4s, Vn.s[lane]".  */
     249  /* { dg-final { scan-assembler-not "dup\\tv\[0-9\]+\.4s, w\[0-9\]+" } } */
     250  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.4s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 3 } } */
     251  
     252  OBSCURE_FUNC (128, 64, f)
     253  TESTFUNC (128, 64, f)
     254  /* "dup  Vd.2d, Rn" is less preferable than "dup  Vd.2d, Vn.d[lane]".  */
     255  /* { dg-final { scan-assembler-not "dup\\tv\[0-9\]+\.2d, x\[0-9\]+" } } */
     256  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2d, v\[0-9\]+\.d\\\[\[0-9\]+\\\]" 3 } } */
     257  
     258  OBSCURE_FUNC (128, 8, p)
     259  TESTFUNC (128, 8, p)
     260  /* Generates "dup  Vd.16b, Rn". Scan found near s8 version.  */
     261  
     262  OBSCURE_FUNC (128, 16, p)
     263  TESTFUNC (128, 16, p)
     264  /* Generates "dup  Vd.8h, Rn". Scan found near s16 version.  */
     265  
     266  OBSCURE_FUNC (128, 8, s)
     267  TESTFUNC (128, 8, s)
     268  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.16b, w\[0-9\]+" 1 } } */
     269  
     270  OBSCURE_FUNC (128, 16, s)
     271  TESTFUNC (128, 16, s)
     272  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.8h, w\[0-9\]+" 1 } } */
     273  
     274  OBSCURE_FUNC (128, 32, s)
     275  TESTFUNC (128, 32, s)
     276  /* "dup  Vd.4s, Rn" is less preferable than "dup  Vd.4s, Vn.s[lane]".  */
     277  /* { dg-final { scan-assembler-not "dup\\tv\[0-9\]+\.4s, w\[0-9\]+" } } */
     278  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.4s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 3 } } */
     279  
     280  OBSCURE_FUNC (128, 64, s)
     281  TESTFUNC (128, 64, s)
     282  /* "dup  Vd.2d, Rn" is less preferable than "dup  Vd.2d, Vn.d[lane]".  */
     283  /* { dg-final { scan-assembler-not "dup\\tv\[0-9\]+\.2d, x\[0-9\]+" } } */
     284  /* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2d, v\[0-9\]+\.d\\\[\[0-9\]+\\\]" 3 } } */
     285  
     286  OBSCURE_FUNC (128, 8, u)
     287  TESTFUNC (128, 8, u)
     288  /* Generates "dup  Vd.16b, Rn". Scan found near s8 version.  */
     289  
     290  OBSCURE_FUNC (128, 16, u)
     291  TESTFUNC (128, 16, u)
     292  /* Generates "dup  Vd.8h, Rn". Scan found near s16 version.  */
     293  
     294  OBSCURE_FUNC (128, 32, u)
     295  TESTFUNC (128, 32, u)
     296  /* Generates "dup  Vd.4s, Rn". Scan found near s32 version.  */
     297  
     298  OBSCURE_FUNC (128, 64, u)
     299  TESTFUNC (128, 64, u)
     300  /* Generates "dup  Vd.2d, Rn". Scan found near s64 version.  */
     301  
     302  int
     303  main (int argc, char **argv)
     304  {
     305    if (test_vmov_n_f32 ())
     306      abort ();
     307    if (test_vmov_n_f64 ())
     308      abort ();
     309    if (test_vmov_n_p8 ())
     310      abort ();
     311    if (test_vmov_n_p16 ())
     312      abort ();
     313    if (test_vmov_n_s8 ())
     314      abort ();
     315    if (test_vmov_n_s16 ())
     316      abort ();
     317    if (test_vmov_n_s32 ())
     318      abort ();
     319    if (test_vmov_n_s64 ())
     320      abort ();
     321    if (test_vmov_n_u8 ())
     322      abort ();
     323    if (test_vmov_n_u16 ())
     324      abort ();
     325    if (test_vmov_n_u32 ())
     326      abort ();
     327    if (test_vmov_n_u64 ())
     328      abort ();
     329  
     330    if (test_vmovq_n_f32 ())
     331      abort ();
     332    if (test_vmovq_n_f64 ())
     333      abort ();
     334    if (test_vmovq_n_p8 ())
     335      abort ();
     336    if (test_vmovq_n_p16 ())
     337      abort ();
     338    if (test_vmovq_n_s8 ())
     339      abort ();
     340    if (test_vmovq_n_s16 ())
     341      abort ();
     342    if (test_vmovq_n_s32 ())
     343      abort ();
     344    if (test_vmovq_n_s64 ())
     345      abort ();
     346    if (test_vmovq_n_u8 ())
     347      abort ();
     348    if (test_vmovq_n_u16 ())
     349      abort ();
     350    if (test_vmovq_n_u32 ())
     351      abort ();
     352    if (test_vmovq_n_u64 ())
     353      abort ();
     354  
     355    return 0;
     356  }
     357