1/* Test Thumb1 insn pattern addsi3_cbranch_scratch.  */
2/* { dg-options "-O2" } */
3/* { dg-skip-if "" { ! { arm_thumb1 } } } */
4
5struct real_value {
6
7  unsigned int cl : 2;
8  unsigned int decimal : 1;
9  unsigned int sign : 1;
10  unsigned int signalling : 1;
11  unsigned int canonical : 1;
12  unsigned int uexp : (32 - 6);
13  unsigned long sig[((128 + (8 * 4)) / (8 * 4))];
14};
15
16enum real_value_class {
17      rvc_zero,
18      rvc_normal,
19      rvc_inf,
20      rvc_nan
21};
22
23extern void exit(int);
24extern int foo(long long *, int, int);
25
26int
27real_to_integer (const struct real_value *r, int *fail, int precision)
28{
29  long long val[2 * (((64*(8)) + 64) / 64)];
30  int exp;
31  int words, w;
32  int result;
33
34  switch (r->cl)
35    {
36    case rvc_zero:
37    underflow:
38      return 100;
39
40    case rvc_inf:
41    case rvc_nan:
42    overflow:
43      *fail = 1;
44
45      if (r->sign)
46 return 200;
47      else
48 return 300;
49
50    case rvc_normal:
51      if (r->decimal)
52 return 400;
53
54      exp = ((int)((r)->uexp ^ (unsigned int)(1 << ((32 - 6) - 1))) - (1 << ((32 - 6) - 1)));
55      if (exp <= 0)
56 goto underflow;
57
58
59      if (exp > precision)
60 goto overflow;
61      words = (precision + 64 - 1) / 64;
62      w = words * 64;
63      for (int i = 0; i < words; i++)
64 {
65   int j = ((128 + (8 * 4)) / (8 * 4)) - (words * 2) + (i * 2);
66   if (j < 0)
67     val[i] = 0;
68   else
69     val[i] = r->sig[j];
70   j += 1;
71   if (j >= 0)
72     val[i] |= (unsigned long long) r->sig[j] << (8 * 4);
73 }
74
75
76      result = foo(val, words, w);
77
78      if (r->sign)
79 return -result;
80      else
81 return result;
82
83    default:
84      exit(2);
85    }
86}
87
88