2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
25 #define cg_upcall_vector name(cg_upcall_vector)
26 #define asm_generated_upcalls name(asm_generated_upcalls)
28 /*#define DEBUG_UPCALL*/
30 #ifdef POINTER_COMPRESSION
31 #define pointer_t_upcall uintptr_t
32 #define int_default_t_upcall intptr_t
34 #define pointer_t_upcall pointer_t
35 #define int_default_t_upcall int_default_t
38 void attr_fastcall
run(frame_s
*, ip_t
);
40 extern bool asm_generated_upcalls
;
42 struct cg_upcall_vector_s
{
43 atomic_type tick_stamp_t ts
;
45 void (*mem_copy
)(void *dest
, const void *src
, size_t size
);
46 void (*mem_clear
)(void *ptr
, size_t size
);
47 void (*cg_upcall_pointer_dereference
)(pointer_t_upcall ptr
);
48 void (*cg_upcall_pointer_reference_owned
)(pointer_t_upcall ptr
);
49 pointer_t (*cg_upcall_flat_to_data
)(frame_s
*fp
, uintptr_t slot
, const unsigned char *flat
);
50 unsigned char *(*cg_upcall_data_alloc_function_reference_mayfail
)(uintptr_t n_curried_arguments
);
51 unsigned char *(*cg_upcall_data_alloc_record_mayfail
)(frame_s
*fp
, uintptr_t slot
);
52 unsigned char *(*cg_upcall_data_alloc_option_mayfail
)(void);
53 unsigned char *(*cg_upcall_data_alloc_array_flat_tag_mayfail
)(uintptr_t t
, int_default_t_upcall n_entries
);
54 unsigned char *(*cg_upcall_data_alloc_array_flat_slot_mayfail
)(frame_s
*fp
, uintptr_t slot
, int_default_t_upcall n_entries
);
55 unsigned char *(*cg_upcall_data_alloc_array_flat_types_ptr_mayfail
)(frame_s
*fp
, uintptr_t local_type
, int_default_t_upcall n_allocated
, int_default_t_upcall n_used
);
56 unsigned char *(*cg_upcall_data_alloc_array_pointers_mayfail
)(int_default_t_upcall n_allocated
, int_default_t_upcall n_used
);
57 pointer_t (*cg_upcall_array_create_flat
)(frame_s
*fp
, int_default_t_upcall length
, uintptr_t content_slot
);
58 pointer_t (*cg_upcall_array_create_pointers
)(frame_s
*fp
, uintptr_t ip_offset
, uintptr_t length_slot
, pointer_t_upcall ptr
);
59 pointer_t (*cg_upcall_array_create_sparse
)(int_default_t_upcall length
, pointer_t_upcall ptr
);
60 pointer_t (*cg_upcall_array_sub
)(pointer_t_upcall array
, int_default_t_upcall start
, int_default_t_upcall end
, bool deref
);
61 pointer_t (*cg_upcall_array_skip
)(pointer_t_upcall array
, int_default_t_upcall start
, bool deref
);
62 pointer_t (*cg_upcall_array_join
)(pointer_t_upcall ptr1
, pointer_t_upcall ptr2
);
63 void *(*cg_upcall_ipret_io
)(frame_s
*fp
, uintptr_t ip_offset
, uintptr_t code_params
);
64 pointer_t (*cg_upcall_ipret_copy_variable_to_pointer
)(frame_s
*src_fp
, uintptr_t src_slot
, bool deref
);
65 int_default_t (*cg_upcall_ipret_system_property
)(int_default_t_upcall idx
);
66 #define f(n, s, u, sz, bits) \
67 bool (*cat(INT_binary_const_,s))(const s *v1, int_default_t_upcall v2, s *r, bool (*op)(const void *, const void *, void *));
68 for_all_int(f
, for_all_empty
)
70 bool (*cat(FIXED_binary_add_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
71 bool (*cat(FIXED_binary_subtract_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
72 #define f(n, s, u, sz, bits) \
73 bool (*cat(FIXED_binary_multiply_,s))(const u *v1, const u *v2, u *r);
76 #define f(n, s, u, sz, bits) \
77 bool (*cat(FIXED_binary_divide_,s))(const u *v1, const u *v2, u *r);
80 #define f(n, s, u, sz, bits) \
81 bool (*cat(FIXED_binary_udivide_,s))(const u *v1, const u *v2, u *r);
84 #define f(n, s, u, sz, bits) \
85 bool (*cat(FIXED_binary_modulo_,s))(const u *v1, const u *v2, u *r);
88 #define f(n, s, u, sz, bits) \
89 bool (*cat(FIXED_binary_umodulo_,s))(const u *v1, const u *v2, u *r);
92 #define f(n, s, u, sz, bits) \
93 bool (*cat(FIXED_binary_power_,s))(const u *v1, const u *v2, u *r);
96 bool (*cat(FIXED_binary_shl_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
97 bool (*cat(FIXED_binary_shr_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
98 bool (*cat(FIXED_binary_ushr_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
99 bool (*cat(FIXED_binary_rol_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
100 bool (*cat(FIXED_binary_ror_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
101 bool (*cat(FIXED_binary_bts_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
102 bool (*cat(FIXED_binary_btr_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
103 bool (*cat(FIXED_binary_btc_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, uintbig_t
*r
);
104 bool (*cat(FIXED_binary_less_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
105 bool (*cat(FIXED_binary_less_equal_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
106 bool (*cat(FIXED_binary_greater_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
107 bool (*cat(FIXED_binary_greater_equal_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
108 bool (*cat(FIXED_binary_uless_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
109 bool (*cat(FIXED_binary_uless_equal_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
110 bool (*cat(FIXED_binary_ugreater_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
111 bool (*cat(FIXED_binary_ugreater_equal_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
112 bool (*cat(FIXED_binary_bt_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, const uintbig_t
*v2
, ajla_flat_option_t
*r
);
113 void (*cat(FIXED_unary_neg_
,TYPE_INT_MAX
))(const uintbig_t
*v1
, uintbig_t
*r
);
114 #define f(n, s, u, sz, bits) \
115 void (*cat(FIXED_unary_bswap_,s))(const u *v1, u *r);
118 #define f(n, s, u, sz, bits) \
119 void (*cat(FIXED_unary_brev_,s))(const u *v1, u *r);
122 #define f(n, s, u, sz, bits) \
123 void (*cat(FIXED_unary_bsf_,s))(const u *v1, u *r);
126 #define f(n, s, u, sz, bits) \
127 void (*cat(FIXED_unary_bsr_,s))(const u *v1, u *r);
130 #define f(n, s, u, sz, bits) \
131 void (*cat(FIXED_unary_popcnt_,s))(const u *v1, u *r);
134 #define f(n, s, u, sz, bits) \
135 bool (*cat(FIXED_uto_int_,s))(const u *v1, int_default_t *r);
138 #define f(n, s, u, sz, bits) \
139 bool (*cat(FIXED_ufrom_int_,s))(const int_default_t *v1, u *r);
142 bool (*cat(INT_binary_add_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, intbig_t
*r
);
143 bool (*cat(INT_binary_subtract_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, intbig_t
*r
);
144 #define f(n, s, u, sz, bits) \
145 bool (*cat(INT_binary_multiply_,s))(const s *v1, const s *v2, s *r);
146 for_all_int(f
, for_all_empty
)
148 #define f(n, s, u, sz, bits) \
149 bool (*cat(INT_binary_divide_,s))(const s *v1, const s *v2, s *r);
150 for_all_int(f
, for_all_empty
)
152 #define f(n, s, u, sz, bits) \
153 bool (*cat(INT_binary_modulo_,s))(const s *v1, const s *v2, s *r);
154 for_all_int(f
, for_all_empty
)
156 #define f(n, s, u, sz, bits) \
157 bool (*cat(INT_binary_power_,s))(const s *v1, const s *v2, s *r);
158 for_all_int(f
, for_all_empty
)
160 bool (*cat(INT_binary_shl_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, intbig_t
*r
);
161 bool (*cat(INT_binary_shr_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, intbig_t
*r
);
162 bool (*cat(INT_binary_bts_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, intbig_t
*r
);
163 bool (*cat(INT_binary_btr_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, intbig_t
*r
);
164 bool (*cat(INT_binary_btc_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, intbig_t
*r
);
165 bool (*cat(INT_binary_bt_
,TYPE_INT_MAX
))(const intbig_t
*v1
, const intbig_t
*v2
, ajla_flat_option_t
*r
);
166 bool (*cat(INT_unary_neg_
,TYPE_INT_MAX
))(const intbig_t
*v1
, intbig_t
*r
);
167 #define f(n, s, u, sz, bits) \
168 bool (*cat(INT_unary_bsf_,s))(const s *v1, s *r);
169 for_all_int(f
, for_all_empty
)
171 #define f(n, s, u, sz, bits) \
172 bool (*cat(INT_unary_bsr_,s))(const s *v1, s *r);
173 for_all_int(f
, for_all_empty
)
175 #define f(n, s, u, sz, bits) \
176 bool (*cat(INT_unary_popcnt_,s))(const s *v1, s *r);
177 for_all_int(f
, for_all_empty
)
179 #define f(n, t, nt, pack, unpack) \
180 bool (*cat(REAL_binary_add_,t))(const t *v1, const t *v2, t *r);
182 void (*cat(REAL_binary_add_,t))(void);
186 #define f(n, t, nt, pack, unpack) \
187 bool (*cat(REAL_binary_subtract_,t))(const t *v1, const t *v2, t *r);
189 void (*cat(REAL_binary_subtract_,t))(void);
193 #define f(n, t, nt, pack, unpack) \
194 bool (*cat(REAL_binary_multiply_,t))(const t *v1, const t *v2, t *r);
196 void (*cat(REAL_binary_multiply_,t))(void);
200 #define f(n, t, nt, pack, unpack) \
201 bool (*cat(REAL_binary_divide_,t))(const t *v1, const t *v2, t *r);
203 void (*cat(REAL_binary_divide_,t))(void);
207 #define f(n, t, nt, pack, unpack) \
208 bool (*cat(REAL_binary_modulo_,t))(const t *v1, const t *v2, t *r);
210 void (*cat(REAL_binary_modulo_,t))(void);
214 #define f(n, t, nt, pack, unpack) \
215 bool (*cat(REAL_binary_power_,t))(const t *v1, const t *v2, t *r);
217 void (*cat(REAL_binary_power_,t))(void);
221 #define f(n, t, nt, pack, unpack) \
222 bool (*cat(REAL_binary_ldexp_,t))(const t *v1, const t *v2, t *r);
224 void (*cat(REAL_binary_ldexp_,t))(void);
228 #define f(n, t, nt, pack, unpack) \
229 bool (*cat(REAL_binary_atan2_,t))(const t *v1, const t *v2, t *r);
231 void (*cat(REAL_binary_atan2_,t))(void);
235 #define f(n, t, nt, pack, unpack) \
236 bool (*cat(REAL_binary_equal_,t))(const t *v1, const t *v2, ajla_flat_option_t *r);
238 void (*cat(REAL_binary_equal_,t))(void);
242 #define f(n, t, nt, pack, unpack) \
243 bool (*cat(REAL_binary_not_equal_,t))(const t *v1, const t *v2, ajla_flat_option_t *r);
245 void (*cat(REAL_binary_not_equal_,t))(void);
249 #define f(n, t, nt, pack, unpack) \
250 bool (*cat(REAL_binary_less_,t))(const t *v1, const t *v2, ajla_flat_option_t *r);
252 void (*cat(REAL_binary_less_,t))(void);
256 #define f(n, t, nt, pack, unpack) \
257 bool (*cat(REAL_binary_less_equal_,t))(const t *v1, const t *v2, ajla_flat_option_t *r);
259 void (*cat(REAL_binary_less_equal_,t))(void);
263 #define f(n, t, nt, pack, unpack) \
264 bool (*cat(REAL_binary_greater_,t))(const t *v1, const t *v2, ajla_flat_option_t *r);
266 void (*cat(REAL_binary_greater_,t))(void);
270 #define f(n, t, nt, pack, unpack) \
271 bool (*cat(REAL_binary_greater_equal_,t))(const t *v1, const t *v2, ajla_flat_option_t *r);
273 void (*cat(REAL_binary_greater_equal_,t))(void);
277 #define f(n, t, nt, pack, unpack) \
278 void (*cat(REAL_unary_neg_,t))(const t *v1, t *r);
280 void (*cat(REAL_unary_neg_,t))(void);
284 #define f(n, t, nt, pack, unpack) \
285 void (*cat(REAL_unary_sqrt_,t))(const t *v1, t *r);
287 void (*cat(REAL_unary_sqrt_,t))(void);
291 #define f(n, t, nt, pack, unpack) \
292 void (*cat(REAL_unary_cbrt_,t))(const t *v1, t *r);
294 void (*cat(REAL_unary_cbrt_,t))(void);
298 #define f(n, t, nt, pack, unpack) \
299 void (*cat(REAL_unary_sin_,t))(const t *v1, t *r);
301 void (*cat(REAL_unary_sin_,t))(void);
305 #define f(n, t, nt, pack, unpack) \
306 void (*cat(REAL_unary_cos_,t))(const t *v1, t *r);
308 void (*cat(REAL_unary_cos_,t))(void);
312 #define f(n, t, nt, pack, unpack) \
313 void (*cat(REAL_unary_tan_,t))(const t *v1, t *r);
315 void (*cat(REAL_unary_tan_,t))(void);
319 #define f(n, t, nt, pack, unpack) \
320 void (*cat(REAL_unary_asin_,t))(const t *v1, t *r);
322 void (*cat(REAL_unary_asin_,t))(void);
326 #define f(n, t, nt, pack, unpack) \
327 void (*cat(REAL_unary_acos_,t))(const t *v1, t *r);
329 void (*cat(REAL_unary_acos_,t))(void);
333 #define f(n, t, nt, pack, unpack) \
334 void (*cat(REAL_unary_atan_,t))(const t *v1, t *r);
336 void (*cat(REAL_unary_atan_,t))(void);
340 #define f(n, t, nt, pack, unpack) \
341 void (*cat(REAL_unary_sinh_,t))(const t *v1, t *r);
343 void (*cat(REAL_unary_sinh_,t))(void);
347 #define f(n, t, nt, pack, unpack) \
348 void (*cat(REAL_unary_cosh_,t))(const t *v1, t *r);
350 void (*cat(REAL_unary_cosh_,t))(void);
354 #define f(n, t, nt, pack, unpack) \
355 void (*cat(REAL_unary_tanh_,t))(const t *v1, t *r);
357 void (*cat(REAL_unary_tanh_,t))(void);
361 #define f(n, t, nt, pack, unpack) \
362 void (*cat(REAL_unary_asinh_,t))(const t *v1, t *r);
364 void (*cat(REAL_unary_asinh_,t))(void);
368 #define f(n, t, nt, pack, unpack) \
369 void (*cat(REAL_unary_acosh_,t))(const t *v1, t *r);
371 void (*cat(REAL_unary_acosh_,t))(void);
375 #define f(n, t, nt, pack, unpack) \
376 void (*cat(REAL_unary_atanh_,t))(const t *v1, t *r);
378 void (*cat(REAL_unary_atanh_,t))(void);
382 #define f(n, t, nt, pack, unpack) \
383 void (*cat(REAL_unary_exp2_,t))(const t *v1, t *r);
385 void (*cat(REAL_unary_exp2_,t))(void);
389 #define f(n, t, nt, pack, unpack) \
390 void (*cat(REAL_unary_exp_,t))(const t *v1, t *r);
392 void (*cat(REAL_unary_exp_,t))(void);
396 #define f(n, t, nt, pack, unpack) \
397 void (*cat(REAL_unary_exp10_,t))(const t *v1, t *r);
399 void (*cat(REAL_unary_exp10_,t))(void);
403 #define f(n, t, nt, pack, unpack) \
404 void (*cat(REAL_unary_log2_,t))(const t *v1, t *r);
406 void (*cat(REAL_unary_log2_,t))(void);
410 #define f(n, t, nt, pack, unpack) \
411 void (*cat(REAL_unary_log_,t))(const t *v1, t *r);
413 void (*cat(REAL_unary_log_,t))(void);
417 #define f(n, t, nt, pack, unpack) \
418 void (*cat(REAL_unary_log10_,t))(const t *v1, t *r);
420 void (*cat(REAL_unary_log10_,t))(void);
424 #define f(n, t, nt, pack, unpack) \
425 void (*cat(REAL_unary_round_,t))(const t *v1, t *r);
427 void (*cat(REAL_unary_round_,t))(void);
431 #define f(n, t, nt, pack, unpack) \
432 void (*cat(REAL_unary_ceil_,t))(const t *v1, t *r);
434 void (*cat(REAL_unary_ceil_,t))(void);
438 #define f(n, t, nt, pack, unpack) \
439 void (*cat(REAL_unary_floor_,t))(const t *v1, t *r);
441 void (*cat(REAL_unary_floor_,t))(void);
445 #define f(n, t, nt, pack, unpack) \
446 void (*cat(REAL_unary_trunc_,t))(const t *v1, t *r);
448 void (*cat(REAL_unary_trunc_,t))(void);
452 #define f(n, t, nt, pack, unpack) \
453 void (*cat(REAL_unary_fract_,t))(const t *v1, t *r);
455 void (*cat(REAL_unary_fract_,t))(void);
459 #define f(n, t, nt, pack, unpack) \
460 void (*cat(REAL_unary_mantissa_,t))(const t *v1, t *r);
462 void (*cat(REAL_unary_mantissa_,t))(void);
466 #define f(n, t, nt, pack, unpack) \
467 void (*cat(REAL_unary_exponent_,t))(const t *v1, t *r);
469 void (*cat(REAL_unary_exponent_,t))(void);
473 #define f(n, t, nt, pack, unpack) \
474 void (*cat(REAL_unary_next_number_,t))(const t *v1, t *r);
476 void (*cat(REAL_unary_next_number_,t))(void);
480 #define f(n, t, nt, pack, unpack) \
481 void (*cat(REAL_unary_prev_number_,t))(const t *v1, t *r);
483 void (*cat(REAL_unary_prev_number_,t))(void);
487 #define f(n, t, nt, pack, unpack) \
488 bool (*cat(REAL_unary_to_int_,t))(const t *val, int_default_t *r);
490 void (*cat(REAL_unary_to_int_,t))(void);
494 #define f(n, t, nt, pack, unpack) \
495 void (*cat(REAL_unary_from_int_,t))(const int_default_t *val, t *r);
497 void (*cat(REAL_unary_from_int_,t))(void);
501 #define f(n, t, nt, pack, unpack) \
502 void (*cat(REAL_unary_is_exception_,t))(const t *v1, ajla_flat_option_t *r);
504 void (*cat(REAL_unary_is_exception_,t))(void);
510 void (*cg_upcall_debug
)(unsigned long x1
, unsigned long x2
, unsigned long x3
, unsigned long x4
);
516 extern struct cg_upcall_vector_s cg_upcall_vector
;
518 #define tick_stamp (cg_upcall_vector.ts)