1/* Test signed integer comparison ops
2   cr, cgr, cgfr, c, cg, cgf, cfi, cgfi
3
4   missing: cy, crl, cgrl, cgfrl
5*/
6
7#include <stdio.h>
8#include <stdint.h>
9#include <inttypes.h>
10#include <limits.h>
11#include "opcodes.h"
12
13#undef RIL_RI
14#define RIL_RI(op1,r1,op2,i2)  \
15            ".short 0x" #op1 #r1 #op2 "\n\t"  \
16            ".long  " #i2 "\n\t"
17
18
19/* Perform a single signed comparison
20   Both operands in register */
21#define SCOMP_REG_REG(insn, v1, v2)        \
22({                                         \
23   int cc;                                 \
24   int64_t op1 = v1;                       \
25   int64_t op2 = v2;                       \
26   asm volatile(   #insn " %1, %2\n\t"     \
27                   "ipm %0\n\t"            \
28                   "srl %0,28\n\t"         \
29                   : "=d" (cc)             \
30                   : "d" (op1), "d" (op2)  \
31                   : "cc");                \
32   printf("%.6s (%"PRId64", %"PRId64") --> cc = %d\n", \
33          #insn, op1, op2, cc);            \
34})
35
36/* Perform a single signed comparison
37   Left operand in register, right operand in memory */
38#define SCOMP_REG_MEM(insn, v1, v2, op2_t) \
39({                                         \
40   int cc;                                 \
41   int64_t op1 = v1;                       \
42   op2_t   op2 = v2;                       \
43   asm volatile(   #insn " %1, %2\n\t"     \
44                   "ipm %0\n\t"            \
45                   "srl %0,28\n\t"         \
46                   : "=d" (cc)             \
47                   : "d" (op1), "Q" (op2)  \
48                   : "cc");                \
49   printf("%.6s (%"PRId64", %"PRId64") --> cc = %d\n", \
50          #insn, op1, (int64_t)op2, cc);            \
51})
52
53/* Perform a single signed comparison
54   Left operand in register, right operand is an immediate constant */
55#define SCOMP_REG_IMM(insn, v1, v2)        \
56({                                         \
57   int cc;                                 \
58   register int64_t op1 asm("8") = v1;     \
59   asm volatile(   insn(8, v2)             \
60                   "ipm %0\n\t"            \
61                   "srl %0,28\n\t"         \
62                   : "=d" (cc)             \
63                   : "d" (op1)             \
64                   : "cc");           \
65   printf("%.6s (%"PRId64", %"PRId64") --> cc = %d\n", \
66          #insn, op1, (int64_t)v2, cc);            \
67})
68
69/* Run a sequence of signed comparisons for a given insn */
70#define run_scomp_reg_reg(insn) \
71({                              \
72   SCOMP_REG_REG(insn,  0,  0); \
73   SCOMP_REG_REG(insn,  0,  1); \
74   SCOMP_REG_REG(insn,  0, -1); \
75   SCOMP_REG_REG(insn,  1,  0); \
76   SCOMP_REG_REG(insn, -1,  0); \
77   SCOMP_REG_REG(insn, -2, -1); \
78   SCOMP_REG_REG(insn, -2, -2); \
79   SCOMP_REG_REG(insn, -2, -3); \
80   SCOMP_REG_REG(insn,  2,  1); \
81   SCOMP_REG_REG(insn,  2,  2); \
82   SCOMP_REG_REG(insn,  2,  3); \
83   SCOMP_REG_REG(insn, -2,  1); \
84   SCOMP_REG_REG(insn,  2, -1); \
85   SCOMP_REG_REG(insn,  INT8_MIN,   INT8_MIN); \
86   SCOMP_REG_REG(insn,  INT8_MIN,   INT8_MAX); \
87   SCOMP_REG_REG(insn,  INT8_MAX,   INT8_MIN); \
88   SCOMP_REG_REG(insn,  INT8_MAX,   INT8_MAX); \
89   SCOMP_REG_REG(insn,  INT16_MIN,  INT16_MIN); \
90   SCOMP_REG_REG(insn,  INT16_MIN,  INT16_MAX); \
91   SCOMP_REG_REG(insn,  INT16_MAX,  INT16_MIN); \
92   SCOMP_REG_REG(insn,  INT16_MAX,  INT16_MAX); \
93   SCOMP_REG_REG(insn,  INT32_MIN,  INT32_MIN); \
94   SCOMP_REG_REG(insn,  INT32_MIN,  INT32_MAX); \
95   SCOMP_REG_REG(insn,  INT32_MAX,  INT32_MIN); \
96   SCOMP_REG_REG(insn,  INT32_MAX,  INT32_MAX); \
97})
98
99/* Run a sequence of signed comparisons for a given insn */
100#define run_scomp_reg_mem(insn, op2_t) \
101({                              \
102   SCOMP_REG_MEM(insn,  0,  0, op2_t); \
103   SCOMP_REG_MEM(insn,  0,  1, op2_t); \
104   SCOMP_REG_MEM(insn,  0, -1, op2_t); \
105   SCOMP_REG_MEM(insn,  1,  0, op2_t); \
106   SCOMP_REG_MEM(insn, -1,  0, op2_t); \
107   SCOMP_REG_MEM(insn, -2, -1, op2_t); \
108   SCOMP_REG_MEM(insn, -2, -2, op2_t); \
109   SCOMP_REG_MEM(insn, -2, -3, op2_t); \
110   SCOMP_REG_MEM(insn,  2,  1, op2_t); \
111   SCOMP_REG_MEM(insn,  2,  2, op2_t); \
112   SCOMP_REG_MEM(insn,  2,  3, op2_t); \
113   SCOMP_REG_MEM(insn, -2,  1, op2_t); \
114   SCOMP_REG_MEM(insn,  2, -1, op2_t); \
115   SCOMP_REG_MEM(insn,  INT8_MIN,   INT8_MIN, op2_t); \
116   SCOMP_REG_MEM(insn,  INT8_MIN,   INT8_MAX, op2_t); \
117   SCOMP_REG_MEM(insn,  INT8_MAX,   INT8_MIN, op2_t); \
118   SCOMP_REG_MEM(insn,  INT8_MAX,   INT8_MAX, op2_t); \
119   SCOMP_REG_MEM(insn,  INT16_MIN,  INT16_MIN, op2_t); \
120   SCOMP_REG_MEM(insn,  INT16_MIN,  INT16_MAX, op2_t); \
121   SCOMP_REG_MEM(insn,  INT16_MAX,  INT16_MIN, op2_t); \
122   SCOMP_REG_MEM(insn,  INT16_MAX,  INT16_MAX, op2_t); \
123   SCOMP_REG_MEM(insn,  INT32_MIN,  INT32_MIN, op2_t); \
124   SCOMP_REG_MEM(insn,  INT32_MIN,  INT32_MAX, op2_t); \
125   SCOMP_REG_MEM(insn,  INT32_MAX,  INT32_MIN, op2_t); \
126   SCOMP_REG_MEM(insn,  INT32_MAX,  INT32_MAX, op2_t); \
127})
128
129/* Run a sequence of signed comparisons for a given insn */
130#define run_scomp_reg_imm(insn) \
131({                              \
132   SCOMP_REG_IMM(insn,  0,  0); \
133   SCOMP_REG_IMM(insn,  0,  1); \
134   SCOMP_REG_IMM(insn,  0, -1); \
135   SCOMP_REG_IMM(insn,  1,  0); \
136   SCOMP_REG_IMM(insn, -1,  0); \
137   SCOMP_REG_IMM(insn, -2, -1); \
138   SCOMP_REG_IMM(insn, -2, -2); \
139   SCOMP_REG_IMM(insn, -2, -3); \
140   SCOMP_REG_IMM(insn,  2,  1); \
141   SCOMP_REG_IMM(insn,  2,  2); \
142   SCOMP_REG_IMM(insn,  2,  3); \
143   SCOMP_REG_IMM(insn, -2,  1); \
144   SCOMP_REG_IMM(insn,  2, -1); \
145   SCOMP_REG_IMM(insn,  INT8_MIN,   INT8_MIN); \
146   SCOMP_REG_IMM(insn,  INT8_MIN,   INT8_MAX); \
147   SCOMP_REG_IMM(insn,  INT8_MAX,   INT8_MIN); \
148   SCOMP_REG_IMM(insn,  INT8_MAX,   INT8_MAX); \
149   SCOMP_REG_IMM(insn,  INT16_MIN,  INT16_MIN); \
150   SCOMP_REG_IMM(insn,  INT16_MIN,  INT16_MAX); \
151   SCOMP_REG_IMM(insn,  INT16_MAX,  INT16_MIN); \
152   SCOMP_REG_IMM(insn,  INT16_MAX,  INT16_MAX); \
153   SCOMP_REG_IMM(insn,  INT32_MIN,  INT32_MIN); \
154   SCOMP_REG_IMM(insn,  INT32_MIN,  INT32_MAX); \
155   SCOMP_REG_IMM(insn,  INT32_MAX,  INT32_MIN); \
156   SCOMP_REG_IMM(insn,  INT32_MAX,  INT32_MAX); \
157})
158
159void
160signed_comparison_reg_reg(void)
161{
162   run_scomp_reg_reg(cr);
163
164   run_scomp_reg_reg(cgr);
165   /* Special cases for cgr */
166   SCOMP_REG_REG(cgr, INT64_MIN, INT64_MIN);
167   SCOMP_REG_REG(cgr, INT64_MIN, INT64_MAX);
168   SCOMP_REG_REG(cgr, INT64_MAX, INT64_MIN);
169   SCOMP_REG_REG(cgr, INT64_MAX, INT64_MAX);
170
171   run_scomp_reg_reg(cgfr);
172   /* Special cases for cgfr */
173   SCOMP_REG_REG(cgfr, INT64_MIN, INT32_MIN);
174   SCOMP_REG_REG(cgfr, INT64_MIN, INT32_MAX);
175   SCOMP_REG_REG(cgfr, INT64_MAX, INT32_MIN);
176   SCOMP_REG_REG(cgfr, INT64_MAX, INT32_MAX);
177}
178
179void
180signed_comparison_reg_mem(void)
181{
182   run_scomp_reg_mem(c, int32_t);
183
184   run_scomp_reg_mem(cg, int64_t);
185   /* Special cases for cg */
186   SCOMP_REG_MEM(cg, INT64_MIN, INT64_MIN, int64_t);
187   SCOMP_REG_MEM(cg, INT64_MIN, INT64_MAX, int64_t);
188   SCOMP_REG_MEM(cg, INT64_MAX, INT64_MIN, int64_t);
189   SCOMP_REG_MEM(cg, INT64_MAX, INT64_MAX, int64_t);
190
191   run_scomp_reg_mem(cgf, int32_t);
192   /* Special cases for cgf */
193   SCOMP_REG_MEM(cgf, INT64_MIN, INT32_MIN, int32_t);
194   SCOMP_REG_MEM(cgf, INT64_MIN, INT32_MAX, int32_t);
195   SCOMP_REG_MEM(cgf, INT64_MAX, INT32_MIN, int32_t);
196   SCOMP_REG_MEM(cgf, INT64_MAX, INT32_MAX, int32_t);
197}
198
199void
200signed_comparison_reg_imm(void)
201{
202   run_scomp_reg_imm(CFI);
203
204   run_scomp_reg_imm(CGFI);
205   /* Special cases for cgfi */
206   SCOMP_REG_IMM(CGFI, INT64_MIN, INT32_MIN);
207   SCOMP_REG_IMM(CGFI, INT64_MIN, INT32_MAX);
208   SCOMP_REG_IMM(CGFI, INT64_MAX, INT32_MIN);
209   SCOMP_REG_IMM(CGFI, INT64_MAX, INT32_MAX);
210}
211
212
213int main(void)
214{
215   signed_comparison_reg_reg();
216   signed_comparison_reg_mem();
217   signed_comparison_reg_imm();
218
219   return 0;
220}
221