2#define REDUCT_OPCODE_H 1
146typedef struct reduct_opcode_info
163#define REDUCT_OPCODE_BASE(_op) ((_op) & ~REDUCT_OPCODE_MODE_CONST)
170#define REDUCT_OPCODE_GET_NAME(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].name)
177#define REDUCT_OPCODE_GET_LAYOUT(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].layout)
184#define REDUCT_OPCODE_IS_COMPARE(_op) \
185 (REDUCT_OPCODE_BASE(_op) >= REDUCT_OPCODE_EQ && REDUCT_OPCODE_BASE(_op) <= REDUCT_OPCODE_GE)
192#define REDUCT_OPCODE_TO_SKIP(_op) \
193 (REDUCT_OPCODE_IS_COMPARE(_op) ? (reduct_opcode_t)((_op) + (REDUCT_OPCODE_JEQ - REDUCT_OPCODE_EQ)) \
201#define REDUCT_OPCODE_INVERT_SKIP(_op) \
202 ((reduct_opcode_t)((REDUCT_OPCODE_BASE(_op) == REDUCT_OPCODE_JEQ ? REDUCT_OPCODE_JNEQ \
203 : REDUCT_OPCODE_BASE(_op) == REDUCT_OPCODE_JNEQ ? REDUCT_OPCODE_JEQ \
204 : REDUCT_OPCODE_BASE(_op) == REDUCT_OPCODE_JLT ? REDUCT_OPCODE_JGE \
205 : REDUCT_OPCODE_BASE(_op) == REDUCT_OPCODE_JGE ? REDUCT_OPCODE_JLT \
206 : REDUCT_OPCODE_BASE(_op) == REDUCT_OPCODE_JLE ? REDUCT_OPCODE_JGT \
207 : REDUCT_OPCODE_BASE(_op) == REDUCT_OPCODE_JGT ? REDUCT_OPCODE_JLE \
209 ((_op) & REDUCT_OPCODE_MODE_CONST)))
216#define REDUCT_OPCODE_TO_RECUR(_op) \
217 (REDUCT_OPCODE_IS_CALL(_op) \
218 ? (reduct_opcode_t)((REDUCT_OPCODE_BASE(_op) == REDUCT_OPCODE_TAILCALL) ? REDUCT_OPCODE_TAILRECUR \
219 : REDUCT_OPCODE_RECUR) \
227#define REDUCT_OPCODE_TO_TAIL(_op) \
228 ((_op) == REDUCT_OPCODE_CALL ? REDUCT_OPCODE_TAILCALL \
229 : (_op) == REDUCT_OPCODE_CALL_CONST ? REDUCT_OPCODE_TAILCALL_CONST \
230 : (_op) == REDUCT_OPCODE_RECUR ? REDUCT_OPCODE_TAILRECUR \
238#define REDUCT_OPCODE_HAS_TARGET(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_HAS_TARGET)
245#define REDUCT_OPCODE_IS_RECUR(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_IS_RECUR)
252#define REDUCT_OPCODE_IS_JUMP(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_IS_JUMP)
259#define REDUCT_OPCODE_HAS_CONST(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_HAS_CONST)
266#define REDUCT_OPCODE_READS_A(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_READ_A)
273#define REDUCT_OPCODE_READS_B(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_READ_B)
280#define REDUCT_OPCODE_READS_C(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_READ_C)
287#define REDUCT_OPCODE_READS_RANGE(_op) \
288 (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_READ_RANGE)
295#define REDUCT_OPCODE_IS_COMMUTATIVE(_op) \
296 (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_IS_COMMUTATIVE)
303#define REDUCT_OPCODE_IS_SKIP(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_IS_SKIP)
310#define REDUCT_OPCODE_IS_BRANCH(_op) \
311 (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & (REDUCT_OPCODE_FLAG_IS_SKIP | REDUCT_OPCODE_FLAG_IS_JUMP))
318#define REDUCT_OPCODE_IS_CALL(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_IS_CALL)
325#define REDUCT_OPCODE_IS_TERMINATOR(_op) \
326 (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_IS_TERMINATOR)
333#define REDUCT_OPCODE_IS_BINARY(_op) \
334 ((reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & (REDUCT_OPCODE_FLAG_READ_B | REDUCT_OPCODE_FLAG_READ_C)) == \
335 (REDUCT_OPCODE_FLAG_READ_B | REDUCT_OPCODE_FLAG_READ_C))
342#define REDUCT_OPCODE_IS_TERNARY(_op) \
343 ((reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & \
344 (REDUCT_OPCODE_FLAG_READ_A | REDUCT_OPCODE_FLAG_READ_B | REDUCT_OPCODE_FLAG_READ_C)) == \
345 (REDUCT_OPCODE_FLAG_READ_A | REDUCT_OPCODE_FLAG_READ_B | REDUCT_OPCODE_FLAG_READ_C))
352#define REDUCT_OPCODE_IS_UNARY(_op) \
353 ((reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & \
354 (REDUCT_OPCODE_FLAG_READ_A | REDUCT_OPCODE_FLAG_READ_B | REDUCT_OPCODE_FLAG_READ_C)) == \
355 REDUCT_OPCODE_FLAG_READ_C)
362#define REDUCT_OPCODE_IS_FORK(_op) (reductOpcodeTable[REDUCT_OPCODE_BASE(_op)].flags & REDUCT_OPCODE_FLAG_IS_FORK)
reduct_opcode_layout_t
Opcode operand layouts.
reduct_opcode_flags_t
Opcode flags.
reduct_opcode_t
Opcode enumeration.
REDUCT_API const reduct_opcode_info_t reductOpcodeTable[128]
Opcode information and flags table.
reduct_opcode_mode_t
Opcode mode enumeration.
@ REDUCT_OPCODE_LAYOUT_AB_RANGE
R(A) B.
@ REDUCT_OPCODE_LAYOUT_C
R/K(C)
@ REDUCT_OPCODE_LAYOUT_AC
R(A) R/K(C)
@ REDUCT_OPCODE_LAYOUT_NONE
No operands.
@ REDUCT_OPCODE_LAYOUT_SAX
sAx, no operands
@ REDUCT_OPCODE_LAYOUT_ABC_RANGE
R(A) B R/K(C)
@ REDUCT_OPCODE_LAYOUT_SAXC
sAx R/K(C)
@ REDUCT_OPCODE_LAYOUT_ABC
R(A) R(B) R/K(C)
@ REDUCT_OPCODE_FLAG_IS_SKIP
Opcode is a skip instruction.
@ REDUCT_OPCODE_FLAG_IS_COMMUTATIVE
Opcode is commutative.
@ REDUCT_OPCODE_FLAG_READ_RANGE
Opcode reads a range of registers starting at A.
@ REDUCT_OPCODE_FLAG_HAS_TARGET
Opcode modifies target register A.
@ REDUCT_OPCODE_FLAG_IS_FORK
Opcode returns a task handle.
@ REDUCT_OPCODE_FLAG_READ_C
Opcode reads from register/constant C.
@ REDUCT_OPCODE_FLAG_IS_CALL
Opcode is a function call.
@ REDUCT_OPCODE_FLAG_IS_JUMP
Opcode is a jump.
@ REDUCT_OPCODE_FLAG_IS_TERMINATOR
Opcode ends basic block reachability.
@ REDUCT_OPCODE_FLAG_HAS_CONST
Opcode uses C operand and has a const version.
@ REDUCT_OPCODE_FLAG_READ_B
Opcode reads from register B.
@ REDUCT_OPCODE_FLAG_IS_RECUR
Opcode is a recursive call.
@ REDUCT_OPCODE_FLAG_READ_A
Opcode reads from register A (or range starting at A).
@ REDUCT_OPCODE_JGE_CONST
@ REDUCT_OPCODE_SUB_CONST
@ REDUCT_OPCODE_DIV
(A, B, C) R(A) = R(B) / R/K(C)
@ REDUCT_OPCODE_JLT_CONST
@ REDUCT_OPCODE_JMPF
(sAx, C) Jump by sAx if R(C) is falsy.
@ REDUCT_OPCODE_JMPT
(sAx, C) Jump by sAx if R(C) is truthy.
@ REDUCT_OPCODE_RECUR
(A, B) Recursively call the current function with B args starting from R(A).
@ REDUCT_OPCODE_DIV_CONST
@ REDUCT_OPCODE_MOD_CONST
@ REDUCT_OPCODE_CLOSURE_CONST
@ REDUCT_OPCODE_SHR
(A, B, C) R(A) = R(B) >> R/K(C)
@ REDUCT_OPCODE_BXOR_CONST
@ REDUCT_OPCODE_BNOT_CONST
@ REDUCT_OPCODE_JEQ_CONST
@ REDUCT_OPCODE_SHL_CONST
@ REDUCT_OPCODE_SHL
(A, B, C) R(A) = R(B) << R/K(C)
@ REDUCT_OPCODE_SUB
(A, B, C) R(A) = R(B) - R/K(C)
@ REDUCT_OPCODE_NEQ
(A, B, C) If R(B) != R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_JNEQ_CONST
@ REDUCT_OPCODE_BOR_CONST
@ REDUCT_OPCODE_MOV
(A, C) Move value in R/K(C) to R(A).
@ REDUCT_OPCODE_JLE_CONST
@ REDUCT_OPCODE_JGT
(B, C) Skip the next instruction if R(B) > R/K(C), else continue.
@ REDUCT_OPCODE_MUL
(A, B, C) R(A) = R(B) * R/K(C)
@ REDUCT_OPCODE_JNEQ
(B, C) Skip the next instruction if R(B) != R/K(C), else continue.
@ REDUCT_OPCODE_ADD
(A, B, C) R(A) = R(B) + R/K(C)
@ REDUCT_OPCODE_JLE
(B, C) Skip the next instruction if R(B) <= R/K(C), else continue.
@ REDUCT_OPCODE_BAND
(A, B, C) R(A) = R(B) & R/K(C)
@ REDUCT_OPCODE_ADD_CONST
@ REDUCT_OPCODE_RET
(C) Return value in R/K(C).
@ REDUCT_OPCODE_CAPTURE_CONST
@ REDUCT_OPCODE_BNOT
(A, C) R(A) = ~R/K(C)
@ REDUCT_OPCODE_BAND_CONST
@ REDUCT_OPCODE_EQ
(A, B, C) If R(B) == R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_SHR_CONST
@ REDUCT_OPCODE_JOIN
(A, C) Wait for task handle in R(C) to complete, result stored in R(A).
@ REDUCT_OPCODE_CALL
(A, B, C) Call callable in R/K(C) with B args starting from R(A). Result in R(A).
@ REDUCT_OPCODE_GT
(A, B, C) If R(B) > R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_JMP
(sAx) Unconditional jump by relative offset sAx.
@ REDUCT_OPCODE_FORK_CONST
@ REDUCT_OPCODE_NOP
No operation.
@ REDUCT_OPCODE_MOV_CONST
@ REDUCT_OPCODE_GE
(A, B, C) If R(B) >= R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_JGE
(B, C) Skip the next instruction if R(B) >= R/K(C), else continue.
@ REDUCT_OPCODE_BOR
(A, B, C) R(A) = R(B) | R/K(C)
@ REDUCT_OPCODE_CLOSURE
(A, C) Wrap the function prototype in K(C) in a closure and store in R(A).
@ REDUCT_OPCODE_JEQ
(B, C) Skip the next instruction if R(B) == R/K(C), else continue.
@ REDUCT_OPCODE_CALL_CONST
@ REDUCT_OPCODE_LE
(A, B, C) If R(B) <= R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_TAILCALL_CONST
@ REDUCT_OPCODE_LIST
(A, B) R(A) = (R(A) R(A + 1) ... R(A + B - 1))
@ REDUCT_OPCODE_JOIN_CONST
@ REDUCT_OPCODE_TAILCALL
(A, B, C) Tail call callable in R/K(C) with B args starting from R(A).
@ REDUCT_OPCODE_TAILRECUR
(A, B) Recursively tail call the current function with B args starting from R(A).
@ REDUCT_OPCODE_BXOR
(A, B, C) R(A) = R(B) ^ R/K(C)
@ REDUCT_OPCODE_CAPTURE
(A, B, C) Capture R/K(C) into constant slot B in closure R(A).
@ REDUCT_OPCODE_JLT
(B, C) Skip the next instruction if R(B) < R/K(C), else continue.
@ REDUCT_OPCODE_MOD
(A, B, C) R(A) = R(B) % R/K(C)
@ REDUCT_OPCODE_JGT_CONST
@ REDUCT_OPCODE_LT
(A, B, C) If R(B) < R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_MUL_CONST
@ REDUCT_OPCODE_RET_CONST
@ REDUCT_OPCODE_NEQ_CONST
@ REDUCT_OPCODE_MODE_REG
Register operand mode.
@ REDUCT_OPCODE_MODE_CONST
Constant operand mode.
Opcode information structure.
reduct_opcode_flags_t flags
reduct_opcode_layout_t layout