Reduct
v4.0.5-1-g4851deb
A functional and immutable language.
Theme:
Default
Round
Robot
Loading...
Searching...
No Matches
inst.h
Go to the documentation of this file.
1
#ifndef REDUCT_INST_H
2
#define REDUCT_INST_H 1
3
4
#include <
reduct/defs.h
>
5
#include <
reduct/opcode.h
>
6
7
/**
8
* @file inst.h
9
* @brief Bytecode instruction format.
10
* @defgroup inst Instruction Format
11
*
12
* Instructions are 32-bit words with the following formats:
13
*
14
* - iABC: [ Opcode:8 | A:8 | B:8 | C:8 ]
15
* - iSAxC: [ Opcode:8 | sAx:16 | C:8 ]
16
*
17
* Fields:
18
* - A: Usually the target/destination register.
19
* - B: Usually the first operand (register).
20
* - C: Usually the second operand (register or constant).
21
* - sAx: Signed offsets for jumps.
22
*
23
* To determine if the C field is a register or a constant the `reduct_mode_t` flags are used to modify the opcode.
24
*
25
* @note The reason we avoid formats such as iABx, used within Lua, is that even if it increases the maximum constant
26
* capacity it means that operations such as `REDUCT_OPCODE_EQUAL` always need to act on registers, which introduces
27
* unnecessary `MOV` instructions to load constants into registers before they can be compared.
28
*
29
* @{
30
*/
31
32
/**
33
* @brief Constant index type.
34
* @typedef reduct_const_t
35
*/
36
typedef
uint16_t
reduct_const_t
;
37
38
/**
39
* @brief Register type.
40
*/
41
typedef
uint16_t
reduct_reg_t
;
42
43
/**
44
* @brief Invalid register value.
45
*/
46
#define REDUCT_REGISTER_INVALID ((reduct_reg_t) - 1)
47
48
/**
49
* @brief Instruction type.
50
* @typedef reduct_inst_t
51
*/
52
typedef
uint32_t
reduct_inst_t
;
53
54
/**
55
* @brief Check if an instruction reads from a specific register.
56
*
57
* @param _inst The instruction.
58
* @param _reg The register index.
59
*/
60
#define REDUCT_INST_READS_REG(_inst, _reg) \
61
((REDUCT_OPCODE_READS_A(REDUCT_INST_GET_OP(_inst)) && (_reg) == REDUCT_INST_GET_A(_inst)) || \
62
(REDUCT_OPCODE_READS_B(REDUCT_INST_GET_OP(_inst)) && (_reg) == REDUCT_INST_GET_B(_inst)) || \
63
(REDUCT_OPCODE_READS_C(REDUCT_INST_GET_OP(_inst)) && (_reg) == REDUCT_INST_GET_C(_inst)) || \
64
(REDUCT_OPCODE_READS_RANGE(REDUCT_INST_GET_OP(_inst)) && (_reg) >= REDUCT_INST_GET_A(_inst) && \
65
(_reg) < REDUCT_INST_GET_A(_inst) + REDUCT_INST_GET_B(_inst)))
66
67
/**
68
* @brief Check if an instruction writes to a specific register.
69
*
70
* @param _inst The instruction.
71
* @param _reg The register index.
72
*/
73
#define REDUCT_INST_WRITES_REG(_inst, _reg) \
74
(REDUCT_OPCODE_HAS_TARGET(REDUCT_INST_GET_OP(_inst)) && (_reg) == REDUCT_INST_GET_A(_inst))
75
76
#define REDUCT_INST_WIDTH_OPCODE 8U
///< Opcode width in bits.
77
#define REDUCT_INST_WIDTH_A 8U
///< A operand width in bits.
78
#define REDUCT_INST_WIDTH_B 8U
///< B operand width in bits.
79
#define REDUCT_INST_WIDTH_C 8U
///< C operand width in bits.
80
#define REDUCT_INST_WIDTH_SAX (REDUCT_INST_WIDTH_A + REDUCT_INST_WIDTH_B)
///< SAx operand width in bits.
81
82
/**
83
* @brief The max number of registers per function frame.
84
*/
85
#define REDUCT_REGISTER_MAX (1U << REDUCT_INST_WIDTH_A)
86
/**
87
* @brief The max number of constants per function.
88
*/
89
#define REDUCT_CONSTANT_MAX (1U << REDUCT_INST_WIDTH_C)
90
91
#define REDUCT_INST_POS_OPCODE 0U
///< Opcode position in bits.
92
#define REDUCT_INST_POS_A (REDUCT_INST_POS_OPCODE + REDUCT_INST_WIDTH_OPCODE)
///< A operand position in bits.
93
#define REDUCT_INST_POS_B (REDUCT_INST_POS_A + REDUCT_INST_WIDTH_A)
///< B operand position in bits.
94
#define REDUCT_INST_POS_C (REDUCT_INST_POS_B + REDUCT_INST_WIDTH_B)
///< C operand position in bits.
95
#define REDUCT_INST_POS_SAX (REDUCT_INST_POS_A)
///< SAx operand position in bits.
96
97
#define REDUCT_INST_MASK_OPCODE ((1U << REDUCT_INST_WIDTH_OPCODE) - 1U)
///< Opcode mask.
98
#define REDUCT_INST_MASK_A ((1U << REDUCT_INST_WIDTH_A) - 1U)
///< A operand mask.
99
#define REDUCT_INST_MASK_B ((1U << REDUCT_INST_WIDTH_B) - 1U)
///< B operand mask.
100
#define REDUCT_INST_MASK_C ((1U << REDUCT_INST_WIDTH_C) - 1U)
///< C operand mask.
101
#define REDUCT_INST_MASK_SAX ((1U << REDUCT_INST_WIDTH_SAX) - 1U)
///< SAx operand mask.
102
103
/**
104
* @brief Create an instruction with opcode, A, B, and C operands.
105
*
106
* @param _op Opcode operand.
107
* @param _a A operand.
108
* @param _b B operand.
109
* @param _c C operand.
110
*/
111
#define REDUCT_INST_MAKE_ABC(_op, _a, _b, _c) \
112
((((reduct_inst_t)(_op)) & REDUCT_INST_MASK_OPCODE) << REDUCT_INST_POS_OPCODE | \
113
(((reduct_inst_t)(_a)) & REDUCT_INST_MASK_A) << REDUCT_INST_POS_A | \
114
(((reduct_inst_t)(_b)) & REDUCT_INST_MASK_B) << REDUCT_INST_POS_B | \
115
(((reduct_inst_t)(_c)) & REDUCT_INST_MASK_C) << REDUCT_INST_POS_C)
116
117
/**
118
* @brief Create an instruction with opcode and SAx operand, and C operand.
119
*
120
* @param _op Opcode operand.
121
* @param _sax SAx operand.
122
* @param _c C operand.
123
*/
124
#define REDUCT_INST_MAKE_SAXC(_op, _sax, _c) \
125
((((reduct_inst_t)(_op)) & REDUCT_INST_MASK_OPCODE) << REDUCT_INST_POS_OPCODE | \
126
(((reduct_inst_t)(_sax)) & REDUCT_INST_MASK_SAX) << REDUCT_INST_POS_A | \
127
(((reduct_inst_t)(_c)) & REDUCT_INST_MASK_C) << REDUCT_INST_POS_C)
128
129
/**
130
* @brief Get the opcode from an instruction.
131
*
132
* @param _inst Instruction.
133
*/
134
#define REDUCT_INST_GET_OP(_inst) (((_inst) >> REDUCT_INST_POS_OPCODE) & REDUCT_INST_MASK_OPCODE)
135
136
/**
137
* @brief Get the A operand from an instruction.
138
*
139
* @param _inst Instruction.
140
*/
141
#define REDUCT_INST_GET_A(_inst) (((_inst) >> REDUCT_INST_POS_A) & REDUCT_INST_MASK_A)
142
143
/**
144
* @brief Get the B operand from an instruction.
145
*
146
* @param _inst Instruction.
147
*/
148
#define REDUCT_INST_GET_B(_inst) (((_inst) >> REDUCT_INST_POS_B) & REDUCT_INST_MASK_B)
149
150
/**
151
* @brief Get the C operand from an instruction.
152
*
153
* @param _inst Instruction.
154
*/
155
#define REDUCT_INST_GET_C(_inst) (((_inst) >> REDUCT_INST_POS_C) & REDUCT_INST_MASK_C)
156
157
/**
158
* @brief Get the SAX operand from an instruction.
159
*
160
* @param _inst Instruction.
161
*/
162
#define REDUCT_INST_GET_SAX(_inst) ((int32_t)(int16_t)(((_inst) >> REDUCT_INST_POS_SAX) & REDUCT_INST_MASK_SAX))
163
164
/**
165
* @brief Set the opcode in an instruction.
166
*
167
* @param _inst Instruction.
168
* @param _op Opcode value.
169
*/
170
#define REDUCT_INST_SET_OP(_inst, _op) \
171
(((_inst) & ~(REDUCT_INST_MASK_OPCODE << REDUCT_INST_POS_OPCODE)) | \
172
(((_op) & REDUCT_INST_MASK_OPCODE) << REDUCT_INST_POS_OPCODE))
173
174
/**
175
* @brief Set the A operand in an instruction.
176
*
177
* @param _inst Instruction.
178
* @param _a A operand value.
179
*/
180
#define REDUCT_INST_SET_A(_inst, _a) \
181
(((_inst) & ~(REDUCT_INST_MASK_A << REDUCT_INST_POS_A)) | (((_a) & REDUCT_INST_MASK_A) << REDUCT_INST_POS_A))
182
183
/**
184
* @brief Set the B operand in an instruction.
185
*
186
* @param _inst Instruction.
187
* @param _b B operand value.
188
*/
189
#define REDUCT_INST_SET_B(_inst, _b) \
190
(((_inst) & ~(REDUCT_INST_MASK_B << REDUCT_INST_POS_B)) | (((_b) & REDUCT_INST_MASK_B) << REDUCT_INST_POS_B))
191
192
/**
193
* @brief Set the C operand in an instruction.
194
*
195
* @param _inst Instruction.
196
* @param _c C operand value.
197
*/
198
#define REDUCT_INST_SET_C(_inst, _c) \
199
(((_inst) & ~(REDUCT_INST_MASK_C << REDUCT_INST_POS_C)) | (((_c) & REDUCT_INST_MASK_C) << REDUCT_INST_POS_C))
200
201
/**
202
* @brief Set the SAX operand in an instruction.
203
*
204
* @param _inst Instruction.
205
* @param _sax SAX operand value.
206
*/
207
#define REDUCT_INST_SET_SAX(_inst, _sax) \
208
(((_inst) & ~(REDUCT_INST_MASK_SAX << REDUCT_INST_POS_A)) | (((_sax) & REDUCT_INST_MASK_SAX) << REDUCT_INST_POS_A))
209
210
#endif
defs.h
reduct_const_t
uint16_t reduct_const_t
Constant index type.
Definition
inst.h:36
reduct_reg_t
uint16_t reduct_reg_t
Register type.
Definition
inst.h:41
reduct_inst_t
uint32_t reduct_inst_t
Instruction type.
Definition
inst.h:52
opcode.h
Bytecode opcodes and properties.
include
reduct
inst.h
Generated on Tue Jun 9 2026 16:27:59 for Reduct by
1.9.8