d3d8/tests: Test the presentation parameters after creating an additional swap chain.
[wine.git] / libs / zydis / src / FormatterBase.c
blob6aad525dc25b2d5ae62b4fbdaab379b750410d61
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
23 * SOFTWARE.
25 ***************************************************************************************************/
27 #include <Zydis/Internal/FormatterBase.h>
28 #include <Zydis/Utils.h>
30 /* ============================================================================================== */
31 /* Constants */
32 /* ============================================================================================== */
34 #include <Generated/FormatterStrings.inc>
36 static const ZydisShortString* const STR_PREF_REX[16] =
38 &STR_PREF_REX_40,
39 &STR_PREF_REX_41,
40 &STR_PREF_REX_42,
41 &STR_PREF_REX_43,
42 &STR_PREF_REX_44,
43 &STR_PREF_REX_45,
44 &STR_PREF_REX_46,
45 &STR_PREF_REX_47,
46 &STR_PREF_REX_48,
47 &STR_PREF_REX_49,
48 &STR_PREF_REX_4A,
49 &STR_PREF_REX_4B,
50 &STR_PREF_REX_4C,
51 &STR_PREF_REX_4D,
52 &STR_PREF_REX_4E,
53 &STR_PREF_REX_4F
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);
84 ZYAN_ASSERT(context);
85 ZYAN_ASSERT(operand);
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)
93 return operand->size;
96 if (!context->operands)
98 // Single operand formatting. We can not derive the explicit size by using the other
99 // operands.
100 return 0;
103 switch (operand->id)
105 case 0:
106 if (context->instruction->operand_count_visible < 2)
108 return 0;
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;
125 break;
126 case 1:
127 case 2:
128 if (context->operands[operand->id - 1].size !=
129 context->operands[operand->id].size)
131 return context->operands[operand->id].size;
133 break;
134 default:
135 break;
138 return 0;
141 /* ============================================================================================== */
142 /* Formatter functions */
143 /* ============================================================================================== */
145 /* ---------------------------------------------------------------------------------------------- */
146 /* Operands */
147 /* ---------------------------------------------------------------------------------------------- */
149 ZyanStatus ZydisFormatterBaseFormatOperandREG(const ZydisFormatter* formatter,
150 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
152 ZYAN_ASSERT(formatter);
153 ZYAN_ASSERT(buffer);
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);
163 ZYAN_ASSERT(buffer);
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);
171 ZyanU8 padding;
172 switch (context->instruction->operand_width)
174 case 16:
175 padding = 4;
176 break;
177 case 32:
178 padding = 8;
179 break;
180 default:
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);
195 ZYAN_ASSERT(buffer);
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);
203 if (absolute)
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);
222 ZYAN_ASSERT(buffer);
223 ZYAN_ASSERT(context);
225 ZyanU64 address;
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)
235 case 16:
236 padding = 4;
237 address = (ZyanU16)address;
238 break;
239 case 32:
240 padding = 8;
241 address = (ZyanU32)address;
242 break;
243 case 64:
244 padding = 16;
245 break;
246 default:
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);
262 ZYAN_ASSERT(buffer);
263 ZYAN_ASSERT(context);
265 ZyanU64 address;
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)
275 case 16:
276 padding = 4;
277 address = (ZyanU16)address;
278 break;
279 case 32:
280 padding = 8;
281 address = (ZyanU32)address;
282 break;
283 case 64:
284 padding = 16;
285 break;
286 default:
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);
298 break;
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);
303 break;
304 default:
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);
315 ZYAN_ASSERT(buffer);
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;
330 ZyanU64 value;
331 ZyanU8 padding = (formatter->imm_padding ==
332 ZYDIS_PADDING_AUTO) ? 0 : (ZyanU8)formatter->imm_padding;
333 switch (context->instruction->operand_width)
335 case 8:
336 if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
338 padding = 2;
340 value = (ZyanU8 )context->operand->imm.value.u;
341 break;
342 case 16:
343 if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
345 padding = 4;
347 value = (ZyanU16)context->operand->imm.value.u;
348 break;
349 case 32:
350 if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
352 padding = 8;
354 value = (ZyanU32)context->operand->imm.value.u;
355 break;
356 case 64:
357 if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
359 padding = 16;
361 value = (ZyanU64)context->operand->imm.value.u;
362 break;
363 default:
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);
380 ZYAN_ASSERT(buffer);
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;
393 break;
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;
402 break;
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;
411 break;
412 default:
413 break;
415 if (printed_segment)
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);
427 ZYAN_ASSERT(buffer);
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)
444 // TODO: Case
445 ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer,
446 TOK_PREF_REX[value & 0x0F]));
447 } else
449 ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string,
450 STR_PREF_REX[value & 0x0F], formatter->case_prefixes));
452 } else
454 switch (value)
456 case 0xF0:
457 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes);
458 break;
459 case 0x2E:
460 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_CS, formatter->case_prefixes);
461 break;
462 case 0x36:
463 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_SS, formatter->case_prefixes);
464 break;
465 case 0x3E:
466 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_DS, formatter->case_prefixes);
467 break;
468 case 0x26:
469 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_ES, formatter->case_prefixes);
470 break;
471 case 0x64:
472 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_FS, formatter->case_prefixes);
473 break;
474 case 0x65:
475 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_GS, formatter->case_prefixes);
476 break;
477 default:
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));
484 break;
487 break;
489 case ZYDIS_PREFIX_TYPE_EFFECTIVE:
490 switch (value)
492 case 0xF0:
493 ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes);
494 break;
495 case 0xF2:
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);
509 break;
510 case 0xF3:
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);
523 break;
524 default:
525 break;
527 break;
528 default:
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);
582 ZYAN_ASSERT(buffer);
583 ZYAN_ASSERT(context);
585 #if defined(ZYDIS_DISABLE_AVX512) && defined(ZYDIS_DISABLE_KNC)
586 ZYAN_UNUSED(formatter);
587 ZYAN_UNUSED(buffer);
588 ZYAN_UNUSED(context);
589 #endif
591 switch (decorator)
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);
604 } else
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);
621 #endif
622 break;
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:
631 break;
632 case ZYDIS_BROADCAST_MODE_1_TO_2:
633 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO2, formatter->case_decorators);
634 break;
635 case ZYDIS_BROADCAST_MODE_1_TO_4:
636 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO4, formatter->case_decorators);
637 break;
638 case ZYDIS_BROADCAST_MODE_1_TO_8:
639 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO8, formatter->case_decorators);
640 break;
641 case ZYDIS_BROADCAST_MODE_1_TO_16:
642 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO16, formatter->case_decorators);
643 break;
644 case ZYDIS_BROADCAST_MODE_1_TO_32:
645 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO32, formatter->case_decorators);
646 break;
647 case ZYDIS_BROADCAST_MODE_1_TO_64:
648 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO64, formatter->case_decorators);
649 break;
650 case ZYDIS_BROADCAST_MODE_4_TO_8:
651 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_4TO8, formatter->case_decorators);
652 break;
653 case ZYDIS_BROADCAST_MODE_4_TO_16:
654 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_4TO16, formatter->case_decorators);
655 break;
656 case ZYDIS_BROADCAST_MODE_8_TO_16:
657 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_8TO16, formatter->case_decorators);
658 break;
659 default:
660 return ZYAN_STATUS_INVALID_ARGUMENT;
663 #endif
664 break;
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:
672 break;
673 case ZYDIS_ROUNDING_MODE_RN:
674 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RN_SAE, formatter->case_decorators);
675 break;
676 case ZYDIS_ROUNDING_MODE_RD:
677 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RD_SAE, formatter->case_decorators);
678 break;
679 case ZYDIS_ROUNDING_MODE_RU:
680 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RU_SAE, formatter->case_decorators);
681 break;
682 case ZYDIS_ROUNDING_MODE_RZ:
683 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RZ_SAE, formatter->case_decorators);
684 break;
685 default:
686 return ZYAN_STATUS_INVALID_ARGUMENT;
688 } else
690 switch (context->instruction->avx.rounding.mode)
692 case ZYDIS_ROUNDING_MODE_INVALID:
693 break;
694 case ZYDIS_ROUNDING_MODE_RN:
695 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RN, formatter->case_decorators);
696 break;
697 case ZYDIS_ROUNDING_MODE_RD:
698 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RD, formatter->case_decorators);
699 break;
700 case ZYDIS_ROUNDING_MODE_RU:
701 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RU, formatter->case_decorators);
702 break;
703 case ZYDIS_ROUNDING_MODE_RZ:
704 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RZ, formatter->case_decorators);
705 break;
706 default:
707 return ZYAN_STATUS_INVALID_ARGUMENT;
710 #endif
711 break;
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);
718 #endif
719 break;
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
727 break;
728 case ZYDIS_SWIZZLE_MODE_CDAB:
729 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_CDAB, formatter->case_decorators);
730 break;
731 case ZYDIS_SWIZZLE_MODE_BADC:
732 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_BADC, formatter->case_decorators);
733 break;
734 case ZYDIS_SWIZZLE_MODE_DACB:
735 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DACB, formatter->case_decorators);
736 break;
737 case ZYDIS_SWIZZLE_MODE_AAAA:
738 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_AAAA, formatter->case_decorators);
739 break;
740 case ZYDIS_SWIZZLE_MODE_BBBB:
741 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_BBBB, formatter->case_decorators);
742 break;
743 case ZYDIS_SWIZZLE_MODE_CCCC:
744 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_CCCC, formatter->case_decorators);
745 break;
746 case ZYDIS_SWIZZLE_MODE_DDDD:
747 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DDDD, formatter->case_decorators);
748 break;
749 default:
750 return ZYAN_STATUS_INVALID_ARGUMENT;
752 #endif
753 break;
754 case ZYDIS_DECORATOR_CONVERSION:
755 #if !defined(ZYDIS_DISABLE_KNC)
756 switch (context->instruction->avx.conversion.mode)
758 case ZYDIS_CONVERSION_MODE_INVALID:
759 break;
760 case ZYDIS_CONVERSION_MODE_FLOAT16:
761 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_FLOAT16, formatter->case_decorators);
762 break;
763 case ZYDIS_CONVERSION_MODE_SINT8:
764 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SINT8, formatter->case_decorators);
765 break;
766 case ZYDIS_CONVERSION_MODE_UINT8:
767 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_UINT8, formatter->case_decorators);
768 break;
769 case ZYDIS_CONVERSION_MODE_SINT16:
770 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SINT16, formatter->case_decorators);
771 break;
772 case ZYDIS_CONVERSION_MODE_UINT16:
773 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_UINT16, formatter->case_decorators);
774 break;
775 default:
776 return ZYAN_STATUS_INVALID_ARGUMENT;
778 #endif
779 break;
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);
786 #endif
787 break;
788 default:
789 return ZYAN_STATUS_INVALID_ARGUMENT;
792 return ZYAN_STATUS_SUCCESS;
795 /* ---------------------------------------------------------------------------------------------- */
797 /* ============================================================================================== */