9
9
#include <stdlib.h>
10
10
#endif
11
11
#include <string.h>
12
+ #include <assert.h>
12
13
13
14
#include "MCInst.h"
14
15
#include "utils.h"
@@ -32,16 +33,19 @@ void MCInst_Init(MCInst *inst)
32
33
inst -> assembly [0 ] = '\0' ;
33
34
inst -> wasm_data .type = WASM_OP_INVALID ;
34
35
inst -> xAcquireRelease = 0 ;
36
+ for (int i = 0 ; i < MAX_MC_OPS ; ++ i )
37
+ inst -> tied_op_idx [i ] = -1 ;
35
38
}
36
39
37
40
void MCInst_clear (MCInst * inst )
38
41
{
39
42
inst -> size = 0 ;
40
43
}
41
44
42
- // do not free @Op
45
+ // does not free @Op
43
46
void MCInst_insert0 (MCInst * inst , int index , MCOperand * Op )
44
47
{
48
+ assert (index < MAX_MC_OPS );
45
49
int i ;
46
50
47
51
for (i = inst -> size ; i > index ; i -- )
@@ -74,6 +78,7 @@ unsigned MCInst_getOpcodePub(const MCInst *inst)
74
78
75
79
MCOperand * MCInst_getOperand (MCInst * inst , unsigned i )
76
80
{
81
+ assert (i < MAX_MC_OPS );
77
82
return & inst -> Operands [i ];
78
83
}
79
84
@@ -85,6 +90,7 @@ unsigned MCInst_getNumOperands(const MCInst *inst)
85
90
// This addOperand2 function doesnt free Op
86
91
void MCInst_addOperand2 (MCInst * inst , MCOperand * Op )
87
92
{
93
+ assert (inst -> size < MAX_MC_OPS );
88
94
inst -> Operands [inst -> size ] = * Op ;
89
95
90
96
inst -> size ++ ;
@@ -110,6 +116,21 @@ bool MCOperand_isFPImm(const MCOperand *op)
110
116
return op -> Kind == kFPImmediate ;
111
117
}
112
118
119
+ bool MCOperand_isDFPImm (const MCOperand * op )
120
+ {
121
+ return op -> Kind == kDFPImmediate ;
122
+ }
123
+
124
+ bool MCOperand_isExpr (const MCOperand * op )
125
+ {
126
+ return op -> Kind == kExpr ;
127
+ }
128
+
129
+ bool MCOperand_isInst (const MCOperand * op )
130
+ {
131
+ return op -> Kind == kInst ;
132
+ }
133
+
113
134
/// getReg - Returns the register number.
114
135
unsigned MCOperand_getReg (const MCOperand * op )
115
136
{
@@ -146,6 +167,7 @@ MCOperand *MCOperand_CreateReg1(MCInst *mcInst, unsigned Reg)
146
167
{
147
168
MCOperand * op = & (mcInst -> Operands [MCINST_CACHE ]);
148
169
170
+ op -> MachineOperandType = kRegister ;
149
171
op -> Kind = kRegister ;
150
172
op -> RegVal = Reg ;
151
173
@@ -157,6 +179,7 @@ void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
157
179
MCOperand * op = & (mcInst -> Operands [mcInst -> size ]);
158
180
mcInst -> size ++ ;
159
181
182
+ op -> MachineOperandType = kRegister ;
160
183
op -> Kind = kRegister ;
161
184
op -> RegVal = Reg ;
162
185
}
@@ -165,6 +188,7 @@ MCOperand *MCOperand_CreateImm1(MCInst *mcInst, int64_t Val)
165
188
{
166
189
MCOperand * op = & (mcInst -> Operands [MCINST_CACHE ]);
167
190
191
+ op -> MachineOperandType = kImmediate ;
168
192
op -> Kind = kImmediate ;
169
193
op -> ImmVal = Val ;
170
194
@@ -173,9 +197,69 @@ MCOperand *MCOperand_CreateImm1(MCInst *mcInst, int64_t Val)
173
197
174
198
void MCOperand_CreateImm0 (MCInst * mcInst , int64_t Val )
175
199
{
200
+ assert (mcInst -> size < MAX_MC_OPS );
176
201
MCOperand * op = & (mcInst -> Operands [mcInst -> size ]);
177
202
mcInst -> size ++ ;
178
203
204
+ op -> MachineOperandType = kImmediate ;
179
205
op -> Kind = kImmediate ;
180
206
op -> ImmVal = Val ;
181
207
}
208
+
209
+ /// Check if any operand of the MCInstrDesc is predicable
210
+ bool MCInst_isPredicable (const MCInstrDesc * MIDesc ) {
211
+ const MCOperandInfo * OpInfo = MIDesc -> OpInfo ;
212
+ unsigned NumOps = MIDesc -> NumOperands ;
213
+ for (unsigned i = 0 ; i < NumOps ; ++ i ) {
214
+ if (MCOperandInfo_isPredicate (& OpInfo [i ])) {
215
+ return true;
216
+ }
217
+ }
218
+ return false;
219
+ }
220
+
221
+ /// Checks if tied operands exist in the instruction and sets
222
+ /// - The writeback flag in detail
223
+ /// - Saves the indices of the tied destination operands.
224
+ void MCInst_handleWriteback (MCInst * MI , const MCInstrDesc * InstDesc ) {
225
+ const MCOperandInfo * OpInfo = InstDesc [MCInst_getOpcode (MI )].OpInfo ;
226
+ unsigned short NumOps = InstDesc [MCInst_getOpcode (MI )].NumOperands ;
227
+
228
+ unsigned i ;
229
+ for (i = 0 ; i < NumOps ; ++ i ) {
230
+ if (MCOperandInfo_isTiedToOp (& OpInfo [i ])) {
231
+ int idx = MCOperandInfo_getOperandConstraint (
232
+ & InstDesc [MCInst_getOpcode (MI )], i , MCOI_TIED_TO );
233
+
234
+ if (idx == -1 )
235
+ continue ;
236
+
237
+ if (i >= MAX_MC_OPS ) {
238
+ assert (0 && "Maximum number of MC operands reached." );
239
+ }
240
+ MI -> tied_op_idx [i ] = idx ;
241
+
242
+ if (MI -> flat_insn -> detail )
243
+ MI -> flat_insn -> detail -> writeback = true;
244
+ }
245
+ }
246
+ }
247
+
248
+ /// Check if operand with OpNum is tied by another operand
249
+ /// (operand is tying destination).
250
+ bool MCInst_opIsTied (const MCInst * MI , unsigned OpNum ) {
251
+ assert (OpNum < MAX_MC_OPS && "Maximum number of MC operands exceeded." );
252
+ for (int i = 0 ; i < MAX_MC_OPS ; ++ i ) {
253
+ if (MI -> tied_op_idx [i ] == OpNum )
254
+ return true;
255
+ }
256
+ return false;
257
+ }
258
+
259
+ /// Check if operand with OpNum is tying another operand
260
+ /// (operand is tying src).
261
+ bool MCInst_opIsTying (const MCInst * MI , unsigned OpNum ) {
262
+ assert (OpNum < MAX_MC_OPS && "Maximum number of MC operands exceeded." );
263
+ return MI -> tied_op_idx [OpNum ] != -1 ;
264
+ }
265
+
0 commit comments