lj_bc.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. ** Bytecode instruction format.
  3. ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
  4. */
  5. #ifndef _LJ_BC_H
  6. #define _LJ_BC_H
  7. #include "lj_def.h"
  8. #include "lj_arch.h"
  9. /* Bytecode instruction format, 32 bit wide, fields of 8 or 16 bit:
  10. **
  11. ** +----+----+----+----+
  12. ** | B | C | A | OP | Format ABC
  13. ** +----+----+----+----+
  14. ** | D | A | OP | Format AD
  15. ** +--------------------
  16. ** MSB LSB
  17. **
  18. ** In-memory instructions are always stored in host byte order.
  19. */
  20. /* Operand ranges and related constants. */
  21. #define BCMAX_A 0xff
  22. #define BCMAX_B 0xff
  23. #define BCMAX_C 0xff
  24. #define BCMAX_D 0xffff
  25. #define BCBIAS_J 0x8000
  26. #define NO_REG BCMAX_A
  27. #define NO_JMP (~(BCPos)0)
  28. /* Macros to get instruction fields. */
  29. #define bc_op(i) ((BCOp)((i)&0xff))
  30. #define bc_a(i) ((BCReg)(((i)>>8)&0xff))
  31. #define bc_b(i) ((BCReg)((i)>>24))
  32. #define bc_c(i) ((BCReg)(((i)>>16)&0xff))
  33. #define bc_d(i) ((BCReg)((i)>>16))
  34. #define bc_j(i) ((ptrdiff_t)bc_d(i)-BCBIAS_J)
  35. /* Macros to set instruction fields. */
  36. #define setbc_byte(p, x, ofs) \
  37. ((uint8_t *)(p))[LJ_ENDIAN_SELECT(ofs, 3-ofs)] = (uint8_t)(x)
  38. #define setbc_op(p, x) setbc_byte(p, (x), 0)
  39. #define setbc_a(p, x) setbc_byte(p, (x), 1)
  40. #define setbc_b(p, x) setbc_byte(p, (x), 3)
  41. #define setbc_c(p, x) setbc_byte(p, (x), 2)
  42. #define setbc_d(p, x) \
  43. ((uint16_t *)(p))[LJ_ENDIAN_SELECT(1, 0)] = (uint16_t)(x)
  44. #define setbc_j(p, x) setbc_d(p, (BCPos)((int32_t)(x)+BCBIAS_J))
  45. /* Macros to compose instructions. */
  46. #define BCINS_ABC(o, a, b, c) \
  47. (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(b)<<24)|((BCIns)(c)<<16))
  48. #define BCINS_AD(o, a, d) \
  49. (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(d)<<16))
  50. #define BCINS_AJ(o, a, j) BCINS_AD(o, a, (BCPos)((int32_t)(j)+BCBIAS_J))
  51. /* Bytecode instruction definition. Order matters, see below.
  52. **
  53. ** (name, filler, Amode, Bmode, Cmode or Dmode, metamethod)
  54. **
  55. ** The opcode name suffixes specify the type for RB/RC or RD:
  56. ** V = variable slot
  57. ** S = string const
  58. ** N = number const
  59. ** P = primitive type (~itype)
  60. ** B = unsigned byte literal
  61. ** M = multiple args/results
  62. */
  63. #define BCDEF(_) \
  64. /* Comparison ops. ORDER OPR. */ \
  65. _(ISLT, var, ___, var, lt) \
  66. _(ISGE, var, ___, var, lt) \
  67. _(ISLE, var, ___, var, le) \
  68. _(ISGT, var, ___, var, le) \
  69. \
  70. _(ISEQV, var, ___, var, eq) \
  71. _(ISNEV, var, ___, var, eq) \
  72. _(ISEQS, var, ___, str, eq) \
  73. _(ISNES, var, ___, str, eq) \
  74. _(ISEQN, var, ___, num, eq) \
  75. _(ISNEN, var, ___, num, eq) \
  76. _(ISEQP, var, ___, pri, eq) \
  77. _(ISNEP, var, ___, pri, eq) \
  78. \
  79. /* Unary test and copy ops. */ \
  80. _(ISTC, dst, ___, var, ___) \
  81. _(ISFC, dst, ___, var, ___) \
  82. _(IST, ___, ___, var, ___) \
  83. _(ISF, ___, ___, var, ___) \
  84. _(ISTYPE, var, ___, lit, ___) \
  85. _(ISNUM, var, ___, lit, ___) \
  86. \
  87. /* Unary ops. */ \
  88. _(MOV, dst, ___, var, ___) \
  89. _(NOT, dst, ___, var, ___) \
  90. _(UNM, dst, ___, var, unm) \
  91. _(LEN, dst, ___, var, len) \
  92. \
  93. /* Binary ops. ORDER OPR. VV last, POW must be next. */ \
  94. _(ADDVN, dst, var, num, add) \
  95. _(SUBVN, dst, var, num, sub) \
  96. _(MULVN, dst, var, num, mul) \
  97. _(DIVVN, dst, var, num, div) \
  98. _(MODVN, dst, var, num, mod) \
  99. \
  100. _(ADDNV, dst, var, num, add) \
  101. _(SUBNV, dst, var, num, sub) \
  102. _(MULNV, dst, var, num, mul) \
  103. _(DIVNV, dst, var, num, div) \
  104. _(MODNV, dst, var, num, mod) \
  105. \
  106. _(ADDVV, dst, var, var, add) \
  107. _(SUBVV, dst, var, var, sub) \
  108. _(MULVV, dst, var, var, mul) \
  109. _(DIVVV, dst, var, var, div) \
  110. _(MODVV, dst, var, var, mod) \
  111. \
  112. _(POW, dst, var, var, pow) \
  113. _(CAT, dst, rbase, rbase, concat) \
  114. \
  115. /* Constant ops. */ \
  116. _(KSTR, dst, ___, str, ___) \
  117. _(KCDATA, dst, ___, cdata, ___) \
  118. _(KSHORT, dst, ___, lits, ___) \
  119. _(KNUM, dst, ___, num, ___) \
  120. _(KPRI, dst, ___, pri, ___) \
  121. _(KNIL, base, ___, base, ___) \
  122. \
  123. /* Upvalue and function ops. */ \
  124. _(UGET, dst, ___, uv, ___) \
  125. _(USETV, uv, ___, var, ___) \
  126. _(USETS, uv, ___, str, ___) \
  127. _(USETN, uv, ___, num, ___) \
  128. _(USETP, uv, ___, pri, ___) \
  129. _(UCLO, rbase, ___, jump, ___) \
  130. _(FNEW, dst, ___, func, gc) \
  131. \
  132. /* Table ops. */ \
  133. _(TNEW, dst, ___, lit, gc) \
  134. _(TDUP, dst, ___, tab, gc) \
  135. _(GGET, dst, ___, str, index) \
  136. _(GSET, var, ___, str, newindex) \
  137. _(TGETV, dst, var, var, index) \
  138. _(TGETS, dst, var, str, index) \
  139. _(TGETB, dst, var, lit, index) \
  140. _(TGETR, dst, var, var, index) \
  141. _(TSETV, var, var, var, newindex) \
  142. _(TSETS, var, var, str, newindex) \
  143. _(TSETB, var, var, lit, newindex) \
  144. _(TSETM, base, ___, num, newindex) \
  145. _(TSETR, var, var, var, newindex) \
  146. \
  147. /* Calls and vararg handling. T = tail call. */ \
  148. _(CALLM, base, lit, lit, call) \
  149. _(CALL, base, lit, lit, call) \
  150. _(CALLMT, base, ___, lit, call) \
  151. _(CALLT, base, ___, lit, call) \
  152. _(ITERC, base, lit, lit, call) \
  153. _(ITERN, base, lit, lit, call) \
  154. _(VARG, base, lit, lit, ___) \
  155. _(ISNEXT, base, ___, jump, ___) \
  156. \
  157. /* Returns. */ \
  158. _(RETM, base, ___, lit, ___) \
  159. _(RET, rbase, ___, lit, ___) \
  160. _(RET0, rbase, ___, lit, ___) \
  161. _(RET1, rbase, ___, lit, ___) \
  162. \
  163. /* Loops and branches. I/J = interp/JIT, I/C/L = init/call/loop. */ \
  164. _(FORI, base, ___, jump, ___) \
  165. _(JFORI, base, ___, jump, ___) \
  166. \
  167. _(FORL, base, ___, jump, ___) \
  168. _(IFORL, base, ___, jump, ___) \
  169. _(JFORL, base, ___, lit, ___) \
  170. \
  171. _(ITERL, base, ___, jump, ___) \
  172. _(IITERL, base, ___, jump, ___) \
  173. _(JITERL, base, ___, lit, ___) \
  174. \
  175. _(LOOP, rbase, ___, jump, ___) \
  176. _(ILOOP, rbase, ___, jump, ___) \
  177. _(JLOOP, rbase, ___, lit, ___) \
  178. \
  179. _(JMP, rbase, ___, jump, ___) \
  180. \
  181. /* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \
  182. _(FUNCF, rbase, ___, ___, ___) \
  183. _(IFUNCF, rbase, ___, ___, ___) \
  184. _(JFUNCF, rbase, ___, lit, ___) \
  185. _(FUNCV, rbase, ___, ___, ___) \
  186. _(IFUNCV, rbase, ___, ___, ___) \
  187. _(JFUNCV, rbase, ___, lit, ___) \
  188. _(FUNCC, rbase, ___, ___, ___) \
  189. _(FUNCCW, rbase, ___, ___, ___)
  190. /* Bytecode opcode numbers. */
  191. typedef enum {
  192. #define BCENUM(name, ma, mb, mc, mt) BC_##name,
  193. BCDEF(BCENUM)
  194. #undef BCENUM
  195. BC__MAX
  196. } BCOp;
  197. LJ_STATIC_ASSERT((int)BC_ISEQV+1 == (int)BC_ISNEV);
  198. LJ_STATIC_ASSERT(((int)BC_ISEQV^1) == (int)BC_ISNEV);
  199. LJ_STATIC_ASSERT(((int)BC_ISEQS^1) == (int)BC_ISNES);
  200. LJ_STATIC_ASSERT(((int)BC_ISEQN^1) == (int)BC_ISNEN);
  201. LJ_STATIC_ASSERT(((int)BC_ISEQP^1) == (int)BC_ISNEP);
  202. LJ_STATIC_ASSERT(((int)BC_ISLT^1) == (int)BC_ISGE);
  203. LJ_STATIC_ASSERT(((int)BC_ISLE^1) == (int)BC_ISGT);
  204. LJ_STATIC_ASSERT(((int)BC_ISLT^3) == (int)BC_ISGT);
  205. LJ_STATIC_ASSERT((int)BC_IST-(int)BC_ISTC == (int)BC_ISF-(int)BC_ISFC);
  206. LJ_STATIC_ASSERT((int)BC_CALLT-(int)BC_CALL == (int)BC_CALLMT-(int)BC_CALLM);
  207. LJ_STATIC_ASSERT((int)BC_CALLMT + 1 == (int)BC_CALLT);
  208. LJ_STATIC_ASSERT((int)BC_RETM + 1 == (int)BC_RET);
  209. LJ_STATIC_ASSERT((int)BC_FORL + 1 == (int)BC_IFORL);
  210. LJ_STATIC_ASSERT((int)BC_FORL + 2 == (int)BC_JFORL);
  211. LJ_STATIC_ASSERT((int)BC_ITERL + 1 == (int)BC_IITERL);
  212. LJ_STATIC_ASSERT((int)BC_ITERL + 2 == (int)BC_JITERL);
  213. LJ_STATIC_ASSERT((int)BC_LOOP + 1 == (int)BC_ILOOP);
  214. LJ_STATIC_ASSERT((int)BC_LOOP + 2 == (int)BC_JLOOP);
  215. LJ_STATIC_ASSERT((int)BC_FUNCF + 1 == (int)BC_IFUNCF);
  216. LJ_STATIC_ASSERT((int)BC_FUNCF + 2 == (int)BC_JFUNCF);
  217. LJ_STATIC_ASSERT((int)BC_FUNCV + 1 == (int)BC_IFUNCV);
  218. LJ_STATIC_ASSERT((int)BC_FUNCV + 2 == (int)BC_JFUNCV);
  219. /* This solves a circular dependency problem, change as needed. */
  220. #define FF_next_N 4
  221. /* Stack slots used by FORI/FORL, relative to operand A. */
  222. enum {
  223. FORL_IDX, FORL_STOP, FORL_STEP, FORL_EXT
  224. };
  225. /* Bytecode operand modes. ORDER BCMode */
  226. typedef enum {
  227. BCMnone, BCMdst, BCMbase, BCMvar, BCMrbase, BCMuv, /* Mode A must be <= 7 */
  228. BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc, BCMjump, BCMcdata,
  229. BCM_max
  230. } BCMode;
  231. #define BCM___ BCMnone
  232. #define bcmode_a(op) ((BCMode)(lj_bc_mode[op] & 7))
  233. #define bcmode_b(op) ((BCMode)((lj_bc_mode[op]>>3) & 15))
  234. #define bcmode_c(op) ((BCMode)((lj_bc_mode[op]>>7) & 15))
  235. #define bcmode_d(op) bcmode_c(op)
  236. #define bcmode_hasd(op) ((lj_bc_mode[op] & (15<<3)) == (BCMnone<<3))
  237. #define bcmode_mm(op) ((MMS)(lj_bc_mode[op]>>11))
  238. #define BCMODE(name, ma, mb, mc, mm) \
  239. (BCM##ma|(BCM##mb<<3)|(BCM##mc<<7)|(MM_##mm<<11)),
  240. #define BCMODE_FF 0
  241. static LJ_AINLINE int bc_isret(BCOp op)
  242. {
  243. return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
  244. }
  245. LJ_DATA const uint16_t lj_bc_mode[];
  246. LJ_DATA const uint16_t lj_bc_ofs[];
  247. #endif