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