1  /* { dg-do run { target { aarch64_sve128_hw } } } */
       2  /* { dg-require-effective-target aarch64_little_endian } */
       3  /* { dg-options "-msve-vector-bits=128" } */
       4  
       5  #include "struct.h"
       6  
       7  struct pst1
       8  {
       9    fixed_uint32_t u32;
      10    fixed_uint64_t u64;
      11  };
      12  
      13  ASM_FUNCTION (make_pst1_asm, struct pst1, (),
      14  	      "mov z0.s, #0x1ffffe00\n\t"
      15  	      "mov z1.d, #0x7f80");
      16  
      17  ASM_FUNCTION (passthru_pst1_asm, struct pst1, (struct pst1), "");
      18  
      19  ASM_FUNCTION (passthru_pst1_z6_asm,
      20  	      struct pst1, (svint32_t, svint32_t, svint32_t, svint32_t,
      21  			    svint32_t, svint32_t, struct pst1),
      22  	      "mov z0.d, z6.d\n\t"
      23  	      "mov z1.d, z7.d");
      24  
      25  ASM_FUNCTION (passthru_pst1_x0_asm,
      26  	      struct pst1, (svint32_t, svint32_t, svint32_t, svint32_t,
      27  			    svint32_t, svint32_t, svint32_t, struct pst1),
      28  	      "ptrue p0.b\n\t"
      29  	      "ld1w z0.s, p0/z, [x0]\n\t"
      30  	      "ld1d z1.d, p0/z, [x0, #1, mul vl]");
      31  
      32  void
      33  test_pst1 (struct pst1 *x)
      34  {
      35    svbool_t pg = svptrue_b8 ();
      36    if (svptest_any (pg, svcmpne (pg, x->u32, 0x1ffffe00))
      37        || svptest_any (pg, svcmpne (pg, x->u64, 0x7f80)))
      38      __builtin_abort ();
      39  }
      40  
      41  struct pst1 deref_pst1 (struct pst1 *ptr) { return *ptr; }
      42  struct pst1 passthru_pst1 (struct pst1 x) { return x; }
      43  
      44  struct pst1
      45  passthru_pst1_z6 (svint32_t z0, svint32_t z1, svint32_t z2, svint32_t z3,
      46  		  svint32_t z4, svint32_t z5, struct pst1 z6)
      47  {
      48    return z6;
      49  }
      50  
      51  struct pst1
      52  passthru_pst1_x0 (svint32_t z0, svint32_t z1, svint32_t z2, svint32_t z3,
      53  		  svint32_t z4, svint32_t z5, svint32_t z6, struct pst1 x0)
      54  {
      55    return x0;
      56  }
      57  
      58  void consume_pst1 (struct pst1 x) { test_pst1 (&x); }
      59  
      60  static void
      61  run_pst1_tests (void)
      62  {
      63    svint32_t s32 = svdup_s32 (0);
      64    svbool_t pg = svptrue_b8 ();
      65  
      66    CLEANSE; struct pst1 res = make_pst1_asm ();
      67    CLEANSE; test_pst1 (&res);
      68    CLEANSE; consume_pst1 (deref_pst1 (&res));
      69    CLEANSE; consume_pst1 (passthru_pst1_asm (res));
      70    CLEANSE; consume_pst1 (passthru_pst1 (res));
      71    CLEANSE; consume_pst1 (passthru_pst1_z6_asm (s32, s32, s32, s32,
      72  					       s32, s32, res));
      73    CLEANSE; consume_pst1 (passthru_pst1_z6 (s32, s32, s32, s32,
      74  					   s32, s32, res));
      75    CLEANSE; consume_pst1 (passthru_pst1_x0_asm (s32, s32, s32, s32,
      76  					       s32, s32, s32, res));
      77    CLEANSE; consume_pst1 (passthru_pst1_x0 (s32, s32, s32, s32,
      78  					   s32, s32, s32, res));
      79  }
      80  
      81  //--------------------------------------------------------------------------
      82  
      83  struct pst2
      84  {
      85    fixed_uint8_t u8;
      86    fixed_uint16_t u16;
      87    struct {
      88      fixed_float64_t f64;
      89      fixed_bool_t pg;
      90    } a[4];
      91    struct pst1 sub;
      92  };
      93  
      94  ASM_FUNCTION (make_pst2_asm, struct pst2, (),
      95  	      "mov z0.b, #100\n\t"
      96  	      "mov z1.h, #99\n\t"
      97  	      "fmov z2.d, #1.0\n\t"
      98  	      "fmov z3.d, #2.0\n\t"
      99  	      "fmov z4.d, #3.0\n\t"
     100  	      "fmov z5.d, #4.0\n\t"
     101  	      "mov z6.s, #98\n\t"
     102  	      "mov z7.d, #97\n\t"
     103  	      "ptrue p0.b, vl5\n\t"
     104  	      "ptrue p1.b, vl6\n\t"
     105  	      "ptrue p2.b, vl7\n\t"
     106  	      "ptrue p3.b, vl8");
     107  
     108  ASM_FUNCTION (passthru_pst2_asm, struct pst2, (struct pst2), "");
     109  
     110  ASM_FUNCTION (passthru_pst2_x0_asm, struct pst2, (svbool_t, struct pst2),
     111  	      "cntd x2, all, mul #9\n\t"
     112  	      "add x2, x2, #15\n\t"
     113  	      "and x2, x2, #-16\n\t"
     114  	      "ptrue p0.b\n\t"
     115  	      "ld1b z0.b, p0/z, [x0, #0, mul vl]\n\t"
     116  	      "ld1h z1.h, p0/z, [x0, #1, mul vl]\n\t"
     117  	      "ld1d z2.d, p0/z, [x0, #2, mul vl]\n\t"
     118  	      "add x1, x0, x2\n\t"
     119  	      "ld1d z3.d, p0/z, [x1, #2, mul vl]\n\t"
     120  	      "ldr p1, [x1, #24, mul vl]\n\t"
     121  	      "add x1, x1, x2\n\t"
     122  	      "ld1d z4.d, p0/z, [x1, #2, mul vl]\n\t"
     123  	      "ldr p2, [x1, #24, mul vl]\n\t"
     124  	      "add x1, x1, x2\n\t"
     125  	      "ld1d z5.d, p0/z, [x1, #2, mul vl]\n\t"
     126  	      "ldr p3, [x1, #24, mul vl]\n\t"
     127  	      "add x1, x1, x2\n\t"
     128  	      "ld1w z6.s, p0/z, [x1, #2, mul vl]\n\t"
     129  	      "ld1d z7.d, p0/z, [x1, #3, mul vl]\n\t"
     130  	      "ldr p0, [x0, #24, mul vl]");
     131  
     132  void
     133  test_pst2 (struct pst2 *x)
     134  {
     135    svbool_t pg = svptrue_b8 ();
     136    if (svptest_any (pg, svcmpne (pg, x->u8, 100))
     137        || svptest_any (pg, svcmpne (pg, x->u16, 99))
     138        || svptest_any (pg, svcmpne (pg, x->a[0].f64, 1.0))
     139        || svptest_any (pg, sveor_z (pg, x->a[0].pg, svptrue_pat_b8 (SV_VL5)))
     140        || svptest_any (pg, svcmpne (pg, x->a[1].f64, 2.0))
     141        || svptest_any (pg, sveor_z (pg, x->a[1].pg, svptrue_pat_b8 (SV_VL6)))
     142        || svptest_any (pg, svcmpne (pg, x->a[2].f64, 3.0))
     143        || svptest_any (pg, sveor_z (pg, x->a[2].pg, svptrue_pat_b8 (SV_VL7)))
     144        || svptest_any (pg, svcmpne (pg, x->a[3].f64, 4.0))
     145        || svptest_any (pg, sveor_z (pg, x->a[3].pg, svptrue_pat_b8 (SV_VL8)))
     146        || svptest_any (pg, svcmpne (pg, x->sub.u32, 98))
     147        || svptest_any (pg, svcmpne (pg, x->sub.u64, 97)))
     148      __builtin_abort ();
     149  }
     150  
     151  struct pst2 deref_pst2 (struct pst2 *ptr) { return *ptr; }
     152  struct pst2 passthru_pst2 (struct pst2 x) { return x; }
     153  
     154  struct pst2
     155  passthru_pst2_x0 (svbool_t pg, struct pst2 x0)
     156  {
     157    return x0;
     158  }
     159  
     160  void
     161  consume_pst2 (struct pst2 x)
     162  {
     163    test_pst2 (&x);
     164  }
     165  
     166  static void
     167  run_pst2_tests (void)
     168  {
     169    CLEANSE; struct pst2 res = make_pst2_asm ();
     170    CLEANSE; test_pst2 (&res);
     171    CLEANSE; consume_pst2 (deref_pst2 (&res));
     172    CLEANSE; consume_pst2 (passthru_pst2_asm (res));
     173    CLEANSE; consume_pst2 (passthru_pst2 (res));
     174    CLEANSE; consume_pst2 (passthru_pst2_x0_asm (svptrue_b8 (), res));
     175    CLEANSE; consume_pst2 (passthru_pst2_x0 (svptrue_b8 (), res));
     176  }
     177  
     178  //--------------------------------------------------------------------------
     179  
     180  struct __attribute__((packed, aligned (2))) pst3
     181  {
     182    fixed_bool_t p;
     183    fixed_float16_t v;
     184  };
     185  
     186  ASM_FUNCTION (make_pst3_asm, struct pst3, (),
     187  	      "ptrue p0.h, vl3\n\t"
     188  	      "fmov z0.h, #5.0");
     189  
     190  ASM_FUNCTION (passthru_pst3_asm, struct pst3, (struct pst3), "");
     191  
     192  ASM_FUNCTION (passthru_pst3_p3_z7_asm,
     193  	      struct pst3, (svbool_t, svbool_t, svbool_t,
     194  			    svint32_t, svint32_t, svint32_t, svint32_t,
     195  			    svint32_t, svint32_t, svint32_t, struct pst3),
     196  	      "mov z0.d, z7.d\n\t"
     197  	      "mov p0.b, p3.b");
     198  
     199  ASM_FUNCTION (passthru_pst3_x0_asm,
     200  	      struct pst3, (svbool_t, svbool_t, svbool_t, svbool_t,
     201  			    struct pst3),
     202  	      "addpl x1, x0, #1\n\t"
     203  	      "ld1h z0.h, p1/z, [x1]\n\t"
     204  	      "ldr p0, [x0]");
     205  
     206  void
     207  test_pst3 (struct pst3 *x)
     208  {
     209    svbool_t pg = svptrue_b8 ();
     210    if (svptest_any (pg, sveor_z (pg, x->p, svptrue_pat_b16 (SV_VL3)))
     211        || svptest_any (pg, svcmpne (pg, x->v, 5.0)))
     212      __builtin_abort ();
     213  }
     214  
     215  struct pst3 deref_pst3 (struct pst3 *ptr) { return *ptr; }
     216  struct pst3 passthru_pst3 (struct pst3 x) { return x; }
     217  
     218  struct pst3
     219  passthru_pst3_p3_z7 (svbool_t p0, svbool_t p1, svbool_t p2,
     220  		     svint32_t z0, svint32_t z1, svint32_t z2, svint32_t z3,
     221  		     svint32_t z4, svint32_t z5, svint32_t z6,
     222  		     struct pst3 p3_z7)
     223  {
     224    return p3_z7;
     225  }
     226  
     227  struct pst3
     228  passthru_pst3_x0 (svbool_t p0, svbool_t p1, svbool_t p2, svbool_t p3,
     229  		  struct pst3 x0)
     230  {
     231    return x0;
     232  }
     233  
     234  void consume_pst3 (struct pst3 x) { test_pst3 (&x); }
     235  
     236  static void
     237  run_pst3_tests (void)
     238  {
     239    svint32_t s32 = svdup_s32 (0);
     240    svbool_t pg = svptrue_b8 ();
     241  
     242    CLEANSE; struct pst3 res = make_pst3_asm ();
     243    CLEANSE; test_pst3 (&res);
     244    CLEANSE; consume_pst3 (deref_pst3 (&res));
     245    CLEANSE; consume_pst3 (passthru_pst3_asm (res));
     246    CLEANSE; consume_pst3 (passthru_pst3 (res));
     247    CLEANSE; consume_pst3 (passthru_pst3_p3_z7_asm (pg, pg, pg,
     248  						  s32, s32, s32, s32,
     249  						  s32, s32, s32, res));
     250    CLEANSE; consume_pst3 (passthru_pst3_p3_z7 (pg, pg, pg,
     251  					      s32, s32, s32, s32,
     252  					      s32, s32, s32, res));
     253    CLEANSE; consume_pst3 (passthru_pst3_x0_asm (pg, pg, pg, pg, res));
     254    CLEANSE; consume_pst3 (passthru_pst3_x0 (pg, pg, pg, pg, res));
     255  }
     256  
     257  //--------------------------------------------------------------------------
     258  
     259  struct pst4
     260  {
     261    fixed_bool_t p1;
     262    fixed_bool_t p2 __attribute__((aligned (256)));
     263    fixed_bool_t p3 __attribute__((aligned (2048)));
     264  };
     265  
     266  ASM_FUNCTION (make_pst4_asm, struct pst4, (),
     267  	      "ptrue p0.h, vl7\n\t"
     268  	      "ptrue p1.h, mul3\n\t"
     269  	      "ptrue p2.h, vl5");
     270  
     271  ASM_FUNCTION (passthru_pst4_asm, struct pst4, (struct pst4), "");
     272  
     273  ASM_FUNCTION (passthru_pst4_p1_asm,
     274  	      struct pst4, (svbool_t, struct pst4),
     275  	      "mov p0.b, p1.b\n\t"
     276  	      "mov p1.b, p2.b\n\t"
     277  	      "mov p2.b, p3.b");
     278  
     279  ASM_FUNCTION (passthru_pst4_x0_asm,
     280  	      struct pst4, (svbool_t, svbool_t, struct pst4),
     281  	      "ldr p0, [x0]\n\t"
     282  	      "add x0, x0, #256\n\t"
     283  	      "ldr p1, [x0]\n\t"
     284  	      "add x0, x0, #2048 - 256\n\t"
     285  	      "ldr p2, [x0]");
     286  
     287  void
     288  test_pst4 (struct pst4 *x)
     289  {
     290    svbool_t pg = svptrue_b8 ();
     291    if (svptest_any (pg, sveor_z (pg, x->p1, svptrue_pat_b16 (SV_VL7)))
     292        || svptest_any (pg, sveor_z (pg, x->p2, svptrue_pat_b16 (SV_MUL3)))
     293        || svptest_any (pg, sveor_z (pg, x->p3, svptrue_pat_b16 (SV_VL5))))
     294      __builtin_abort ();
     295  }
     296  
     297  struct pst4 deref_pst4 (struct pst4 *ptr) { return *ptr; }
     298  struct pst4 passthru_pst4 (struct pst4 x) { return x; }
     299  
     300  struct pst4
     301  passthru_pst4_p1 (svbool_t p0, struct pst4 p1)
     302  {
     303    return p1;
     304  }
     305  
     306  struct pst4
     307  passthru_pst4_x0 (svbool_t p0, svbool_t p1, struct pst4 x0)
     308  {
     309    return x0;
     310  }
     311  
     312  void consume_pst4 (struct pst4 x) { test_pst4 (&x); }
     313  
     314  static void
     315  run_pst4_tests (void)
     316  {
     317    svbool_t pg = svptrue_b8 ();
     318  
     319    CLEANSE; struct pst4 res = make_pst4_asm ();
     320    CLEANSE; test_pst4 (&res);
     321    CLEANSE; consume_pst4 (deref_pst4 (&res));
     322    CLEANSE; consume_pst4 (passthru_pst4_asm (res));
     323    CLEANSE; consume_pst4 (passthru_pst4 (res));
     324    CLEANSE; consume_pst4 (passthru_pst4_p1_asm (pg, res));
     325    CLEANSE; consume_pst4 (passthru_pst4_p1 (pg, res));
     326    CLEANSE; consume_pst4 (passthru_pst4_x0_asm (pg, pg, res));
     327    CLEANSE; consume_pst4 (passthru_pst4_x0 (pg, pg, res));
     328  }
     329  
     330  //--------------------------------------------------------------------------
     331  
     332  struct pst5
     333  {
     334    fixed_uint16_t v[8];
     335  };
     336  
     337  ASM_FUNCTION (make_pst5_asm, struct pst5, (),
     338  	      "index z0.h, #0, #-1\n\t"
     339  	      "index z1.h, #0, #-2\n\t"
     340  	      "index z2.h, #0, #-3\n\t"
     341  	      "index z3.h, #0, #-4\n\t"
     342  	      "index z4.h, #0, #-5\n\t"
     343  	      "index z5.h, #0, #-6\n\t"
     344  	      "index z6.h, #0, #-7\n\t"
     345  	      "index z7.h, #0, #-8");
     346  
     347  ASM_FUNCTION (passthru_pst5_asm, struct pst5, (struct pst5), "");
     348  
     349  void
     350  test_pst5 (struct pst5 *x)
     351  {
     352    svbool_t pg = svptrue_b8 ();
     353    for (int i = 0; i < 8; ++i)
     354      if (svptest_any (pg, svcmpne (pg, x->v[i], svindex_u16 (0, -1 - i))))
     355        __builtin_abort ();
     356  }
     357  
     358  struct pst5 deref_pst5 (struct pst5 *ptr) { return *ptr; }
     359  struct pst5 passthru_pst5 (struct pst5 x) { return x; }
     360  
     361  void consume_pst5 (struct pst5 x) { test_pst5 (&x); }
     362  
     363  static void
     364  run_pst5_tests (void)
     365  {
     366    CLEANSE; struct pst5 res = make_pst5_asm ();
     367    CLEANSE; test_pst5 (&res);
     368    CLEANSE; consume_pst5 (deref_pst5 (&res));
     369    CLEANSE; consume_pst5 (passthru_pst5_asm (res));
     370    CLEANSE; consume_pst5 (passthru_pst5 (res));
     371  }
     372  
     373  //--------------------------------------------------------------------------
     374  
     375  struct pst6
     376  {
     377    fixed_uint16_t v[9];
     378  };
     379  
     380  ASM_FUNCTION (make_pst6_asm, struct pst6, (),
     381  	      "mov x0, #10\n\t"
     382  	      "ptrue p0.b\n"
     383  	      "1:\n\t"
     384  	      "index z0.h, #0, w0\n\t"
     385  	      "st1h z0.h, p0, [x8]\n\t"
     386  	      "add x0, x0, #1\n\t"
     387  	      "incb x8\n\t"
     388  	      "cmp x0, #19\n\t"
     389  	      "bne 1b");
     390  
     391  ASM_FUNCTION (passthru_pst6_asm, struct pst6, (struct pst6),
     392  	      "mov x1, x0\n\t"
     393  	      "mov x0, x8\n\t"
     394  	      "cntb x2, all, mul #9\n\t"
     395  	      "b memcpy");
     396  
     397  void
     398  test_pst6 (struct pst6 *x)
     399  {
     400    svbool_t pg = svptrue_b8 ();
     401    for (int i = 0; i < 9; ++i)
     402      if (svptest_any (pg, svcmpne (pg, x->v[i], svindex_u16 (0, i + 10))))
     403        __builtin_abort ();
     404  }
     405  
     406  struct pst6 deref_pst6 (struct pst6 *ptr) { return *ptr; }
     407  struct pst6 passthru_pst6 (struct pst6 x) { return x; }
     408  
     409  void consume_pst6 (struct pst6 x) { test_pst6 (&x); }
     410  
     411  static void
     412  run_pst6_tests (void)
     413  {
     414    CLEANSE; struct pst6 res = make_pst6_asm ();
     415    CLEANSE; test_pst6 (&res);
     416    CLEANSE; consume_pst6 (deref_pst6 (&res));
     417    CLEANSE; consume_pst6 (passthru_pst6_asm (res));
     418    CLEANSE; consume_pst6 (passthru_pst6 (res));
     419  }
     420  
     421  //--------------------------------------------------------------------------
     422  
     423  struct pst7
     424  {
     425    fixed_bool_t p[2][2];
     426  };
     427  
     428  ASM_FUNCTION (make_pst7_asm, struct pst7, (),
     429  	      "ptrue p0.b, vl6\n\t"
     430  	      "ptrue p1.b, vl7\n\t"
     431  	      "ptrue p2.h, vl3\n\t"
     432  	      "ptrue p3.h, vl2");
     433  
     434  ASM_FUNCTION (passthru_pst7_asm, struct pst7, (struct pst7), "");
     435  
     436  void
     437  test_pst7 (struct pst7 *x)
     438  {
     439    svbool_t pg = svptrue_b8 ();
     440    if (svptest_any (pg, sveor_z (pg, x->p[0][0], svptrue_pat_b8 (SV_VL6)))
     441        || svptest_any (pg, sveor_z (pg, x->p[0][1], svptrue_pat_b8 (SV_VL7)))
     442        || svptest_any (pg, sveor_z (pg, x->p[1][0], svptrue_pat_b16 (SV_VL3)))
     443        || svptest_any (pg, sveor_z (pg, x->p[1][1], svptrue_pat_b16 (SV_VL2))))
     444      __builtin_abort ();
     445  }
     446  
     447  struct pst7 deref_pst7 (struct pst7 *ptr) { return *ptr; }
     448  struct pst7 passthru_pst7 (struct pst7 x) { return x; }
     449  
     450  void consume_pst7 (struct pst7 x) { test_pst7 (&x); }
     451  
     452  static void
     453  run_pst7_tests (void)
     454  {
     455    CLEANSE; struct pst7 res = make_pst7_asm ();
     456    CLEANSE; test_pst7 (&res);
     457    CLEANSE; consume_pst7 (deref_pst7 (&res));
     458    CLEANSE; consume_pst7 (passthru_pst7_asm (res));
     459    CLEANSE; consume_pst7 (passthru_pst7 (res));
     460  }
     461  
     462  //--------------------------------------------------------------------------
     463  
     464  struct pst8
     465  {
     466    fixed_bool_t p[2][3];
     467  };
     468  
     469  ASM_FUNCTION (make_pst8_asm, struct pst8, (),
     470  	      "ptrue p3.h, vl2\n\t"
     471  	      "str p3, [x8]\n\t"
     472  	      "ptrue p3.h, vl3\n\t"
     473  	      "str p3, [x8, #1, mul vl]\n\t"
     474  	      "ptrue p3.h, vl4\n\t"
     475  	      "str p3, [x8, #2, mul vl]\n\t"
     476  	      "ptrue p3.s, vl2\n\t"
     477  	      "str p3, [x8, #3, mul vl]\n\t"
     478  	      "ptrue p3.s, vl3\n\t"
     479  	      "str p3, [x8, #4, mul vl]\n\t"
     480  	      "ptrue p3.s, vl4\n\t"
     481  	      "str p3, [x8, #5, mul vl]");
     482  
     483  ASM_FUNCTION (passthru_pst8_asm, struct pst8, (struct pst8),
     484  	      "cntw x1, all, mul #3\n\t"
     485  	      "whilelo p0.b, xzr, x1\n\t"
     486  	      "ld1b z0.b, p0/z, [x0]\n\t"
     487  	      "st1b z0.b, p0, [x8]");
     488  
     489  void
     490  test_pst8 (struct pst8 *x)
     491  {
     492    svbool_t pg = svptrue_b8 ();
     493    if (svptest_any (pg, sveor_z (pg, x->p[0][0], svptrue_pat_b16 (SV_VL2)))
     494        || svptest_any (pg, sveor_z (pg, x->p[0][1], svptrue_pat_b16 (SV_VL3)))
     495        || svptest_any (pg, sveor_z (pg, x->p[0][2], svptrue_pat_b16 (SV_VL4)))
     496        || svptest_any (pg, sveor_z (pg, x->p[1][0], svptrue_pat_b32 (SV_VL2)))
     497        || svptest_any (pg, sveor_z (pg, x->p[1][1], svptrue_pat_b32 (SV_VL3)))
     498        || svptest_any (pg, sveor_z (pg, x->p[1][2], svptrue_pat_b32 (SV_VL4))))
     499      __builtin_abort ();
     500  }
     501  
     502  struct pst8 deref_pst8 (struct pst8 *ptr) { return *ptr; }
     503  struct pst8 passthru_pst8 (struct pst8 x) { return x; }
     504  
     505  void consume_pst8 (struct pst8 x) { test_pst8 (&x); }
     506  
     507  static void
     508  run_pst8_tests (void)
     509  {
     510    CLEANSE; struct pst8 res = make_pst8_asm ();
     511    CLEANSE; test_pst8 (&res);
     512    CLEANSE; consume_pst8 (deref_pst8 (&res));
     513    CLEANSE; consume_pst8 (passthru_pst8_asm (res));
     514    CLEANSE; consume_pst8 (passthru_pst8 (res));
     515  }
     516  
     517  //--------------------------------------------------------------------------
     518  
     519  struct nonpst1
     520  {
     521    int x;
     522    fixed_uint8_t v;
     523    fixed_bool_t p;
     524  };
     525  
     526  ASM_FUNCTION (make_nonpst1_asm, struct nonpst1, (),
     527  	      "mov w0, #42\n\t"
     528  	      "str w0, [x8]\n\t"
     529  	      "add x0, x8, #16\n\t"
     530  	      "ptrue p0.b\n\t"
     531  	      "index z0.b, #0, #3\n\t"
     532  	      "st1b z0.b, p0, [x0]\n\t"
     533  	      "ptrue p3.b, vl5\n\t"
     534  	      "str p3, [x0, #8, mul vl]");
     535  
     536  ASM_FUNCTION (passthru_nonpst1_asm, struct nonpst1, (struct nonpst1),
     537  	      "mov x1, x0\n\t"
     538  	      "mov x0, x8\n\t"
     539  	      "cntd x2, all, mul #9\n\t"
     540  	      "add x2, x2, #16\n\t"
     541  	      "b memcpy");
     542  
     543  void
     544  test_nonpst1 (struct nonpst1 *x)
     545  {
     546    svbool_t pg = svptrue_b8 ();
     547    if (x->x != 42
     548        || svptest_any (pg, svcmpne (pg, x->v, svindex_u8 (0, 3)))
     549        || svptest_any (pg, sveor_z (pg, x->p, svptrue_pat_b8 (SV_VL5))))
     550      __builtin_abort ();
     551  }
     552  
     553  struct nonpst1 deref_nonpst1 (struct nonpst1 *ptr) { return *ptr; }
     554  struct nonpst1 passthru_nonpst1 (struct nonpst1 x) { return x; }
     555  
     556  void consume_nonpst1 (struct nonpst1 x) { test_nonpst1 (&x); }
     557  
     558  static void
     559  run_nonpst1_tests (void)
     560  {
     561    CLEANSE; struct nonpst1 res = make_nonpst1_asm ();
     562    CLEANSE; test_nonpst1 (&res);
     563    CLEANSE; consume_nonpst1 (deref_nonpst1 (&res));
     564    CLEANSE; consume_nonpst1 (passthru_nonpst1_asm (res));
     565    CLEANSE; consume_nonpst1 (passthru_nonpst1 (res));
     566  }
     567  
     568  //--------------------------------------------------------------------------
     569  
     570  struct nonpst2
     571  {
     572    union { struct { fixed_bool_t p; }; };
     573  };
     574  
     575  ASM_FUNCTION (make_nonpst2_asm, struct nonpst2, (),
     576  	      "ptrue p3.h, mul3\n\t"
     577  	      "cntd x2\n\t"
     578  	      "cmp x2, #16\n\t"
     579  	      "b.ls 1f\n\t"
     580  	      "str p3, [x8]\n\t"
     581  	      "ret\n"
     582  	      "1:\n\t"
     583  	      "addvl sp, sp, #-1\n\t"
     584  	      "str p3, [sp]\n\t"
     585  	      "ldp x0, x1, [sp]\n\t"
     586  	      "addvl sp, sp, #1");
     587  
     588  ASM_FUNCTION (passthru_nonpst2_asm, struct nonpst2, (struct nonpst2),
     589  	      "cntb x2\n\t"
     590  	      "cmp x2, #128\n\t"
     591  	      "b.eq 1f\n\t"
     592  	      "b.lo 2f\n\t"
     593  	      "ldr p3, [x0]\n\t"
     594  	      "str p3, [x8]\n"
     595  	      "1:\n\t"
     596  	      "ret\n"
     597  	      "2:\n\t"
     598  	      "mov x3, #-1\n\t"
     599  #if __ARM_BIG_ENDIAN
     600  	      "lsr x3, x3, x2\n\t"
     601  #else
     602  	      "lsl x3, x3, x2\n\t"
     603  #endif
     604  	      "bic x1, x0, x3\n\t"
     605  	      "cmp x2, #64\n\t"
     606  	      "csel x0, x0, x1, eq");
     607  
     608  void
     609  test_nonpst2 (struct nonpst2 *x)
     610  {
     611    svbool_t pg = svptrue_b8 ();
     612    if (svptest_any (pg, sveor_z (pg, x->p, svptrue_pat_b16 (SV_MUL3))))
     613      __builtin_abort ();
     614  }
     615  
     616  struct nonpst2 deref_nonpst2 (struct nonpst2 *ptr) { return *ptr; }
     617  struct nonpst2 passthru_nonpst2 (struct nonpst2 x) { return x; }
     618  
     619  void consume_nonpst2 (struct nonpst2 x) { test_nonpst2 (&x); }
     620  
     621  static void
     622  run_nonpst2_tests (void)
     623  {
     624    CLEANSE; struct nonpst2 res = make_nonpst2_asm ();
     625    CLEANSE; test_nonpst2 (&res);
     626    CLEANSE; consume_nonpst2 (deref_nonpst2 (&res));
     627    CLEANSE; consume_nonpst2 (passthru_nonpst2_asm (res));
     628    CLEANSE; consume_nonpst2 (passthru_nonpst2 (res));
     629  }
     630  
     631  //--------------------------------------------------------------------------
     632  
     633  struct nonpst3
     634  {
     635    union { struct { fixed_int32_t v; }; };
     636  };
     637  
     638  ASM_FUNCTION (make_nonpst3_asm, struct nonpst3, (),
     639  	      "ptrue p0.b\n\t"
     640  	      "index z1.s, #15, #-9\n\t"
     641  	      "cntb x2\n\t"
     642  	      "cmp x2, #16\n\t"
     643  	      "b.ls 1f\n\t"
     644  	      "st1w z1.s, p0, [x8]\n\t"
     645  	      "ret\n"
     646  	      "1:\n\t"
     647  	      "addvl sp, sp, #-1\n\t"
     648  	      "st1w z1.s, p0, [sp]\n\t"
     649  	      "ldp x0, x1, [sp]\n\t"
     650  	      "addvl sp, sp, #1");
     651  
     652  ASM_FUNCTION (passthru_nonpst3_asm, struct nonpst3, (struct nonpst3),
     653  	      "cntb x2\n\t"
     654  	      "cmp x2, #16\n\t"
     655  	      "b.ls 1f\n\t"
     656  	      "ptrue p0.b\n\t"
     657  	      "ld1w z1.s, p0/z, [x0]\n\t"
     658  	      "st1w z1.s, p0, [x8]\n"
     659  	      "1:");
     660  
     661  void
     662  test_nonpst3 (struct nonpst3 *x)
     663  {
     664    svbool_t pg = svptrue_b8 ();
     665    if (svptest_any (pg, svcmpne (pg, x->v, svindex_s32 (15, -9))))
     666      __builtin_abort ();
     667  }
     668  
     669  struct nonpst3 deref_nonpst3 (struct nonpst3 *ptr) { return *ptr; }
     670  struct nonpst3 passthru_nonpst3 (struct nonpst3 x) { return x; }
     671  
     672  void consume_nonpst3 (struct nonpst3 x) { test_nonpst3 (&x); }
     673  
     674  static void
     675  run_nonpst3_tests (void)
     676  {
     677    CLEANSE; struct nonpst3 res = make_nonpst3_asm ();
     678    CLEANSE; test_nonpst3 (&res);
     679    CLEANSE; consume_nonpst3 (deref_nonpst3 (&res));
     680    CLEANSE; consume_nonpst3 (passthru_nonpst3_asm (res));
     681    CLEANSE; consume_nonpst3 (passthru_nonpst3 (res));
     682  }
     683  
     684  //--------------------------------------------------------------------------
     685  
     686  int
     687  main (void)
     688  {
     689    run_pst1_tests ();
     690    run_pst2_tests ();
     691    run_pst3_tests ();
     692    run_pst4_tests ();
     693    run_pst5_tests ();
     694    run_pst6_tests ();
     695    run_pst7_tests ();
     696    run_pst8_tests ();
     697    run_nonpst1_tests ();
     698    run_nonpst2_tests ();
     699    run_nonpst3_tests ();
     700    return 0;
     701  }