d3d8/tests: Test the presentation parameters after creating an additional swap chain.
[wine.git] / libs / zydis / src / FormatterATT.c
blobbb183bdcc11dd49e68e3c2f5a908bf36a1734264
1 /***************************************************************************************************
3 Zyan Disassembler Library (Zydis)
5 Original Author : Florian Bernd, Joel Hoener
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
25 ***************************************************************************************************/
27 #include <Zydis/Internal/FormatterATT.h>
29 /* ============================================================================================== */
30 /* Constants */
31 /* ============================================================================================== */
33 #include <Generated/FormatterStrings.inc>
35 /* ============================================================================================== */
36 /* Formatter functions */
37 /* ============================================================================================== */
39 /* ---------------------------------------------------------------------------------------------- */
40 /* Instruction */
41 /* ---------------------------------------------------------------------------------------------- */
43 ZyanStatus ZydisFormatterATTFormatInstruction(const ZydisFormatter* formatter,
44 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
46 ZYAN_ASSERT(formatter);
47 ZYAN_ASSERT(buffer);
48 ZYAN_ASSERT(context);
49 ZYAN_ASSERT(context->instruction);
50 ZYAN_ASSERT(context->operands);
52 ZYAN_CHECK(formatter->func_print_prefixes(formatter, buffer, context));
53 ZYAN_CHECK(formatter->func_print_mnemonic(formatter, buffer, context));
55 ZyanUPointer state_mnemonic;
56 ZYDIS_BUFFER_REMEMBER(buffer, state_mnemonic);
58 const ZyanI8 c = (ZyanI8)context->instruction->operand_count_visible - 1;
59 for (ZyanI8 i = c; i >= 0; --i)
61 const ZydisDecodedOperand* const operand = &context->operands[i];
63 // Print embedded-mask registers as decorator instead of a regular operand
64 if ((i == 1) && (operand->type == ZYDIS_OPERAND_TYPE_REGISTER) &&
65 (operand->encoding == ZYDIS_OPERAND_ENCODING_MASK))
67 continue;
70 ZyanUPointer buffer_state;
71 ZYDIS_BUFFER_REMEMBER(buffer, buffer_state);
73 if (buffer_state != state_mnemonic)
75 ZYDIS_BUFFER_APPEND(buffer, DELIM_OPERAND);
76 } else
78 ZYDIS_BUFFER_APPEND(buffer, DELIM_MNEMONIC);
81 // Set current operand
82 context->operand = operand;
84 ZyanStatus status;
85 if (formatter->func_pre_operand)
87 status = formatter->func_pre_operand(formatter, buffer, context);
88 if (status == ZYDIS_STATUS_SKIP_TOKEN)
90 ZYAN_CHECK(ZydisFormatterBufferRestore(buffer, buffer_state));
91 continue;
93 if (!ZYAN_SUCCESS(status))
95 return status;
99 switch (operand->type)
101 case ZYDIS_OPERAND_TYPE_REGISTER:
102 status = formatter->func_format_operand_reg(formatter, buffer, context);
103 break;
104 case ZYDIS_OPERAND_TYPE_MEMORY:
105 status = formatter->func_format_operand_mem(formatter, buffer, context);
106 break;
107 case ZYDIS_OPERAND_TYPE_POINTER:
108 status = formatter->func_format_operand_ptr(formatter, buffer, context);
109 break;
110 case ZYDIS_OPERAND_TYPE_IMMEDIATE:
111 status = formatter->func_format_operand_imm(formatter, buffer, context);
112 break;
113 default:
114 return ZYAN_STATUS_INVALID_ARGUMENT;
116 if (status == ZYDIS_STATUS_SKIP_TOKEN)
118 ZYAN_CHECK(ZydisFormatterBufferRestore(buffer, buffer_state));
119 continue;
121 if (!ZYAN_SUCCESS(status))
123 return status;
126 if (formatter->func_post_operand)
128 status = formatter->func_post_operand(formatter, buffer, context);
129 if (status == ZYDIS_STATUS_SKIP_TOKEN)
131 ZYAN_CHECK(ZydisFormatterBufferRestore(buffer, buffer_state));
132 continue;
134 if (ZYAN_SUCCESS(status))
136 return status;
140 #if !defined(ZYDIS_DISABLE_AVX512) || !defined(ZYDIS_DISABLE_KNC)
141 if ((context->instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
142 (context->instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
144 if ((i == 0) &&
145 (context->instruction->operand_count_visible > 1) &&
146 (context->operands[1].encoding == ZYDIS_OPERAND_ENCODING_MASK))
148 ZYAN_CHECK(formatter->func_print_decorator(formatter, buffer, context,
149 ZYDIS_DECORATOR_MASK));
151 if (operand->type == ZYDIS_OPERAND_TYPE_MEMORY)
153 ZYAN_CHECK(formatter->func_print_decorator(formatter, buffer, context,
154 ZYDIS_DECORATOR_BC));
155 if (context->instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
157 ZYAN_CHECK(formatter->func_print_decorator(formatter, buffer, context,
158 ZYDIS_DECORATOR_CONVERSION));
159 ZYAN_CHECK(formatter->func_print_decorator(formatter, buffer, context,
160 ZYDIS_DECORATOR_EH));
162 } else
164 ZyanBool decorate_operand;
165 if (i == (context->instruction->operand_count_visible - 1))
167 decorate_operand = operand->type != ZYDIS_OPERAND_TYPE_IMMEDIATE;
169 else
171 decorate_operand =
172 (context->instruction->operand_count_visible > (i + 1)) &&
173 ((context->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
174 (context->operands[i + 1].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN));
176 if (decorate_operand)
178 if (context->instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
180 ZYAN_CHECK(formatter->func_print_decorator(formatter, buffer, context,
181 ZYDIS_DECORATOR_SWIZZLE));
183 ZYAN_CHECK(formatter->func_print_decorator(formatter, buffer, context,
184 ZYDIS_DECORATOR_RC));
185 ZYAN_CHECK(formatter->func_print_decorator(formatter, buffer, context,
186 ZYDIS_DECORATOR_SAE));
190 #endif
193 return ZYAN_STATUS_SUCCESS;
196 /* ---------------------------------------------------------------------------------------------- */
197 /* Operands */
198 /* ---------------------------------------------------------------------------------------------- */
200 ZyanStatus ZydisFormatterATTFormatOperandMEM(const ZydisFormatter* formatter,
201 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
203 ZYAN_ASSERT(formatter);
204 ZYAN_ASSERT(buffer);
205 ZYAN_ASSERT(context);
207 ZYAN_CHECK(formatter->func_print_segment(formatter, buffer, context));
209 const ZyanBool absolute = !formatter->force_relative_riprel &&
210 (context->runtime_address != ZYDIS_RUNTIME_ADDRESS_NONE);
211 if (absolute && context->operand->mem.disp.has_displacement &&
212 (context->operand->mem.index == ZYDIS_REGISTER_NONE) &&
213 ((context->operand->mem.base == ZYDIS_REGISTER_NONE) ||
214 (context->operand->mem.base == ZYDIS_REGISTER_EIP ) ||
215 (context->operand->mem.base == ZYDIS_REGISTER_RIP )))
217 // EIP/RIP-relative or absolute-displacement address operand
218 ZYAN_CHECK(formatter->func_print_address_abs(formatter, buffer, context));
219 } else
221 const ZyanBool should_print_reg = context->operand->mem.base != ZYDIS_REGISTER_NONE;
222 const ZyanBool should_print_idx = context->operand->mem.index != ZYDIS_REGISTER_NONE;
223 const ZyanBool neither_reg_nor_idx = !should_print_reg && !should_print_idx;
225 // Regular memory operand
226 if (neither_reg_nor_idx)
228 ZYAN_CHECK(formatter->func_print_address_abs(formatter, buffer, context));
229 } else if (context->operand->mem.disp.has_displacement && context->operand->mem.disp.value)
231 ZYAN_CHECK(formatter->func_print_disp(formatter, buffer, context));
234 if (neither_reg_nor_idx)
236 return ZYAN_STATUS_SUCCESS;
239 ZYDIS_BUFFER_APPEND(buffer, MEMORY_BEGIN_ATT);
241 if (should_print_reg)
243 ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context,
244 context->operand->mem.base));
246 if (should_print_idx)
248 ZYDIS_BUFFER_APPEND(buffer, DELIM_MEMORY);
249 ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context,
250 context->operand->mem.index));
251 if (context->operand->mem.scale &&
252 (context->operand->mem.type != ZYDIS_MEMOP_TYPE_MIB) &&
253 ((context->operand->mem.scale > 1) || formatter->force_memory_scale))
255 ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_DELIMITER);
256 ZYDIS_BUFFER_APPEND(buffer, DELIM_MEMORY);
257 ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_IMMEDIATE);
258 ZYAN_CHECK(ZydisStringAppendDecU(&buffer->string, context->operand->mem.scale, 0,
259 ZYAN_NULL, ZYAN_NULL));
263 ZYDIS_BUFFER_APPEND(buffer, MEMORY_END_ATT);
264 return ZYAN_STATUS_SUCCESS;
267 return ZYAN_STATUS_SUCCESS;
270 /* ---------------------------------------------------------------------------------------------- */
271 /* Elemental tokens */
272 /* ---------------------------------------------------------------------------------------------- */
274 ZyanStatus ZydisFormatterATTPrintMnemonic(const ZydisFormatter* formatter,
275 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
277 ZYAN_ASSERT(formatter);
278 ZYAN_ASSERT(buffer);
279 ZYAN_ASSERT(context);
280 ZYAN_ASSERT(context->instruction);
281 ZYAN_ASSERT(context->operands);
283 const ZydisShortString* mnemonic = ZydisMnemonicGetStringWrapped(
284 context->instruction->mnemonic);
285 if (!mnemonic)
287 ZYDIS_BUFFER_APPEND_CASE(buffer, INVALID_MNEMONIC, formatter->case_mnemonic);
288 return ZYAN_STATUS_SUCCESS;
291 ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_MNEMONIC);
292 if (context->instruction->meta.branch_type == ZYDIS_BRANCH_TYPE_FAR)
294 ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string, &STR_FAR_ATT,
295 formatter->case_mnemonic));
297 ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string, mnemonic, formatter->case_mnemonic));
299 // Append operand-size suffix
300 ZyanU32 size = 0;
301 for (ZyanU8 i = 0; i < context->instruction->operand_count_visible; ++i)
303 const ZydisDecodedOperand* const operand = &context->operands[i];
304 if ((operand->type == ZYDIS_OPERAND_TYPE_MEMORY) &&
305 ((operand->mem.type == ZYDIS_MEMOP_TYPE_MEM) ||
306 (operand->mem.type == ZYDIS_MEMOP_TYPE_VSIB)))
308 size = ZydisFormatterHelperGetExplicitSize(formatter, context, operand);
309 break;
313 switch (size)
315 case 8: ZydisStringAppendShort(&buffer->string, &STR_SIZE_8_ATT ); break;
316 case 16: ZydisStringAppendShort(&buffer->string, &STR_SIZE_16_ATT ); break;
317 case 32: ZydisStringAppendShort(&buffer->string, &STR_SIZE_32_ATT ); break;
318 case 64: ZydisStringAppendShort(&buffer->string, &STR_SIZE_64_ATT ); break;
319 case 128: ZydisStringAppendShort(&buffer->string, &STR_SIZE_128_ATT); break;
320 case 256: ZydisStringAppendShort(&buffer->string, &STR_SIZE_256_ATT); break;
321 case 512: ZydisStringAppendShort(&buffer->string, &STR_SIZE_512_ATT); break;
322 default:
323 break;
326 if (formatter->print_branch_size)
328 switch (context->instruction->meta.branch_type)
330 case ZYDIS_BRANCH_TYPE_NONE:
331 break;
332 case ZYDIS_BRANCH_TYPE_SHORT:
333 return ZydisStringAppendShortCase(&buffer->string, &STR_SHORT,
334 formatter->case_mnemonic);
335 case ZYDIS_BRANCH_TYPE_NEAR:
336 return ZydisStringAppendShortCase(&buffer->string, &STR_NEAR,
337 formatter->case_mnemonic);
338 default:
339 return ZYAN_STATUS_INVALID_ARGUMENT;
343 return ZYAN_STATUS_SUCCESS;
346 ZyanStatus ZydisFormatterATTPrintRegister(const ZydisFormatter* formatter,
347 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisRegister reg)
349 ZYAN_UNUSED(context);
351 ZYAN_ASSERT(formatter);
352 ZYAN_ASSERT(buffer);
353 ZYAN_ASSERT(context);
355 ZYDIS_BUFFER_APPEND(buffer, REGISTER);
356 const ZydisShortString* str = ZydisRegisterGetStringWrapped(reg);
357 if (!str)
359 return ZydisStringAppendShortCase(&buffer->string, &STR_INVALID_REG,
360 formatter->case_registers);
362 return ZydisStringAppendShortCase(&buffer->string, str, formatter->case_registers);
365 ZyanStatus ZydisFormatterATTPrintAddressABS(const ZydisFormatter* formatter,
366 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
368 ZYAN_ASSERT(formatter);
369 ZYAN_ASSERT(buffer);
370 ZYAN_ASSERT(context);
372 if ((context->instruction->meta.branch_type != ZYDIS_BRANCH_TYPE_NONE) &&
373 (context->operand->type == ZYDIS_OPERAND_TYPE_MEMORY))
375 ZYDIS_BUFFER_APPEND(buffer, MUL);
378 return ZydisFormatterBasePrintAddressABS(formatter, buffer, context);
381 ZyanStatus ZydisFormatterATTPrintDISP(const ZydisFormatter* formatter,
382 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
384 ZYAN_ASSERT(formatter);
385 ZYAN_ASSERT(buffer);
386 ZYAN_ASSERT(context);
388 ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_DISPLACEMENT);
389 switch (formatter->disp_signedness)
391 case ZYDIS_SIGNEDNESS_AUTO:
392 case ZYDIS_SIGNEDNESS_SIGNED:
393 ZYDIS_STRING_APPEND_NUM_S(formatter, formatter->disp_base, &buffer->string,
394 context->operand->mem.disp.value, formatter->disp_padding,
395 formatter->hex_force_leading_number, ZYAN_FALSE);
396 break;
397 case ZYDIS_SIGNEDNESS_UNSIGNED:
398 ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->disp_base, &buffer->string,
399 context->operand->mem.disp.value, formatter->disp_padding,
400 formatter->hex_force_leading_number);
401 break;
402 default:
403 return ZYAN_STATUS_INVALID_ARGUMENT;
406 return ZYAN_STATUS_SUCCESS;
409 ZyanStatus ZydisFormatterATTPrintIMM(const ZydisFormatter* formatter,
410 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
412 ZYAN_ASSERT(formatter);
413 ZYAN_ASSERT(buffer);
414 ZYAN_ASSERT(context);
416 ZYDIS_BUFFER_APPEND(buffer, IMMEDIATE);
417 return ZydisFormatterBasePrintIMM(formatter, buffer, context);
420 /* ---------------------------------------------------------------------------------------------- */
422 /* ============================================================================================== */