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