1 /***************************************************************************************************
3 Zyan Disassembler Library (Zydis)
5 Original Author : Florian Bernd, Joel Hoener
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 ***************************************************************************************************/
27 #include <Zydis/Internal/FormatterBase.h>
28 #include <Zydis/Utils.h>
30 /* ============================================================================================== */
32 /* ============================================================================================== */
34 #include <Generated/FormatterStrings.inc>
36 static const ZydisShortString
* const STR_PREF_REX
[16] =
56 static const ZydisPredefinedToken
* const TOK_PREF_REX
[16] =
58 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_40
,
59 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_41
,
60 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_42
,
61 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_43
,
62 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_44
,
63 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_45
,
64 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_46
,
65 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_47
,
66 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_48
,
67 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_49
,
68 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_4A
,
69 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_4B
,
70 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_4C
,
71 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_4D
,
72 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_4E
,
73 (const ZydisPredefinedToken
* const)&TOK_DATA_PREF_REX_4F
76 /* ============================================================================================== */
77 /* Helper functions */
78 /* ============================================================================================== */
80 ZyanU32
ZydisFormatterHelperGetExplicitSize(const ZydisFormatter
* formatter
,
81 ZydisFormatterContext
* context
, const ZydisDecodedOperand
* operand
)
83 ZYAN_ASSERT(formatter
);
87 ZYAN_ASSERT(operand
->type
== ZYDIS_OPERAND_TYPE_MEMORY
);
88 ZYAN_ASSERT((operand
->mem
.type
== ZYDIS_MEMOP_TYPE_MEM
) ||
89 (operand
->mem
.type
== ZYDIS_MEMOP_TYPE_VSIB
));
91 if (formatter
->force_memory_size
)
96 if (!context
->operands
)
98 // Single operand formatting. We can not derive the explicit size by using the other
106 if (context
->instruction
->operand_count_visible
< 2)
110 if ((context
->operands
[1].type
== ZYDIS_OPERAND_TYPE_UNUSED
) ||
111 (context
->operands
[1].type
== ZYDIS_OPERAND_TYPE_IMMEDIATE
))
113 return context
->operands
[0].size
;
115 if (context
->operands
[0].size
!= context
->operands
[1].size
)
117 return context
->operands
[0].size
;
119 if ((context
->operands
[1].type
== ZYDIS_OPERAND_TYPE_REGISTER
) &&
120 (context
->operands
[1].visibility
== ZYDIS_OPERAND_VISIBILITY_IMPLICIT
) &&
121 (context
->operands
[1].reg
.value
== ZYDIS_REGISTER_CL
))
123 return context
->operands
[0].size
;
128 if (context
->operands
[operand
->id
- 1].size
!=
129 context
->operands
[operand
->id
].size
)
131 return context
->operands
[operand
->id
].size
;
141 /* ============================================================================================== */
142 /* Formatter functions */
143 /* ============================================================================================== */
145 /* ---------------------------------------------------------------------------------------------- */
147 /* ---------------------------------------------------------------------------------------------- */
149 ZyanStatus
ZydisFormatterBaseFormatOperandREG(const ZydisFormatter
* formatter
,
150 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
152 ZYAN_ASSERT(formatter
);
154 ZYAN_ASSERT(context
);
156 return formatter
->func_print_register(formatter
, buffer
, context
, context
->operand
->reg
.value
);
159 ZyanStatus
ZydisFormatterBaseFormatOperandPTR(const ZydisFormatter
* formatter
,
160 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
162 ZYAN_ASSERT(formatter
);
164 ZYAN_ASSERT(context
);
166 ZYDIS_BUFFER_APPEND_TOKEN(buffer
, ZYDIS_TOKEN_IMMEDIATE
);
167 ZYDIS_STRING_APPEND_NUM_U(formatter
, formatter
->addr_base
, &buffer
->string
,
168 context
->operand
->ptr
.segment
, 4, formatter
->hex_force_leading_number
);
169 ZYDIS_BUFFER_APPEND(buffer
, DELIM_SEGMENT
);
172 switch (context
->instruction
->operand_width
)
181 return ZYAN_STATUS_INVALID_ARGUMENT
;
184 ZYDIS_BUFFER_APPEND_TOKEN(buffer
, ZYDIS_TOKEN_IMMEDIATE
);
185 ZYDIS_STRING_APPEND_NUM_U(formatter
, formatter
->addr_base
, &buffer
->string
,
186 context
->operand
->ptr
.offset
, padding
, formatter
->hex_force_leading_number
);
188 return ZYAN_STATUS_SUCCESS
;
191 ZyanStatus
ZydisFormatterBaseFormatOperandIMM(const ZydisFormatter
* formatter
,
192 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
194 ZYAN_ASSERT(formatter
);
196 ZYAN_ASSERT(context
);
198 // The immediate operand contains an address
199 if (context
->operand
->imm
.is_relative
)
201 const ZyanBool absolute
= !formatter
->force_relative_branches
&&
202 (context
->runtime_address
!= ZYDIS_RUNTIME_ADDRESS_NONE
);
205 return formatter
->func_print_address_abs(formatter
, buffer
, context
);
207 return formatter
->func_print_address_rel(formatter
, buffer
, context
);
210 // The immediate operand contains an actual ordinal value
211 return formatter
->func_print_imm(formatter
, buffer
, context
);
214 /* ---------------------------------------------------------------------------------------------- */
215 /* Elemental tokens */
216 /* ---------------------------------------------------------------------------------------------- */
218 ZyanStatus
ZydisFormatterBasePrintAddressABS(const ZydisFormatter
* formatter
,
219 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
221 ZYAN_ASSERT(formatter
);
223 ZYAN_ASSERT(context
);
226 ZYAN_CHECK(ZydisCalcAbsoluteAddress(context
->instruction
, context
->operand
,
227 context
->runtime_address
, &address
));
228 ZyanU8 padding
= (formatter
->addr_padding_absolute
==
229 ZYDIS_PADDING_AUTO
) ? 0 : (ZyanU8
)formatter
->addr_padding_absolute
;
230 if ((formatter
->addr_padding_absolute
== ZYDIS_PADDING_AUTO
) &&
231 (formatter
->addr_base
== ZYDIS_NUMERIC_BASE_HEX
))
233 switch (context
->instruction
->stack_width
)
237 address
= (ZyanU16
)address
;
241 address
= (ZyanU32
)address
;
247 return ZYAN_STATUS_INVALID_ARGUMENT
;
251 ZYDIS_BUFFER_APPEND_TOKEN(buffer
, ZYDIS_TOKEN_ADDRESS_ABS
);
252 ZYDIS_STRING_APPEND_NUM_U(formatter
, formatter
->addr_base
, &buffer
->string
, address
, padding
,
253 formatter
->hex_force_leading_number
);
255 return ZYAN_STATUS_SUCCESS
;
258 ZyanStatus
ZydisFormatterBasePrintAddressREL(const ZydisFormatter
* formatter
,
259 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
261 ZYAN_ASSERT(formatter
);
263 ZYAN_ASSERT(context
);
266 ZYAN_CHECK(ZydisCalcAbsoluteAddress(context
->instruction
, context
->operand
, 0, &address
));
268 ZyanU8 padding
= (formatter
->addr_padding_relative
==
269 ZYDIS_PADDING_AUTO
) ? 0 : (ZyanU8
)formatter
->addr_padding_relative
;
270 if ((formatter
->addr_padding_relative
== ZYDIS_PADDING_AUTO
) &&
271 (formatter
->addr_base
== ZYDIS_NUMERIC_BASE_HEX
))
273 switch (context
->instruction
->stack_width
)
277 address
= (ZyanU16
)address
;
281 address
= (ZyanU32
)address
;
287 return ZYAN_STATUS_INVALID_ARGUMENT
;
291 ZYDIS_BUFFER_APPEND_TOKEN(buffer
, ZYDIS_TOKEN_ADDRESS_REL
);
292 switch (formatter
->addr_signedness
)
294 case ZYDIS_SIGNEDNESS_AUTO
:
295 case ZYDIS_SIGNEDNESS_SIGNED
:
296 ZYDIS_STRING_APPEND_NUM_S(formatter
, formatter
->addr_base
, &buffer
->string
, address
,
297 padding
, formatter
->hex_force_leading_number
, ZYAN_TRUE
);
299 case ZYDIS_SIGNEDNESS_UNSIGNED
:
300 ZYAN_CHECK(ZydisStringAppendShort(&buffer
->string
, &STR_ADD
));
301 ZYDIS_STRING_APPEND_NUM_U(formatter
, formatter
->addr_base
, &buffer
->string
, address
,
302 padding
, formatter
->hex_force_leading_number
);
305 return ZYAN_STATUS_INVALID_ARGUMENT
;
308 return ZYAN_STATUS_SUCCESS
;
311 ZyanStatus
ZydisFormatterBasePrintIMM(const ZydisFormatter
* formatter
,
312 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
314 ZYAN_ASSERT(formatter
);
316 ZYAN_ASSERT(context
);
318 ZYDIS_BUFFER_APPEND_TOKEN(buffer
, ZYDIS_TOKEN_IMMEDIATE
);
320 const ZyanBool is_signed
=
321 (formatter
->imm_signedness
== ZYDIS_SIGNEDNESS_SIGNED
) ||
322 (formatter
->imm_signedness
== ZYDIS_SIGNEDNESS_AUTO
&& (context
->operand
->imm
.is_signed
));
323 if (is_signed
&& (context
->operand
->imm
.value
.s
< 0))
325 ZYDIS_STRING_APPEND_NUM_S(formatter
, formatter
->imm_base
, &buffer
->string
,
326 context
->operand
->imm
.value
.s
, formatter
->imm_padding
,
327 formatter
->hex_force_leading_number
, ZYAN_FALSE
);
328 return ZYAN_STATUS_SUCCESS
;
331 ZyanU8 padding
= (formatter
->imm_padding
==
332 ZYDIS_PADDING_AUTO
) ? 0 : (ZyanU8
)formatter
->imm_padding
;
333 switch (context
->instruction
->operand_width
)
336 if (formatter
->imm_padding
== ZYDIS_PADDING_AUTO
)
340 value
= (ZyanU8
)context
->operand
->imm
.value
.u
;
343 if (formatter
->imm_padding
== ZYDIS_PADDING_AUTO
)
347 value
= (ZyanU16
)context
->operand
->imm
.value
.u
;
350 if (formatter
->imm_padding
== ZYDIS_PADDING_AUTO
)
354 value
= (ZyanU32
)context
->operand
->imm
.value
.u
;
357 if (formatter
->imm_padding
== ZYDIS_PADDING_AUTO
)
361 value
= (ZyanU64
)context
->operand
->imm
.value
.u
;
364 return ZYAN_STATUS_INVALID_ARGUMENT
;
366 ZYDIS_STRING_APPEND_NUM_U(formatter
, formatter
->imm_base
, &buffer
->string
, value
, padding
,
367 formatter
->hex_force_leading_number
);
369 return ZYAN_STATUS_SUCCESS
;
372 /* ---------------------------------------------------------------------------------------------- */
373 /* Optional tokens */
374 /* ---------------------------------------------------------------------------------------------- */
376 ZyanStatus
ZydisFormatterBasePrintSegment(const ZydisFormatter
* formatter
,
377 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
379 ZYAN_ASSERT(formatter
);
381 ZYAN_ASSERT(context
);
383 ZyanBool printed_segment
= ZYAN_FALSE
;
384 switch (context
->operand
->mem
.segment
)
386 case ZYDIS_REGISTER_ES
:
387 case ZYDIS_REGISTER_CS
:
388 case ZYDIS_REGISTER_FS
:
389 case ZYDIS_REGISTER_GS
:
390 ZYAN_CHECK(formatter
->func_print_register(formatter
, buffer
, context
,
391 context
->operand
->mem
.segment
));
392 printed_segment
= ZYAN_TRUE
;
394 case ZYDIS_REGISTER_SS
:
395 if ((formatter
->force_memory_segment
) ||
396 (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_SEGMENT_SS
))
398 ZYAN_CHECK(formatter
->func_print_register(formatter
, buffer
, context
,
399 context
->operand
->mem
.segment
));
400 printed_segment
= ZYAN_TRUE
;
403 case ZYDIS_REGISTER_DS
:
404 if ((formatter
->force_memory_segment
) ||
405 (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_SEGMENT_DS
))
407 ZYAN_CHECK(formatter
->func_print_register(formatter
, buffer
, context
,
408 context
->operand
->mem
.segment
));
409 printed_segment
= ZYAN_TRUE
;
417 ZYDIS_BUFFER_APPEND(buffer
, DELIM_SEGMENT
);
420 return ZYAN_STATUS_SUCCESS
;
423 ZyanStatus
ZydisFormatterBasePrintPrefixes(const ZydisFormatter
* formatter
,
424 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
)
426 ZYAN_ASSERT(formatter
);
428 ZYAN_ASSERT(context
);
430 if (formatter
->detailed_prefixes
)
432 for (ZyanU8 i
= 0; i
< context
->instruction
->raw
.prefix_count
; ++i
)
434 const ZyanU8 value
= context
->instruction
->raw
.prefixes
[i
].value
;
435 switch (context
->instruction
->raw
.prefixes
[i
].type
)
437 case ZYDIS_PREFIX_TYPE_IGNORED
:
438 case ZYDIS_PREFIX_TYPE_MANDATORY
:
440 if ((value
& 0xF0) == 0x40)
442 if (buffer
->is_token_list
)
445 ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer
,
446 TOK_PREF_REX
[value
& 0x0F]));
449 ZYAN_CHECK(ZydisStringAppendShortCase(&buffer
->string
,
450 STR_PREF_REX
[value
& 0x0F], formatter
->case_prefixes
));
457 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_LOCK
, formatter
->case_prefixes
);
460 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_SEG_CS
, formatter
->case_prefixes
);
463 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_SEG_SS
, formatter
->case_prefixes
);
466 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_SEG_DS
, formatter
->case_prefixes
);
469 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_SEG_ES
, formatter
->case_prefixes
);
472 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_SEG_FS
, formatter
->case_prefixes
);
475 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_SEG_GS
, formatter
->case_prefixes
);
478 ZYDIS_BUFFER_APPEND_TOKEN(buffer
, ZYDIS_TOKEN_PREFIX
);
479 ZYAN_CHECK(ZydisStringAppendHexU(&buffer
->string
, value
, 0,
480 formatter
->hex_force_leading_number
, formatter
->hex_uppercase
,
481 ZYAN_NULL
, ZYAN_NULL
));
482 ZYDIS_BUFFER_APPEND_TOKEN(buffer
, ZYDIS_TOKEN_WHITESPACE
);
483 ZYAN_CHECK(ZydisStringAppendShort(&buffer
->string
, &STR_WHITESPACE
));
489 case ZYDIS_PREFIX_TYPE_EFFECTIVE
:
493 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_LOCK
, formatter
->case_prefixes
);
496 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_XACQUIRE
)
498 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_XACQUIRE
, formatter
->case_prefixes
);
500 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_REPNE
)
502 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_REPNE
, formatter
->case_prefixes
);
505 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_BND
)
507 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_BND
, formatter
->case_prefixes
);
511 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_XRELEASE
)
513 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_XRELEASE
, formatter
->case_prefixes
);
515 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_REP
)
517 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_REP
, formatter
->case_prefixes
);
519 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_REPE
)
521 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_REPE
, formatter
->case_prefixes
);
529 return ZYAN_STATUS_INVALID_ARGUMENT
;
532 return ZYAN_STATUS_SUCCESS
;
535 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_XACQUIRE
)
537 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_XACQUIRE
, formatter
->case_prefixes
);
539 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_XRELEASE
)
541 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_XRELEASE
, formatter
->case_prefixes
);
544 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_LOCK
)
546 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_LOCK
, formatter
->case_prefixes
);
549 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_BND
)
551 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_BND
, formatter
->case_prefixes
);
554 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_NOTRACK
)
556 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_NOTRACK
, formatter
->case_prefixes
);
559 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_REP
)
561 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_REP
, formatter
->case_prefixes
);
562 return ZYAN_STATUS_SUCCESS
;
564 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_REPE
)
566 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_REPE
, formatter
->case_prefixes
);
567 return ZYAN_STATUS_SUCCESS
;
569 if (context
->instruction
->attributes
& ZYDIS_ATTRIB_HAS_REPNE
)
571 ZYDIS_BUFFER_APPEND_CASE(buffer
, PREF_REPNE
, formatter
->case_prefixes
);
572 return ZYAN_STATUS_SUCCESS
;
575 return ZYAN_STATUS_SUCCESS
;
578 ZyanStatus
ZydisFormatterBasePrintDecorator(const ZydisFormatter
* formatter
,
579 ZydisFormatterBuffer
* buffer
, ZydisFormatterContext
* context
, ZydisDecorator decorator
)
581 ZYAN_ASSERT(formatter
);
583 ZYAN_ASSERT(context
);
585 #if defined(ZYDIS_DISABLE_AVX512) && defined(ZYDIS_DISABLE_KNC)
586 ZYAN_UNUSED(formatter
);
588 ZYAN_UNUSED(context
);
593 case ZYDIS_DECORATOR_MASK
:
595 #if !defined(ZYDIS_DISABLE_AVX512) || !defined(ZYDIS_DISABLE_KNC)
596 if (context
->instruction
->avx
.mask
.reg
!= ZYDIS_REGISTER_K0
)
598 if (buffer
->is_token_list
)
600 ZYDIS_BUFFER_APPEND(buffer
, DECO_BEGIN
);
601 ZYAN_CHECK(formatter
->func_print_register(formatter
, buffer
, context
,
602 context
->instruction
->avx
.mask
.reg
));
603 ZYDIS_BUFFER_APPEND(buffer
, DECO_END
);
606 ZYAN_CHECK(ZydisStringAppendShort(&buffer
->string
, &STR_DECO_BEGIN
));
607 ZYAN_CHECK(formatter
->func_print_register(formatter
, buffer
, context
,
608 context
->instruction
->avx
.mask
.reg
));
609 ZYAN_CHECK(ZydisStringAppendShort(&buffer
->string
, &STR_DECO_END
));
612 // Only print the zeroing decorator, if the instruction is not a "zeroing masking only"
613 // instruction (e.g. `vcmpsd`)
614 if ((context
->instruction
->avx
.mask
.mode
== ZYDIS_MASK_MODE_ZEROING
||
615 context
->instruction
->avx
.mask
.mode
== ZYDIS_MASK_MODE_CONTROL_ZEROING
) &&
616 (context
->instruction
->raw
.evex
.z
))
618 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_ZERO
, formatter
->case_decorators
);
624 case ZYDIS_DECORATOR_BC
:
625 #if !defined(ZYDIS_DISABLE_AVX512)
626 if (!context
->instruction
->avx
.broadcast
.is_static
)
628 switch (context
->instruction
->avx
.broadcast
.mode
)
630 case ZYDIS_BROADCAST_MODE_INVALID
:
632 case ZYDIS_BROADCAST_MODE_1_TO_2
:
633 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_1TO2
, formatter
->case_decorators
);
635 case ZYDIS_BROADCAST_MODE_1_TO_4
:
636 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_1TO4
, formatter
->case_decorators
);
638 case ZYDIS_BROADCAST_MODE_1_TO_8
:
639 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_1TO8
, formatter
->case_decorators
);
641 case ZYDIS_BROADCAST_MODE_1_TO_16
:
642 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_1TO16
, formatter
->case_decorators
);
644 case ZYDIS_BROADCAST_MODE_1_TO_32
:
645 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_1TO32
, formatter
->case_decorators
);
647 case ZYDIS_BROADCAST_MODE_1_TO_64
:
648 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_1TO64
, formatter
->case_decorators
);
650 case ZYDIS_BROADCAST_MODE_4_TO_8
:
651 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_4TO8
, formatter
->case_decorators
);
653 case ZYDIS_BROADCAST_MODE_4_TO_16
:
654 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_4TO16
, formatter
->case_decorators
);
656 case ZYDIS_BROADCAST_MODE_8_TO_16
:
657 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_8TO16
, formatter
->case_decorators
);
660 return ZYAN_STATUS_INVALID_ARGUMENT
;
665 case ZYDIS_DECORATOR_RC
:
666 #if !defined(ZYDIS_DISABLE_AVX512)
667 if (context
->instruction
->avx
.has_sae
)
669 switch (context
->instruction
->avx
.rounding
.mode
)
671 case ZYDIS_ROUNDING_MODE_INVALID
:
673 case ZYDIS_ROUNDING_MODE_RN
:
674 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RN_SAE
, formatter
->case_decorators
);
676 case ZYDIS_ROUNDING_MODE_RD
:
677 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RD_SAE
, formatter
->case_decorators
);
679 case ZYDIS_ROUNDING_MODE_RU
:
680 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RU_SAE
, formatter
->case_decorators
);
682 case ZYDIS_ROUNDING_MODE_RZ
:
683 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RZ_SAE
, formatter
->case_decorators
);
686 return ZYAN_STATUS_INVALID_ARGUMENT
;
690 switch (context
->instruction
->avx
.rounding
.mode
)
692 case ZYDIS_ROUNDING_MODE_INVALID
:
694 case ZYDIS_ROUNDING_MODE_RN
:
695 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RN
, formatter
->case_decorators
);
697 case ZYDIS_ROUNDING_MODE_RD
:
698 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RD
, formatter
->case_decorators
);
700 case ZYDIS_ROUNDING_MODE_RU
:
701 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RU
, formatter
->case_decorators
);
703 case ZYDIS_ROUNDING_MODE_RZ
:
704 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_RZ
, formatter
->case_decorators
);
707 return ZYAN_STATUS_INVALID_ARGUMENT
;
712 case ZYDIS_DECORATOR_SAE
:
713 #if !defined(ZYDIS_DISABLE_AVX512)
714 if (context
->instruction
->avx
.has_sae
&& !context
->instruction
->avx
.rounding
.mode
)
716 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_SAE
, formatter
->case_decorators
);
720 case ZYDIS_DECORATOR_SWIZZLE
:
721 #if !defined(ZYDIS_DISABLE_KNC)
722 switch (context
->instruction
->avx
.swizzle
.mode
)
724 case ZYDIS_SWIZZLE_MODE_INVALID
:
725 case ZYDIS_SWIZZLE_MODE_DCBA
:
726 // Nothing to do here
728 case ZYDIS_SWIZZLE_MODE_CDAB
:
729 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_CDAB
, formatter
->case_decorators
);
731 case ZYDIS_SWIZZLE_MODE_BADC
:
732 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_BADC
, formatter
->case_decorators
);
734 case ZYDIS_SWIZZLE_MODE_DACB
:
735 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_DACB
, formatter
->case_decorators
);
737 case ZYDIS_SWIZZLE_MODE_AAAA
:
738 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_AAAA
, formatter
->case_decorators
);
740 case ZYDIS_SWIZZLE_MODE_BBBB
:
741 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_BBBB
, formatter
->case_decorators
);
743 case ZYDIS_SWIZZLE_MODE_CCCC
:
744 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_CCCC
, formatter
->case_decorators
);
746 case ZYDIS_SWIZZLE_MODE_DDDD
:
747 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_DDDD
, formatter
->case_decorators
);
750 return ZYAN_STATUS_INVALID_ARGUMENT
;
754 case ZYDIS_DECORATOR_CONVERSION
:
755 #if !defined(ZYDIS_DISABLE_KNC)
756 switch (context
->instruction
->avx
.conversion
.mode
)
758 case ZYDIS_CONVERSION_MODE_INVALID
:
760 case ZYDIS_CONVERSION_MODE_FLOAT16
:
761 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_FLOAT16
, formatter
->case_decorators
);
763 case ZYDIS_CONVERSION_MODE_SINT8
:
764 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_SINT8
, formatter
->case_decorators
);
766 case ZYDIS_CONVERSION_MODE_UINT8
:
767 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_UINT8
, formatter
->case_decorators
);
769 case ZYDIS_CONVERSION_MODE_SINT16
:
770 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_SINT16
, formatter
->case_decorators
);
772 case ZYDIS_CONVERSION_MODE_UINT16
:
773 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_UINT16
, formatter
->case_decorators
);
776 return ZYAN_STATUS_INVALID_ARGUMENT
;
780 case ZYDIS_DECORATOR_EH
:
781 #if !defined(ZYDIS_DISABLE_KNC)
782 if (context
->instruction
->avx
.has_eviction_hint
)
784 ZYDIS_BUFFER_APPEND_CASE(buffer
, DECO_EH
, formatter
->case_decorators
);
789 return ZYAN_STATUS_INVALID_ARGUMENT
;
792 return ZYAN_STATUS_SUCCESS
;
795 /* ---------------------------------------------------------------------------------------------- */
797 /* ============================================================================================== */