(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
graphite/
id-15.c
       1  /* { dg-require-effective-target int32plus } */
       2  
       3  typedef long unsigned int size_t;
       4  extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
       5  
       6  static void
       7  encode (words, low, hi)
       8       long *words;
       9       unsigned long low;
      10       long hi;
      11  {
      12    words[0] = ((low) & (((unsigned long) 1 << (sizeof(unsigned long) / 2)) - 1));
      13    words[1] = ((unsigned long) (low) >> sizeof(unsigned long) / 2);
      14    words[2] = ((hi) & (((unsigned long) 1 << (sizeof(unsigned long) / 2)) - 1));
      15    words[3] = ((unsigned long) (hi) >> sizeof(unsigned long) / 2);
      16  }
      17  
      18  static void
      19  decode (words, low, hi)
      20       long *words;
      21       unsigned long *low;
      22       long *hi;
      23  {
      24    *low = words[0] + words[1] * ((unsigned long) 1 << sizeof(unsigned long) / 2);
      25    *hi = words[2] + words[3] * ((unsigned long) 1 << sizeof(unsigned long) / 2);
      26  }
      27  
      28  int
      29  neg_double (l1, h1, lv, hv)
      30       unsigned long l1;
      31       long h1;
      32       unsigned long *lv;
      33       long *hv;
      34  {
      35    if (l1 == 0)
      36      {
      37        *lv = 0;
      38        *hv = - h1;
      39        return (*hv & h1) < 0;
      40      }
      41    else
      42      {
      43        *lv = -l1;
      44        *hv = ~h1;
      45        return 0;
      46      }
      47  }
      48  
      49  int
      50  add_double (l1, h1, l2, h2, lv, hv)
      51       unsigned long l1, l2;
      52       long h1, h2;
      53       unsigned long *lv;
      54       long *hv;
      55  {
      56    unsigned long l;
      57    long h;
      58  
      59    l = l1 + l2;
      60    h = h1 + h2 + (l < l1);
      61  
      62    *lv = l;
      63    *hv = h;
      64    return ((~((h1) ^ (h2)) & ((h1) ^ (h))) < 0);
      65  }
      66  
      67  int
      68  mul_double (l1, h1, l2, h2, lv, hv)
      69       unsigned long l1, l2;
      70       long h1, h2;
      71       unsigned long *lv;
      72       long *hv;
      73  {
      74    long arg1[4];
      75    long arg2[4];
      76    long prod[4 * 2];
      77    unsigned long carry;
      78    int i, j, k;
      79    unsigned long toplow, neglow;
      80    long tophigh, neghigh;
      81  
      82    encode (arg1, l1, h1);
      83    encode (arg2, l2, h2);
      84  
      85    memset ((char *) prod, 0, sizeof prod);
      86  
      87    for (i = 0; i < 4; i++)
      88      {
      89        carry = 0;
      90        for (j = 0; j < 4; j++)
      91  	{
      92  	  k = i + j;
      93  
      94  	  carry += arg1[i] * arg2[j];
      95  
      96  	  carry += prod[k];
      97  	  prod[k] = ((carry) & (((unsigned long) 1 << (sizeof(unsigned long) / 2)) - 1));
      98  	  carry = ((unsigned long) (carry) >> sizeof(unsigned long) / 2);
      99  	}
     100        prod[i + 4] = carry;
     101      }
     102  
     103    decode (prod, lv, hv);
     104  
     105  
     106  
     107    decode (prod + 4, &toplow, &tophigh);
     108    if (h1 < 0)
     109      {
     110        neg_double (l2, h2, &neglow, &neghigh);
     111        add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
     112      }
     113    if (h2 < 0)
     114      {
     115        neg_double (l1, h1, &neglow, &neghigh);
     116        add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
     117      }
     118    return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
     119  }