@@ -100,50 +100,112 @@ ir_opnd_t ir_mem(uint8_t num_bits, ir_opnd_t base, int32_t disp);
100
100
// Instruction opcodes
101
101
enum yjit_ir_op
102
102
{
103
- // Comment strings in the generated code
103
+ // Add a comment into the IR at the point that this instruction is added. It
104
+ // won't have any impact on that actual compiled code, but it will impact
105
+ // the output of ir_print_insns. Accepts as its only operand an EIR_IMM
106
+ // operand (typically generated by ir_str_ptr).
104
107
OP_COMMENT ,
105
108
106
- // Named intra-block label we can jump to
109
+ // Add a label into the IR at the point that this instruction is added. It
110
+ // will eventually be translated into an offset when generating code such
111
+ // that EIR_LABEL_IDX operands know where to jump to. Accepts as its only
112
+ // operand an EIR_LABEL_NAME operand (typically generated by ir_label_opnd).
107
113
OP_LABEL ,
108
114
109
- // Arithmetic instructions
115
+ // Add two operands together, and return the result as a new operand. This
116
+ // operand can then be used as the operand on another instruction. It
117
+ // accepts two operands, which can be of any type
118
+ //
119
+ // Under the hood when allocating registers, the IR will determine the most
120
+ // efficient way to get these values into memory. For example, if both
121
+ // operands are immediates, then it will load the first one into a register
122
+ // first with a mov instruction and then add them together. If one of them
123
+ // is a register, however, it will just perform a single add instruction.
110
124
OP_ADD ,
111
- OP_SUB ,
112
- OP_AND ,
113
- OP_NOT ,
114
125
115
- // For later:
116
- // These encode Ruby true/false semantics
117
- // Can be used to enable op fusion of Ruby compare + branch
118
- // JUMP_TRUE (opnd, target),
119
- // JUMP_FALSE (opnd, target)
126
+ // This is the same as the OP_ADD instruction, except for subtraction.
127
+ OP_SUB ,
120
128
121
- // For later:
122
- // GUARD_HEAP (opnd, target)
123
- // GUARD_IMM (opnd, target)
124
- // GUARD_FIXNUM (opnd, target)
129
+ // This is the same as the OP_ADD instruction, except that it performs the
130
+ // binary AND operation.
131
+ OP_AND ,
125
132
126
- // Comparison
127
- OP_CMP ,
128
- OP_TEST ,
133
+ // Perform the NOT operation on an individual operand, and return the result
134
+ // as a new operand. This operand can then be used as the operand on another
135
+ // instruction.
136
+ OP_NOT ,
129
137
130
- // Conditional jumps
138
+ // The following are conditional jump instructions. They all accept as their
139
+ // first operand an EIR_LABEL_NAME, which is used as the target of the jump.
140
+ //
141
+ // The OP_JUMP_EQ instruction accepts two additional operands, to be
142
+ // compared for equality. If they're equal, then the generated code jumps to
143
+ // the target label. If they're not, then it continues on to the next
144
+ // instruction.
131
145
OP_JUMP_EQ ,
146
+
147
+ // The OP_JUMP_NE instruction is very similar to the OP_JUMP_EQ instruction,
148
+ // except it compares for inequality instead.
132
149
OP_JUMP_NE ,
150
+
151
+ // Checks the overflow flag and conditionally jumps to the target if it is
152
+ // currently set.
133
153
OP_JUMP_OVF ,
134
154
155
+ // A low-level call instruction for calling a function by a pointer. It
156
+ // accepts one operand of type EIR_IMM that should be a pointer to the
157
+ // function. Usually this is done by first casting the function to a void*,
158
+ // as in: ir_const_ptr((void *)&my_function)).
135
159
OP_CALL ,
160
+
161
+ // Calls a function by a pointer and returns an operand that contains the
162
+ // result of the function. Accepts as its operands a pointer to a function
163
+ // of type EIR_IMM (usually generated from ir_const_ptr) and a variable
164
+ // number of arguments to the function being called.
165
+ //
166
+ // This is the higher-level instruction that should be used when you want to
167
+ // call a function with arguments, as opposed to OP_CALL which is
168
+ // lower-level and just calls a function without moving arguments into
169
+ // registers for you.
136
170
OP_CCALL ,
171
+
172
+ // Returns from the function being generated immediately. This is different
173
+ // from OP_RETVAL in that it does nothing with the return value register
174
+ // (whatever is in there is what will get returned). Accepts no operands.
137
175
OP_RET ,
138
- OP_RETVAL ,
139
176
140
- //COUNTER_INC (counter_name)
177
+ // First, moves a value into the return value register. Then, returns from
178
+ // the generated function. Accepts as its only operand the value that should
179
+ // be returned from the generated function.
180
+ OP_RETVAL ,
141
181
142
- // Low-level instructions
143
- OP_LEA ,
182
+ // A low-level mov instruction. It accepts two operands. The first must
183
+ // either be an EIR_REG or a EIR_INSN_OUT that resolves to a register. The
184
+ // second can be anything else. Most of the time, this instruction shouldn't
185
+ // be used by the developer, since other instructions break down to this
186
+ // one.
144
187
OP_MOV ,
145
188
146
- // Upper bound for opcodes
189
+ // For later:
190
+ // These encode Ruby true/false semantics
191
+ // Can be used to enable op fusion of Ruby compare + branch.
192
+ // OP_JUMP_TRUE, // (opnd, target)
193
+ // OP_JUMP_FALSE, // (opnd, target)
194
+
195
+ // For later:
196
+ // OP_GUARD_HEAP, // (opnd, target)
197
+ // OP_GUARD_IMM, // (opnd, target)
198
+ // OP_GUARD_FIXNUM, // (opnd, target)
199
+
200
+ // For later:
201
+ // OP_COUNTER_INC, (counter_name)
202
+
203
+ // For later:
204
+ // OP_LEA,
205
+ // OP_CMP,
206
+ // OP_TEST,
207
+
208
+ // Upper bound for opcodes. Not used for actual instructions.
147
209
OP_MAX
148
210
};
149
211
0 commit comments