summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/rx/builtins.c
blob: 2a6241d7cce75dbae570c787275332a5c5a93dd0 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* { dg-do run } */
/* { dg-options "-fno-ipa-cp-clone" } */

/* Verify that the RX specific builtin functions work.  */

/* IPA CP cloning is disabled because the constant propagation
   has no understanding of the saturation behaviour of the
   __builtin_rx_sat function and so it will optimize away the
   saturation addition test.  */
   
#include <stdlib.h>
#include <stdio.h>

/* We need to prevent these functions from being inlined
   as otherwise gcc will attempt to optimize away their
   arguments and we need the operations on them in order
   to correctly set the psw flags.  */

int saturate_add         (int, int)      __attribute__((__noinline__));
int exchange             (int, int)      __attribute__((__noinline__));

int
half_word_swap (int arg)
{
  return __builtin_rx_revw (arg);
}

int
saturate_add (int arg1, int arg2)
{
  arg1 += arg2;
  return __builtin_rx_sat (arg1);
}

int
exchange (int arg1, int arg2)
{
  arg1 = __builtin_rx_xchg (arg2);
  return arg1;
}

long
multiply_and_accumulate (long arg1, long arg2, long arg3)
{
  __builtin_rx_mvtaclo (0);
  __builtin_rx_mvtachi (0);

  __builtin_rx_mullo (arg1, arg2);
  __builtin_rx_mulhi (arg1, arg2);
  __builtin_rx_maclo (arg1, arg3);
  __builtin_rx_machi (arg1, arg3);

  __builtin_rx_racw (1);
  
  arg1 = __builtin_rx_mvfachi ();
  arg1 += __builtin_rx_mvfacmi ();

  return arg1;
}

int
rxround (float arg)
{
  return __builtin_rx_round (arg);
}

/* #define DEBUG 1 */

#ifdef DEBUG
#define CHECK_0ARG(func, result)					\
  if (func () != result)						\
    {									\
      printf (#func " () fails: %x not %x\n", func (), result);		\
      abort ();								\
    }

#define CHECK_1ARG(func, arg, result)					\
  if (func (arg) != result)						\
    {									\
      printf (#func " (" #arg ") fails: %x not %x\n", func (arg), result); \
      abort ();								\
    }

#define CHECK_2ARG(func, arg1, arg2, result)				\
  if (func (arg1, arg2) != result)					\
    {									\
      printf (#func " (" #arg1 "," #arg2 ") fails: %x not %x\n",	\
	      func (arg1, arg2), result);				\
      abort ();								\
    }

#define CHECK_3ARG(func, arg1, arg2, arg3, result)			\
  if (func (arg1, arg2, arg3) != result)				\
    {									\
      printf (#func " (" #arg1 "," #arg2 "," #arg3 ") fails: %x not %x\n",	\
	      func (arg1, arg2, arg3), result);				\
      abort ();								\
    }
#else
#define CHECK_0ARG(func, result)					\
  if (func () != result)						\
    abort ();

#define CHECK_1ARG(func, arg, result)					\
  if (func (arg) != result)						\
    abort ();

#define CHECK_2ARG(func, arg1, arg2, result)				\
  if (func (arg1, arg2) != result)					\
    abort ();

#define CHECK_3ARG(func, arg1, arg2, arg3, result)			\
  if (func (arg1, arg2, arg3) != result)				\
    abort ();
#endif

int
main (void)
{
  CHECK_1ARG (half_word_swap, 0x12345678, 0x34127856);
  CHECK_2ARG (saturate_add, 0x80000000, 0x80000000, 0x80000000);
  CHECK_3ARG (multiply_and_accumulate, 0x111, 0x222, 0x333, 0x70007);
  CHECK_1ARG (rxround, 0.5, 1);
  return 0;
}

/* The following builtins are compiled but
   not executed because they need OS support.  */

void
rxbreak (void)
{
  __builtin_rx_brk ();
}

void
interrupt (void)
{
  __builtin_rx_int (0x12);
}

int
get_stack_pointer (void)
{
  return __builtin_rx_mvfc (2);
}

void
set_stack_pointer (int value)
{
  __builtin_rx_mvtc (2, value);
  __builtin_rx_mvtc (2, 0x1234);
}

void
wait (void)
{
  __builtin_rx_wait ();
}

void
rmpa (int * multiplicand, int * multiplier, int num)
{
  __builtin_rx_rmpa ();
}

void
set_interrupts (void)
{
  __builtin_mvtipl (3);
}