aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/gcc.target/avr/torture/int24-mul.c
blob: c85d9327712db58fc9ef72c78593db105280cf89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* { dg-do run } */
/* { dg-options "-w" } */

#include <stdlib.h>

const __flash __int24 vals[] =
  {
    0, 1, 2, 3, -1, -2, -3, 0xff, 0x100, 0x101,
    0xffL * 0xff, 0xfffL * 0xfff, 0x101010L, 0xaaaaaaL
  };

void test_u (void)
{
  unsigned int i;
  unsigned long la, lb, lc;
  __uint24 a, b, c;

  int S = sizeof (vals) / sizeof (*vals);

  for (i = 0; i < 500; i++)
    {
      if (i < S*S)
        {
          a = vals[i / S];
          b = vals[i % S];
        }
      else
        {
          if (i & 1)
            a += 0x7654321L;
          else
            b += 0x5fe453L;
        }

      c = a * b;

      la = a;
      lb = b;
      lc = 0xffffff & (la * lb);
      
      if (c != lc)
        abort();
    }
}

#define TEST_N_U(A1,A2,B)                       \
  do {                                          \
    if ((0xffffff & (A1*B)) != A2*B)            \
      abort();                                  \
  } while (0)

void test_nu (void)
{
  unsigned long la;
  unsigned int i;
  int S = sizeof (vals) / sizeof (*vals);
  __uint24 a;
  
  for (i = 0; i < 500; i++)
    {
      a = i < S
        ? vals[i % S]
        : a + 0x7654321;

      la = a;

      TEST_N_U (la, a, 2);
      TEST_N_U (la, a, 3);
      TEST_N_U (la, a, 4);
      TEST_N_U (la, a, 5);
      TEST_N_U (la, a, 15);
      TEST_N_U (la, a, 16);
      TEST_N_U (la, a, 128);
      TEST_N_U (la, a, 0x1000);
    }
}
     
int main (void)
{
  test_u();
  test_nu();
  
  exit(0);
    
  return 0;
}