12 create_overflow_fn (gcc_jit_context
*ctxt
,
15 const char *builtin_name
)
17 /* Create the equivalent of this C:
20 test_overflow_T_OP (T x, T y, bool *ovf)
24 *ovf = ...; // did overflow happen?
29 gcc_jit_type
*t_bool
=
30 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_BOOL
);
31 gcc_jit_type
*t_bool_star
=
32 gcc_jit_type_get_pointer (t_bool
);
35 gcc_jit_context_new_param (
40 gcc_jit_context_new_param (
45 gcc_jit_context_new_param (
49 gcc_jit_param
*params
[3] = {x
, y
, ovf
};
51 gcc_jit_function
*func
=
52 gcc_jit_context_new_function (ctxt
,
54 GCC_JIT_FUNCTION_EXPORTED
,
59 gcc_jit_lvalue
*result
=
60 gcc_jit_function_new_local (func
, NULL
, type
, "result");
62 gcc_jit_block
*b_initial
=
63 gcc_jit_function_new_block (func
, "initial");
65 /* The builtins are listed in builtins.def as being variadic, but
66 the have these signatures:
67 bool __builtin_add_overflow (type1 a, type2 b, type3 *res);
68 bool __builtin_sub_overflow (type1 a, type2 b, type3 *res);
69 bool __builtin_mul_overflow (type1 a, type2 b, type3 *res); */
71 gcc_jit_function
*builtin_fn
=
72 gcc_jit_context_get_builtin_function (ctxt
, builtin_name
);
74 /* Construct a call of the form:
75 (returns bool) __builtin_add_overflow (x, y, &result). */
76 gcc_jit_rvalue
*args
[3] = {gcc_jit_param_as_rvalue (x
),
77 gcc_jit_param_as_rvalue (y
),
78 gcc_jit_lvalue_get_address (result
, NULL
)};
79 gcc_jit_rvalue
*call
=
80 gcc_jit_context_new_call (ctxt
,
85 /* "*ovf = BUILTIN_CALL ();" */
86 gcc_jit_block_add_assignment (
88 gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (ovf
),
92 /* "return result;" */
93 gcc_jit_block_end_with_return (
95 gcc_jit_lvalue_as_rvalue (result
));
99 create_code (gcc_jit_context
*ctxt
, void *user_data
)
102 gcc_jit_type
*int_type
=
103 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_INT
);
104 create_overflow_fn (ctxt
, int_type
,
105 "test_overflow_int_add",
106 "__builtin_add_overflow");
107 create_overflow_fn (ctxt
, int_type
,
108 "test_overflow_int_sub",
109 "__builtin_sub_overflow");
110 create_overflow_fn (ctxt
, int_type
,
111 "test_overflow_int_mul",
112 "__builtin_mul_overflow");
115 gcc_jit_type
*uint_type
=
116 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_UNSIGNED_INT
);
117 create_overflow_fn (ctxt
, uint_type
,
118 "test_overflow_uint_add",
119 "__builtin_add_overflow");
120 create_overflow_fn (ctxt
, uint_type
,
121 "test_overflow_uint_sub",
122 "__builtin_sub_overflow");
123 create_overflow_fn (ctxt
, uint_type
,
124 "test_overflow_uint_mul",
125 "__builtin_mul_overflow");
129 verify_int_overflow_fn (gcc_jit_result
*jit_result
,
130 const char *funcname
,
135 CHECK_NON_NULL (jit_result
);
136 typedef int (*overflow_fn_type
) (int, int, bool *);
137 overflow_fn_type fn
=
138 (overflow_fn_type
)gcc_jit_result_get_code (jit_result
, funcname
);
141 /* Call the function: */
143 int actual_result
= fn (x
, y
, &actual_ovf
);
144 note ("%s (%d, %d) returned: %d with ovf: %d",
145 funcname
, x
, y
, actual_result
, actual_ovf
);
146 CHECK_VALUE (actual_result
, expected_result
);
147 CHECK_VALUE (actual_ovf
, expected_ovf
);
151 verify_uint_overflow_fn (gcc_jit_result
*jit_result
,
152 const char *funcname
,
153 unsigned int x
, unsigned int y
,
154 unsigned int expected_result
,
157 CHECK_NON_NULL (jit_result
);
158 typedef unsigned int (*overflow_fn_type
) (unsigned int, unsigned int,
160 overflow_fn_type fn
=
161 (overflow_fn_type
)gcc_jit_result_get_code (jit_result
, funcname
);
164 /* Call the function: */
166 unsigned int actual_result
= fn (x
, y
, &actual_ovf
);
167 note ("%s (%d, %d) returned: %d with ovf: %d",
168 funcname
, x
, y
, actual_result
, actual_ovf
);
169 CHECK_VALUE (actual_result
, expected_result
);
170 CHECK_VALUE (actual_ovf
, expected_ovf
);
174 verify_code (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
176 verify_int_overflow_fn (result
, "test_overflow_int_add",
179 verify_int_overflow_fn (result
, "test_overflow_int_add",
182 verify_int_overflow_fn (result
, "test_overflow_int_sub",
185 verify_int_overflow_fn (result
, "test_overflow_int_sub",
188 verify_int_overflow_fn (result
, "test_overflow_int_mul",
191 verify_int_overflow_fn (result
, "test_overflow_int_mul",
194 verify_int_overflow_fn (result
, "test_overflow_int_mul",
198 verify_uint_overflow_fn (result
, "test_overflow_uint_add",
201 verify_uint_overflow_fn (result
, "test_overflow_uint_add",
203 (((unsigned int)INT_MAX
) + 1), 0);
204 verify_uint_overflow_fn (result
, "test_overflow_uint_add",
207 verify_uint_overflow_fn (result
, "test_overflow_uint_sub",
210 verify_uint_overflow_fn (result
, "test_overflow_uint_sub",
212 ((unsigned int)INT_MIN
- 1), 0);
213 verify_uint_overflow_fn (result
, "test_overflow_uint_mul",
216 verify_uint_overflow_fn (result
, "test_overflow_uint_mul",
219 verify_uint_overflow_fn (result
, "test_overflow_uint_mul",
221 (unsigned int)INT_MAX
* 2, 0);
222 verify_uint_overflow_fn (result
, "test_overflow_uint_mul",
224 -2/*(unsigned int)INT_MAX * 2*/, 1);