(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.c-torture/
execute/
bswap-2.c
       1  /* { dg-require-effective-target int32plus } */
       2  
       3  #ifdef __UINT32_TYPE__
       4  typedef __UINT32_TYPE__ uint32_t;
       5  #else
       6  typedef __UINT32_TYPE__ unsigned;
       7  #endif
       8  
       9  struct bitfield {
      10    unsigned char f0:7;
      11    unsigned char   :1;
      12    unsigned char f1:7;
      13    unsigned char   :1;
      14    unsigned char f2:7;
      15    unsigned char   :1;
      16    unsigned char f3:7;
      17  };
      18  
      19  struct ok {
      20    unsigned char f0;
      21    unsigned char f1;
      22    unsigned char f2;
      23    unsigned char f3;
      24  };
      25  
      26  union bf_or_uint32 {
      27    struct ok inval;
      28    struct bitfield bfval;
      29  };
      30  
      31  __attribute__ ((noinline, noclone)) uint32_t
      32  partial_read_le32 (union bf_or_uint32 in)
      33  {
      34    return in.bfval.f0 | (in.bfval.f1 << 8)
      35  	 | (in.bfval.f2 << 16) | (in.bfval.f3 << 24);
      36  }
      37  
      38  __attribute__ ((noinline, noclone)) uint32_t
      39  partial_read_be32 (union bf_or_uint32 in)
      40  {
      41    return in.bfval.f3 | (in.bfval.f2 << 8)
      42  	 | (in.bfval.f1 << 16) | (in.bfval.f0 << 24);
      43  }
      44  
      45  __attribute__ ((noinline, noclone)) uint32_t
      46  fake_read_le32 (char *x, char *y)
      47  {
      48    unsigned char c0, c1, c2, c3;
      49  
      50    c0 = x[0];
      51    c1 = x[1];
      52    *y = 1;
      53    c2 = x[2];
      54    c3 = x[3];
      55    return c0 | c1 << 8 | c2 << 16 | c3 << 24;
      56  }
      57  
      58  __attribute__ ((noinline, noclone)) uint32_t
      59  fake_read_be32 (char *x, char *y)
      60  {
      61    unsigned char c0, c1, c2, c3;
      62  
      63    c0 = x[0];
      64    c1 = x[1];
      65    *y = 1;
      66    c2 = x[2];
      67    c3 = x[3];
      68    return c3 | c2 << 8 | c1 << 16 | c0 << 24;
      69  }
      70  
      71  __attribute__ ((noinline, noclone)) uint32_t
      72  incorrect_read_le32 (char *x, char *y)
      73  {
      74    unsigned char c0, c1, c2, c3;
      75  
      76    c0 = x[0];
      77    c1 = x[1];
      78    c2 = x[2];
      79    c3 = x[3];
      80    *y = 1;
      81    return c0 | c1 << 8 | c2 << 16 | c3 << 24;
      82  }
      83  
      84  __attribute__ ((noinline, noclone)) uint32_t
      85  incorrect_read_be32 (char *x, char *y)
      86  {
      87    unsigned char c0, c1, c2, c3;
      88  
      89    c0 = x[0];
      90    c1 = x[1];
      91    c2 = x[2];
      92    c3 = x[3];
      93    *y = 1;
      94    return c3 | c2 << 8 | c1 << 16 | c0 << 24;
      95  }
      96  
      97  int
      98  main ()
      99  {
     100    union bf_or_uint32 bfin;
     101    uint32_t out;
     102    char cin[] = { 0x83, 0x85, 0x87, 0x89 };
     103  
     104    if (sizeof (uint32_t) * __CHAR_BIT__ != 32)
     105      return 0;
     106    bfin.inval = (struct ok) { 0x83, 0x85, 0x87, 0x89 };
     107    out = partial_read_le32 (bfin);
     108    /* Test what bswap would do if its check are not strict enough instead of
     109       what is the expected result as there is too many possible results with
     110       bitfields.  */
     111    if (out == 0x89878583)
     112      __builtin_abort ();
     113    bfin.inval = (struct ok) { 0x83, 0x85, 0x87, 0x89 };
     114    out = partial_read_be32 (bfin);
     115    /* Test what bswap would do if its check are not strict enough instead of
     116       what is the expected result as there is too many possible results with
     117       bitfields.  */
     118    if (out == 0x83858789)
     119      __builtin_abort ();
     120    out = fake_read_le32 (cin, &cin[2]);
     121    if (out != 0x89018583)
     122      __builtin_abort ();
     123    cin[2] = 0x87;
     124    out = fake_read_be32 (cin, &cin[2]);
     125    if (out != 0x83850189)
     126      __builtin_abort ();
     127    cin[2] = 0x87;
     128    out = incorrect_read_le32 (cin, &cin[2]);
     129    if (out != 0x89878583)
     130      __builtin_abort ();
     131    cin[2] = 0x87;
     132    out = incorrect_read_be32 (cin, &cin[2]);
     133    if (out != 0x83858789)
     134      __builtin_abort ();
     135    return 0;
     136  }