1 /*
2 * Copyright (C) 2012-2020 Free Software Foundation, Inc.
3 *
4 * This file is part of GNU lightning.
5 *
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 * Andy Wingo
19 */
20
21 #ifndef _jit_h
22 #define _jit_h
23
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <string.h>
28 #include <stddef.h>
29
30 #include "lightening/endian.h"
31
32 CHOOSE_32_64(typedef int32_t jit_word_t,
33 typedef int64_t jit_word_t);
34 CHOOSE_32_64(typedef uint32_t jit_uword_t,
35 typedef uint64_t jit_uword_t);
36 typedef float jit_float32_t;
37 typedef double jit_float64_t;
38 typedef void* jit_pointer_t;
39 typedef int jit_bool_t;
40
41 typedef void* jit_addr_t;
42 typedef ptrdiff_t jit_off_t;
43 typedef intptr_t jit_imm_t;
44 typedef uintptr_t jit_uimm_t;
45
46 typedef struct jit_gpr { uint8_t regno; } jit_gpr_t;
47 typedef struct jit_fpr { uint8_t regno; } jit_fpr_t;
48
49 // Precondition: regno between 0 and 63, inclusive.
50 #define JIT_GPR(regno) ((jit_gpr_t) { regno })
51 #define JIT_FPR(regno) ((jit_fpr_t) { regno })
52
jit_gpr_regno(jit_gpr_t reg)53 static inline uint8_t jit_gpr_regno (jit_gpr_t reg) { return reg.regno; }
jit_fpr_regno(jit_fpr_t reg)54 static inline uint8_t jit_fpr_regno (jit_fpr_t reg) { return reg.regno; }
55
56 static inline jit_bool_t
jit_same_gprs(jit_gpr_t a,jit_gpr_t b)57 jit_same_gprs (jit_gpr_t a, jit_gpr_t b)
58 {
59 return jit_gpr_regno (a) == jit_gpr_regno (b);
60 }
61
62 static inline jit_bool_t
jit_same_fprs(jit_fpr_t a,jit_fpr_t b)63 jit_same_fprs (jit_fpr_t a, jit_fpr_t b)
64 {
65 return jit_fpr_regno (a) == jit_fpr_regno (b);
66 }
67
68 #if defined(__i386__) || defined(__x86_64__)
69 # include "lightening/x86.h"
70 #elif defined(__mips__)
71 # include "lightening/mips.h"
72 #elif defined(__arm__)
73 # include "lightening/arm.h"
74 #elif defined(__ppc__) || defined(__powerpc__)
75 # include "lightening/ppc.h"
76 #elif defined(__aarch64__)
77 # include "lightening/aarch64.h"
78 #elif defined(__s390__) || defined(__s390x__)
79 # include "lightening/s390.h"
80 #endif
81
82 enum jit_reloc_kind
83 {
84 JIT_RELOC_ABSOLUTE,
85 JIT_RELOC_REL8,
86 JIT_RELOC_REL16,
87 JIT_RELOC_REL32,
88 JIT_RELOC_REL64,
89 #ifdef JIT_NEEDS_LITERAL_POOL
90 JIT_RELOC_JMP_WITH_VENEER,
91 JIT_RELOC_JCC_WITH_VENEER,
92 JIT_RELOC_LOAD_FROM_POOL,
93 #endif
94 JIT_RELOC_MASK = 15,
95 JIT_RELOC_FLAG_0 = 16,
96 };
97
98 typedef struct jit_reloc
99 {
100 uint8_t kind;
101 uint8_t inst_start_offset;
102 uint8_t pc_base_offset;
103 uint8_t rsh;
104 uint32_t offset;
105 } jit_reloc_t;
106
107 #if defined(__GNUC__) && (__GNUC__ >= 4)
108 # define JIT_API extern __attribute__ ((__visibility__("hidden")))
109 #else
110 # define JIT_API extern
111 #endif
112
113 typedef struct jit_state jit_state_t;
114
115 enum jit_operand_abi
116 {
117 JIT_OPERAND_ABI_UINT8,
118 JIT_OPERAND_ABI_INT8,
119 JIT_OPERAND_ABI_UINT16,
120 JIT_OPERAND_ABI_INT16,
121 JIT_OPERAND_ABI_UINT32,
122 JIT_OPERAND_ABI_INT32,
123 JIT_OPERAND_ABI_UINT64,
124 JIT_OPERAND_ABI_INT64,
125 JIT_OPERAND_ABI_POINTER,
126 JIT_OPERAND_ABI_FLOAT,
127 JIT_OPERAND_ABI_DOUBLE,
128 JIT_OPERAND_ABI_WORD = CHOOSE_32_64(JIT_OPERAND_ABI_INT32,
129 JIT_OPERAND_ABI_INT64)
130 };
131
132 enum jit_operand_kind
133 {
134 JIT_OPERAND_KIND_IMM,
135 JIT_OPERAND_KIND_GPR,
136 JIT_OPERAND_KIND_FPR,
137 JIT_OPERAND_KIND_MEM
138 };
139
140 typedef struct jit_operand
141 {
142 enum jit_operand_abi abi;
143 enum jit_operand_kind kind;
144 union
145 {
146 intptr_t imm;
147 struct { jit_gpr_t gpr; ptrdiff_t addend; } gpr;
148 jit_fpr_t fpr;
149 struct { jit_gpr_t base; ptrdiff_t offset; ptrdiff_t addend; } mem;
150 } loc;
151 } jit_operand_t;
152
153 static inline jit_operand_t
jit_operand_imm(enum jit_operand_abi abi,intptr_t imm)154 jit_operand_imm (enum jit_operand_abi abi, intptr_t imm)
155 {
156 return (jit_operand_t){ abi, JIT_OPERAND_KIND_IMM, { .imm = imm } };
157 }
158
159 static inline jit_operand_t
jit_operand_gpr_with_addend(enum jit_operand_abi abi,jit_gpr_t gpr,ptrdiff_t addend)160 jit_operand_gpr_with_addend (enum jit_operand_abi abi, jit_gpr_t gpr,
161 ptrdiff_t addend)
162 {
163 return (jit_operand_t){ abi, JIT_OPERAND_KIND_GPR,
164 { .gpr = { gpr, addend } } };
165 }
166
167 static inline jit_operand_t
jit_operand_gpr(enum jit_operand_abi abi,jit_gpr_t gpr)168 jit_operand_gpr (enum jit_operand_abi abi, jit_gpr_t gpr)
169 {
170 return jit_operand_gpr_with_addend (abi, gpr, 0);
171 }
172
173 static inline jit_operand_t
jit_operand_fpr(enum jit_operand_abi abi,jit_fpr_t fpr)174 jit_operand_fpr (enum jit_operand_abi abi, jit_fpr_t fpr)
175 {
176 return (jit_operand_t){ abi, JIT_OPERAND_KIND_FPR, { .fpr = fpr } };
177 }
178
179 static inline jit_operand_t
jit_operand_mem_with_addend(enum jit_operand_abi abi,jit_gpr_t base,ptrdiff_t offset,ptrdiff_t addend)180 jit_operand_mem_with_addend (enum jit_operand_abi abi, jit_gpr_t base,
181 ptrdiff_t offset, ptrdiff_t addend)
182 {
183 return (jit_operand_t){ abi, JIT_OPERAND_KIND_MEM,
184 { .mem = { base, offset, addend } } };
185 }
186
187 static inline jit_operand_t
jit_operand_mem(enum jit_operand_abi abi,jit_gpr_t base,ptrdiff_t offset)188 jit_operand_mem (enum jit_operand_abi abi, jit_gpr_t base, ptrdiff_t offset)
189 {
190 return jit_operand_mem_with_addend (abi, base, offset, 0);
191 }
192
193 static inline jit_operand_t
jit_operand_addi(jit_operand_t op,ptrdiff_t addend)194 jit_operand_addi (jit_operand_t op, ptrdiff_t addend)
195 {
196 switch (op.kind) {
197 case JIT_OPERAND_KIND_GPR:
198 return jit_operand_gpr_with_addend (op.abi, op.loc.gpr.gpr,
199 op.loc.gpr.addend + addend);
200 case JIT_OPERAND_KIND_MEM:
201 return jit_operand_mem_with_addend (op.abi, op.loc.mem.base,
202 op.loc.mem.offset,
203 op.loc.mem.addend + addend);
204 default:
205 abort ();
206 }
207 }
208
209 JIT_API jit_bool_t init_jit(void);
210
211 JIT_API jit_state_t *jit_new_state(void* (*alloc_fn)(size_t),
212 void (*free_fn)(void*));
213 JIT_API void jit_destroy_state(jit_state_t*);
214
215 JIT_API void jit_begin(jit_state_t*, uint8_t*, size_t);
216 JIT_API jit_bool_t jit_has_overflow(jit_state_t*);
217 JIT_API void jit_reset(jit_state_t*);
218 JIT_API void* jit_end(jit_state_t*, size_t*);
219
220 JIT_API void jit_align(jit_state_t*, unsigned);
221
222 JIT_API jit_pointer_t jit_address(jit_state_t*);
223 typedef void (*jit_function_pointer_t)();
224 JIT_API jit_function_pointer_t jit_address_to_function_pointer(jit_pointer_t);
225 JIT_API void jit_patch_here(jit_state_t*, jit_reloc_t);
226 JIT_API void jit_patch_there(jit_state_t*, jit_reloc_t, jit_pointer_t);
227
228 JIT_API void jit_move_operands (jit_state_t *_jit, jit_operand_t *dst,
229 jit_operand_t *src, size_t argc);
230
231 JIT_API size_t jit_align_stack (jit_state_t *_jit, size_t expand);
232 JIT_API void jit_shrink_stack (jit_state_t *_jit, size_t diff);
233
234 JIT_API size_t jit_enter_jit_abi (jit_state_t *_jit,
235 size_t v, size_t vf, size_t frame_size);
236 JIT_API void jit_leave_jit_abi (jit_state_t *_jit,
237 size_t v, size_t vf, size_t frame_size);
238
239 /* Note that all functions that take jit_operand_t args[] use the args
240 as scratch space while shuffling values into position. */
241 JIT_API void jit_calli(jit_state_t *, jit_pointer_t f,
242 size_t argc, jit_operand_t args[]);
243 JIT_API void jit_callr(jit_state_t *, jit_gpr_t f,
244 size_t argc, jit_operand_t args[]);
245 JIT_API void jit_locate_args(jit_state_t*, size_t argc, jit_operand_t args[]);
246 JIT_API void jit_load_args(jit_state_t*, size_t argc, jit_operand_t dst[]);
247
248 static inline void
jit_calli_0(jit_state_t * _jit,jit_pointer_t f)249 jit_calli_0(jit_state_t *_jit, jit_pointer_t f)
250 {
251 return jit_calli(_jit, f, 0, NULL);
252 }
253
254 static inline void
jit_calli_1(jit_state_t * _jit,jit_pointer_t f,jit_operand_t arg)255 jit_calli_1(jit_state_t *_jit, jit_pointer_t f, jit_operand_t arg)
256 {
257 jit_operand_t args[] = { arg };
258 return jit_calli(_jit, f, 1, args);
259 }
260
261 static inline void
jit_calli_2(jit_state_t * _jit,jit_pointer_t f,jit_operand_t a,jit_operand_t b)262 jit_calli_2(jit_state_t *_jit, jit_pointer_t f, jit_operand_t a,
263 jit_operand_t b)
264 {
265 jit_operand_t args[] = { a, b };
266 return jit_calli(_jit, f, 2, args);
267 }
268
269 static inline void
jit_calli_3(jit_state_t * _jit,jit_pointer_t f,jit_operand_t a,jit_operand_t b,jit_operand_t c)270 jit_calli_3(jit_state_t *_jit, jit_pointer_t f, jit_operand_t a,
271 jit_operand_t b, jit_operand_t c)
272 {
273 jit_operand_t args[] = { a, b, c };
274 return jit_calli(_jit, f, 3, args);
275 }
276
277 static inline void
jit_callr_0(jit_state_t * _jit,jit_gpr_t f)278 jit_callr_0(jit_state_t *_jit, jit_gpr_t f)
279 {
280 return jit_callr(_jit, f, 0, NULL);
281 }
282
283 static inline void
jit_callr_1(jit_state_t * _jit,jit_gpr_t f,jit_operand_t arg)284 jit_callr_1(jit_state_t *_jit, jit_gpr_t f, jit_operand_t arg)
285 {
286 jit_operand_t args[] = { arg };
287 return jit_callr(_jit, f, 1, args);
288 }
289
290 static inline void
jit_callr_2(jit_state_t * _jit,jit_gpr_t f,jit_operand_t a,jit_operand_t b)291 jit_callr_2(jit_state_t *_jit, jit_gpr_t f, jit_operand_t a, jit_operand_t b)
292 {
293 jit_operand_t args[] = { a, b };
294 return jit_callr(_jit, f, 2, args);
295 }
296
297 static inline void
jit_callr_3(jit_state_t * _jit,jit_gpr_t f,jit_operand_t a,jit_operand_t b,jit_operand_t c)298 jit_callr_3(jit_state_t *_jit, jit_gpr_t f, jit_operand_t a, jit_operand_t b,
299 jit_operand_t c)
300 {
301 jit_operand_t args[] = { a, b, c };
302 return jit_callr(_jit, f, 3, args);
303 }
304
305 static inline void
jit_load_args_1(jit_state_t * _jit,jit_operand_t a)306 jit_load_args_1(jit_state_t *_jit, jit_operand_t a)
307 {
308 jit_operand_t args[] = { a };
309 return jit_load_args(_jit, 1, args);
310 }
311
312 static inline void
jit_load_args_2(jit_state_t * _jit,jit_operand_t a,jit_operand_t b)313 jit_load_args_2(jit_state_t *_jit, jit_operand_t a, jit_operand_t b)
314 {
315 jit_operand_t args[] = { a, b };
316 return jit_load_args(_jit, 2, args);
317 }
318
319 static inline void
jit_load_args_3(jit_state_t * _jit,jit_operand_t a,jit_operand_t b,jit_operand_t c)320 jit_load_args_3(jit_state_t *_jit, jit_operand_t a, jit_operand_t b,
321 jit_operand_t c)
322 {
323 jit_operand_t args[] = { a, b, c };
324 return jit_load_args(_jit, 3, args);
325 }
326
327 #define JIT_PROTO_0(stem, ret) \
328 ret jit_##stem (jit_state_t* _jit)
329 #define JIT_PROTO_1(stem, ret, ta) \
330 ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a)
331 #define JIT_PROTO_2(stem, ret, ta, tb) \
332 ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a, jit_##tb##_t b)
333 #define JIT_PROTO_3(stem, ret, ta, tb, tc) \
334 ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a, jit_##tb##_t b, jit_##tc##_t c)
335 #define JIT_PROTO_4(stem, ret, ta, tb, tc, td) \
336 ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a, jit_##tb##_t b, jit_##tc##_t c, jit_##td##_t d)
337
338 #define JIT_PROTO_RFF__(stem) JIT_PROTO_2(stem, jit_reloc_t, fpr, fpr)
339 #define JIT_PROTO_RGG__(stem) JIT_PROTO_2(stem, jit_reloc_t, gpr, gpr)
340 #define JIT_PROTO_RG___(stem) JIT_PROTO_1(stem, jit_reloc_t, gpr)
341 #define JIT_PROTO_RGi__(stem) JIT_PROTO_2(stem, jit_reloc_t, gpr, imm)
342 #define JIT_PROTO_RGu__(stem) JIT_PROTO_2(stem, jit_reloc_t, gpr, uimm)
343 #define JIT_PROTO_R____(stem) JIT_PROTO_0(stem, jit_reloc_t)
344 #define JIT_PROTO__FFF_(stem) JIT_PROTO_3(stem, void, fpr, fpr, fpr)
345 #define JIT_PROTO__FF__(stem) JIT_PROTO_2(stem, void, fpr, fpr)
346 #define JIT_PROTO__FGG_(stem) JIT_PROTO_3(stem, void, fpr, gpr, gpr)
347 #define JIT_PROTO__FG__(stem) JIT_PROTO_2(stem, void, fpr, gpr)
348 #define JIT_PROTO__FGo_(stem) JIT_PROTO_3(stem, void, fpr, gpr, off)
349 #define JIT_PROTO__F___(stem) JIT_PROTO_1(stem, void, fpr)
350 #define JIT_PROTO__Fd__(stem) JIT_PROTO_2(stem, void, fpr, float64)
351 #define JIT_PROTO__Ff__(stem) JIT_PROTO_2(stem, void, fpr, float32)
352 #define JIT_PROTO__Fp__(stem) JIT_PROTO_2(stem, void, fpr, pointer)
353 #define JIT_PROTO__GF__(stem) JIT_PROTO_2(stem, void, gpr, fpr)
354 #define JIT_PROTO__GGF_(stem) JIT_PROTO_3(stem, void, gpr, gpr, fpr)
355 #define JIT_PROTO__GGGG(stem) JIT_PROTO_4(stem, void, gpr, gpr, gpr, gpr)
356 #define JIT_PROTO__GGG_(stem) JIT_PROTO_3(stem, void, gpr, gpr, gpr)
357 #define JIT_PROTO__GGGi(stem) JIT_PROTO_4(stem, void, gpr, gpr, gpr, imm)
358 #define JIT_PROTO__GGGu(stem) JIT_PROTO_4(stem, void, gpr, gpr, gpr, uimm)
359 #define JIT_PROTO__GG__(stem) JIT_PROTO_2(stem, void, gpr, gpr)
360 #define JIT_PROTO__GGi_(stem) JIT_PROTO_3(stem, void, gpr, gpr, imm)
361 #define JIT_PROTO__GGo_(stem) JIT_PROTO_3(stem, void, gpr, gpr, off)
362 #define JIT_PROTO__GGu_(stem) JIT_PROTO_3(stem, void, gpr, gpr, uimm)
363 #define JIT_PROTO__G___(stem) JIT_PROTO_1(stem, void, gpr)
364 #define JIT_PROTO__Gi__(stem) JIT_PROTO_2(stem, void, gpr, imm)
365 #define JIT_PROTO__Gp__(stem) JIT_PROTO_2(stem, void, gpr, pointer)
366 #define JIT_PROTO______(stem) JIT_PROTO_0(stem, void)
367 #define JIT_PROTO__i___(stem) JIT_PROTO_1(stem, void, imm)
368 #define JIT_PROTO__oGF_(stem) JIT_PROTO_3(stem, void, off, gpr, fpr)
369 #define JIT_PROTO__oGG_(stem) JIT_PROTO_3(stem, void, off, gpr, gpr)
370 #define JIT_PROTO__pF__(stem) JIT_PROTO_2(stem, void, pointer, fpr)
371 #define JIT_PROTO__pG__(stem) JIT_PROTO_2(stem, void, pointer, gpr)
372 #define JIT_PROTO__p___(stem) JIT_PROTO_1(stem, void, pointer)
373
374 #define FOR_EACH_INSTRUCTION(M) \
375 M(_GGG_, addr) \
376 M(_FFF_, addr_f) \
377 M(_FFF_, addr_d) \
378 M(_GGi_, addi) \
379 M(_GGG_, addcr) \
380 M(_GGi_, addci) \
381 M(_GGG_, addxr) \
382 M(_GGi_, addxi) \
383 M(_GGG_, subr) \
384 M(_FFF_, subr_f) \
385 M(_FFF_, subr_d) \
386 M(_GGi_, subi) \
387 M(_GGG_, subcr) \
388 M(_GGi_, subci) \
389 M(_GGG_, subxr) \
390 M(_GGi_, subxi) \
391 M(_GGG_, mulr) \
392 M(_FFF_, mulr_f) \
393 M(_FFF_, mulr_d) \
394 M(_GGi_, muli) \
395 M(_GGGG, qmulr) \
396 M(_GGGi, qmuli) \
397 M(_GGGG, qmulr_u) \
398 M(_GGGu, qmuli_u) \
399 M(_GGG_, divr) \
400 M(_FFF_, divr_f) \
401 M(_FFF_, divr_d) \
402 M(_GGi_, divi) \
403 M(_GGG_, divr_u) \
404 M(_GGu_, divi_u) \
405 M(_GGGG, qdivr) \
406 M(_GGGi, qdivi) \
407 M(_GGGG, qdivr_u) \
408 M(_GGGu, qdivi_u) \
409 M(_GGG_, remr) \
410 M(_GGi_, remi) \
411 M(_GGG_, remr_u) \
412 M(_GGu_, remi_u) \
413 \
414 M(_GGG_, andr) \
415 M(_GGu_, andi) \
416 M(_GGG_, orr) \
417 M(_GGu_, ori) \
418 M(_GGG_, xorr) \
419 M(_GGu_, xori) \
420 \
421 M(_GGG_, lshr) \
422 M(_GGu_, lshi) \
423 M(_GGG_, rshr) \
424 M(_GGu_, rshi) \
425 M(_GGG_, rshr_u) \
426 M(_GGu_, rshi_u) \
427 \
428 M(_GG__, negr) \
429 M(_GG__, comr) \
430 \
431 M(_GG__, movr) \
432 M(_Gi__, movi) \
433 M(RG___, mov_addr) \
434 M(_GG__, extr_c) \
435 M(_GG__, extr_uc) \
436 M(_GG__, extr_s) \
437 M(_GG__, extr_us) \
438 WHEN_64(M(_GG__, extr_i)) \
439 WHEN_64(M(_GG__, extr_ui)) \
440 \
441 M(_GG__, bswapr_us) \
442 M(_GG__, bswapr_ui) \
443 WHEN_64(M(_GG__, bswapr_ul)) \
444 \
445 M(_GG__, ldr_c) \
446 M(_Gp__, ldi_c) \
447 M(_GG__, ldr_uc) \
448 M(_Gp__, ldi_uc) \
449 M(_GG__, ldr_s) \
450 M(_Gp__, ldi_s) \
451 M(_GG__, ldr_us) \
452 M(_Gp__, ldi_us) \
453 M(_GG__, ldr_i) \
454 M(_Gp__, ldi_i) \
455 WHEN_64(M(_GG__, ldr_ui)) \
456 WHEN_64(M(_Gp__, ldi_ui)) \
457 WHEN_64(M(_GG__, ldr_l)) \
458 WHEN_64(M(_Gp__, ldi_l)) \
459 M(_FG__, ldr_f) \
460 M(_Fp__, ldi_f) \
461 M(_FG__, ldr_d) \
462 M(_Fp__, ldi_d) \
463 \
464 M(_GGG_, ldxr_c) \
465 M(_GGo_, ldxi_c) \
466 M(_GGG_, ldxr_uc) \
467 M(_GGo_, ldxi_uc) \
468 M(_GGG_, ldxr_s) \
469 M(_GGo_, ldxi_s) \
470 M(_GGG_, ldxr_us) \
471 M(_GGo_, ldxi_us) \
472 M(_GGG_, ldxr_i) \
473 M(_GGo_, ldxi_i) \
474 WHEN_64(M(_GGG_, ldxr_ui)) \
475 WHEN_64(M(_GGo_, ldxi_ui)) \
476 WHEN_64(M(_GGG_, ldxr_l)) \
477 WHEN_64(M(_GGo_, ldxi_l)) \
478 M(_FGG_, ldxr_f) \
479 M(_FGo_, ldxi_f) \
480 M(_FGG_, ldxr_d) \
481 M(_FGo_, ldxi_d) \
482 \
483 M(_GG__, ldr_atomic) \
484 M(_GG__, str_atomic) \
485 M(_GGG_, swap_atomic) \
486 M(_GGGG, cas_atomic) \
487 \
488 M(_GG__, str_c) \
489 M(_pG__, sti_c) \
490 M(_GG__, str_s) \
491 M(_pG__, sti_s) \
492 M(_GG__, str_i) \
493 M(_pG__, sti_i) \
494 WHEN_64(M(_GG__, str_l)) \
495 WHEN_64(M(_pG__, sti_l)) \
496 M(_GF__, str_f) \
497 M(_pF__, sti_f) \
498 M(_GF__, str_d) \
499 M(_pF__, sti_d) \
500 \
501 M(_GGG_, stxr_c) \
502 M(_oGG_, stxi_c) \
503 M(_GGG_, stxr_s) \
504 M(_oGG_, stxi_s) \
505 M(_GGG_, stxr_i) \
506 M(_oGG_, stxi_i) \
507 WHEN_64(M(_GGG_, stxr_l)) \
508 WHEN_64(M(_oGG_, stxi_l)) \
509 M(_GGF_, stxr_f) \
510 M(_oGF_, stxi_f) \
511 M(_GGF_, stxr_d) \
512 M(_oGF_, stxi_d) \
513 \
514 M(RGG__, bltr) \
515 M(RFF__, bltr_f) \
516 M(RFF__, bltr_d) \
517 M(RGi__, blti) \
518 M(RGG__, bltr_u) \
519 M(RGu__, blti_u) \
520 M(RGG__, bler) \
521 M(RFF__, bler_f) \
522 M(RFF__, bler_d) \
523 M(RGi__, blei) \
524 M(RGG__, bler_u) \
525 M(RGu__, blei_u) \
526 M(RGG__, beqr) \
527 M(RFF__, beqr_f) \
528 M(RFF__, beqr_d) \
529 M(RGi__, beqi) \
530 M(RGG__, bger) \
531 M(RFF__, bger_f) \
532 M(RFF__, bger_d) \
533 M(RGi__, bgei) \
534 M(RGG__, bger_u) \
535 M(RGu__, bgei_u) \
536 M(RGG__, bgtr) \
537 M(RFF__, bgtr_f) \
538 M(RFF__, bgtr_d) \
539 M(RGi__, bgti) \
540 M(RGG__, bgtr_u) \
541 M(RGu__, bgti_u) \
542 M(RGG__, bner) \
543 M(RFF__, bner_f) \
544 M(RFF__, bner_d) \
545 M(RGi__, bnei) \
546 \
547 M(RFF__, bunltr_f) \
548 M(RFF__, bunltr_d) \
549 M(RFF__, bunler_f) \
550 M(RFF__, bunler_d) \
551 M(RFF__, buneqr_f) \
552 M(RFF__, buneqr_d) \
553 M(RFF__, bunger_f) \
554 M(RFF__, bunger_d) \
555 M(RFF__, bungtr_f) \
556 M(RFF__, bungtr_d) \
557 M(RFF__, bltgtr_f) \
558 M(RFF__, bltgtr_d) \
559 M(RFF__, bordr_f) \
560 M(RFF__, bordr_d) \
561 M(RFF__, bunordr_f) \
562 M(RFF__, bunordr_d) \
563 \
564 M(RGG__, bmsr) \
565 M(RGu__, bmsi) \
566 M(RGG__, bmcr) \
567 M(RGu__, bmci) \
568 \
569 M(RGG__, boaddr) \
570 M(RGi__, boaddi) \
571 M(RGG__, boaddr_u) \
572 M(RGu__, boaddi_u) \
573 M(RGG__, bxaddr) \
574 M(RGi__, bxaddi) \
575 M(RGG__, bxaddr_u) \
576 M(RGu__, bxaddi_u) \
577 M(RGG__, bosubr) \
578 M(RGi__, bosubi) \
579 M(RGG__, bosubr_u) \
580 M(RGu__, bosubi_u) \
581 M(RGG__, bxsubr) \
582 M(RGi__, bxsubi) \
583 M(RGG__, bxsubr_u) \
584 M(RGu__, bxsubi_u) \
585 \
586 M(_G___, jmpr) \
587 M(_p___, jmpi) \
588 M(R____, jmp) \
589 \
590 M(_p___, jmpi_with_link) \
591 M(_____, pop_link_register) \
592 M(_____, push_link_register) \
593 \
594 M(_____, ret) \
595 M(_G___, retr) \
596 M(_F___, retr_f) \
597 M(_F___, retr_d) \
598 M(_i___, reti) \
599 M(_G___, retval_c) \
600 M(_G___, retval_uc) \
601 M(_G___, retval_s) \
602 M(_G___, retval_us) \
603 M(_G___, retval_i) \
604 WHEN_64(M(_G___, retval_ui)) \
605 WHEN_64(M(_G___, retval_l)) \
606 M(_F___, retval_f) \
607 M(_F___, retval_d) \
608 \
609 M(_____, breakpoint) \
610 \
611 M(_FF__, negr_f) \
612 M(_FF__, negr_d) \
613 M(_FF__, absr_f) \
614 M(_FF__, absr_d) \
615 M(_FF__, sqrtr_f) \
616 M(_FF__, sqrtr_d) \
617 \
618 M(_GF__, truncr_f_i) \
619 M(_FG__, extr_f) \
620 M(_FG__, extr_d) \
621 M(_FF__, extr_d_f) \
622 M(_FF__, extr_f_d) \
623 M(_FF__, movr_f) \
624 M(_FF__, movr_d) \
625 M(_Ff__, movi_f) \
626 M(_Fd__, movi_d) \
627 M(_GF__, truncr_d_i) \
628 WHEN_64(M(_GF__, truncr_f_l)) \
629 WHEN_64(M(_GF__, truncr_d_l)) \
630 /* EOL */
631
632 #define DECLARE_INSTRUCTION(kind, stem) JIT_API JIT_PROTO_##kind(stem);
633 FOR_EACH_INSTRUCTION(DECLARE_INSTRUCTION)
634 #undef DECLARE_INSTRUCTION
635
636 #if __WORDSIZE == 32
637 # define jit_ldr(j,u,v) jit_ldr_i(j,u,v)
638 # define jit_ldi(j,u,v) jit_ldi_i(j,u,v)
639 # define jit_ldxr(j,u,v,w) jit_ldxr_i(j,u,v,w)
640 # define jit_ldxi(j,u,v,w) jit_ldxi_i(j,u,v,w)
641 # define jit_str(j,u,v) jit_str_i(j,u,v)
642 # define jit_sti(j,u,v) jit_sti_i(j,u,v)
643 # define jit_stxr(j,u,v,w) jit_stxr_i(j,u,v,w)
644 # define jit_stxi(j,u,v,w) jit_stxi_i(j,u,v,w)
645 # define jit_retval(j,u) jit_retval_i(j,u)
646 # define jit_bswapr(j,u,v) jit_bswapr_ui(j,u,v)
647 # define jit_truncr_d(j,u,v) jit_truncr_d_i(j,u,v)
648 # define jit_truncr_f(j,u,v) jit_truncr_f_i(j,u,v)
649 #else
650 # define jit_ldr(j,u,v) jit_ldr_l(j,u,v)
651 # define jit_ldi(j,u,v) jit_ldi_l(j,u,v)
652 # define jit_ldxr(j,u,v,w) jit_ldxr_l(j,u,v,w)
653 # define jit_ldxi(j,u,v,w) jit_ldxi_l(j,u,v,w)
654 # define jit_str(j,u,v) jit_str_l(j,u,v)
655 # define jit_sti(j,u,v) jit_sti_l(j,u,v)
656 # define jit_stxr(j,u,v,w) jit_stxr_l(j,u,v,w)
657 # define jit_stxi(j,u,v,w) jit_stxi_l(j,u,v,w)
658 # define jit_retval(j,u) jit_retval_l(j,u)
659 # define jit_bswapr(j,u,v) jit_bswapr_ul(j,u,v)
660 # define jit_truncr_d(j,u,v) jit_truncr_d_l(j,u,v)
661 # define jit_truncr_f(j,u,v) jit_truncr_f_l(j,u,v)
662 #endif
663
664 void jit_begin_data(jit_state_t *, size_t max_size_or_zero);
665 void jit_end_data(jit_state_t *);
666 void jit_emit_u8(jit_state_t *, uint8_t);
667 void jit_emit_u16(jit_state_t *, uint16_t);
668 void jit_emit_u32(jit_state_t *, uint32_t);
669 void jit_emit_u64(jit_state_t *, uint64_t);
670 void jit_emit_ptr(jit_state_t *, void *);
671 jit_reloc_t jit_emit_addr(jit_state_t *);
672
673 #endif /* _jit_h */
674