1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stddef.h>
4 #include <stdbool.h>
5 
6 #include "libgccjit.h"
7 
8 #include "harness.h"
9 
10 /**********************************************************************
11  Unary ops
12  **********************************************************************/
13 
14 static const char *
make_test_of_unary_op(gcc_jit_context * ctxt,gcc_jit_type * type,enum gcc_jit_unary_op op,const char * funcname)15 make_test_of_unary_op (gcc_jit_context *ctxt,
16 		       gcc_jit_type *type,
17 		       enum gcc_jit_unary_op op,
18 		       const char *funcname)
19 {
20   /* Make a test function of the form:
21        T test_unary_op (T a)
22        {
23 	  return OP a;
24        }
25      and return a debug dump of the OP so that
26      the caller can sanity-check the debug dump implementation.
27   */
28   gcc_jit_param *param_a =
29     gcc_jit_context_new_param (ctxt, NULL, type, "a");
30   gcc_jit_function *test_fn =
31     gcc_jit_context_new_function (ctxt, NULL,
32 				  GCC_JIT_FUNCTION_EXPORTED,
33 				  type,
34 				  funcname,
35 				  1, &param_a,
36 				  0);
37   gcc_jit_rvalue *unary_op = gcc_jit_context_new_unary_op (
38     ctxt,
39     NULL,
40     op,
41     type,
42     gcc_jit_param_as_rvalue (param_a));
43 
44   gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial");
45   gcc_jit_block_end_with_return (initial, NULL, unary_op);
46 
47   return gcc_jit_object_get_debug_string (
48     gcc_jit_rvalue_as_object (unary_op));
49 }
50 
51 
52 static void
make_tests_of_unary_ops(gcc_jit_context * ctxt)53 make_tests_of_unary_ops (gcc_jit_context *ctxt)
54 {
55   gcc_jit_type *int_type =
56     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
57 
58   CHECK_STRING_VALUE (
59     make_test_of_unary_op (ctxt,
60 			   int_type,
61 			   GCC_JIT_UNARY_OP_MINUS,
62 			   "test_UNARY_OP_MINUS_on_int"),
63     "-(a)");
64   CHECK_STRING_VALUE (
65     make_test_of_unary_op (ctxt,
66 			   int_type,
67 			   GCC_JIT_UNARY_OP_BITWISE_NEGATE,
68 			   "test_UNARY_OP_BITWISE_NEGATE_on_int"),
69     "~(a)");
70   CHECK_STRING_VALUE (
71     make_test_of_unary_op (ctxt,
72 			   int_type,
73 			   GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
74 			   "test_UNARY_OP_LOGICAL_NEGATE_on_int"),
75     "!(a)");
76   CHECK_STRING_VALUE (
77     make_test_of_unary_op (ctxt,
78 			   int_type,
79 			   GCC_JIT_UNARY_OP_ABS,
80 			   "test_UNARY_OP_ABS_on_int"),
81     "abs (a)");
82 }
83 
84 static void
verify_unary_ops(gcc_jit_result * result)85 verify_unary_ops (gcc_jit_result *result)
86 {
87   typedef int (*test_fn) (int);
88 
89   test_fn test_UNARY_OP_MINUS_on_int =
90     (test_fn)gcc_jit_result_get_code (result,
91 				      "test_UNARY_OP_MINUS_on_int");
92   CHECK_NON_NULL (test_UNARY_OP_MINUS_on_int);
93   CHECK_VALUE (test_UNARY_OP_MINUS_on_int (0), 0);
94   CHECK_VALUE (test_UNARY_OP_MINUS_on_int (42), -42);
95   CHECK_VALUE (test_UNARY_OP_MINUS_on_int (-5), 5);
96 
97   test_fn test_UNARY_OP_BITWISE_NEGATE_on_int =
98     (test_fn)gcc_jit_result_get_code (result,
99 				      "test_UNARY_OP_BITWISE_NEGATE_on_int");
100   CHECK_NON_NULL (test_UNARY_OP_BITWISE_NEGATE_on_int);
101   CHECK_VALUE (test_UNARY_OP_BITWISE_NEGATE_on_int (0), ~0);
102   CHECK_VALUE (test_UNARY_OP_BITWISE_NEGATE_on_int (42), ~42);
103   CHECK_VALUE (test_UNARY_OP_BITWISE_NEGATE_on_int (-5), ~-5);
104 
105   test_fn test_UNARY_OP_LOGICAL_NEGATE_on_int =
106     (test_fn)gcc_jit_result_get_code (result,
107 				      "test_UNARY_OP_LOGICAL_NEGATE_on_int");
108   CHECK_NON_NULL (test_UNARY_OP_LOGICAL_NEGATE_on_int);
109   CHECK_VALUE (test_UNARY_OP_LOGICAL_NEGATE_on_int (0), 1);
110   CHECK_VALUE (test_UNARY_OP_LOGICAL_NEGATE_on_int (42), 0);
111   CHECK_VALUE (test_UNARY_OP_LOGICAL_NEGATE_on_int (-5), 0);
112 
113   test_fn test_UNARY_OP_ABS_on_int =
114     (test_fn)gcc_jit_result_get_code (result,
115 				      "test_UNARY_OP_ABS_on_int");
116   CHECK_NON_NULL (test_UNARY_OP_ABS_on_int);
117   CHECK_VALUE (test_UNARY_OP_ABS_on_int (0), 0);
118   CHECK_VALUE (test_UNARY_OP_ABS_on_int (42), 42);
119   CHECK_VALUE (test_UNARY_OP_ABS_on_int (-5), 5);
120 }
121 
122 /**********************************************************************
123  Binary ops
124  **********************************************************************/
125 
126 static const char *
make_test_of_binary_op(gcc_jit_context * ctxt,gcc_jit_type * type,enum gcc_jit_binary_op op,const char * funcname)127 make_test_of_binary_op (gcc_jit_context *ctxt,
128 			gcc_jit_type *type,
129 			enum gcc_jit_binary_op op,
130 			const char *funcname)
131 {
132   /* Make a test function of the form:
133        T test_binary_op (T a, T b)
134        {
135 	  return a OP b;
136        }
137   */
138   gcc_jit_param *param_a =
139     gcc_jit_context_new_param (ctxt, NULL, type, "a");
140   gcc_jit_param *param_b =
141     gcc_jit_context_new_param (ctxt, NULL, type, "b");
142   gcc_jit_param *params[] = {param_a, param_b};
143   gcc_jit_function *test_fn =
144     gcc_jit_context_new_function (ctxt, NULL,
145 				  GCC_JIT_FUNCTION_EXPORTED,
146 				  type,
147 				  funcname,
148 				  2, params,
149 				  0);
150   gcc_jit_rvalue *binary_op =
151     gcc_jit_context_new_binary_op (
152       ctxt,
153       NULL,
154       op,
155       type,
156       gcc_jit_param_as_rvalue (param_a),
157       gcc_jit_param_as_rvalue (param_b));
158 
159   gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial");
160   gcc_jit_block_end_with_return (initial, NULL, binary_op);
161 
162   return gcc_jit_object_get_debug_string (
163     gcc_jit_rvalue_as_object (binary_op));
164 }
165 
166 
167 static void
make_tests_of_binary_ops(gcc_jit_context * ctxt)168 make_tests_of_binary_ops (gcc_jit_context *ctxt)
169 {
170   gcc_jit_type *int_type =
171     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
172 
173   /* Test binary ops.  */
174   CHECK_STRING_VALUE (
175     make_test_of_binary_op (ctxt,
176 			    int_type,
177 			    GCC_JIT_BINARY_OP_PLUS,
178 			    "test_BINARY_OP_PLUS_on_int"),
179     "a + b");
180   CHECK_STRING_VALUE (
181     make_test_of_binary_op (ctxt,
182 			    int_type,
183 			    GCC_JIT_BINARY_OP_MINUS,
184 			    "test_BINARY_OP_MINUS_on_int"),
185     "a - b");
186   CHECK_STRING_VALUE (
187     make_test_of_binary_op (ctxt,
188 			    int_type,
189 			    GCC_JIT_BINARY_OP_MULT,
190 			    "test_BINARY_OP_MULT_on_int"),
191     "a * b");
192   CHECK_STRING_VALUE (
193     make_test_of_binary_op (ctxt,
194 			    int_type,
195 			    GCC_JIT_BINARY_OP_DIVIDE,
196 			    "test_BINARY_OP_DIVIDE_on_int"),
197     "a / b");
198   /* TODO: test for DIVIDE on float or double */
199   CHECK_STRING_VALUE (
200     make_test_of_binary_op (ctxt,
201 			    int_type,
202 			    GCC_JIT_BINARY_OP_MODULO,
203 			    "test_BINARY_OP_MODULO_on_int"),
204     "a % b");
205   CHECK_STRING_VALUE (
206     make_test_of_binary_op (ctxt,
207 			    int_type,
208 			    GCC_JIT_BINARY_OP_BITWISE_AND,
209 			    "test_BINARY_OP_BITWISE_AND_on_int"),
210     "a & b");
211   CHECK_STRING_VALUE (
212     make_test_of_binary_op (ctxt,
213 			    int_type,
214 			    GCC_JIT_BINARY_OP_BITWISE_XOR,
215 			    "test_BINARY_OP_BITWISE_XOR_on_int"),
216     "a ^ b");
217   CHECK_STRING_VALUE (
218     make_test_of_binary_op (ctxt,
219 			    int_type,
220 			    GCC_JIT_BINARY_OP_BITWISE_OR,
221 			    "test_BINARY_OP_BITWISE_OR_on_int"),
222     "a | b");
223   CHECK_STRING_VALUE (
224     make_test_of_binary_op (ctxt,
225 			    int_type,
226 			    GCC_JIT_BINARY_OP_LOGICAL_AND,
227 			    "test_BINARY_OP_LOGICAL_AND_on_int"),
228     "a && b");
229   CHECK_STRING_VALUE (
230     make_test_of_binary_op (ctxt,
231 			    int_type,
232 			    GCC_JIT_BINARY_OP_LOGICAL_OR,
233 			    "test_BINARY_OP_LOGICAL_OR_on_int"),
234     "a || b");
235   CHECK_STRING_VALUE (
236     make_test_of_binary_op (ctxt,
237 			    int_type,
238 			    GCC_JIT_BINARY_OP_LSHIFT,
239 			    "test_BINARY_OP_LSHIFT_on_int"),
240     "a << b");
241   CHECK_STRING_VALUE (
242     make_test_of_binary_op (ctxt,
243 			    int_type,
244 			    GCC_JIT_BINARY_OP_RSHIFT,
245 			    "test_BINARY_OP_RSHIFT_on_int"),
246     "a >> b");
247 }
248 
249 static void
verify_binary_ops(gcc_jit_result * result)250 verify_binary_ops (gcc_jit_result *result)
251 {
252   typedef int (*test_fn) (int, int);
253 
254   test_fn test_BINARY_OP_PLUS_on_int =
255     (test_fn)gcc_jit_result_get_code (result,
256 				      "test_BINARY_OP_PLUS_on_int");
257   CHECK_NON_NULL (test_BINARY_OP_PLUS_on_int);
258   CHECK_VALUE (test_BINARY_OP_PLUS_on_int (0, 0), 0);
259   CHECK_VALUE (test_BINARY_OP_PLUS_on_int (1, 2), 3);
260   CHECK_VALUE (test_BINARY_OP_PLUS_on_int (100, -1), 99);
261   CHECK_VALUE (test_BINARY_OP_PLUS_on_int (-1, -4), -5);
262 
263   test_fn test_BINARY_OP_MINUS_on_int =
264     (test_fn)gcc_jit_result_get_code (result,
265 				      "test_BINARY_OP_MINUS_on_int");
266   CHECK_NON_NULL (test_BINARY_OP_MINUS_on_int);
267   CHECK_VALUE (test_BINARY_OP_MINUS_on_int (0, 0), 0);
268   CHECK_VALUE (test_BINARY_OP_MINUS_on_int (1, 2), -1);
269   CHECK_VALUE (test_BINARY_OP_MINUS_on_int (100, -1), 101);
270   CHECK_VALUE (test_BINARY_OP_MINUS_on_int (-1, -4), 3);
271 
272   test_fn test_BINARY_OP_MULT_on_int =
273     (test_fn)gcc_jit_result_get_code (result,
274 				      "test_BINARY_OP_MULT_on_int");
275   CHECK_NON_NULL (test_BINARY_OP_MULT_on_int);
276   CHECK_VALUE (test_BINARY_OP_MULT_on_int (0, 0), 0);
277   CHECK_VALUE (test_BINARY_OP_MULT_on_int (1, 2), 2);
278   CHECK_VALUE (test_BINARY_OP_MULT_on_int (100, -1), -100);
279   CHECK_VALUE (test_BINARY_OP_MULT_on_int (-1, -4), 4);
280   CHECK_VALUE (test_BINARY_OP_MULT_on_int (7, 10), 70);
281 
282   test_fn test_BINARY_OP_DIVIDE_on_int =
283     (test_fn)gcc_jit_result_get_code (result,
284 				      "test_BINARY_OP_DIVIDE_on_int");
285   CHECK_NON_NULL (test_BINARY_OP_DIVIDE_on_int);
286   CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (7, 2), 3);
287   CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (100, -1), (100 / -1));
288   CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (-1, -4), (-1 / -4));
289   CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (60, 5), 12);
290 
291   /* TODO: test for DIVIDE on float or double */
292 
293   test_fn test_BINARY_OP_MODULO_on_int =
294     (test_fn)gcc_jit_result_get_code (result,
295 				      "test_BINARY_OP_MODULO_on_int");
296   CHECK_NON_NULL (test_BINARY_OP_MODULO_on_int);
297   CHECK_VALUE (test_BINARY_OP_MODULO_on_int (7, 2), 1);
298   CHECK_VALUE (test_BINARY_OP_MODULO_on_int (100, -1), (100 % -1));
299   CHECK_VALUE (test_BINARY_OP_MODULO_on_int (-1, -4), (-1 % -4));
300   CHECK_VALUE (test_BINARY_OP_MODULO_on_int (60, 5), 0);
301 
302   test_fn test_BINARY_OP_BITWISE_AND_on_int =
303     (test_fn)gcc_jit_result_get_code (result,
304 				      "test_BINARY_OP_BITWISE_AND_on_int");
305   CHECK_NON_NULL (test_BINARY_OP_BITWISE_AND_on_int);
306   CHECK_VALUE (test_BINARY_OP_BITWISE_AND_on_int (0xf0f0, 0x7777), 0x7070);
307 
308   test_fn test_BINARY_OP_BITWISE_XOR_on_int =
309     (test_fn)gcc_jit_result_get_code (result,
310 				      "test_BINARY_OP_BITWISE_XOR_on_int");
311   CHECK_NON_NULL (test_BINARY_OP_BITWISE_XOR_on_int);
312   CHECK_VALUE (test_BINARY_OP_BITWISE_XOR_on_int (0xf0f0, 0x7777), 0x8787);
313 
314   test_fn test_BINARY_OP_BITWISE_OR_on_int =
315     (test_fn)gcc_jit_result_get_code (result,
316 				      "test_BINARY_OP_BITWISE_OR_on_int");
317   CHECK_NON_NULL (test_BINARY_OP_BITWISE_OR_on_int);
318   CHECK_VALUE (test_BINARY_OP_BITWISE_OR_on_int (0xf0f0, 0x7777), 0xf7f7);
319 
320   test_fn test_BINARY_OP_LOGICAL_AND_on_int =
321     (test_fn)gcc_jit_result_get_code (result,
322 				      "test_BINARY_OP_LOGICAL_AND_on_int");
323   CHECK_NON_NULL (test_BINARY_OP_LOGICAL_AND_on_int);
324   CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (0, 0), 0);
325   CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (42, 0), 0);
326   CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (0, -13), 0);
327   CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (1997, 1998), 1);
328 
329   test_fn test_BINARY_OP_LOGICAL_OR_on_int =
330     (test_fn)gcc_jit_result_get_code (result,
331 				      "test_BINARY_OP_LOGICAL_OR_on_int");
332   CHECK_NON_NULL (test_BINARY_OP_LOGICAL_OR_on_int);
333   CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (0, 0), 0);
334   CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (42, 0), 1);
335   CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (0, -13), 1);
336   CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (1997, 1998), 1);
337 
338   test_fn test_BINARY_OP_LSHIFT_on_int =
339     (test_fn)gcc_jit_result_get_code (result,
340 				      "test_BINARY_OP_LSHIFT_on_int");
341   CHECK_NON_NULL (test_BINARY_OP_LSHIFT_on_int);
342   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (0, 0), 0);
343   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (0, 1), 0);
344   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (0, 2), 0);
345   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 0), 1);
346   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 1), 2);
347   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 2), 4);
348   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 3), 8);
349   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (3, 0), 3);
350   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (3, 1), 6);
351   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (3, 5), 3 * 32);
352   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (42, 0), 42);
353   CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (42, 1), 84);
354 
355   test_fn test_BINARY_OP_RSHIFT_on_int =
356     (test_fn)gcc_jit_result_get_code (result,
357 				      "test_BINARY_OP_RSHIFT_on_int");
358   CHECK_NON_NULL (test_BINARY_OP_RSHIFT_on_int);
359   CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (0, 0), 0);
360   CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (42, 0), 42);
361   CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (42, 1), 21);
362   CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (42, 2), 10);
363 }
364 
365 /**********************************************************************
366  Comparisons
367  **********************************************************************/
368 
369 static const char *
make_test_of_comparison(gcc_jit_context * ctxt,gcc_jit_type * type,enum gcc_jit_comparison op,const char * funcname)370 make_test_of_comparison (gcc_jit_context *ctxt,
371 			 gcc_jit_type *type,
372 			 enum gcc_jit_comparison op,
373 			 const char *funcname)
374 {
375   /* Make a test function of the form:
376        bool test_comparison_op (T a, T b)
377        {
378 	  return a OP b;
379        }
380   */
381   gcc_jit_param *param_a =
382     gcc_jit_context_new_param (ctxt, NULL, type, "a");
383   gcc_jit_param *param_b =
384     gcc_jit_context_new_param (ctxt, NULL, type, "b");
385   gcc_jit_param *params[] = {param_a, param_b};
386   gcc_jit_type *bool_type =
387     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL);
388   gcc_jit_function *test_fn =
389     gcc_jit_context_new_function (ctxt, NULL,
390 				  GCC_JIT_FUNCTION_EXPORTED,
391 				  bool_type,
392 				  funcname,
393 				  2, params,
394 				  0);
395   gcc_jit_rvalue *comparison =
396     gcc_jit_context_new_comparison (
397       ctxt,
398       NULL,
399       op,
400       gcc_jit_param_as_rvalue (param_a),
401       gcc_jit_param_as_rvalue (param_b));
402 
403   gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial");
404   gcc_jit_block_end_with_return (initial, NULL, comparison);
405 
406   return gcc_jit_object_get_debug_string (
407     gcc_jit_rvalue_as_object (comparison));
408 }
409 
410 static void
make_tests_of_comparisons(gcc_jit_context * ctxt)411 make_tests_of_comparisons (gcc_jit_context *ctxt)
412 {
413   gcc_jit_type *int_type =
414     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
415 
416   CHECK_STRING_VALUE (
417     make_test_of_comparison (ctxt,
418 			     int_type,
419 			     GCC_JIT_COMPARISON_EQ,
420 			     "test_COMPARISON_EQ_on_int"),
421     "a == b");
422   CHECK_STRING_VALUE (
423     make_test_of_comparison (ctxt,
424 			     int_type,
425 			     GCC_JIT_COMPARISON_NE,
426 			     "test_COMPARISON_NE_on_int"),
427     "a != b");
428   CHECK_STRING_VALUE (
429     make_test_of_comparison (ctxt,
430 			     int_type,
431 			     GCC_JIT_COMPARISON_LT,
432 			     "test_COMPARISON_LT_on_int"),
433     "a < b");
434   CHECK_STRING_VALUE (
435     make_test_of_comparison (ctxt,
436 			     int_type,
437 			     GCC_JIT_COMPARISON_LE,
438 			     "test_COMPARISON_LE_on_int"),
439     "a <= b");
440   CHECK_STRING_VALUE (
441     make_test_of_comparison (ctxt,
442 			     int_type,
443 			     GCC_JIT_COMPARISON_GT,
444 			     "test_COMPARISON_GT_on_int"),
445     "a > b");
446   CHECK_STRING_VALUE (
447     make_test_of_comparison (ctxt,
448 			     int_type,
449 			     GCC_JIT_COMPARISON_GE,
450 			     "test_COMPARISON_GE_on_int"),
451     "a >= b");
452 }
453 
454 static void
verify_comparisons(gcc_jit_result * result)455 verify_comparisons (gcc_jit_result *result)
456 {
457   typedef bool (*test_fn) (int, int);
458 
459   test_fn test_COMPARISON_EQ_on_int =
460     (test_fn)gcc_jit_result_get_code (result,
461 				      "test_COMPARISON_EQ_on_int");
462   CHECK_NON_NULL (test_COMPARISON_EQ_on_int);
463   CHECK_VALUE (test_COMPARISON_EQ_on_int (0, 0), 1);
464   CHECK_VALUE (test_COMPARISON_EQ_on_int (1, 2), 0);
465 
466   test_fn test_COMPARISON_NE_on_int =
467     (test_fn)gcc_jit_result_get_code (result,
468 				      "test_COMPARISON_NE_on_int");
469   CHECK_NON_NULL (test_COMPARISON_NE_on_int);
470   CHECK_VALUE (test_COMPARISON_NE_on_int (0, 0), 0);
471   CHECK_VALUE (test_COMPARISON_NE_on_int (1, 2), 1);
472 
473   test_fn test_COMPARISON_LT_on_int =
474     (test_fn)gcc_jit_result_get_code (result,
475 				      "test_COMPARISON_LT_on_int");
476   CHECK_NON_NULL (test_COMPARISON_LT_on_int);
477   CHECK_VALUE (test_COMPARISON_LT_on_int (0, 0), 0);
478   CHECK_VALUE (test_COMPARISON_LT_on_int (1, 2), 1);
479   CHECK_VALUE (test_COMPARISON_LT_on_int (2, 1), 0);
480   CHECK_VALUE (test_COMPARISON_LT_on_int (-2, 1), 1);
481 
482   test_fn test_COMPARISON_LE_on_int =
483     (test_fn)gcc_jit_result_get_code (result,
484 				      "test_COMPARISON_LE_on_int");
485   CHECK_NON_NULL (test_COMPARISON_LE_on_int);
486   CHECK_VALUE (test_COMPARISON_LE_on_int (0, 0), 1);
487   CHECK_VALUE (test_COMPARISON_LE_on_int (1, 2), 1);
488   CHECK_VALUE (test_COMPARISON_LE_on_int (2, 1), 0);
489 
490   test_fn test_COMPARISON_GT_on_int =
491     (test_fn)gcc_jit_result_get_code (result,
492 				      "test_COMPARISON_GT_on_int");
493   CHECK_NON_NULL (test_COMPARISON_GT_on_int);
494   CHECK_VALUE (test_COMPARISON_GT_on_int (0, 0), 0);
495   CHECK_VALUE (test_COMPARISON_GT_on_int (1, 2), 0);
496   CHECK_VALUE (test_COMPARISON_GT_on_int (2, 1), 1);
497 
498   test_fn test_COMPARISON_GE_on_int =
499     (test_fn)gcc_jit_result_get_code (result,
500 				      "test_COMPARISON_GE_on_int");
501   CHECK_NON_NULL (test_COMPARISON_GE_on_int);
502   CHECK_VALUE (test_COMPARISON_GE_on_int (0, 0), 1);
503   CHECK_VALUE (test_COMPARISON_GE_on_int (1, 2), 0);
504   CHECK_VALUE (test_COMPARISON_GE_on_int (2, 1), 1);
505 }
506 
507 /**********************************************************************
508  Casts
509  **********************************************************************/
510 
511 static const char*
make_test_of_cast(gcc_jit_context * ctxt,gcc_jit_type * input_type,gcc_jit_type * output_type,const char * funcname)512 make_test_of_cast (gcc_jit_context *ctxt,
513 		   gcc_jit_type *input_type,
514 		   gcc_jit_type *output_type,
515 		   const char *funcname)
516 {
517   /* Make a test function of the form:
518        OUTPUT_TYPE test_cast_* (INPUT_TYPE a)
519        {
520           return (OUTPUT_TYPE)a;
521        }
522   */
523   gcc_jit_param *param_a =
524     gcc_jit_context_new_param (ctxt, NULL, input_type, "a");
525   gcc_jit_param *params[] = {param_a};
526   gcc_jit_function *test_fn =
527     gcc_jit_context_new_function (ctxt, NULL,
528 				  GCC_JIT_FUNCTION_EXPORTED,
529 				  output_type,
530 				  funcname,
531 				  1, params,
532 				  0);
533   gcc_jit_rvalue *cast =
534     gcc_jit_context_new_cast (
535       ctxt,
536       NULL,
537       gcc_jit_param_as_rvalue (param_a),
538       output_type);
539   gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial");
540   gcc_jit_block_end_with_return (initial, NULL, cast);
541 
542   return gcc_jit_object_get_debug_string (
543     gcc_jit_rvalue_as_object (cast));
544 }
545 
546 /* For use by test_cast_from_array_of_ints_to_int_ptr.  */
called_pointer_checking_function(int * ints)547 extern int called_pointer_checking_function (int *ints)
548 {
549   CHECK_VALUE (ints[0], 10);
550   CHECK_VALUE (ints[1], 4);
551   return ints[0] * ints[1];
552 }
553 
554 static void
make_tests_of_casts(gcc_jit_context * ctxt)555 make_tests_of_casts (gcc_jit_context *ctxt)
556 {
557   gcc_jit_type *int_type =
558     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
559   gcc_jit_type *long_type =
560     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG);
561   gcc_jit_type *float_type =
562     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
563   gcc_jit_type *bool_type =
564     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL);
565   gcc_jit_type *array_int_type =
566     gcc_jit_context_new_array_type (ctxt, NULL,
567 				    int_type,
568 				    2);
569   gcc_jit_type *int_ptr_type =
570     gcc_jit_type_get_pointer (int_type);
571 
572   /* float/int conversions */
573   CHECK_STRING_VALUE (
574     make_test_of_cast (ctxt,
575 		       float_type,
576 		       int_type,
577 		       "test_cast_from_float_to_int"),
578     "(int)a");
579   CHECK_STRING_VALUE (
580     make_test_of_cast (ctxt,
581 		       int_type,
582 		       float_type,
583 		       "test_cast_from_int_to_float"),
584     "(float)a");
585 
586   /* bool/int conversions */
587   CHECK_STRING_VALUE (
588     make_test_of_cast (ctxt,
589 		       bool_type,
590 		       int_type,
591 		       "test_cast_from_bool_to_int"),
592     "(int)a");
593   CHECK_STRING_VALUE (
594     make_test_of_cast (ctxt,
595 		       int_type,
596 		       bool_type,
597 		       "test_cast_from_int_to_bool"),
598     "(bool)a");
599 
600   /* bool/long conversions */
601   CHECK_STRING_VALUE (
602     make_test_of_cast (ctxt,
603 		       bool_type,
604 		       long_type,
605 		       "test_cast_from_bool_to_long"),
606     "(long)a");
607   CHECK_STRING_VALUE (
608     make_test_of_cast (ctxt,
609 		       long_type,
610 		       bool_type,
611 		       "test_cast_from_long_to_bool"),
612     "(bool)a");
613 
614   /* array/ptr conversions */
615   {
616     gcc_jit_function *test_fn =
617       gcc_jit_context_new_function (
618 	ctxt, NULL,
619 	GCC_JIT_FUNCTION_EXPORTED,
620 	int_type,
621 	"test_cast_from_array_of_ints_to_int_ptr",
622 	0, NULL,
623 	0);
624     /* Equivalent to:
625           int test_cast_from_array_of_ints_to_int_ptr (void)
626 	  {
627 	    int array[2];
628 	    array[0] = 10;
629 	    array[1] = 4;
630 	    return called_pointer_checking_function (array);
631 	  }
632     */
633 
634     gcc_jit_param *param_ints =
635       gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ints");
636     gcc_jit_function *called_fn =
637       gcc_jit_context_new_function (
638 	ctxt, NULL,
639 	GCC_JIT_FUNCTION_IMPORTED,
640 	int_type,
641 	"called_pointer_checking_function",
642 	1, &param_ints,
643 	0);
644 
645     gcc_jit_lvalue *array =
646       gcc_jit_function_new_local (test_fn, NULL,
647 				  array_int_type,
648 				  "array");
649     gcc_jit_block *block =
650       gcc_jit_function_new_block (test_fn, "block");
651     /* array[0] = 10; */
652     gcc_jit_block_add_assignment (
653       block, NULL,
654       gcc_jit_context_new_array_access (
655 	ctxt, NULL,
656 	gcc_jit_lvalue_as_rvalue (array),
657 	gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)),
658       gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 10));
659     /* array[1] = 4; */
660     gcc_jit_block_add_assignment (
661       block, NULL,
662       gcc_jit_context_new_array_access (
663 	ctxt, NULL,
664 	gcc_jit_lvalue_as_rvalue (array),
665 	gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)),
666       gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 4));
667     gcc_jit_rvalue *cast =
668       gcc_jit_context_new_cast (
669 	ctxt,
670 	NULL,
671 	/* We need a get_address here.  */
672 	gcc_jit_lvalue_get_address (array, NULL),
673 	int_ptr_type);
674     gcc_jit_block_end_with_return (
675       block, NULL,
676       gcc_jit_context_new_call (
677 	ctxt, NULL,
678 	called_fn,
679 	1, &cast));
680 
681     CHECK_STRING_VALUE (
682       gcc_jit_object_get_debug_string (
683 	gcc_jit_rvalue_as_object (cast)),
684       "(int *)&array");
685   }
686 }
687 
688 static void
verify_casts(gcc_jit_result * result)689 verify_casts (gcc_jit_result *result)
690 {
691   /* float to int */
692   {
693     typedef int (*fn_type) (float);
694     fn_type test_cast_from_float_to_int =
695       (fn_type)gcc_jit_result_get_code (result,
696 					"test_cast_from_float_to_int");
697     CHECK_NON_NULL (test_cast_from_float_to_int);
698     CHECK_VALUE (test_cast_from_float_to_int (4.2), 4);
699   }
700 
701   /* int to float */
702   {
703     typedef float (*fn_type) (int);
704     fn_type test_cast_from_int_to_float =
705       (fn_type)gcc_jit_result_get_code (result,
706 					"test_cast_from_int_to_float");
707     CHECK_NON_NULL (test_cast_from_int_to_float);
708     CHECK_VALUE (test_cast_from_int_to_float (4), 4.0);
709   }
710 
711   /* bool to int */
712   {
713     typedef int (*fn_type) (bool);
714     fn_type test_cast_from_bool_to_int =
715       (fn_type)gcc_jit_result_get_code (result,
716 					"test_cast_from_bool_to_int");
717     CHECK_NON_NULL (test_cast_from_bool_to_int);
718     CHECK_VALUE (test_cast_from_bool_to_int (0), 0);
719     CHECK_VALUE (test_cast_from_bool_to_int (1), 1);
720   }
721 
722   /* int to bool */
723   {
724     typedef bool (*fn_type) (int);
725     fn_type test_cast_from_int_to_bool =
726       (fn_type)gcc_jit_result_get_code (result,
727 					"test_cast_from_int_to_bool");
728     CHECK_NON_NULL (test_cast_from_int_to_bool);
729     CHECK_VALUE (test_cast_from_int_to_bool (0), 0);
730     CHECK_VALUE (test_cast_from_int_to_bool (1), 1);
731   }
732 
733   /* bool to long */
734   {
735     typedef long (*fn_type) (bool);
736     fn_type test_cast_from_bool_to_long =
737       (fn_type)gcc_jit_result_get_code (result,
738 					"test_cast_from_bool_to_long");
739     CHECK_NON_NULL (test_cast_from_bool_to_long);
740     CHECK_VALUE (test_cast_from_bool_to_long (0), 0);
741     CHECK_VALUE (test_cast_from_bool_to_long (1), 1);
742   }
743 
744   /* long to bool */
745   {
746     typedef bool (*fn_type) (long);
747     fn_type test_cast_from_long_to_bool =
748       (fn_type)gcc_jit_result_get_code (result,
749 					"test_cast_from_long_to_bool");
750     CHECK_NON_NULL (test_cast_from_long_to_bool);
751     CHECK_VALUE (test_cast_from_long_to_bool (0), 0);
752     CHECK_VALUE (test_cast_from_long_to_bool (1), 1);
753   }
754 
755   /* array to ptr */
756   {
757     typedef int (*fn_type) (void);
758     fn_type test_cast_from_array_of_ints_to_int_ptr =
759       (fn_type)gcc_jit_result_get_code (
760 	result,
761 	"test_cast_from_array_of_ints_to_int_ptr");
762     CHECK_NON_NULL (test_cast_from_array_of_ints_to_int_ptr);
763     CHECK_VALUE (test_cast_from_array_of_ints_to_int_ptr (), 40);
764   }
765 }
766 
767 /**********************************************************************
768  Dereferences
769  **********************************************************************/
770 
771 static void
make_tests_of_dereferences(gcc_jit_context * ctxt)772 make_tests_of_dereferences (gcc_jit_context *ctxt)
773 {
774   /*
775        int test_dereference_read (int *ptr)
776        {
777 	 return *ptr;
778        }
779        void test_dereference_write (int *ptr, int i)
780        {
781 	 *ptr = i;
782        }
783   */
784   gcc_jit_type *void_type =
785     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
786   gcc_jit_type *int_type =
787     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
788   gcc_jit_type *int_ptr_type =
789     gcc_jit_type_get_pointer (int_type);
790   {
791     gcc_jit_param *param_ptr =
792       gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ptr");
793     gcc_jit_function *test_dereference_read =
794       gcc_jit_context_new_function (ctxt, NULL,
795 				    GCC_JIT_FUNCTION_EXPORTED,
796 				    int_type,
797 				    "test_dereference_read",
798 				    1, &param_ptr,
799 				    0);
800     gcc_jit_block *initial =
801       gcc_jit_function_new_block (test_dereference_read, "initial");
802     gcc_jit_block_end_with_return (
803       initial,
804       NULL,
805       gcc_jit_lvalue_as_rvalue (
806 	gcc_jit_rvalue_dereference (
807 	  gcc_jit_param_as_rvalue (param_ptr),
808 	  NULL)));
809   }
810 
811   {
812     gcc_jit_param *param_ptr =
813       gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ptr");
814     gcc_jit_param *param_i =
815       gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
816     gcc_jit_param *params[] = {param_ptr, param_i};
817     gcc_jit_function *test_dereference_write =
818       gcc_jit_context_new_function (ctxt, NULL,
819 				    GCC_JIT_FUNCTION_EXPORTED,
820 				    void_type,
821 				    "test_dereference_write",
822 				    2, params,
823 				    0);
824     gcc_jit_block *initial =
825       gcc_jit_function_new_block (test_dereference_write, "initial");
826     gcc_jit_block_add_assignment (
827       initial,
828       NULL,
829       gcc_jit_rvalue_dereference (
830 	gcc_jit_param_as_rvalue (param_ptr),
831 	NULL),
832       gcc_jit_param_as_rvalue (param_i));
833     gcc_jit_block_end_with_void_return (initial, NULL);
834   }
835 }
836 
837 static void
verify_dereferences(gcc_jit_result * result)838 verify_dereferences (gcc_jit_result *result)
839 {
840   int a = 42;
841   int b = -99;
842 
843   {
844     typedef int (*test_read) (int *);
845     test_read test_dereference_read =
846       (test_read)gcc_jit_result_get_code (result,
847 					  "test_dereference_read");
848     CHECK_NON_NULL (test_dereference_read);
849     CHECK_VALUE (test_dereference_read (&a), 42);
850     CHECK_VALUE (test_dereference_read (&b), -99);
851   }
852 
853  {
854     typedef void (*test_write) (int *, int);
855     test_write test_dereference_write =
856       (test_write)gcc_jit_result_get_code (result,
857 					  "test_dereference_write");
858     CHECK_NON_NULL (test_dereference_write);
859     test_dereference_write (&a, -55);
860     CHECK_VALUE (a, -55);
861 
862     test_dereference_write (&b, 404);
863     CHECK_VALUE (b, 404);
864   }
865 }
866 
867 /**********************************************************************
868  gcc_jit_lvalue_get_address
869  **********************************************************************/
870 
871 int test_global;
872 static void
make_test_of_get_address(gcc_jit_context * ctxt)873 make_test_of_get_address (gcc_jit_context *ctxt)
874 {
875   /*
876      void *test_get_address (void)
877      {
878 	return &test_global;
879      }
880   */
881   gcc_jit_type *int_type =
882     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
883   gcc_jit_lvalue *test_global =
884     gcc_jit_context_new_global (
885       ctxt,
886       NULL,
887       GCC_JIT_GLOBAL_IMPORTED,
888       int_type,
889       "test_global");
890 
891  gcc_jit_type *void_ptr_type =
892     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
893 
894   gcc_jit_function *test_get_address =
895     gcc_jit_context_new_function (ctxt, NULL,
896 				  GCC_JIT_FUNCTION_EXPORTED,
897 				  void_ptr_type,
898 				  "test_get_address",
899 				  0, NULL,
900 				  0);
901   gcc_jit_block *initial =
902     gcc_jit_function_new_block (test_get_address, "initial");
903   gcc_jit_block_end_with_return (
904     initial,
905     NULL,
906     gcc_jit_lvalue_get_address (
907       test_global,
908       NULL));
909 }
910 
911 static void
verify_get_address(gcc_jit_result * result)912 verify_get_address (gcc_jit_result *result)
913 {
914   typedef void *(*test_fn) (void);
915     test_fn test_get_address =
916       (test_fn)gcc_jit_result_get_code (result,
917 					"test_get_address");
918   CHECK_NON_NULL (test_get_address);
919   CHECK_VALUE (test_get_address (), &test_global);
920 }
921 
922 /**********************************************************************
923  Vector values
924  **********************************************************************/
925 
926 static void
make_test_of_vectors(gcc_jit_context * ctxt)927 make_test_of_vectors (gcc_jit_context *ctxt)
928 {
929   gcc_jit_type *scalar_type;
930   gcc_jit_type *vec_type;
931   gcc_jit_rvalue *elements[4];
932 
933   scalar_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
934 
935   vec_type = gcc_jit_type_get_vector (scalar_type, 4);
936 
937   elements[0] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, 1);
938   elements[1] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, -2);
939   elements[2] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, 3);
940   elements[3] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, -4);
941 
942   gcc_jit_rvalue *vec_rvalue
943     = gcc_jit_context_new_rvalue_from_vector (ctxt, NULL, vec_type,
944 					      4, elements);
945   CHECK_STRING_VALUE (
946     gcc_jit_object_get_debug_string (
947       gcc_jit_rvalue_as_object (vec_rvalue)),
948     "{(int)1, (int)-2, (int)3, (int)-4}");
949 }
950 
951 /**********************************************************************
952  Code for harness
953  **********************************************************************/
954 
955 void
create_code(gcc_jit_context * ctxt,void * user_data)956 create_code (gcc_jit_context *ctxt, void *user_data)
957 {
958   make_tests_of_unary_ops (ctxt);
959   make_tests_of_binary_ops (ctxt);
960   make_tests_of_comparisons (ctxt);
961   make_tests_of_casts (ctxt);
962   make_tests_of_dereferences (ctxt);
963   make_test_of_get_address (ctxt);
964   make_test_of_vectors (ctxt);
965 }
966 
967 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)968 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
969 {
970   CHECK_NON_NULL (result);
971 
972   verify_unary_ops (result);
973   verify_binary_ops (result);
974   verify_comparisons (result);
975   verify_casts (result);
976   verify_dereferences (result);
977   verify_get_address (result);
978 }
979