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