1 /*BEGIN_LEGAL
2
3 Copyright (c) 2018 Intel Corporation
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 END_LEGAL */
18
19 #ifndef XED_ENCODER_HL_H
20 # define XED_ENCODER_HL_H
21 #include "xed-types.h"
22 #include "xed-reg-enum.h"
23 #include "xed-state.h"
24 #include "xed-iclass-enum.h"
25 #include "xed-portability.h"
26 #include "xed-encode.h"
27
28
29 typedef struct {
30 xed_uint64_t displacement;
31 xed_uint32_t displacement_bits;
32 } xed_enc_displacement_t; /* fixme bad name */
33
34 /// @name Memory Displacement
35 //@{
36 /// @ingroup ENCHL
37 /// a memory displacement (not for branches)
38 /// @param displacement The value of the displacement
39 /// @param displacement_bits The width of the displacement in bits. Typically 8 or 32.
40 /// @returns #xed_enc_displacement_t
41 static XED_INLINE
xed_disp(xed_uint64_t displacement,xed_uint32_t displacement_bits)42 xed_enc_displacement_t xed_disp(xed_uint64_t displacement,
43 xed_uint32_t displacement_bits ) {
44 xed_enc_displacement_t x;
45 x.displacement = displacement;
46 x.displacement_bits = displacement_bits;
47 return x;
48 }
49 //@}
50
51 typedef struct {
52 xed_reg_enum_t seg;
53 xed_reg_enum_t base;
54 xed_reg_enum_t index;
55 xed_uint32_t scale;
56 xed_enc_displacement_t disp;
57 } xed_memop_t;
58
59
60 typedef enum {
61 XED_ENCODER_OPERAND_TYPE_INVALID,
62 XED_ENCODER_OPERAND_TYPE_BRDISP,
63 XED_ENCODER_OPERAND_TYPE_REG,
64 XED_ENCODER_OPERAND_TYPE_IMM0,
65 XED_ENCODER_OPERAND_TYPE_SIMM0,
66 XED_ENCODER_OPERAND_TYPE_IMM1,
67 XED_ENCODER_OPERAND_TYPE_MEM,
68 XED_ENCODER_OPERAND_TYPE_PTR,
69
70 /* special for things with suppressed implicit memops */
71 XED_ENCODER_OPERAND_TYPE_SEG0,
72
73 /* special for things with suppressed implicit memops */
74 XED_ENCODER_OPERAND_TYPE_SEG1,
75
76 /* specific operand storage fields -- must supply a name */
77 XED_ENCODER_OPERAND_TYPE_OTHER
78 } xed_encoder_operand_type_t;
79
80 typedef struct {
81 xed_encoder_operand_type_t type;
82 union {
83 xed_reg_enum_t reg;
84 xed_int32_t brdisp;
85 xed_uint64_t imm0;
86 xed_uint8_t imm1;
87 struct {
88 xed_operand_enum_t operand_name;
89 xed_uint32_t value;
90 } s;
91 xed_memop_t mem;
92 } u;
93 xed_uint32_t width_bits;
94 } xed_encoder_operand_t;
95
96 /// @name Branch Displacement
97 //@{
98 /// @ingroup ENCHL
99 /// a relative branch displacement operand
100 /// @param brdisp The branch displacement
101 /// @param width_bits The width of the displacement in bits. Typically 8 or 32.
102 /// @returns xed_encoder_operand_t An operand.
xed_relbr(xed_int32_t brdisp,xed_uint_t width_bits)103 static XED_INLINE xed_encoder_operand_t xed_relbr(xed_int32_t brdisp,
104 xed_uint_t width_bits) {
105 xed_encoder_operand_t o;
106 o.type = XED_ENCODER_OPERAND_TYPE_BRDISP;
107 o.u.brdisp = brdisp;
108 o.width_bits = width_bits;
109 return o;
110 }
111 //@}
112
113 /// @name Pointer Displacement
114 //@{
115 /// @ingroup ENCHL
116 /// a relative displacement for a PTR operand -- the subsequent imm0 holds
117 ///the 16b selector
118 /// @param brdisp The displacement for a far pointer operand
119 /// @param width_bits The width of the far pointr displacement in bits.
120 /// @returns xed_encoder_operand_t An operand.
xed_ptr(xed_int32_t brdisp,xed_uint_t width_bits)121 static XED_INLINE xed_encoder_operand_t xed_ptr(xed_int32_t brdisp,
122 xed_uint_t width_bits) {
123 xed_encoder_operand_t o;
124 o.type = XED_ENCODER_OPERAND_TYPE_PTR;
125 o.u.brdisp = brdisp;
126 o.width_bits = width_bits;
127 return o;
128 }
129 //@}
130
131 /// @name Register and Immediate Operands
132 //@{
133 /// @ingroup ENCHL
134 /// a register operand
135 /// @param reg A #xed_reg_enum_t register operand
136 /// @returns xed_encoder_operand_t An operand.
xed_reg(xed_reg_enum_t reg)137 static XED_INLINE xed_encoder_operand_t xed_reg(xed_reg_enum_t reg) {
138 xed_encoder_operand_t o;
139 o.type = XED_ENCODER_OPERAND_TYPE_REG;
140 o.u.reg = reg;
141 o.width_bits = 0;
142 return o;
143 }
144
145 /// @ingroup ENCHL
146 /// a first immediate operand (known as IMM0)
147 /// @param v An immdediate operand.
148 /// @param width_bits The immediate width in bits.
149 /// @returns xed_encoder_operand_t An operand.
xed_imm0(xed_uint64_t v,xed_uint_t width_bits)150 static XED_INLINE xed_encoder_operand_t xed_imm0(xed_uint64_t v,
151 xed_uint_t width_bits) {
152 xed_encoder_operand_t o;
153 o.type = XED_ENCODER_OPERAND_TYPE_IMM0;
154 o.u.imm0 = v;
155 o.width_bits = width_bits;
156 return o;
157 }
158 /// @ingroup ENCHL
159 /// an 32b signed immediate operand
160 /// @param v An signed immdediate operand.
161 /// @param width_bits The immediate width in bits.
162 /// @returns xed_encoder_operand_t An operand.
xed_simm0(xed_int32_t v,xed_uint_t width_bits)163 static XED_INLINE xed_encoder_operand_t xed_simm0(xed_int32_t v,
164 xed_uint_t width_bits) {
165 xed_encoder_operand_t o;
166 o.type = XED_ENCODER_OPERAND_TYPE_SIMM0;
167 /* sign conversion: we store the int32 in an uint64. It gets sign
168 extended. Later we convert it to the right width_bits for the
169 instruction. The maximum width_bits of a signed immediate is currently
170 32b. */
171 o.u.imm0 = v;
172 o.width_bits = width_bits;
173 return o;
174 }
175
176 /// @ingroup ENCHL
177 /// The 2nd immediate operand (known as IMM1) for rare instructions that require it.
178 /// @param v The 2nd immdediate (byte-width) operand
179 /// @returns xed_encoder_operand_t An operand.
xed_imm1(xed_uint8_t v)180 static XED_INLINE xed_encoder_operand_t xed_imm1(xed_uint8_t v) {
181 xed_encoder_operand_t o;
182 o.type = XED_ENCODER_OPERAND_TYPE_IMM1;
183 o.u.imm1 = v;
184 o.width_bits = 8;
185 return o;
186 }
187
188
189 /// @ingroup ENCHL
190 /// an operand storage field name and value
xed_other(xed_operand_enum_t operand_name,xed_int32_t value)191 static XED_INLINE xed_encoder_operand_t xed_other(
192 xed_operand_enum_t operand_name,
193 xed_int32_t value) {
194 xed_encoder_operand_t o;
195 o.type = XED_ENCODER_OPERAND_TYPE_OTHER;
196 o.u.s.operand_name = operand_name;
197 o.u.s.value = value;
198 o.width_bits = 0;
199 return o;
200 }
201 //@}
202
203
204 //@}
205
206 /// @name Memory and Segment-releated Operands
207 //@{
208
209 /// @ingroup ENCHL
210 /// seg reg override for implicit suppressed memory ops
xed_seg0(xed_reg_enum_t seg0)211 static XED_INLINE xed_encoder_operand_t xed_seg0(xed_reg_enum_t seg0) {
212 xed_encoder_operand_t o;
213 o.type = XED_ENCODER_OPERAND_TYPE_SEG0;
214 o.u.reg = seg0;
215 return o;
216 }
217
218 /// @ingroup ENCHL
219 /// seg reg override for implicit suppressed memory ops
xed_seg1(xed_reg_enum_t seg1)220 static XED_INLINE xed_encoder_operand_t xed_seg1(xed_reg_enum_t seg1) {
221 xed_encoder_operand_t o;
222 o.type = XED_ENCODER_OPERAND_TYPE_SEG1;
223 o.u.reg = seg1;
224 return o;
225 }
226
227 /// @ingroup ENCHL
228 /// memory operand - base only
229 /// @param base The base register
230 /// @param width_bits The length of the memory reference in bits.
231 /// @returns xed_encoder_operand_t An operand.
xed_mem_b(xed_reg_enum_t base,xed_uint_t width_bits)232 static XED_INLINE xed_encoder_operand_t xed_mem_b(xed_reg_enum_t base,
233 xed_uint_t width_bits) {
234 xed_encoder_operand_t o;
235 o.type = XED_ENCODER_OPERAND_TYPE_MEM;
236 o.u.mem.base = base;
237 o.u.mem.seg = XED_REG_INVALID;
238 o.u.mem.index= XED_REG_INVALID;
239 o.u.mem.scale = 0;
240 o.u.mem.disp.displacement = 0;
241 o.u.mem.disp.displacement_bits = 0;
242 o.width_bits = width_bits;
243 return o;
244 }
245
246 /// @ingroup ENCHL
247 /// memory operand - base and displacement only
248 /// @param base The base register
249 /// @param disp The displacement
250 /// @param width_bits The length of the memory reference in bits.
251 /// @returns xed_encoder_operand_t An operand.
xed_mem_bd(xed_reg_enum_t base,xed_enc_displacement_t disp,xed_uint_t width_bits)252 static XED_INLINE xed_encoder_operand_t xed_mem_bd(xed_reg_enum_t base,
253 xed_enc_displacement_t disp,
254 xed_uint_t width_bits) {
255 xed_encoder_operand_t o;
256 o.type = XED_ENCODER_OPERAND_TYPE_MEM;
257 o.u.mem.base = base;
258 o.u.mem.seg = XED_REG_INVALID;
259 o.u.mem.index= XED_REG_INVALID;
260 o.u.mem.scale = 0;
261 o.u.mem.disp =disp;
262 o.width_bits = width_bits;
263 return o;
264 }
265
266 /// @ingroup ENCHL
267 /// memory operand - base, index, scale, displacement
268 /// @param base The base register
269 /// @param index The index register
270 /// @param scale The scale for the index register value
271 /// @param disp The displacement
272 /// @param width_bits The length of the memory reference in bits.
273 /// @returns xed_encoder_operand_t An operand.
xed_mem_bisd(xed_reg_enum_t base,xed_reg_enum_t index,xed_uint_t scale,xed_enc_displacement_t disp,xed_uint_t width_bits)274 static XED_INLINE xed_encoder_operand_t xed_mem_bisd(xed_reg_enum_t base,
275 xed_reg_enum_t index,
276 xed_uint_t scale,
277 xed_enc_displacement_t disp,
278 xed_uint_t width_bits) {
279 xed_encoder_operand_t o;
280 o.type = XED_ENCODER_OPERAND_TYPE_MEM;
281 o.u.mem.base = base;
282 o.u.mem.seg = XED_REG_INVALID;
283 o.u.mem.index= index;
284 o.u.mem.scale = scale;
285 o.u.mem.disp = disp;
286 o.width_bits = width_bits;
287 return o;
288 }
289
290
291 /// @ingroup ENCHL
292 /// memory operand - segment and base only
293 /// @param seg The segment override register
294 /// @param base The base register
295 /// @param width_bits The length of the memory reference in bits.
296 /// @returns xed_encoder_operand_t An operand.
xed_mem_gb(xed_reg_enum_t seg,xed_reg_enum_t base,xed_uint_t width_bits)297 static XED_INLINE xed_encoder_operand_t xed_mem_gb(xed_reg_enum_t seg,
298 xed_reg_enum_t base,
299 xed_uint_t width_bits) {
300 xed_encoder_operand_t o;
301 o.type = XED_ENCODER_OPERAND_TYPE_MEM;
302 o.u.mem.base = base;
303 o.u.mem.seg = seg;
304 o.u.mem.index= XED_REG_INVALID;
305 o.u.mem.scale = 0;
306 o.u.mem.disp.displacement = 0;
307 o.u.mem.disp.displacement_bits = 0;
308 o.width_bits = width_bits;
309 return o;
310 }
311
312 /// @ingroup ENCHL
313 /// memory operand - segment, base and displacement only
314 /// @param seg The segment override register
315 /// @param base The base register
316 /// @param disp The displacement
317 /// @param width_bits The length of the memory reference in bits.
318 /// @returns xed_encoder_operand_t An operand.
xed_mem_gbd(xed_reg_enum_t seg,xed_reg_enum_t base,xed_enc_displacement_t disp,xed_uint_t width_bits)319 static XED_INLINE xed_encoder_operand_t xed_mem_gbd(xed_reg_enum_t seg,
320 xed_reg_enum_t base,
321 xed_enc_displacement_t disp,
322 xed_uint_t width_bits) {
323 xed_encoder_operand_t o;
324 o.type = XED_ENCODER_OPERAND_TYPE_MEM;
325 o.u.mem.base = base;
326 o.u.mem.seg = seg;
327 o.u.mem.index= XED_REG_INVALID;
328 o.u.mem.scale = 0;
329 o.u.mem.disp = disp;
330 o.width_bits = width_bits;
331 return o;
332 }
333
334 /// @ingroup ENCHL
335 /// memory operand - segment and displacement only
336 /// @param seg The segment override register
337 /// @param disp The displacement
338 /// @param width_bits The length of the memory reference in bits.
339 /// @returns xed_encoder_operand_t An operand.
xed_mem_gd(xed_reg_enum_t seg,xed_enc_displacement_t disp,xed_uint_t width_bits)340 static XED_INLINE xed_encoder_operand_t xed_mem_gd(xed_reg_enum_t seg,
341 xed_enc_displacement_t disp,
342 xed_uint_t width_bits) {
343 xed_encoder_operand_t o;
344 o.type = XED_ENCODER_OPERAND_TYPE_MEM;
345 o.u.mem.base = XED_REG_INVALID;
346 o.u.mem.seg = seg;
347 o.u.mem.index= XED_REG_INVALID;
348 o.u.mem.scale = 0;
349 o.u.mem.disp = disp;
350 o.width_bits = width_bits;
351 return o;
352 }
353
354 /// @ingroup ENCHL
355 /// memory operand - segment, base, index, scale, and displacement
356 /// @param seg The segment override register
357 /// @param base The base register
358 /// @param index The index register
359 /// @param scale The scale for the index register value
360 /// @param disp The displacement
361 /// @param width_bits The length of the memory reference in bits.
362 /// @returns xed_encoder_operand_t An operand.
xed_mem_gbisd(xed_reg_enum_t seg,xed_reg_enum_t base,xed_reg_enum_t index,xed_uint_t scale,xed_enc_displacement_t disp,xed_uint_t width_bits)363 static XED_INLINE xed_encoder_operand_t xed_mem_gbisd(xed_reg_enum_t seg,
364 xed_reg_enum_t base,
365 xed_reg_enum_t index,
366 xed_uint_t scale,
367 xed_enc_displacement_t disp,
368 xed_uint_t width_bits) {
369 xed_encoder_operand_t o;
370 o.type = XED_ENCODER_OPERAND_TYPE_MEM;
371 o.u.mem.base = base;
372 o.u.mem.seg = seg;
373 o.u.mem.index= index;
374 o.u.mem.scale = scale;
375 o.u.mem.disp = disp;
376 o.width_bits = width_bits;
377 return o;
378 }
379 //@}
380
381 typedef union {
382 struct {
383 xed_uint32_t rep :1;
384 xed_uint32_t repne :1;
385 xed_uint32_t br_hint_taken :1;
386 xed_uint32_t br_hint_not_taken :1;
387 } s;
388 xed_uint32_t i;
389 } xed_encoder_prefixes_t;
390
391 #define XED_ENCODER_OPERANDS_MAX 5 /* FIXME */
392 typedef struct {
393 xed_state_t mode;
394 xed_iclass_enum_t iclass; /*FIXME: use iform instead? or allow either */
395 xed_uint32_t effective_operand_width;
396
397 /* the effective_address_width is only requires to be set for
398 * instructions * with implicit suppressed memops or memops with no
399 * base or index regs. When base or index regs are present, XED pick
400 * this up automatically from the register names.
401
402 * FIXME: make effective_address_width required by all encodes for
403 * unifority. Add to xed_inst[0123]() APIs??? */
404 xed_uint32_t effective_address_width;
405
406 xed_encoder_prefixes_t prefixes;
407 xed_uint32_t noperands;
408 xed_encoder_operand_t operands[XED_ENCODER_OPERANDS_MAX];
409 } xed_encoder_instruction_t;
410
411 /// @name Instruction Properties and prefixes
412 //@{
413 /// @ingroup ENCHL
414 /// This is to specify effective address size different than the
415 /// default. For things with base or index regs, XED picks it up from the
416 /// registers. But for things that have implicit memops, or no base or index
417 /// reg, we must allow the user to set the address width directly.
418 /// @param x The #xed_encoder_instruction_t being filled in.
419 /// @param width_bits The intended effective address size in bits. Values: 16, 32 or 64.
xed_addr(xed_encoder_instruction_t * x,xed_uint_t width_bits)420 static XED_INLINE void xed_addr(xed_encoder_instruction_t* x,
421 xed_uint_t width_bits) {
422 x->effective_address_width = width_bits;
423 }
424
425
426 /// @ingroup ENCHL
427 /// To add a REP (0xF3) prefix.
428 /// @param x The #xed_encoder_instruction_t being filled in.
xed_rep(xed_encoder_instruction_t * x)429 static XED_INLINE void xed_rep(xed_encoder_instruction_t* x) {
430 x->prefixes.s.rep=1;
431 }
432
433 /// @ingroup ENCHL
434 /// To add a REPNE (0xF2) prefix.
435 /// @param x The #xed_encoder_instruction_t being filled in.
xed_repne(xed_encoder_instruction_t * x)436 static XED_INLINE void xed_repne(xed_encoder_instruction_t* x) {
437 x->prefixes.s.repne=1;
438 }
439
440
441
442
443 /// @ingroup ENCHL
444 /// convert a #xed_encoder_instruction_t to a #xed_encoder_request_t for
445 /// encoding
446 XED_DLL_EXPORT xed_bool_t
447 xed_convert_to_encoder_request(xed_encoder_request_t* out,
448 xed_encoder_instruction_t* in);
449
450 //@}
451
452 /// @name Creating instructions from operands
453 //@{
454
455 /// @ingroup ENCHL
456 /// instruction with no operands
457 /// @param inst The #xed_encoder_instruction_t to be filled in
458 /// @param mode The xed_state_t including the machine mode and stack address width.
459 /// @param iclass The #xed_iclass_enum_t
460 /// @param effective_operand_width in bits
xed_inst0(xed_encoder_instruction_t * inst,xed_state_t mode,xed_iclass_enum_t iclass,xed_uint_t effective_operand_width)461 static XED_INLINE void xed_inst0(
462 xed_encoder_instruction_t* inst,
463 xed_state_t mode,
464 xed_iclass_enum_t iclass,
465 xed_uint_t effective_operand_width) {
466
467 inst->mode=mode;
468 inst->iclass = iclass;
469 inst->effective_operand_width = effective_operand_width;
470 inst->effective_address_width = 0;
471 inst->prefixes.i = 0;
472 inst->noperands = 0;
473 }
474
475 /// @ingroup ENCHL
476 /// instruction with one operand
477 /// @param inst The #xed_encoder_instruction_t to be filled in
478 /// @param mode The xed_state_t including the machine mode and stack address width.
479 /// @param iclass The #xed_iclass_enum_t
480 /// @param effective_operand_width in bits
481 /// @param op0 the operand
xed_inst1(xed_encoder_instruction_t * inst,xed_state_t mode,xed_iclass_enum_t iclass,xed_uint_t effective_operand_width,xed_encoder_operand_t op0)482 static XED_INLINE void xed_inst1(
483 xed_encoder_instruction_t* inst,
484 xed_state_t mode,
485 xed_iclass_enum_t iclass,
486 xed_uint_t effective_operand_width,
487 xed_encoder_operand_t op0) {
488
489 inst->mode=mode;
490 inst->iclass = iclass;
491 inst->effective_operand_width = effective_operand_width;
492 inst->effective_address_width = 0;
493 inst->prefixes.i = 0;
494 inst->operands[0] = op0;
495 inst->noperands = 1;
496 }
497
498 /// @ingroup ENCHL
499 /// instruction with two operands
500 /// @param inst The #xed_encoder_instruction_t to be filled in
501 /// @param mode The xed_state_t including the machine mode and stack address width.
502 /// @param iclass The #xed_iclass_enum_t
503 /// @param effective_operand_width in bits
504 /// @param op0 the 1st operand
505 /// @param op1 the 2nd operand
xed_inst2(xed_encoder_instruction_t * inst,xed_state_t mode,xed_iclass_enum_t iclass,xed_uint_t effective_operand_width,xed_encoder_operand_t op0,xed_encoder_operand_t op1)506 static XED_INLINE void xed_inst2(
507 xed_encoder_instruction_t* inst,
508 xed_state_t mode,
509 xed_iclass_enum_t iclass,
510 xed_uint_t effective_operand_width,
511 xed_encoder_operand_t op0,
512 xed_encoder_operand_t op1) {
513
514 inst->mode=mode;
515 inst->iclass = iclass;
516 inst->effective_operand_width = effective_operand_width;
517 inst->effective_address_width = 0;
518 inst->prefixes.i = 0;
519 inst->operands[0] = op0;
520 inst->operands[1] = op1;
521 inst->noperands = 2;
522 }
523
524 /// @ingroup ENCHL
525 /// instruction with three operands
526 /// @param inst The #xed_encoder_instruction_t to be filled in
527 /// @param mode The xed_state_t including the machine mode and stack address width.
528 /// @param iclass The #xed_iclass_enum_t
529 /// @param effective_operand_width in bits
530 /// @param op0 the 1st operand
531 /// @param op1 the 2nd operand
532 /// @param op2 the 3rd operand
xed_inst3(xed_encoder_instruction_t * inst,xed_state_t mode,xed_iclass_enum_t iclass,xed_uint_t effective_operand_width,xed_encoder_operand_t op0,xed_encoder_operand_t op1,xed_encoder_operand_t op2)533 static XED_INLINE void xed_inst3(
534 xed_encoder_instruction_t* inst,
535 xed_state_t mode,
536 xed_iclass_enum_t iclass,
537 xed_uint_t effective_operand_width,
538 xed_encoder_operand_t op0,
539 xed_encoder_operand_t op1,
540 xed_encoder_operand_t op2) {
541
542 inst->mode=mode;
543 inst->iclass = iclass;
544 inst->effective_operand_width = effective_operand_width;
545 inst->effective_address_width = 0;
546 inst->prefixes.i = 0;
547 inst->operands[0] = op0;
548 inst->operands[1] = op1;
549 inst->operands[2] = op2;
550 inst->noperands = 3;
551 }
552
553
554 /// @ingroup ENCHL
555 /// instruction with four operands
556 /// @param inst The #xed_encoder_instruction_t to be filled in
557 /// @param mode The xed_state_t including the machine mode and stack address width.
558 /// @param iclass The #xed_iclass_enum_t
559 /// @param effective_operand_width in bits
560 /// @param op0 the 1st operand
561 /// @param op1 the 2nd operand
562 /// @param op2 the 3rd operand
563 /// @param op3 the 4th operand
xed_inst4(xed_encoder_instruction_t * inst,xed_state_t mode,xed_iclass_enum_t iclass,xed_uint_t effective_operand_width,xed_encoder_operand_t op0,xed_encoder_operand_t op1,xed_encoder_operand_t op2,xed_encoder_operand_t op3)564 static XED_INLINE void xed_inst4(
565 xed_encoder_instruction_t* inst,
566 xed_state_t mode,
567 xed_iclass_enum_t iclass,
568 xed_uint_t effective_operand_width,
569 xed_encoder_operand_t op0,
570 xed_encoder_operand_t op1,
571 xed_encoder_operand_t op2,
572 xed_encoder_operand_t op3) {
573
574 inst->mode=mode;
575 inst->iclass = iclass;
576 inst->effective_operand_width = effective_operand_width;
577 inst->effective_address_width = 0;
578 inst->prefixes.i = 0;
579 inst->operands[0] = op0;
580 inst->operands[1] = op1;
581 inst->operands[2] = op2;
582 inst->operands[3] = op3;
583 inst->noperands = 4;
584 }
585
586 /// @ingroup ENCHL
587 /// instruction with five operands
588 /// @param inst The #xed_encoder_instruction_t to be filled in
589 /// @param mode The xed_state_t including the machine mode and stack address width.
590 /// @param iclass The #xed_iclass_enum_t
591 /// @param effective_operand_width in bits
592 /// @param op0 the 1st operand
593 /// @param op1 the 2nd operand
594 /// @param op2 the 3rd operand
595 /// @param op3 the 4th operand
596 /// @param op4 the 5th operand
xed_inst5(xed_encoder_instruction_t * inst,xed_state_t mode,xed_iclass_enum_t iclass,xed_uint_t effective_operand_width,xed_encoder_operand_t op0,xed_encoder_operand_t op1,xed_encoder_operand_t op2,xed_encoder_operand_t op3,xed_encoder_operand_t op4)597 static XED_INLINE void xed_inst5(
598 xed_encoder_instruction_t* inst,
599 xed_state_t mode,
600 xed_iclass_enum_t iclass,
601 xed_uint_t effective_operand_width,
602 xed_encoder_operand_t op0,
603 xed_encoder_operand_t op1,
604 xed_encoder_operand_t op2,
605 xed_encoder_operand_t op3,
606 xed_encoder_operand_t op4) {
607
608 inst->mode=mode;
609 inst->iclass = iclass;
610 inst->effective_operand_width = effective_operand_width;
611 inst->effective_address_width = 0;
612 inst->prefixes.i = 0;
613 inst->operands[0] = op0;
614 inst->operands[1] = op1;
615 inst->operands[2] = op2;
616 inst->operands[3] = op3;
617 inst->operands[4] = op4;
618 inst->noperands = 5;
619 }
620
621
622 /// @ingroup ENCHL
623 /// instruction with an array of operands. The maximum number is
624 /// XED_ENCODER_OPERANDS_MAX. The array's contents are copied.
625 /// @param inst The #xed_encoder_instruction_t to be filled in
626 /// @param mode The xed_state_t including the machine mode and stack address width.
627 /// @param iclass The #xed_iclass_enum_t
628 /// @param effective_operand_width in bits
629 /// @param number_of_operands length of the subsequent array
630 /// @param operand_array An array of #xed_encoder_operand_t objects
xed_inst(xed_encoder_instruction_t * inst,xed_state_t mode,xed_iclass_enum_t iclass,xed_uint_t effective_operand_width,xed_uint_t number_of_operands,const xed_encoder_operand_t * operand_array)631 static XED_INLINE void xed_inst(
632 xed_encoder_instruction_t* inst,
633 xed_state_t mode,
634 xed_iclass_enum_t iclass,
635 xed_uint_t effective_operand_width,
636 xed_uint_t number_of_operands,
637 const xed_encoder_operand_t* operand_array) {
638
639 xed_uint_t i;
640 inst->mode=mode;
641 inst->iclass = iclass;
642 inst->effective_operand_width = effective_operand_width;
643 inst->effective_address_width = 0;
644 inst->prefixes.i = 0;
645 xed_assert(number_of_operands < XED_ENCODER_OPERANDS_MAX);
646 for(i=0;i<number_of_operands;i++) {
647 inst->operands[i] = operand_array[i];
648 }
649 inst->noperands = number_of_operands;
650 }
651
652 //@}
653
654 /*
655 xed_encoder_instruction_t x,y;
656
657 xed_inst2(&x, state, XED_ICLASS_ADD, 32,
658 xed_reg(XED_REG_EAX),
659 xed_mem_bd(XED_REG_EDX, xed_disp(0x11223344, 32), 32));
660
661 xed_inst2(&y, state, XED_ICLASS_ADD, 32,
662 xed_reg(XED_REG_EAX),
663 xed_mem_gbisd(XED_REG_FS, XED_REG_EAX, XED_REG_ESI,4,
664 xed_disp(0x11223344, 32), 32));
665
666 */
667
668 #endif
669