92#define REDUCT_REG_INVALID ((reduct_reg_t) - 1)
99#define REDUCT_INST_WIDTH_OPCODE 6ULL
100#define REDUCT_INST_WIDTH_A 8ULL
101#define REDUCT_INST_WIDTH_B 8ULL
102#define REDUCT_INST_WIDTH_C 10ULL
103#define REDUCT_INST_WIDTH_SBX (REDUCT_INST_WIDTH_B + REDUCT_INST_WIDTH_C)
108#define REDUCT_REGISTER_MAX (1ULL << REDUCT_INST_WIDTH_A)
112#define REDUCT_CONSTANT_MAX (1ULL << REDUCT_INST_WIDTH_C)
114#define REDUCT_INST_POS_OPCODE 0ULL
115#define REDUCT_INST_POS_A (REDUCT_INST_POS_OPCODE + REDUCT_INST_WIDTH_OPCODE)
116#define REDUCT_INST_POS_B (REDUCT_INST_POS_A + REDUCT_INST_WIDTH_A)
117#define REDUCT_INST_POS_C (REDUCT_INST_POS_B + REDUCT_INST_WIDTH_B)
119#define REDUCT_INST_MASK_OPCODE ((1ULL << REDUCT_INST_WIDTH_OPCODE) - 1ULL)
120#define REDUCT_INST_MASK_A ((1ULL << REDUCT_INST_WIDTH_A) - 1ULL)
121#define REDUCT_INST_MASK_B ((1ULL << REDUCT_INST_WIDTH_B) - 1ULL)
122#define REDUCT_INST_MASK_C ((1ULL << REDUCT_INST_WIDTH_C) - 1ULL)
123#define REDUCT_INST_MASK_SBX ((1ULL << REDUCT_INST_WIDTH_SBX) - 1ULL)
133#define REDUCT_INST_MAKE_ABC(_op, _a, _b, _c) \
134 ((((reduct_inst_t)(_op)) & REDUCT_INST_MASK_OPCODE) << REDUCT_INST_POS_OPCODE | \
135 (((reduct_inst_t)(_a)) & REDUCT_INST_MASK_A) << REDUCT_INST_POS_A | \
136 (((reduct_inst_t)(_b)) & REDUCT_INST_MASK_B) << REDUCT_INST_POS_B | \
137 (((reduct_inst_t)(_c)) & REDUCT_INST_MASK_C) << REDUCT_INST_POS_C)
146#define REDUCT_INST_MAKE_ASBX(_op, _a, _sbx) \
147 ((((reduct_inst_t)(_op)) & REDUCT_INST_MASK_OPCODE) << REDUCT_INST_POS_OPCODE | \
148 (((reduct_inst_t)(_a)) & REDUCT_INST_MASK_A) << REDUCT_INST_POS_A | \
149 (((reduct_inst_t)(_sbx)) & REDUCT_INST_MASK_SBX) << REDUCT_INST_POS_B)
156#define REDUCT_INST_GET_OP(_inst) (((_inst) >> REDUCT_INST_POS_OPCODE) & REDUCT_INST_MASK_OPCODE)
163#define REDUCT_INST_GET_OP_BASE(_inst) \
164 (((_inst) >> REDUCT_INST_POS_OPCODE) & (REDUCT_INST_MASK_OPCODE & ~REDUCT_MODE_CONST))
171#define REDUCT_INST_GET_A(_inst) (((_inst) >> REDUCT_INST_POS_A) & REDUCT_INST_MASK_A)
178#define REDUCT_INST_GET_B(_inst) (((_inst) >> REDUCT_INST_POS_B) & REDUCT_INST_MASK_B)
185#define REDUCT_INST_GET_C(_inst) (((_inst) >> REDUCT_INST_POS_C) & REDUCT_INST_MASK_C)
192#define REDUCT_INST_GET_SBX(_inst) \
193 ((reduct_int64_t)(((_inst) >> REDUCT_INST_POS_B) & REDUCT_INST_MASK_SBX) << (32ULL - REDUCT_INST_WIDTH_SBX) >> \
194 (32ULL - REDUCT_INST_WIDTH_SBX))
202#define REDUCT_INST_SET_A(_inst, _a) \
203 (((_inst) & ~(REDUCT_INST_MASK_A << REDUCT_INST_POS_A)) | (((_a) & REDUCT_INST_MASK_A) << REDUCT_INST_POS_A))
211#define REDUCT_INST_SET_SBX(_inst, _sbx) \
212 (((_inst) & ~(REDUCT_INST_MASK_SBX << REDUCT_INST_POS_B)) | (((_sbx) & REDUCT_INST_MASK_SBX) << REDUCT_INST_POS_B))
reduct_mode_t
Opcode mode enumeration.
reduct_opcode_t
Opcode enumeration.
reduct_uint32_t reduct_inst_t
Instruction type.
reduct_uint16_t reduct_reg_t
Register type.
@ REDUCT_MODE_REG
Register operand mode.
@ REDUCT_MODE_NONE
Invalid mode.
@ REDUCT_MODE_CONST
Constant operand mode.
@ REDUCT_MODE_TARGET
Compilation target hint mode.
@ REDUCT_OPCODE_DIV
(A, B, C) R(A) = R(B) / R/K(C)
@ REDUCT_OPCODE_JMPF
(A, sBx) Jump by sBx if R(A) is falsy.
@ REDUCT_OPCODE_JMPT
(A, sBx) Jump by sBx if R(A) is truthy.
@ REDUCT_OPCODE_APPEND
(A, C) Append value in R/K(C) to the back of the list in R(A).
@ REDUCT_OPCODE_SHR
(A, B, C) R(A) = R(B) >> R/K(C)
@ REDUCT_OPCODE_SEQ
(A, B, C) If R(B) === R/K(C) store true in R(A), else false.
@ 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_MOV
(A, C) Move value in R/K(C) to R(A).
@ REDUCT_OPCODE_MUL
(A, B, C) R(A) = R(B) * R/K(C)
@ REDUCT_OPCODE_ADD
(A, B, C) R(A) = R(B) + R/K(C)
@ REDUCT_OPCODE_BAND
(A, B, C) R(A) = R(B) & R/K(C)
@ REDUCT_OPCODE_RET
(C) Return value in R/K(C).
@ REDUCT_OPCODE_BNOT
(A, C) R(A) = ~R/K(C)
@ REDUCT_OPCODE_EQ
(A, B, C) If R(B) == R/K(C) store true in R(A), else false.
@ 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
(sBx) Unconditional jump by relative offset sBx.
@ REDUCT_OPCODE_SNEQ
(A, B, C) If R(B) !== R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_GE
(A, B, C) If R(B) >= R/K(C) store true in R(A), else false.
@ 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
(A, C) Skip the next instruction if R(A) == R/K(C), else continue.
@ REDUCT_OPCODE_LE
(A, B, C) If R(B) <= R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_LIST
(A) Create a new list and store it in R(A).
@ REDUCT_OPCODE_TAILCALL
(A, B, C) Tail call callable in R/K(C) 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_MOD
(A, B, C) R(A) = R(B) % R/K(C)
@ REDUCT_OPCODE_LT
(A, B, C) If R(B) < R/K(C) store true in R(A), else false.