xref: /haiku/src/libs/zydis/Zydis/FormatterBase.c (revision 1003e004e6c97eb60657a98928dd334e141c59ee)
1*1003e004SJérôme Duval /***************************************************************************************************
2*1003e004SJérôme Duval 
3*1003e004SJérôme Duval   Zyan Disassembler Library (Zydis)
4*1003e004SJérôme Duval 
5*1003e004SJérôme Duval   Original Author : Florian Bernd, Joel Hoener
6*1003e004SJérôme Duval 
7*1003e004SJérôme Duval  * Permission is hereby granted, free of charge, to any person obtaining a copy
8*1003e004SJérôme Duval  * of this software and associated documentation files (the "Software"), to deal
9*1003e004SJérôme Duval  * in the Software without restriction, including without limitation the rights
10*1003e004SJérôme Duval  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11*1003e004SJérôme Duval  * copies of the Software, and to permit persons to whom the Software is
12*1003e004SJérôme Duval  * furnished to do so, subject to the following conditions:
13*1003e004SJérôme Duval  *
14*1003e004SJérôme Duval  * The above copyright notice and this permission notice shall be included in all
15*1003e004SJérôme Duval  * copies or substantial portions of the Software.
16*1003e004SJérôme Duval  *
17*1003e004SJérôme Duval  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*1003e004SJérôme Duval  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*1003e004SJérôme Duval  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20*1003e004SJérôme Duval  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*1003e004SJérôme Duval  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22*1003e004SJérôme Duval  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23*1003e004SJérôme Duval  * SOFTWARE.
24*1003e004SJérôme Duval 
25*1003e004SJérôme Duval ***************************************************************************************************/
26*1003e004SJérôme Duval 
27*1003e004SJérôme Duval #include <Zydis/Internal/FormatterBase.h>
28*1003e004SJérôme Duval #include <Zydis/Utils.h>
29*1003e004SJérôme Duval 
30*1003e004SJérôme Duval /* ============================================================================================== */
31*1003e004SJérôme Duval /* Constants                                                                                      */
32*1003e004SJérôme Duval /* ============================================================================================== */
33*1003e004SJérôme Duval 
34*1003e004SJérôme Duval #include <Generated/FormatterStrings.inc>
35*1003e004SJérôme Duval 
36*1003e004SJérôme Duval static const ZydisShortString* const STR_PREF_REX[16] =
37*1003e004SJérôme Duval {
38*1003e004SJérôme Duval     &STR_PREF_REX_40,
39*1003e004SJérôme Duval     &STR_PREF_REX_41,
40*1003e004SJérôme Duval     &STR_PREF_REX_42,
41*1003e004SJérôme Duval     &STR_PREF_REX_43,
42*1003e004SJérôme Duval     &STR_PREF_REX_44,
43*1003e004SJérôme Duval     &STR_PREF_REX_45,
44*1003e004SJérôme Duval     &STR_PREF_REX_46,
45*1003e004SJérôme Duval     &STR_PREF_REX_47,
46*1003e004SJérôme Duval     &STR_PREF_REX_48,
47*1003e004SJérôme Duval     &STR_PREF_REX_49,
48*1003e004SJérôme Duval     &STR_PREF_REX_4A,
49*1003e004SJérôme Duval     &STR_PREF_REX_4B,
50*1003e004SJérôme Duval     &STR_PREF_REX_4C,
51*1003e004SJérôme Duval     &STR_PREF_REX_4D,
52*1003e004SJérôme Duval     &STR_PREF_REX_4E,
53*1003e004SJérôme Duval     &STR_PREF_REX_4F
54*1003e004SJérôme Duval };
55*1003e004SJérôme Duval 
56*1003e004SJérôme Duval static const ZydisPredefinedToken* const TOK_PREF_REX[16] =
57*1003e004SJérôme Duval {
58*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_40,
59*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_41,
60*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_42,
61*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_43,
62*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_44,
63*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_45,
64*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_46,
65*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_47,
66*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_48,
67*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_49,
68*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4A,
69*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4B,
70*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4C,
71*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4D,
72*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4E,
73*1003e004SJérôme Duval     (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4F
74*1003e004SJérôme Duval };
75*1003e004SJérôme Duval 
76*1003e004SJérôme Duval /* ============================================================================================== */
77*1003e004SJérôme Duval /* Helper functions                                                                               */
78*1003e004SJérôme Duval /* ============================================================================================== */
79*1003e004SJérôme Duval 
ZydisFormatterHelperGetExplicitSize(const ZydisFormatter * formatter,ZydisFormatterContext * context,const ZydisDecodedOperand * operand)80*1003e004SJérôme Duval ZyanU32 ZydisFormatterHelperGetExplicitSize(const ZydisFormatter* formatter,
81*1003e004SJérôme Duval     ZydisFormatterContext* context, const ZydisDecodedOperand* operand)
82*1003e004SJérôme Duval {
83*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
84*1003e004SJérôme Duval     ZYAN_ASSERT(context);
85*1003e004SJérôme Duval     ZYAN_ASSERT(operand);
86*1003e004SJérôme Duval 
87*1003e004SJérôme Duval     ZYAN_ASSERT(operand->type == ZYDIS_OPERAND_TYPE_MEMORY);
88*1003e004SJérôme Duval     ZYAN_ASSERT((operand->mem.type == ZYDIS_MEMOP_TYPE_MEM) ||
89*1003e004SJérôme Duval                 (operand->mem.type == ZYDIS_MEMOP_TYPE_AGEN) ||
90*1003e004SJérôme Duval                 (operand->mem.type == ZYDIS_MEMOP_TYPE_VSIB));
91*1003e004SJérôme Duval 
92*1003e004SJérôme Duval     if (formatter->force_memory_size)
93*1003e004SJérôme Duval     {
94*1003e004SJérôme Duval         return operand->size;
95*1003e004SJérôme Duval     }
96*1003e004SJérôme Duval     else if (operand->mem.type == ZYDIS_MEMOP_TYPE_AGEN)
97*1003e004SJérôme Duval     {
98*1003e004SJérôme Duval         return 0;
99*1003e004SJérôme Duval     }
100*1003e004SJérôme Duval 
101*1003e004SJérôme Duval     if (!context->operands)
102*1003e004SJérôme Duval     {
103*1003e004SJérôme Duval         // Single operand formatting. We can not derive the explicit size by using the other
104*1003e004SJérôme Duval         // operands.
105*1003e004SJérôme Duval         return 0;
106*1003e004SJérôme Duval     }
107*1003e004SJérôme Duval 
108*1003e004SJérôme Duval     switch (operand->id)
109*1003e004SJérôme Duval     {
110*1003e004SJérôme Duval     case 0:
111*1003e004SJérôme Duval         if (context->instruction->operand_count_visible < 2)
112*1003e004SJérôme Duval         {
113*1003e004SJérôme Duval             return 0;
114*1003e004SJérôme Duval         }
115*1003e004SJérôme Duval         if ((context->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
116*1003e004SJérôme Duval             (context->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
117*1003e004SJérôme Duval         {
118*1003e004SJérôme Duval             return context->operands[0].size;
119*1003e004SJérôme Duval         }
120*1003e004SJérôme Duval         if (context->operands[0].size != context->operands[1].size)
121*1003e004SJérôme Duval         {
122*1003e004SJérôme Duval             return context->operands[0].size;
123*1003e004SJérôme Duval         }
124*1003e004SJérôme Duval         if ((context->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
125*1003e004SJérôme Duval             (context->operands[1].visibility == ZYDIS_OPERAND_VISIBILITY_IMPLICIT) &&
126*1003e004SJérôme Duval             (context->operands[1].reg.value == ZYDIS_REGISTER_CL))
127*1003e004SJérôme Duval         {
128*1003e004SJérôme Duval             return context->operands[0].size;
129*1003e004SJérôme Duval         }
130*1003e004SJérôme Duval         break;
131*1003e004SJérôme Duval     case 1:
132*1003e004SJérôme Duval     case 2:
133*1003e004SJérôme Duval         if (context->operands[operand->id - 1].size !=
134*1003e004SJérôme Duval             context->operands[operand->id].size)
135*1003e004SJérôme Duval         {
136*1003e004SJérôme Duval             return context->operands[operand->id].size;
137*1003e004SJérôme Duval         }
138*1003e004SJérôme Duval         break;
139*1003e004SJérôme Duval     default:
140*1003e004SJérôme Duval         break;
141*1003e004SJérôme Duval     }
142*1003e004SJérôme Duval 
143*1003e004SJérôme Duval     return 0;
144*1003e004SJérôme Duval }
145*1003e004SJérôme Duval 
146*1003e004SJérôme Duval /* ============================================================================================== */
147*1003e004SJérôme Duval /* Formatter functions                                                                            */
148*1003e004SJérôme Duval /* ============================================================================================== */
149*1003e004SJérôme Duval 
150*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
151*1003e004SJérôme Duval /* Operands                                                                                       */
152*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
153*1003e004SJérôme Duval 
ZydisFormatterBaseFormatOperandREG(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)154*1003e004SJérôme Duval ZyanStatus ZydisFormatterBaseFormatOperandREG(const ZydisFormatter* formatter,
155*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
156*1003e004SJérôme Duval {
157*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
158*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
159*1003e004SJérôme Duval     ZYAN_ASSERT(context);
160*1003e004SJérôme Duval 
161*1003e004SJérôme Duval     return formatter->func_print_register(formatter, buffer, context, context->operand->reg.value);
162*1003e004SJérôme Duval }
163*1003e004SJérôme Duval 
ZydisFormatterBaseFormatOperandPTR(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)164*1003e004SJérôme Duval ZyanStatus ZydisFormatterBaseFormatOperandPTR(const ZydisFormatter* formatter,
165*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
166*1003e004SJérôme Duval {
167*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
168*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
169*1003e004SJérôme Duval     ZYAN_ASSERT(context);
170*1003e004SJérôme Duval 
171*1003e004SJérôme Duval     ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_IMMEDIATE);
172*1003e004SJérôme Duval     ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string,
173*1003e004SJérôme Duval         context->operand->ptr.segment, 4, formatter->hex_force_leading_number);
174*1003e004SJérôme Duval     ZYDIS_BUFFER_APPEND(buffer, DELIM_SEGMENT);
175*1003e004SJérôme Duval 
176*1003e004SJérôme Duval     ZyanU8 padding;
177*1003e004SJérôme Duval     switch (context->instruction->operand_width)
178*1003e004SJérôme Duval     {
179*1003e004SJérôme Duval     case 16:
180*1003e004SJérôme Duval         padding = 4;
181*1003e004SJérôme Duval         break;
182*1003e004SJérôme Duval     case 32:
183*1003e004SJérôme Duval         padding = 8;
184*1003e004SJérôme Duval         break;
185*1003e004SJérôme Duval     default:
186*1003e004SJérôme Duval         return ZYAN_STATUS_INVALID_ARGUMENT;
187*1003e004SJérôme Duval     }
188*1003e004SJérôme Duval 
189*1003e004SJérôme Duval     ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_IMMEDIATE);
190*1003e004SJérôme Duval     ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string,
191*1003e004SJérôme Duval         context->operand->ptr.offset , padding, formatter->hex_force_leading_number);
192*1003e004SJérôme Duval 
193*1003e004SJérôme Duval     return ZYAN_STATUS_SUCCESS;
194*1003e004SJérôme Duval }
195*1003e004SJérôme Duval 
ZydisFormatterBaseFormatOperandIMM(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)196*1003e004SJérôme Duval ZyanStatus ZydisFormatterBaseFormatOperandIMM(const ZydisFormatter* formatter,
197*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
198*1003e004SJérôme Duval {
199*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
200*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
201*1003e004SJérôme Duval     ZYAN_ASSERT(context);
202*1003e004SJérôme Duval 
203*1003e004SJérôme Duval     // The immediate operand contains an address
204*1003e004SJérôme Duval     if (context->operand->imm.is_relative)
205*1003e004SJérôme Duval     {
206*1003e004SJérôme Duval         const ZyanBool absolute = !formatter->force_relative_branches &&
207*1003e004SJérôme Duval             (context->runtime_address != ZYDIS_RUNTIME_ADDRESS_NONE);
208*1003e004SJérôme Duval         if (absolute)
209*1003e004SJérôme Duval         {
210*1003e004SJérôme Duval             return formatter->func_print_address_abs(formatter, buffer, context);
211*1003e004SJérôme Duval         }
212*1003e004SJérôme Duval         return formatter->func_print_address_rel(formatter, buffer, context);
213*1003e004SJérôme Duval     }
214*1003e004SJérôme Duval 
215*1003e004SJérôme Duval     // The immediate operand contains an actual ordinal value
216*1003e004SJérôme Duval     return formatter->func_print_imm(formatter, buffer, context);
217*1003e004SJérôme Duval }
218*1003e004SJérôme Duval 
219*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
220*1003e004SJérôme Duval /* Elemental tokens                                                                               */
221*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
222*1003e004SJérôme Duval 
ZydisFormatterBasePrintAddressABS(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)223*1003e004SJérôme Duval ZyanStatus ZydisFormatterBasePrintAddressABS(const ZydisFormatter* formatter,
224*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
225*1003e004SJérôme Duval {
226*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
227*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
228*1003e004SJérôme Duval     ZYAN_ASSERT(context);
229*1003e004SJérôme Duval 
230*1003e004SJérôme Duval     ZyanU64 address;
231*1003e004SJérôme Duval     ZYAN_CHECK(ZydisCalcAbsoluteAddress(context->instruction, context->operand,
232*1003e004SJérôme Duval         context->runtime_address, &address));
233*1003e004SJérôme Duval     ZyanU8 padding = (formatter->addr_padding_absolute ==
234*1003e004SJérôme Duval         ZYDIS_PADDING_AUTO) ? 0 : (ZyanU8)formatter->addr_padding_absolute;
235*1003e004SJérôme Duval     if ((formatter->addr_padding_absolute == ZYDIS_PADDING_AUTO) &&
236*1003e004SJérôme Duval         (formatter->addr_base == ZYDIS_NUMERIC_BASE_HEX))
237*1003e004SJérôme Duval     {
238*1003e004SJérôme Duval         switch (context->instruction->address_width)
239*1003e004SJérôme Duval         {
240*1003e004SJérôme Duval         case 16:
241*1003e004SJérôme Duval             padding =  4;
242*1003e004SJérôme Duval             address = (ZyanU16)address;
243*1003e004SJérôme Duval             break;
244*1003e004SJérôme Duval         case 32:
245*1003e004SJérôme Duval             padding =  8;
246*1003e004SJérôme Duval             address = (ZyanU32)address;
247*1003e004SJérôme Duval             break;
248*1003e004SJérôme Duval         case 64:
249*1003e004SJérôme Duval             padding = 16;
250*1003e004SJérôme Duval             break;
251*1003e004SJérôme Duval         default:
252*1003e004SJérôme Duval             return ZYAN_STATUS_INVALID_ARGUMENT;
253*1003e004SJérôme Duval         }
254*1003e004SJérôme Duval     }
255*1003e004SJérôme Duval 
256*1003e004SJérôme Duval     ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_ADDRESS_ABS);
257*1003e004SJérôme Duval     ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string, address, padding,
258*1003e004SJérôme Duval         formatter->hex_force_leading_number);
259*1003e004SJérôme Duval 
260*1003e004SJérôme Duval     return ZYAN_STATUS_SUCCESS;
261*1003e004SJérôme Duval }
262*1003e004SJérôme Duval 
ZydisFormatterBasePrintAddressREL(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)263*1003e004SJérôme Duval ZyanStatus ZydisFormatterBasePrintAddressREL(const ZydisFormatter* formatter,
264*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
265*1003e004SJérôme Duval {
266*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
267*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
268*1003e004SJérôme Duval     ZYAN_ASSERT(context);
269*1003e004SJérôme Duval 
270*1003e004SJérôme Duval     ZyanU64 address;
271*1003e004SJérôme Duval     ZYAN_CHECK(ZydisCalcAbsoluteAddress(context->instruction, context->operand, 0, &address));
272*1003e004SJérôme Duval 
273*1003e004SJérôme Duval     ZyanU8 padding = (formatter->addr_padding_relative ==
274*1003e004SJérôme Duval         ZYDIS_PADDING_AUTO) ? 0 : (ZyanU8)formatter->addr_padding_relative;
275*1003e004SJérôme Duval     if ((formatter->addr_padding_relative == ZYDIS_PADDING_AUTO) &&
276*1003e004SJérôme Duval         (formatter->addr_base == ZYDIS_NUMERIC_BASE_HEX))
277*1003e004SJérôme Duval     {
278*1003e004SJérôme Duval         switch (context->instruction->address_width)
279*1003e004SJérôme Duval         {
280*1003e004SJérôme Duval         case 16:
281*1003e004SJérôme Duval             padding =  4;
282*1003e004SJérôme Duval             address = (ZyanU16)address;
283*1003e004SJérôme Duval             break;
284*1003e004SJérôme Duval         case 32:
285*1003e004SJérôme Duval             padding =  8;
286*1003e004SJérôme Duval             address = (ZyanU32)address;
287*1003e004SJérôme Duval             break;
288*1003e004SJérôme Duval         case 64:
289*1003e004SJérôme Duval             padding = 16;
290*1003e004SJérôme Duval             break;
291*1003e004SJérôme Duval         default:
292*1003e004SJérôme Duval             return ZYAN_STATUS_INVALID_ARGUMENT;
293*1003e004SJérôme Duval         }
294*1003e004SJérôme Duval     }
295*1003e004SJérôme Duval 
296*1003e004SJérôme Duval     ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_ADDRESS_REL);
297*1003e004SJérôme Duval     switch (formatter->addr_signedness)
298*1003e004SJérôme Duval     {
299*1003e004SJérôme Duval     case ZYDIS_SIGNEDNESS_AUTO:
300*1003e004SJérôme Duval     case ZYDIS_SIGNEDNESS_SIGNED:
301*1003e004SJérôme Duval         ZYDIS_STRING_APPEND_NUM_S(formatter, formatter->addr_base, &buffer->string, address,
302*1003e004SJérôme Duval             padding, formatter->hex_force_leading_number, ZYAN_TRUE);
303*1003e004SJérôme Duval         break;
304*1003e004SJérôme Duval     case ZYDIS_SIGNEDNESS_UNSIGNED:
305*1003e004SJérôme Duval         ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_ADD));
306*1003e004SJérôme Duval         ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string, address,
307*1003e004SJérôme Duval             padding, formatter->hex_force_leading_number);
308*1003e004SJérôme Duval         break;
309*1003e004SJérôme Duval     default:
310*1003e004SJérôme Duval         return ZYAN_STATUS_INVALID_ARGUMENT;
311*1003e004SJérôme Duval     }
312*1003e004SJérôme Duval 
313*1003e004SJérôme Duval     return ZYAN_STATUS_SUCCESS;
314*1003e004SJérôme Duval }
315*1003e004SJérôme Duval 
ZydisFormatterBasePrintIMM(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)316*1003e004SJérôme Duval ZyanStatus ZydisFormatterBasePrintIMM(const ZydisFormatter* formatter,
317*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
318*1003e004SJérôme Duval {
319*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
320*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
321*1003e004SJérôme Duval     ZYAN_ASSERT(context);
322*1003e004SJérôme Duval 
323*1003e004SJérôme Duval     ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_IMMEDIATE);
324*1003e004SJérôme Duval 
325*1003e004SJérôme Duval     const ZyanBool is_signed =
326*1003e004SJérôme Duval         (formatter->imm_signedness == ZYDIS_SIGNEDNESS_SIGNED) ||
327*1003e004SJérôme Duval         (formatter->imm_signedness == ZYDIS_SIGNEDNESS_AUTO && (context->operand->imm.is_signed));
328*1003e004SJérôme Duval     if (is_signed && (context->operand->imm.value.s < 0))
329*1003e004SJérôme Duval     {
330*1003e004SJérôme Duval         ZYDIS_STRING_APPEND_NUM_S(formatter, formatter->imm_base, &buffer->string,
331*1003e004SJérôme Duval             context->operand->imm.value.s, formatter->imm_padding,
332*1003e004SJérôme Duval             formatter->hex_force_leading_number, ZYAN_FALSE);
333*1003e004SJérôme Duval         return ZYAN_STATUS_SUCCESS;
334*1003e004SJérôme Duval     }
335*1003e004SJérôme Duval     ZyanU64 value;
336*1003e004SJérôme Duval     ZyanU8 padding = (formatter->imm_padding ==
337*1003e004SJérôme Duval         ZYDIS_PADDING_AUTO) ? 0 : (ZyanU8)formatter->imm_padding;
338*1003e004SJérôme Duval     switch (context->instruction->operand_width)
339*1003e004SJérôme Duval     {
340*1003e004SJérôme Duval     case 8:
341*1003e004SJérôme Duval         if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
342*1003e004SJérôme Duval         {
343*1003e004SJérôme Duval             padding =  2;
344*1003e004SJérôme Duval         }
345*1003e004SJérôme Duval         value = (ZyanU8 )context->operand->imm.value.u;
346*1003e004SJérôme Duval         break;
347*1003e004SJérôme Duval     case 16:
348*1003e004SJérôme Duval         if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
349*1003e004SJérôme Duval         {
350*1003e004SJérôme Duval             padding =  4;
351*1003e004SJérôme Duval         }
352*1003e004SJérôme Duval         value = (ZyanU16)context->operand->imm.value.u;
353*1003e004SJérôme Duval         break;
354*1003e004SJérôme Duval     case 32:
355*1003e004SJérôme Duval         if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
356*1003e004SJérôme Duval         {
357*1003e004SJérôme Duval             padding =  8;
358*1003e004SJérôme Duval         }
359*1003e004SJérôme Duval         value = (ZyanU32)context->operand->imm.value.u;
360*1003e004SJérôme Duval         break;
361*1003e004SJérôme Duval     case 64:
362*1003e004SJérôme Duval         if (formatter->imm_padding == ZYDIS_PADDING_AUTO)
363*1003e004SJérôme Duval         {
364*1003e004SJérôme Duval             padding = 16;
365*1003e004SJérôme Duval         }
366*1003e004SJérôme Duval         value = (ZyanU64)context->operand->imm.value.u;
367*1003e004SJérôme Duval         break;
368*1003e004SJérôme Duval     default:
369*1003e004SJérôme Duval         return ZYAN_STATUS_INVALID_ARGUMENT;
370*1003e004SJérôme Duval     }
371*1003e004SJérôme Duval     ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->imm_base, &buffer->string, value, padding,
372*1003e004SJérôme Duval         formatter->hex_force_leading_number);
373*1003e004SJérôme Duval 
374*1003e004SJérôme Duval     return ZYAN_STATUS_SUCCESS;
375*1003e004SJérôme Duval }
376*1003e004SJérôme Duval 
377*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
378*1003e004SJérôme Duval /* Optional tokens                                                                                */
379*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
380*1003e004SJérôme Duval 
ZydisFormatterBasePrintSegment(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)381*1003e004SJérôme Duval ZyanStatus ZydisFormatterBasePrintSegment(const ZydisFormatter* formatter,
382*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
383*1003e004SJérôme Duval {
384*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
385*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
386*1003e004SJérôme Duval     ZYAN_ASSERT(context);
387*1003e004SJérôme Duval 
388*1003e004SJérôme Duval     ZyanBool printed_segment = ZYAN_FALSE;
389*1003e004SJérôme Duval     switch (context->operand->mem.segment)
390*1003e004SJérôme Duval     {
391*1003e004SJérôme Duval     case ZYDIS_REGISTER_ES:
392*1003e004SJérôme Duval     case ZYDIS_REGISTER_CS:
393*1003e004SJérôme Duval     case ZYDIS_REGISTER_FS:
394*1003e004SJérôme Duval     case ZYDIS_REGISTER_GS:
395*1003e004SJérôme Duval         ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context,
396*1003e004SJérôme Duval             context->operand->mem.segment));
397*1003e004SJérôme Duval         printed_segment = ZYAN_TRUE;
398*1003e004SJérôme Duval         break;
399*1003e004SJérôme Duval     case ZYDIS_REGISTER_SS:
400*1003e004SJérôme Duval         if ((formatter->force_memory_segment) ||
401*1003e004SJérôme Duval             (context->instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS))
402*1003e004SJérôme Duval         {
403*1003e004SJérôme Duval             ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context,
404*1003e004SJérôme Duval                 context->operand->mem.segment));
405*1003e004SJérôme Duval             printed_segment = ZYAN_TRUE;
406*1003e004SJérôme Duval         }
407*1003e004SJérôme Duval         break;
408*1003e004SJérôme Duval     case ZYDIS_REGISTER_DS:
409*1003e004SJérôme Duval         if ((formatter->force_memory_segment) ||
410*1003e004SJérôme Duval             (context->instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS))
411*1003e004SJérôme Duval         {
412*1003e004SJérôme Duval             ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context,
413*1003e004SJérôme Duval                 context->operand->mem.segment));
414*1003e004SJérôme Duval             printed_segment = ZYAN_TRUE;
415*1003e004SJérôme Duval         }
416*1003e004SJérôme Duval         break;
417*1003e004SJérôme Duval     default:
418*1003e004SJérôme Duval         break;
419*1003e004SJérôme Duval     }
420*1003e004SJérôme Duval     if (printed_segment)
421*1003e004SJérôme Duval     {
422*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND(buffer, DELIM_SEGMENT);
423*1003e004SJérôme Duval     }
424*1003e004SJérôme Duval 
425*1003e004SJérôme Duval     return ZYAN_STATUS_SUCCESS;
426*1003e004SJérôme Duval }
427*1003e004SJérôme Duval 
ZydisFormatterBasePrintPrefixes(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context)428*1003e004SJérôme Duval ZyanStatus ZydisFormatterBasePrintPrefixes(const ZydisFormatter* formatter,
429*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
430*1003e004SJérôme Duval {
431*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
432*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
433*1003e004SJérôme Duval     ZYAN_ASSERT(context);
434*1003e004SJérôme Duval 
435*1003e004SJérôme Duval     if (formatter->detailed_prefixes)
436*1003e004SJérôme Duval     {
437*1003e004SJérôme Duval         for (ZyanU8 i = 0; i < context->instruction->raw.prefix_count; ++i)
438*1003e004SJérôme Duval         {
439*1003e004SJérôme Duval             const ZyanU8 value = context->instruction->raw.prefixes[i].value;
440*1003e004SJérôme Duval             switch (context->instruction->raw.prefixes[i].type)
441*1003e004SJérôme Duval             {
442*1003e004SJérôme Duval             case ZYDIS_PREFIX_TYPE_IGNORED:
443*1003e004SJérôme Duval             case ZYDIS_PREFIX_TYPE_MANDATORY:
444*1003e004SJérôme Duval             {
445*1003e004SJérôme Duval                 if ((value & 0xF0) == 0x40)
446*1003e004SJérôme Duval                 {
447*1003e004SJérôme Duval                     if (buffer->is_token_list)
448*1003e004SJérôme Duval                     {
449*1003e004SJérôme Duval                         // TODO: Case
450*1003e004SJérôme Duval                         ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer,
451*1003e004SJérôme Duval                             TOK_PREF_REX[value & 0x0F]));
452*1003e004SJérôme Duval                     } else
453*1003e004SJérôme Duval                     {
454*1003e004SJérôme Duval                         ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string,
455*1003e004SJérôme Duval                             STR_PREF_REX[value & 0x0F], formatter->case_prefixes));
456*1003e004SJérôme Duval                     }
457*1003e004SJérôme Duval                 } else
458*1003e004SJérôme Duval                 {
459*1003e004SJérôme Duval                     switch (value)
460*1003e004SJérôme Duval                     {
461*1003e004SJérôme Duval                     case 0xF0:
462*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes);
463*1003e004SJérôme Duval                         break;
464*1003e004SJérôme Duval                     case 0x2E:
465*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_CS, formatter->case_prefixes);
466*1003e004SJérôme Duval                         break;
467*1003e004SJérôme Duval                     case 0x36:
468*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_SS, formatter->case_prefixes);
469*1003e004SJérôme Duval                         break;
470*1003e004SJérôme Duval                     case 0x3E:
471*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_DS, formatter->case_prefixes);
472*1003e004SJérôme Duval                         break;
473*1003e004SJérôme Duval                     case 0x26:
474*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_ES, formatter->case_prefixes);
475*1003e004SJérôme Duval                         break;
476*1003e004SJérôme Duval                     case 0x64:
477*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_FS, formatter->case_prefixes);
478*1003e004SJérôme Duval                         break;
479*1003e004SJérôme Duval                     case 0x65:
480*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_GS, formatter->case_prefixes);
481*1003e004SJérôme Duval                         break;
482*1003e004SJérôme Duval                     default:
483*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_PREFIX);
484*1003e004SJérôme Duval                         ZYAN_CHECK(ZydisStringAppendHexU(&buffer->string, value, 0,
485*1003e004SJérôme Duval                             formatter->hex_force_leading_number, formatter->hex_uppercase,
486*1003e004SJérôme Duval                             ZYAN_NULL, ZYAN_NULL));
487*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_WHITESPACE);
488*1003e004SJérôme Duval                         ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_WHITESPACE));
489*1003e004SJérôme Duval                         break;
490*1003e004SJérôme Duval                     }
491*1003e004SJérôme Duval                 }
492*1003e004SJérôme Duval                 break;
493*1003e004SJérôme Duval             }
494*1003e004SJérôme Duval             case ZYDIS_PREFIX_TYPE_EFFECTIVE:
495*1003e004SJérôme Duval                 switch (value)
496*1003e004SJérôme Duval                 {
497*1003e004SJérôme Duval                 case 0xF0:
498*1003e004SJérôme Duval                     ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes);
499*1003e004SJérôme Duval                     break;
500*1003e004SJérôme Duval                 case 0xF2:
501*1003e004SJérôme Duval                     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE)
502*1003e004SJérôme Duval                     {
503*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XACQUIRE, formatter->case_prefixes);
504*1003e004SJérôme Duval                     }
505*1003e004SJérôme Duval                     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE)
506*1003e004SJérôme Duval                     {
507*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPNE, formatter->case_prefixes);
508*1003e004SJérôme Duval                     }
509*1003e004SJérôme Duval 
510*1003e004SJérôme Duval                     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_BND)
511*1003e004SJérôme Duval                     {
512*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_BND, formatter->case_prefixes);
513*1003e004SJérôme Duval                     }
514*1003e004SJérôme Duval                     break;
515*1003e004SJérôme Duval                 case 0xF3:
516*1003e004SJérôme Duval                     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE)
517*1003e004SJérôme Duval                     {
518*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XRELEASE, formatter->case_prefixes);
519*1003e004SJérôme Duval                     }
520*1003e004SJérôme Duval                     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REP)
521*1003e004SJérôme Duval                     {
522*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REP, formatter->case_prefixes);
523*1003e004SJérôme Duval                     }
524*1003e004SJérôme Duval                     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPE)
525*1003e004SJérôme Duval                     {
526*1003e004SJérôme Duval                         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPE, formatter->case_prefixes);
527*1003e004SJérôme Duval                     }
528*1003e004SJérôme Duval                     break;
529*1003e004SJérôme Duval                 default:
530*1003e004SJérôme Duval                     break;
531*1003e004SJérôme Duval                 }
532*1003e004SJérôme Duval                 break;
533*1003e004SJérôme Duval             default:
534*1003e004SJérôme Duval                 return ZYAN_STATUS_INVALID_ARGUMENT;
535*1003e004SJérôme Duval             }
536*1003e004SJérôme Duval         }
537*1003e004SJérôme Duval         return ZYAN_STATUS_SUCCESS;
538*1003e004SJérôme Duval     }
539*1003e004SJérôme Duval 
540*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE)
541*1003e004SJérôme Duval     {
542*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XACQUIRE, formatter->case_prefixes);
543*1003e004SJérôme Duval     }
544*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE)
545*1003e004SJérôme Duval     {
546*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XRELEASE, formatter->case_prefixes);
547*1003e004SJérôme Duval     }
548*1003e004SJérôme Duval 
549*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK)
550*1003e004SJérôme Duval     {
551*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes);
552*1003e004SJérôme Duval     }
553*1003e004SJérôme Duval 
554*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_BND)
555*1003e004SJérôme Duval     {
556*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_BND, formatter->case_prefixes);
557*1003e004SJérôme Duval     }
558*1003e004SJérôme Duval 
559*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_NOTRACK)
560*1003e004SJérôme Duval     {
561*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_NOTRACK, formatter->case_prefixes);
562*1003e004SJérôme Duval     }
563*1003e004SJérôme Duval 
564*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REP)
565*1003e004SJérôme Duval     {
566*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REP, formatter->case_prefixes);
567*1003e004SJérôme Duval         return ZYAN_STATUS_SUCCESS;
568*1003e004SJérôme Duval     }
569*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPE)
570*1003e004SJérôme Duval     {
571*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPE, formatter->case_prefixes);
572*1003e004SJérôme Duval         return ZYAN_STATUS_SUCCESS;
573*1003e004SJérôme Duval     }
574*1003e004SJérôme Duval     if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE)
575*1003e004SJérôme Duval     {
576*1003e004SJérôme Duval         ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPNE, formatter->case_prefixes);
577*1003e004SJérôme Duval         return ZYAN_STATUS_SUCCESS;
578*1003e004SJérôme Duval     }
579*1003e004SJérôme Duval 
580*1003e004SJérôme Duval     return ZYAN_STATUS_SUCCESS;
581*1003e004SJérôme Duval }
582*1003e004SJérôme Duval 
ZydisFormatterBasePrintDecorator(const ZydisFormatter * formatter,ZydisFormatterBuffer * buffer,ZydisFormatterContext * context,ZydisDecorator decorator)583*1003e004SJérôme Duval ZyanStatus ZydisFormatterBasePrintDecorator(const ZydisFormatter* formatter,
584*1003e004SJérôme Duval     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator)
585*1003e004SJérôme Duval {
586*1003e004SJérôme Duval     ZYAN_ASSERT(formatter);
587*1003e004SJérôme Duval     ZYAN_ASSERT(buffer);
588*1003e004SJérôme Duval     ZYAN_ASSERT(context);
589*1003e004SJérôme Duval 
590*1003e004SJérôme Duval #if defined(ZYDIS_DISABLE_AVX512) && defined(ZYDIS_DISABLE_KNC)
591*1003e004SJérôme Duval     ZYAN_UNUSED(formatter);
592*1003e004SJérôme Duval     ZYAN_UNUSED(buffer);
593*1003e004SJérôme Duval     ZYAN_UNUSED(context);
594*1003e004SJérôme Duval #endif
595*1003e004SJérôme Duval 
596*1003e004SJérôme Duval     switch (decorator)
597*1003e004SJérôme Duval     {
598*1003e004SJérôme Duval     case ZYDIS_DECORATOR_MASK:
599*1003e004SJérôme Duval     {
600*1003e004SJérôme Duval #if !defined(ZYDIS_DISABLE_AVX512) || !defined(ZYDIS_DISABLE_KNC)
601*1003e004SJérôme Duval         if (context->instruction->avx.mask.reg != ZYDIS_REGISTER_K0)
602*1003e004SJérôme Duval         {
603*1003e004SJérôme Duval             if (buffer->is_token_list)
604*1003e004SJérôme Duval             {
605*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND(buffer, DECO_BEGIN);
606*1003e004SJérôme Duval                 ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context,
607*1003e004SJérôme Duval                     context->instruction->avx.mask.reg));
608*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND(buffer, DECO_END);
609*1003e004SJérôme Duval             } else
610*1003e004SJérôme Duval             {
611*1003e004SJérôme Duval                 ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_DECO_BEGIN));
612*1003e004SJérôme Duval                 ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context,
613*1003e004SJérôme Duval                     context->instruction->avx.mask.reg));
614*1003e004SJérôme Duval                 ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_DECO_END));
615*1003e004SJérôme Duval             }
616*1003e004SJérôme Duval 
617*1003e004SJérôme Duval             // Only print the zeroing decorator, if the instruction is not a "zeroing masking only"
618*1003e004SJérôme Duval             // instruction (e.g. `vcmpsd`)
619*1003e004SJérôme Duval             if ((context->instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZEROING ||
620*1003e004SJérôme Duval                  context->instruction->avx.mask.mode == ZYDIS_MASK_MODE_CONTROL_ZEROING) &&
621*1003e004SJérôme Duval                 (context->instruction->raw.evex.z))
622*1003e004SJérôme Duval             {
623*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_ZERO, formatter->case_decorators);
624*1003e004SJérôme Duval             }
625*1003e004SJérôme Duval         }
626*1003e004SJérôme Duval #endif
627*1003e004SJérôme Duval         break;
628*1003e004SJérôme Duval     }
629*1003e004SJérôme Duval     case ZYDIS_DECORATOR_BC:
630*1003e004SJérôme Duval #if !defined(ZYDIS_DISABLE_AVX512)
631*1003e004SJérôme Duval         if (!context->instruction->avx.broadcast.is_static)
632*1003e004SJérôme Duval         {
633*1003e004SJérôme Duval             switch (context->instruction->avx.broadcast.mode)
634*1003e004SJérôme Duval             {
635*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_INVALID:
636*1003e004SJérôme Duval                 break;
637*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_1_TO_2:
638*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO2, formatter->case_decorators);
639*1003e004SJérôme Duval                 break;
640*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_1_TO_4:
641*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO4, formatter->case_decorators);
642*1003e004SJérôme Duval                 break;
643*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_1_TO_8:
644*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO8, formatter->case_decorators);
645*1003e004SJérôme Duval                 break;
646*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_1_TO_16:
647*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO16, formatter->case_decorators);
648*1003e004SJérôme Duval                 break;
649*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_1_TO_32:
650*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO32, formatter->case_decorators);
651*1003e004SJérôme Duval                 break;
652*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_1_TO_64:
653*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO64, formatter->case_decorators);
654*1003e004SJérôme Duval                 break;
655*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_4_TO_8:
656*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_4TO8, formatter->case_decorators);
657*1003e004SJérôme Duval                 break;
658*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_4_TO_16:
659*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_4TO16, formatter->case_decorators);
660*1003e004SJérôme Duval                 break;
661*1003e004SJérôme Duval             case ZYDIS_BROADCAST_MODE_8_TO_16:
662*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_8TO16, formatter->case_decorators);
663*1003e004SJérôme Duval                 break;
664*1003e004SJérôme Duval             default:
665*1003e004SJérôme Duval                 return ZYAN_STATUS_INVALID_ARGUMENT;
666*1003e004SJérôme Duval             }
667*1003e004SJérôme Duval         }
668*1003e004SJérôme Duval #endif
669*1003e004SJérôme Duval         break;
670*1003e004SJérôme Duval     case ZYDIS_DECORATOR_RC:
671*1003e004SJérôme Duval #if !defined(ZYDIS_DISABLE_AVX512)
672*1003e004SJérôme Duval         if (context->instruction->avx.has_sae)
673*1003e004SJérôme Duval         {
674*1003e004SJérôme Duval             switch (context->instruction->avx.rounding.mode)
675*1003e004SJérôme Duval             {
676*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_INVALID:
677*1003e004SJérôme Duval                 break;
678*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RN:
679*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RN_SAE, formatter->case_decorators);
680*1003e004SJérôme Duval                 break;
681*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RD:
682*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RD_SAE, formatter->case_decorators);
683*1003e004SJérôme Duval                 break;
684*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RU:
685*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RU_SAE, formatter->case_decorators);
686*1003e004SJérôme Duval                 break;
687*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RZ:
688*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RZ_SAE, formatter->case_decorators);
689*1003e004SJérôme Duval                 break;
690*1003e004SJérôme Duval             default:
691*1003e004SJérôme Duval                 return ZYAN_STATUS_INVALID_ARGUMENT;
692*1003e004SJérôme Duval             }
693*1003e004SJérôme Duval         } else
694*1003e004SJérôme Duval         {
695*1003e004SJérôme Duval             switch (context->instruction->avx.rounding.mode)
696*1003e004SJérôme Duval             {
697*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_INVALID:
698*1003e004SJérôme Duval                 break;
699*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RN:
700*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RN, formatter->case_decorators);
701*1003e004SJérôme Duval                 break;
702*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RD:
703*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RD, formatter->case_decorators);
704*1003e004SJérôme Duval                 break;
705*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RU:
706*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RU, formatter->case_decorators);
707*1003e004SJérôme Duval                 break;
708*1003e004SJérôme Duval             case ZYDIS_ROUNDING_MODE_RZ:
709*1003e004SJérôme Duval                 ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RZ, formatter->case_decorators);
710*1003e004SJérôme Duval                 break;
711*1003e004SJérôme Duval             default:
712*1003e004SJérôme Duval                 return ZYAN_STATUS_INVALID_ARGUMENT;
713*1003e004SJérôme Duval             }
714*1003e004SJérôme Duval         }
715*1003e004SJérôme Duval #endif
716*1003e004SJérôme Duval         break;
717*1003e004SJérôme Duval     case ZYDIS_DECORATOR_SAE:
718*1003e004SJérôme Duval #if !defined(ZYDIS_DISABLE_AVX512)
719*1003e004SJérôme Duval         if (context->instruction->avx.has_sae && !context->instruction->avx.rounding.mode)
720*1003e004SJérôme Duval         {
721*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SAE, formatter->case_decorators);
722*1003e004SJérôme Duval         }
723*1003e004SJérôme Duval #endif
724*1003e004SJérôme Duval         break;
725*1003e004SJérôme Duval     case ZYDIS_DECORATOR_SWIZZLE:
726*1003e004SJérôme Duval #if !defined(ZYDIS_DISABLE_KNC)
727*1003e004SJérôme Duval         switch (context->instruction->avx.swizzle.mode)
728*1003e004SJérôme Duval         {
729*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_INVALID:
730*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_DCBA:
731*1003e004SJérôme Duval             // Nothing to do here
732*1003e004SJérôme Duval             break;
733*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_CDAB:
734*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_CDAB, formatter->case_decorators);
735*1003e004SJérôme Duval             break;
736*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_BADC:
737*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_BADC, formatter->case_decorators);
738*1003e004SJérôme Duval             break;
739*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_DACB:
740*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DACB, formatter->case_decorators);
741*1003e004SJérôme Duval             break;
742*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_AAAA:
743*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_AAAA, formatter->case_decorators);
744*1003e004SJérôme Duval             break;
745*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_BBBB:
746*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_BBBB, formatter->case_decorators);
747*1003e004SJérôme Duval             break;
748*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_CCCC:
749*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_CCCC, formatter->case_decorators);
750*1003e004SJérôme Duval             break;
751*1003e004SJérôme Duval         case ZYDIS_SWIZZLE_MODE_DDDD:
752*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DDDD, formatter->case_decorators);
753*1003e004SJérôme Duval             break;
754*1003e004SJérôme Duval         default:
755*1003e004SJérôme Duval             return ZYAN_STATUS_INVALID_ARGUMENT;
756*1003e004SJérôme Duval         }
757*1003e004SJérôme Duval #endif
758*1003e004SJérôme Duval         break;
759*1003e004SJérôme Duval     case ZYDIS_DECORATOR_CONVERSION:
760*1003e004SJérôme Duval #if !defined(ZYDIS_DISABLE_KNC)
761*1003e004SJérôme Duval         switch (context->instruction->avx.conversion.mode)
762*1003e004SJérôme Duval         {
763*1003e004SJérôme Duval         case ZYDIS_CONVERSION_MODE_INVALID:
764*1003e004SJérôme Duval             break;
765*1003e004SJérôme Duval         case ZYDIS_CONVERSION_MODE_FLOAT16:
766*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_FLOAT16, formatter->case_decorators);
767*1003e004SJérôme Duval             break;
768*1003e004SJérôme Duval         case ZYDIS_CONVERSION_MODE_SINT8:
769*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SINT8, formatter->case_decorators);
770*1003e004SJérôme Duval             break;
771*1003e004SJérôme Duval         case ZYDIS_CONVERSION_MODE_UINT8:
772*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_UINT8, formatter->case_decorators);
773*1003e004SJérôme Duval             break;
774*1003e004SJérôme Duval         case ZYDIS_CONVERSION_MODE_SINT16:
775*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SINT16, formatter->case_decorators);
776*1003e004SJérôme Duval             break;
777*1003e004SJérôme Duval         case ZYDIS_CONVERSION_MODE_UINT16:
778*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_UINT16, formatter->case_decorators);
779*1003e004SJérôme Duval             break;
780*1003e004SJérôme Duval         default:
781*1003e004SJérôme Duval             return ZYAN_STATUS_INVALID_ARGUMENT;
782*1003e004SJérôme Duval         }
783*1003e004SJérôme Duval #endif
784*1003e004SJérôme Duval         break;
785*1003e004SJérôme Duval     case ZYDIS_DECORATOR_EH:
786*1003e004SJérôme Duval #if !defined(ZYDIS_DISABLE_KNC)
787*1003e004SJérôme Duval         if (context->instruction->avx.has_eviction_hint)
788*1003e004SJérôme Duval         {
789*1003e004SJérôme Duval             ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_EH, formatter->case_decorators);
790*1003e004SJérôme Duval         }
791*1003e004SJérôme Duval #endif
792*1003e004SJérôme Duval         break;
793*1003e004SJérôme Duval     default:
794*1003e004SJérôme Duval         return ZYAN_STATUS_INVALID_ARGUMENT;
795*1003e004SJérôme Duval     }
796*1003e004SJérôme Duval 
797*1003e004SJérôme Duval     return ZYAN_STATUS_SUCCESS;
798*1003e004SJérôme Duval }
799*1003e004SJérôme Duval 
800*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
801*1003e004SJérôme Duval 
802*1003e004SJérôme Duval /* ============================================================================================== */
803