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/>.
22 typedef uint16_t code_t
;
24 #define OPCODE_MASK 0xffff
26 #define OPCODE_OP_FLAG_STRICT 0x0001
27 #define OPCODE_FLAG_FREE_ARGUMENT 0x0002
28 #define OPCODE_FLAG_FREE_ARGUMENT_2 0x0004
29 #define OPCODE_CALL_MAY_LEND 0x0004 /* OPCODE_FLAG_FREE_ARGUMENT must not be set */
30 #define OPCODE_CALL_MAY_GIVE 0x0008 /* OPCODE_FLAG_FREE_ARGUMENT must be set */
31 #define OPCODE_FLAG_FUSED 0x0008
32 #define OPCODE_ARRAY_FILL_FLAG_SPARSE 0x0004
33 #define OPCODE_ARRAY_INDEX_IN_RANGE 0x0004
34 #define OPCODE_STRUCT_MAY_BORROW 0x0008
35 #define FLAG_NEED_BOTH_EXCEPTIONS_TO_FAIL 0x0100 /* not used in code, used internally in ipret.c */
36 #define FLAG_FIRST_EXCEPTION 0x0200 /* not used in code, used internally in ipret.c */
37 #define FLAG_TESTING_FOR_EXCEPTION 0x0400 /* not used in code, used internally in ipret.c */
38 #define OPCODE_MAY_RETURN_FLAT 0x0001
40 #define OPCODE_FIXED_OP_MULT 1
41 #define OPCODE_FIXED_OP_add 0
42 #define OPCODE_FIXED_OP_subtract 1
43 #define OPCODE_FIXED_OP_multiply 2
44 #define OPCODE_FIXED_OP_divide 3
45 #define OPCODE_FIXED_OP_divide_alt1 4
46 #define OPCODE_FIXED_OP_udivide 5
47 #define OPCODE_FIXED_OP_udivide_alt1 6
48 #define OPCODE_FIXED_OP_modulo 7
49 #define OPCODE_FIXED_OP_modulo_alt1 8
50 #define OPCODE_FIXED_OP_umodulo 9
51 #define OPCODE_FIXED_OP_umodulo_alt1 10
52 #define OPCODE_FIXED_OP_power 11
53 #define OPCODE_FIXED_OP_and 12
54 #define OPCODE_FIXED_OP_or 13
55 #define OPCODE_FIXED_OP_xor 14
56 #define OPCODE_FIXED_OP_shl 15
57 #define OPCODE_FIXED_OP_shr 16
58 #define OPCODE_FIXED_OP_ushr 17
59 #define OPCODE_FIXED_OP_rol 18
60 #define OPCODE_FIXED_OP_ror 19
61 #define OPCODE_FIXED_OP_bts 20
62 #define OPCODE_FIXED_OP_btr 21
63 #define OPCODE_FIXED_OP_btc 22
64 #define OPCODE_FIXED_OP_equal 23
65 #define OPCODE_FIXED_OP_not_equal 24
66 #define OPCODE_FIXED_OP_less 25
67 #define OPCODE_FIXED_OP_less_equal 26
68 #define OPCODE_FIXED_OP_uless 27
69 #define OPCODE_FIXED_OP_uless_equal 28
70 #define OPCODE_FIXED_OP_bt 29
71 #define OPCODE_FIXED_OP_UNARY 30
72 #define OPCODE_FIXED_OP_not 30
73 #define OPCODE_FIXED_OP_neg 31
74 #define OPCODE_FIXED_OP_inc 32
75 #define OPCODE_FIXED_OP_dec 33
76 #define OPCODE_FIXED_OP_bswap 34
77 #define OPCODE_FIXED_OP_bswap_alt1 35
78 #define OPCODE_FIXED_OP_brev 36
79 #define OPCODE_FIXED_OP_brev_alt1 37
80 #define OPCODE_FIXED_OP_bsf 38
81 #define OPCODE_FIXED_OP_bsf_alt1 39
82 #define OPCODE_FIXED_OP_bsr 40
83 #define OPCODE_FIXED_OP_bsr_alt1 41
84 #define OPCODE_FIXED_OP_popcnt 42
85 #define OPCODE_FIXED_OP_popcnt_alt1 43
86 #define OPCODE_FIXED_OP_to_int 44
87 #define OPCODE_FIXED_OP_uto_int 45
88 #define OPCODE_FIXED_OP_from_int 46
89 #define OPCODE_FIXED_OP_ufrom_int 47
90 #define OPCODE_FIXED_OP_N 48
91 #define OPCODE_FIXED_OP_move 48
92 #define OPCODE_FIXED_OP_copy 49
93 #define OPCODE_FIXED_OP_ldc 50
94 #define OPCODE_FIXED_OP_ldc16 51
96 #define OPCODE_FIXED_TYPE_MULT 52
97 #define OPCODE_FIXED_TYPE_int8_t 0
98 #define OPCODE_FIXED_TYPE_int16_t 1
99 #define OPCODE_FIXED_TYPE_int32_t 2
100 #define OPCODE_FIXED_TYPE_int64_t 3
101 #define OPCODE_FIXED_TYPE_int128_t 4
103 #define OPCODE_INT_OP_MULT 1
104 #define OPCODE_INT_OP_add 0
105 #define OPCODE_INT_OP_subtract 1
106 #define OPCODE_INT_OP_multiply 2
107 #define OPCODE_INT_OP_divide 3
108 #define OPCODE_INT_OP_divide_alt1 4
109 #define OPCODE_INT_OP_modulo 5
110 #define OPCODE_INT_OP_modulo_alt1 6
111 #define OPCODE_INT_OP_power 7
112 #define OPCODE_INT_OP_and 8
113 #define OPCODE_INT_OP_or 9
114 #define OPCODE_INT_OP_xor 10
115 #define OPCODE_INT_OP_shl 11
116 #define OPCODE_INT_OP_shr 12
117 #define OPCODE_INT_OP_bts 13
118 #define OPCODE_INT_OP_btr 14
119 #define OPCODE_INT_OP_btc 15
120 #define OPCODE_INT_OP_equal 16
121 #define OPCODE_INT_OP_not_equal 17
122 #define OPCODE_INT_OP_less 18
123 #define OPCODE_INT_OP_less_equal 19
124 #define OPCODE_INT_OP_bt 20
125 #define OPCODE_INT_OP_UNARY 21
126 #define OPCODE_INT_OP_not 21
127 #define OPCODE_INT_OP_neg 22
128 #define OPCODE_INT_OP_inc 23
129 #define OPCODE_INT_OP_dec 24
130 #define OPCODE_INT_OP_bsf 25
131 #define OPCODE_INT_OP_bsr 26
132 #define OPCODE_INT_OP_popcnt 27
133 #define OPCODE_INT_OP_popcnt_alt1 28
134 #define OPCODE_INT_OP_to_int 29
135 #define OPCODE_INT_OP_from_int 30
136 #define OPCODE_INT_OP_N 31
137 #define OPCODE_INT_OP_move 31
138 #define OPCODE_INT_OP_copy 32
139 #define OPCODE_INT_OP_ldc 33
140 #define OPCODE_INT_OP_ldc16 34
142 #define OPCODE_INT_TYPE_MULT 35
143 #define OPCODE_INT_TYPE_int8_t 0
144 #define OPCODE_INT_TYPE_int16_t 1
145 #define OPCODE_INT_TYPE_int32_t 2
146 #define OPCODE_INT_TYPE_int64_t 3
147 #define OPCODE_INT_TYPE_int128_t 4
149 #define OPCODE_REAL_OP_MULT 1
150 #define OPCODE_REAL_OP_add 0
151 #define OPCODE_REAL_OP_add_alt1 1
152 #define OPCODE_REAL_OP_add_alt2 2
153 #define OPCODE_REAL_OP_subtract 3
154 #define OPCODE_REAL_OP_subtract_alt1 4
155 #define OPCODE_REAL_OP_subtract_alt2 5
156 #define OPCODE_REAL_OP_multiply 6
157 #define OPCODE_REAL_OP_multiply_alt1 7
158 #define OPCODE_REAL_OP_multiply_alt2 8
159 #define OPCODE_REAL_OP_divide 9
160 #define OPCODE_REAL_OP_divide_alt1 10
161 #define OPCODE_REAL_OP_divide_alt2 11
162 #define OPCODE_REAL_OP_modulo 12
163 #define OPCODE_REAL_OP_power 13
164 #define OPCODE_REAL_OP_ldexp 14
165 #define OPCODE_REAL_OP_atan2 15
166 #define OPCODE_REAL_OP_equal 16
167 #define OPCODE_REAL_OP_equal_alt1 17
168 #define OPCODE_REAL_OP_equal_alt2 18
169 #define OPCODE_REAL_OP_not_equal 19
170 #define OPCODE_REAL_OP_not_equal_alt1 20
171 #define OPCODE_REAL_OP_not_equal_alt2 21
172 #define OPCODE_REAL_OP_less 22
173 #define OPCODE_REAL_OP_less_alt1 23
174 #define OPCODE_REAL_OP_less_alt2 24
175 #define OPCODE_REAL_OP_less_equal 25
176 #define OPCODE_REAL_OP_less_equal_alt1 26
177 #define OPCODE_REAL_OP_less_equal_alt2 27
178 #define OPCODE_REAL_OP_UNARY 28
179 #define OPCODE_REAL_OP_neg 28
180 #define OPCODE_REAL_OP_neg_alt1 29
181 #define OPCODE_REAL_OP_neg_alt2 30
182 #define OPCODE_REAL_OP_sqrt 31
183 #define OPCODE_REAL_OP_sqrt_alt1 32
184 #define OPCODE_REAL_OP_sqrt_alt2 33
185 #define OPCODE_REAL_OP_cbrt 35
186 #define OPCODE_REAL_OP_sin 36
187 #define OPCODE_REAL_OP_cos 37
188 #define OPCODE_REAL_OP_tan 38
189 #define OPCODE_REAL_OP_asin 39
190 #define OPCODE_REAL_OP_acos 40
191 #define OPCODE_REAL_OP_atan 41
192 #define OPCODE_REAL_OP_sinh 42
193 #define OPCODE_REAL_OP_cosh 43
194 #define OPCODE_REAL_OP_tanh 44
195 #define OPCODE_REAL_OP_asinh 45
196 #define OPCODE_REAL_OP_acosh 46
197 #define OPCODE_REAL_OP_atanh 47
198 #define OPCODE_REAL_OP_exp2 48
199 #define OPCODE_REAL_OP_exp 49
200 #define OPCODE_REAL_OP_exp10 50
201 #define OPCODE_REAL_OP_log2 51
202 #define OPCODE_REAL_OP_log 52
203 #define OPCODE_REAL_OP_log10 53
204 #define OPCODE_REAL_OP_round 54
205 #define OPCODE_REAL_OP_floor 55
206 #define OPCODE_REAL_OP_ceil 56
207 #define OPCODE_REAL_OP_trunc 57
208 #define OPCODE_REAL_OP_fract 58
209 #define OPCODE_REAL_OP_mantissa 59
210 #define OPCODE_REAL_OP_exponent 60
211 #define OPCODE_REAL_OP_next_number 61
212 #define OPCODE_REAL_OP_prev_number 62
213 #define OPCODE_REAL_OP_to_int 63
214 #define OPCODE_REAL_OP_to_int_alt1 64
215 #define OPCODE_REAL_OP_to_int_alt2 65
216 #define OPCODE_REAL_OP_from_int 66
217 #define OPCODE_REAL_OP_from_int_alt1 67
218 #define OPCODE_REAL_OP_from_int_alt2 68
219 #define OPCODE_REAL_OP_is_exception 69
220 #define OPCODE_REAL_OP_is_exception_alt1 70
221 #define OPCODE_REAL_OP_is_exception_alt2 71
222 #define OPCODE_REAL_OP_N 72
223 #define OPCODE_REAL_OP_move 72
224 #define OPCODE_REAL_OP_copy 73
225 #define OPCODE_REAL_OP_ldc 74
227 #define OPCODE_REAL_TYPE_MULT 75
228 #define OPCODE_REAL_TYPE_real16_t 0
229 #define OPCODE_REAL_TYPE_real32_t 1
230 #define OPCODE_REAL_TYPE_real64_t 2
231 #define OPCODE_REAL_TYPE_real80_t 3
232 #define OPCODE_REAL_TYPE_real128_t 4
234 #define OPCODE_BOOL_OP_MULT 1
235 #define OPCODE_BOOL_OP_and 0
236 #define OPCODE_BOOL_OP_or 1
237 #define OPCODE_BOOL_OP_equal 2
238 #define OPCODE_BOOL_OP_not_equal 3
239 #define OPCODE_BOOL_OP_less 4
240 #define OPCODE_BOOL_OP_less_equal 5
241 #define OPCODE_BOOL_OP_UNARY 6
242 #define OPCODE_BOOL_OP_not 6
243 #define OPCODE_BOOL_OP_N 7
244 #define OPCODE_BOOL_OP_move 7
245 #define OPCODE_BOOL_OP_copy 8
247 #define OPCODE_BOOL_TYPE_MULT 9
249 #define OPCODE_FIXED_OP 0
250 #define OPCODE_INT_OP (OPCODE_FIXED_OP + OPCODE_FIXED_TYPE_MULT * TYPE_FIXED_N)
251 #define OPCODE_REAL_OP (OPCODE_INT_OP + OPCODE_INT_TYPE_MULT * TYPE_INT_N)
252 #define OPCODE_BOOL_OP (OPCODE_REAL_OP + OPCODE_REAL_TYPE_MULT * TYPE_REAL_N)
253 #define OPCODE_EXTRA (OPCODE_BOOL_OP + OPCODE_BOOL_TYPE_MULT)
256 OPCODE_INT_LDC_LONG
= OPCODE_EXTRA
,
257 OPCODE_IS_EXCEPTION
, /* src, dest, strict flag */
258 OPCODE_EXCEPTION_CLASS
, /* src, dest, strict flag */
259 OPCODE_EXCEPTION_TYPE
, /* src, dest, strict flag */
260 OPCODE_EXCEPTION_AUX
, /* src, dest, strict flag */
261 OPCODE_SYSTEM_PROPERTY
, /* src, dest, strict flag */
265 OPCODE_REF_MOVE_CLEAR
,
267 OPCODE_BOX_MOVE_CLEAR
,
269 OPCODE_TAKE_BORROWED
,
271 OPCODE_DEREFERENCE_CLEAR
,
273 OPCODE_ESCAPE_NONFLAT
,
277 OPCODE_JMP_FALSE
, /* var, false_offset*2, exception_offset*2 */
279 OPCODE_LOAD_FN
, /* n_arg, result, fn_idx, [arg_var, arg_deref] */
280 OPCODE_CURRY
, /* n_arg, result, fn_thunk, fn_deref, [arg_var, arg_deref] */
281 OPCODE_CALL
, /* n_arg, n_ret, fn_idx, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
282 OPCODE_CALL_STRICT
, /* n_arg, n_ret, fn_idx, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
283 OPCODE_CALL_SPARK
, /* n_arg, n_ret, fn_idx, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
284 OPCODE_CALL_LAZY
, /* n_arg, n_ret, fn_idx, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
285 OPCODE_CALL_CACHE
, /* n_arg, n_ret, fn_idx, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
286 OPCODE_CALL_SAVE
, /* n_arg, n_ret, fn_idx, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
287 OPCODE_CALL_INDIRECT
, /* n_arg, n_ret, fn_thunk, fn_deref, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
288 OPCODE_CALL_INDIRECT_STRICT
, /* n_arg, n_ret, fn_thunk, fn_deref, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
289 OPCODE_CALL_INDIRECT_SPARK
, /* n_arg, n_ret, fn_thunk, fn_deref, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
290 OPCODE_CALL_INDIRECT_LAZY
, /* n_arg, n_ret, fn_thunk, fn_deref, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
291 OPCODE_CALL_INDIRECT_CACHE
, /* n_arg, n_ret, fn_thunk, fn_deref, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
292 OPCODE_CALL_INDIRECT_SAVE
, /* n_arg, n_ret, fn_thunk, fn_deref, [arg_var, arg_deref], [ret_var(32), ret_flag(16)] */
293 OPCODE_RETURN
, /* val, arg_deref ... */
294 OPCODE_STRUCTURED
, /* struct, element ... */
295 #define OPCODE_STRUCTURED_RECORD 0x01 /* + element_slot, record_type */
296 #define OPCODE_STRUCTURED_OPTION 0x02 /* + option, nothing */
297 #define OPCODE_STRUCTURED_ARRAY 0x03 /* + index_slot, nothing */
298 #define OPCODE_STRUCTURED_MASK 0x0f
299 #define OPCODE_STRUCTURED_FREE_VARIABLE 0x10
300 #define OPCODE_STRUCTURED_FLAG_END 0x20
301 OPCODE_RECORD_CREATE
, /* result, n_entries, [entry_var, arg_deref] */
302 OPCODE_RECORD_LOAD
, /* record, slot, result, (strict_flag | borrow_flag) */
303 OPCODE_OPTION_CREATE_EMPTY_FLAT
,/* result, option */
304 OPCODE_OPTION_CREATE_EMPTY
, /* result, option */
305 OPCODE_OPTION_CREATE
, /* result, option, arg_var, arg_deref */
306 OPCODE_OPTION_LOAD
, /* option, idx, result, (strict_flag | borrow_flag) */
307 OPCODE_OPTION_TEST_FLAT
, /* var, option, result */
308 OPCODE_OPTION_TEST
, /* var, option, result */
309 OPCODE_OPTION_ORD_FLAT
, /* var, result */
310 OPCODE_OPTION_ORD
, /* var, result */
311 OPCODE_ARRAY_CREATE
, /* result, n_entries, [entry_var, arg_deref] */
312 OPCODE_ARRAY_CREATE_EMPTY_FLAT
, /* result, local_type */
313 OPCODE_ARRAY_CREATE_EMPTY
, /* result */
314 OPCODE_ARRAY_FILL
, /* content_var, content_deref | flag_sparse, length_var, result */
315 OPCODE_ARRAY_STRING
, /* result, length, [chars] */
316 OPCODE_ARRAY_UNICODE
, /* result, length, [chars] */
317 OPCODE_ARRAY_LOAD
, /* array, idx slot, result, (strict_flag | borrow_flag) */
318 OPCODE_ARRAY_LEN
, /* array, result, strict_flag */
319 OPCODE_ARRAY_LEN_GREATER_THAN
, /* array, size, result, strict_flag */
320 OPCODE_ARRAY_SUB
, /* array, start, end, result, strict_flags | deref */
321 OPCODE_ARRAY_SKIP
, /* array, start, result, strict_flags | deref */
322 OPCODE_ARRAY_APPEND
, /* result, arg_deref1 | arg_deref2, arg1, arg2 */
323 OPCODE_ARRAY_APPEND_ONE_FLAT
, /* result, arg_deref1 | arg_deref2, arg1, arg2 */
324 OPCODE_ARRAY_APPEND_ONE
, /* result, arg_deref1 | arg_deref2, arg1, arg2 */
325 OPCODE_ARRAY_FLATTEN
, /* result, arg_deref1, arg1 */
326 OPCODE_IO
, /* (code, n_outputs, n_inputs, n_params), 32-bit: outputs, inputs, params */
327 OPCODE_INTERNAL_FUNCTION
,
334 OPCODE_MODE_MULT_0
= (OPCODE_N
- 1),
335 OPCODE_MODE_MULT_1
= (OPCODE_MODE_MULT_0
| (OPCODE_MODE_MULT_0
>> 1)),
336 OPCODE_MODE_MULT_2
= (OPCODE_MODE_MULT_1
| (OPCODE_MODE_MULT_1
>> 2)),
337 OPCODE_MODE_MULT_4
= (OPCODE_MODE_MULT_2
| (OPCODE_MODE_MULT_2
>> 4)),
338 OPCODE_MODE_MULT_8
= (OPCODE_MODE_MULT_4
| (OPCODE_MODE_MULT_4
>> 8)),
339 OPCODE_MODE_MULT
= OPCODE_MODE_MULT_8
+ 1,