1  /* PR rtl-optimization/91347 */
       2  /* Reported by John David Anglin <danglin@gcc.gnu.org> */
       3  /* { dg-require-effective-target int32plus } */
       4  
       5  typedef unsigned short __u16;
       6  typedef __signed__ int __s32;
       7  typedef unsigned int __u32;
       8  typedef __signed__ long long __s64;
       9  typedef unsigned long long __u64;
      10  typedef __u16 u16;
      11  typedef __s32 s32;
      12  typedef __u32 u32;
      13  typedef __u64 u64;
      14  typedef _Bool bool;
      15  typedef s32 int32_t;
      16  typedef u32 uint32_t;
      17  typedef u64 uint64_t;
      18  
      19  char hex_asc_upper[16];
      20  u16 decpair[100];
      21  
      22  static __attribute__ ((noipa)) void
      23  put_dec_full4 (char *buf, unsigned r)
      24  {
      25   unsigned q;
      26   q = (r * 0x147b) >> 19;
      27   *((u16 *)buf) = decpair[r - 100*q];
      28   buf += 2;
      29   *((u16 *)buf) = decpair[q];
      30  }
      31  
      32  static __attribute__ ((noipa)) unsigned
      33  put_dec_helper4 (char *buf, unsigned x)
      34  {
      35    uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43;
      36    put_dec_full4(buf, x - q * 10000);
      37    return q;
      38  }
      39  
      40  static __attribute__ ((noipa)) char *
      41  put_dec (char *buf, unsigned long long n)
      42  {
      43   uint32_t d3, d2, d1, q, h;
      44   d1 = ((uint32_t)n >> 16);
      45   h = (n >> 32);
      46   d2 = (h ) & 0xffff;
      47   d3 = (h >> 16);
      48   q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);
      49   q = put_dec_helper4(buf, q);
      50   q += 7671 * d3 + 9496 * d2 + 6 * d1;
      51   q = put_dec_helper4(buf+4, q);
      52   q += 4749 * d3 + 42 * d2;
      53   q = put_dec_helper4(buf+8, q);
      54   return buf;
      55  }
      56  
      57  struct printf_spec {
      58   unsigned int type:8;
      59   signed int field_width:24;
      60   unsigned int flags:8;
      61   unsigned int base:8;
      62   signed int precision:16;
      63  } __attribute__((__packed__));
      64  
      65  static __attribute__ ((noipa)) char *
      66  number (char *buf, char *end, unsigned long long num, struct printf_spec spec)
      67  {
      68  
      69   char tmp[3 * sizeof(num)] __attribute__((__aligned__(2)));
      70   char sign;
      71   char locase;
      72   int need_pfx = ((spec.flags & 64) && spec.base != 10);
      73   int i;
      74   bool is_zero = num == 0LL;
      75   int field_width = spec.field_width;
      76   int precision = spec.precision;
      77  
      78   i = 0;
      79   if (num < spec.base)
      80    tmp[i++] = hex_asc_upper[num] | locase;
      81   else if (spec.base != 10) {
      82    int mask = spec.base - 1;
      83    int shift = 3;
      84    if (spec.base == 16)
      85     shift = 4;
      86    else
      87      __builtin_abort ();
      88    do {
      89     tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase);
      90     num >>= shift;
      91    } while (num);
      92   } else {
      93    i = put_dec(tmp, num) - tmp;
      94   }
      95   return buf;
      96  }
      97  
      98  static __attribute__ ((noipa)) char *
      99  pointer_string (char *buf, char *end, const void *ptr, struct printf_spec spec)
     100  {
     101   spec.base = 16;
     102   spec.flags = 0;
     103   return number(buf, end, 100, spec);
     104  }
     105  
     106  int
     107  main (void)
     108  {
     109    struct printf_spec spec;
     110    char *s = pointer_string (0, 0, 0, spec);
     111    return 0;
     112  }