lightening.h 20 KB

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