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