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