1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 
5 #include "libgccjit.h"
6 
7 #include "harness.h"
8 
9 /* Quote from here in docs/topics/functions.rst.  */
10 
11 void
create_code(gcc_jit_context * ctxt,void * user_data)12 create_code (gcc_jit_context *ctxt, void *user_data)
13 {
14   /* Let's try to inject the equivalent of:
15       int
16       test_switch (int x)
17       {
18 	switch (x)
19 	  {
20 	  case 0 ... 5:
21 	     return 3;
22 
23 	  case 25 ... 27:
24 	     return 4;
25 
26 	  case -42 ... -17:
27 	     return 83;
28 
29 	  case 40:
30 	     return 8;
31 
32 	  default:
33 	     return 10;
34 	  }
35       }
36    */
37   gcc_jit_type *t_int =
38     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
39   gcc_jit_type *return_type = t_int;
40   gcc_jit_param *x =
41     gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
42   gcc_jit_param *params[1] = {x};
43   gcc_jit_function *func =
44     gcc_jit_context_new_function (ctxt, NULL,
45 				  GCC_JIT_FUNCTION_EXPORTED,
46 				  return_type,
47 				  "test_switch",
48 				  1, params, 0);
49 
50   gcc_jit_block *b_initial =
51     gcc_jit_function_new_block (func, "initial");
52 
53   gcc_jit_block *b_default =
54     gcc_jit_function_new_block (func, "default");
55   gcc_jit_block *b_case_0_5 =
56     gcc_jit_function_new_block (func, "case_0_5");
57   gcc_jit_block *b_case_25_27 =
58     gcc_jit_function_new_block (func, "case_25_27");
59   gcc_jit_block *b_case_m42_m17 =
60     gcc_jit_function_new_block (func, "case_m42_m17");
61   gcc_jit_block *b_case_40 =
62     gcc_jit_function_new_block (func, "case_40");
63 
64   gcc_jit_case *cases[4] = {
65     gcc_jit_context_new_case (
66       ctxt,
67       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0),
68       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5),
69       b_case_0_5),
70     gcc_jit_context_new_case (
71       ctxt,
72       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25),
73       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27),
74       b_case_25_27),
75     gcc_jit_context_new_case (
76       ctxt,
77       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42),
78       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17),
79       b_case_m42_m17),
80     gcc_jit_context_new_case (
81       ctxt,
82       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
83       gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
84       b_case_40)
85   };
86   gcc_jit_block_end_with_switch (
87     b_initial, NULL,
88     gcc_jit_param_as_rvalue (x),
89     b_default,
90     4, cases);
91 
92   gcc_jit_block_end_with_return (
93     b_case_0_5, NULL,
94     gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
95   gcc_jit_block_end_with_return (
96     b_case_25_27, NULL,
97     gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4));
98   gcc_jit_block_end_with_return (
99     b_case_m42_m17, NULL,
100     gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83));
101   gcc_jit_block_end_with_return (
102     b_case_40, NULL,
103     gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8));
104   gcc_jit_block_end_with_return (
105     b_default, NULL,
106     gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
107 }
108 
109 /* Quote up to here in docs/topics/functions.rst.  */
110 
111 static int
c_test_switch(int x)112 c_test_switch (int x)
113 {
114   switch (x)
115     {
116     case 0 ... 5:
117       return 3;
118     case 25 ... 27:
119       return 4;
120     case -42 ... -17:
121       return 83;
122     case 40:
123       return 8;
124     default:
125       return 10;
126     }
127 }
128 
129 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)130 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
131 {
132   typedef int (*test_switch_type) (int);
133   CHECK_NON_NULL (result);
134   test_switch_type test_switch =
135     (test_switch_type)gcc_jit_result_get_code (result, "test_switch");
136   CHECK_NON_NULL (test_switch);
137 
138   int i;
139 
140   for (i = -255; i < 255; i++)
141     {
142       int val = test_switch (i);
143       int exp = c_test_switch (i);
144       if (val != exp)
145 	fail ("test_switch (%i) returned: %i; expected; %i", i, val, exp);
146     }
147 }
148