VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-template.c@ 67079

Last change on this file since 67079 was 67079, checked in by vboxsync, 8 years ago

bs3-cpu-generated-1: cleanups

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 281.8 KB
Line 
1/* $Id: bs3-cpu-generated-1-template.c 67079 2017-05-25 09:43:41Z vboxsync $ */
2/** @file
3 * BS3Kit - bs3-cpu-generated-1, C code template.
4 */
5
6/*
7 * Copyright (C) 2007-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#ifndef BS3_INSTANTIATING_CMN
28# error "BS3_INSTANTIATING_CMN not defined"
29#endif
30
31
32/*********************************************************************************************************************************
33* Header Files *
34*********************************************************************************************************************************/
35#include <iprt/asm.h>
36#include <iprt/asm-amd64-x86.h>
37
38#include "bs3-cpu-generated-1.h"
39
40
41/*********************************************************************************************************************************
42* Defined Constants And Macros *
43*********************************************************************************************************************************/
44#define BS3CG1_WITH_VEX
45
46#define P_CS X86_OP_PRF_CS
47#define P_SS X86_OP_PRF_SS
48#define P_DS X86_OP_PRF_DS
49#define P_ES X86_OP_PRF_ES
50#define P_FS X86_OP_PRF_FS
51#define P_GS X86_OP_PRF_GS
52#define P_OZ X86_OP_PRF_SIZE_OP
53#define P_AZ X86_OP_PRF_SIZE_ADDR
54#define P_LK X86_OP_PRF_LOCK
55#define P_RN X86_OP_PRF_REPNZ
56#define P_RZ X86_OP_PRF_REPZ
57
58#define REX_WRBX (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B | X86_OP_REX_X)
59#define REX_W___ (X86_OP_REX_W)
60#define REX_WR__ (X86_OP_REX_W | X86_OP_REX_R)
61#define REX_W_B_ (X86_OP_REX_W | X86_OP_REX_B)
62#define REX_W__X (X86_OP_REX_W | X86_OP_REX_X)
63#define REX_WRB_ (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B)
64#define REX_WR_X (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_X)
65#define REX_W_BX (X86_OP_REX_W | X86_OP_REX_B | X86_OP_REX_X)
66#define REX__R__ (X86_OP_REX_R)
67#define REX__RB_ (X86_OP_REX_R | X86_OP_REX_B)
68#define REX__R_X (X86_OP_REX_R | X86_OP_REX_X)
69#define REX__RBX (X86_OP_REX_R | X86_OP_REX_B | X86_OP_REX_X)
70#define REX___B_ (X86_OP_REX_B)
71#define REX___BX (X86_OP_REX_B | X86_OP_REX_X)
72#define REX____X (X86_OP_REX_X)
73#define REX_____ (0x40)
74
75
76/** @def BS3CG1_DPRINTF
77 * Debug print macro.
78 */
79#if 0
80# define BS3CG1_DPRINTF(a_ArgList) Bs3TestPrintf a_ArgList
81# define BS3CG1_DEBUG_CTX_MOD
82#else
83# define BS3CG1_DPRINTF(a_ArgList) do { } while (0)
84#endif
85
86/**
87 * Checks if this is a 64-bit test target or not.
88 * Helps avoid ifdefs or code bloat.
89 */
90#if ARCH_BITS == 64
91# define BS3CG1_IS_64BIT_TARGET(a_pThis) BS3_MODE_IS_64BIT_CODE((a_pThis)->bMode)
92#else
93# define BS3CG1_IS_64BIT_TARGET(a_pThis) (false)
94#endif
95
96
97/*********************************************************************************************************************************
98* Structures and Typedefs *
99*********************************************************************************************************************************/
100/** Operand value location. */
101typedef enum BS3CG1OPLOC
102{
103 BS3CG1OPLOC_INVALID = 0,
104 BS3CG1OPLOC_CTX,
105 BS3CG1OPLOC_CTX_ZX_VLMAX,
106 BS3CG1OPLOC_IMM,
107 BS3CG1OPLOC_MEM,
108 BS3CG1OPLOC_MEM_RW,
109 BS3CG1OPLOC_MEM_WO,
110 BS3CG1OPLOC_END
111} BS3CG1OPLOC;
112AssertCompile(BS3CG1OPLOC_END <= 16);
113
114
115/**
116 * Encoder callback.
117 * @returns Next encoding. If equal or less to @a iEncoding, no
118 * further encodings are available for testing.
119 * @param pThis The state.
120 * @param iEncoding The encoding.
121 */
122typedef BS3_DECL_NEAR(unsigned) FNBS3CG1ENCODER(struct BS3CG1STATE *pThis, unsigned iEncoding);
123/** Pointer to a encoder callback. */
124typedef FNBS3CG1ENCODER *PFNBS3CG1ENCODER;
125
126
127/**
128 * The state.
129 */
130typedef struct BS3CG1STATE
131{
132 /** @name Instruction details (expanded from BS3CG1INSTR).
133 * @{ */
134 /** Pointer to the mnemonic string (not terminated) (g_achBs3Cg1Mnemonics). */
135 const char BS3_FAR *pchMnemonic;
136 /** Pointer to the test header. */
137 PCBS3CG1TESTHDR pTestHdr;
138 /** Pointer to the per operand flags (g_abBs3Cg1Operands). */
139 const uint8_t BS3_FAR *pabOperands;
140 /** Opcode bytes (g_abBs3Cg1Opcodes). */
141 const uint8_t BS3_FAR *pabOpcodes;
142 /** The current instruction number in the input array (for error reporting). */
143 uint32_t iInstr;
144
145 /** The instruction flags. */
146 uint32_t fFlags;
147 /** The encoding. */
148 BS3CG1ENC enmEncoding;
149 /** The non-invalid encoding. This may differ from enmEncoding when
150 * Bs3Cg1CalcNoneIntelInvalidEncoding has been called. */
151 BS3CG1ENC enmEncodingNonInvalid;
152 /** The CPU test / CPU ID. */
153 BS3CG1CPU enmCpuTest;
154 /** Prefix sensitivity and requirements. */
155 BS3CG1PFXKIND enmPrefixKind;
156 /** Exception type (SSE, AVX). */
157 BS3CG1XCPTTYPE enmXcptType;
158 /** Per operand flags. */
159 BS3CG1OP aenmOperands[4];
160 /** Opcode bytes. */
161 uint8_t abOpcodes[4];
162 /** The instruction encoder. */
163 PFNBS3CG1ENCODER pfnEncoder;
164
165 /** The length of the mnemonic. */
166 uint8_t cchMnemonic;
167 /** Whether to advance the mnemonic pointer or not. */
168 uint8_t fAdvanceMnemonic;
169 /** The opcode map number. */
170 uint8_t uOpcodeMap;
171 /** The number of opcode bytes. */
172 uint8_t cbOpcodes;
173 /** Number of operands. */
174 uint8_t cOperands;
175 /** @} */
176
177 /** Operand size in bytes (0 if not applicable). */
178 uint8_t cbOperand;
179 /** Current VEX.L value (UINT8_MAX if not applicable). */
180 uint8_t uVexL;
181 /** Current target ring (0..3). */
182 uint8_t uCpl;
183
184 /** The current test number. */
185 uint8_t iTest;
186
187 /** Target mode (g_bBs3CurrentMode). */
188 uint8_t bMode;
189 /** The CPU vendor (BS3CPUVENDOR). */
190 uint8_t bCpuVendor;
191 /** First ring being tested. */
192 uint8_t iFirstRing;
193 /** End of rings being tested. */
194 uint8_t iEndRing;
195
196
197 /** @name Current encoded instruction.
198 * @{ */
199 /** The size of the current instruction that we're testing. */
200 uint8_t cbCurInstr;
201 /** The size the prefixes. */
202 uint8_t cbCurPrefix;
203 /** The offset into abCurInstr of the immediate. */
204 uint8_t offCurImm;
205 /** Buffer for assembling the current instruction. */
206 uint8_t abCurInstr[23];
207
208 /** Set if the encoding can't be tested in the same ring as this test code.
209 * This is used to deal with encodings modifying SP/ESP/RSP. */
210 bool fSameRingNotOkay;
211 /** Whether to work the extended context too. */
212 bool fWorkExtCtx;
213 /** The aOperands index of the modrm.reg operand (if applicable). */
214 uint8_t iRegOp;
215 /** The aOperands index of the modrm.rm operand (if applicable). */
216 uint8_t iRmOp;
217
218 /** Operands details. */
219 struct
220 {
221 uint8_t cbOp;
222 /** BS3CG1OPLOC_XXX. */
223 uint8_t enmLocation;
224 /** BS3CG1OPLOC_XXX for memory encodings (MODRM.rm field). */
225 uint8_t enmLocationMem : 4;
226 /** BS3CG1OPLOC_XXX for register encodings (MODRM.rm field). */
227 uint8_t enmLocationReg : 4;
228 /** The BS3CG1DST value for this field.
229 * Set to BS3CG1DST_INVALID if memory or immediate. */
230 uint8_t idxField;
231 /** The base BS3CG1DST value for this field.
232 * Used only by some generalized encoders when dealing with registers. */
233 uint8_t idxFieldBase;
234 /** Depends on enmLocation.
235 * - BS3CG1OPLOC_IMM: offset relative to start of the instruction.
236 * - BS3CG1OPLOC_MEM: offset should be subtracted from &pbDataPg[_4K].
237 * - BS3CG1OPLOC_MEM_RW: offset should be subtracted from &pbDataPg[_4K].
238 * - BS3CG1OPLOC_MEM_RO: offset should be subtracted from &pbDataPg[_4K].
239 * - BS3CG1OPLOC_CTX: not used (use idxField instead).
240 */
241 uint8_t off;
242 } aOperands[4];
243 /** @} */
244
245 /** Page to put code in. When paging is enabled, the page before and after
246 * are marked not-present. */
247 uint8_t BS3_FAR *pbCodePg;
248 /** The flat address corresponding to pbCodePg. */
249 uintptr_t uCodePgFlat;
250 /** The 16-bit address corresponding to pbCodePg if relevant for bMode. */
251 RTFAR16 CodePgFar;
252 /** The IP/EIP/RIP value for pbCodePg[0] relative to CS (bMode). */
253 uintptr_t CodePgRip;
254
255 /** Page for placing data operands in. When paging is enabled, the page before
256 * and after are marked not-present. */
257 uint8_t BS3_FAR *pbDataPg;
258 /** The flat address corresponding to pbDataPg. */
259 uintptr_t uDataPgFlat;
260 /** The 16-bit address corresponding to pbDataPg. */
261 RTFAR16 DataPgFar;
262
263 /** The name corresponding to bMode. */
264 const char BS3_FAR *pszMode;
265 /** The short name corresponding to bMode. */
266 const char BS3_FAR *pszModeShort;
267
268 /** @name Expected result (modifiable by output program).
269 * @{ */
270 /** The expected exception based on operand values or result.
271 * UINT8_MAX if no special exception expected. */
272 uint8_t bValueXcpt;
273 /** @} */
274 /** Alignment exception expected by the encoder.
275 * UINT8_MAX if no special exception expected. */
276 uint8_t bAlignmentXcpt;
277 /** Set by the encoding method to indicating invalid encoding. */
278 bool fInvalidEncoding;
279 /** The result of Bs3Cg1CpuSetupFirst(). */
280 bool fCpuSetupFirstResult;
281
282 /** The context we're working on. */
283 BS3REGCTX Ctx;
284 /** The trap context and frame. */
285 BS3TRAPFRAME TrapFrame;
286 /** Initial contexts, one for each ring. */
287 BS3REGCTX aInitialCtxs[4];
288
289 /** The extended context we're working on (input, expected output). */
290 PBS3EXTCTX pExtCtx;
291 /** The extended result context (analoguous to TrapFrame). */
292 PBS3EXTCTX pResultExtCtx;
293 /** The initial extended context. */
294 PBS3EXTCTX pInitialExtCtx;
295
296 /** Memory operand scratch space. */
297 union
298 {
299 uint8_t ab[128];
300 uint16_t au16[128 / sizeof(uint16_t)];
301 uint32_t au32[128 / sizeof(uint32_t)];
302 uint64_t au64[128 / sizeof(uint64_t)];
303 } MemOp;
304
305 /** Array parallel to aInitialCtxs for saving segment registers. */
306 struct
307 {
308 RTSEL ds;
309 } aSavedSegRegs[4];
310
311} BS3CG1STATE;
312/** Pointer to the generated test state. */
313typedef BS3CG1STATE *PBS3CG1STATE;
314
315
316#define BS3CG1_PF_OZ UINT16_C(0x0001)
317#define BS3CG1_PF_AZ UINT16_C(0x0002)
318#define BS3CG1_PF_CS UINT16_C(0x0004)
319#define BS3CG1_PF_DS UINT16_C(0x0008)
320#define BS3CG1_PF_ES UINT16_C(0x0010)
321#define BS3CG1_PF_FS UINT16_C(0x0020)
322#define BS3CG1_PF_GS UINT16_C(0x0040)
323#define BS3CG1_PF_SS UINT16_C(0x0080)
324#define BS3CG1_PF_SEGS (BS3CG1_PF_CS | BS3CG1_PF_DS | BS3CG1_PF_ES | BS3CG1_PF_FS | BS3CG1_PF_GS | BS3CG1_PF_SS)
325#define BS3CG1_PF_MEM (BS3CG1_PF_SEGS | BS3CG1_PF_AZ)
326#define BS3CG1_PF_LK UINT16_C(0x0100)
327#define BS3CG1_PF_RN UINT16_C(0x0200)
328#define BS3CG1_PF_RZ UINT16_C(0x0400)
329#define BS3CG1_PF_W UINT16_C(0x0800) /**< REX.W */
330#define BS3CG1_PF_R UINT16_C(0x1000) /**< REX.R */
331#define BS3CG1_PF_B UINT16_C(0x2000) /**< REX.B */
332#define BS3CG1_PF_X UINT16_C(0x4000) /**< REX.X */
333
334
335/** Used in g_cbBs3Cg1DstFields to indicate that it's one of the 4 operands. */
336#define BS3CG1DSTSIZE_OPERAND UINT8_C(255)
337/** Used in g_cbBs3Cg1DstFields to indicate that the operand size determins
338 * the field size (2, 4, or 8). */
339#define BS3CG1DSTSIZE_OPERAND_SIZE_GRP UINT8_C(254)
340
341
342
343/*********************************************************************************************************************************
344* Global Variables *
345*********************************************************************************************************************************/
346/** Destination field sizes indexed by bBS3CG1DST.
347 * Zero means operand size sized. */
348static const uint8_t g_acbBs3Cg1DstFields[] =
349{
350 /* [BS3CG1DST_INVALID] = */ BS3CG1DSTSIZE_OPERAND,
351
352 /* [BS3CG1DST_OP1] = */ BS3CG1DSTSIZE_OPERAND,
353 /* [BS3CG1DST_OP2] = */ BS3CG1DSTSIZE_OPERAND,
354 /* [BS3CG1DST_OP3] = */ BS3CG1DSTSIZE_OPERAND,
355 /* [BS3CG1DST_OP4] = */ BS3CG1DSTSIZE_OPERAND,
356 /* [BS3CG1DST_EFL] = */ 4,
357 /* [BS3CG1DST_EFL_UNDEF]=*/ 4,
358
359 /* [BS3CG1DST_AL] = */ 1,
360 /* [BS3CG1DST_CL] = */ 1,
361 /* [BS3CG1DST_DL] = */ 1,
362 /* [BS3CG1DST_BL] = */ 1,
363 /* [BS3CG1DST_AH] = */ 1,
364 /* [BS3CG1DST_CH] = */ 1,
365 /* [BS3CG1DST_DH] = */ 1,
366 /* [BS3CG1DST_BH] = */ 1,
367 /* [BS3CG1DST_SPL] = */ 1,
368 /* [BS3CG1DST_BPL] = */ 1,
369 /* [BS3CG1DST_SIL] = */ 1,
370 /* [BS3CG1DST_DIL] = */ 1,
371 /* [BS3CG1DST_R8L] = */ 1,
372 /* [BS3CG1DST_R9L] = */ 1,
373 /* [BS3CG1DST_R10L] = */ 1,
374 /* [BS3CG1DST_R11L] = */ 1,
375 /* [BS3CG1DST_R12L] = */ 1,
376 /* [BS3CG1DST_R13L] = */ 1,
377 /* [BS3CG1DST_R14L] = */ 1,
378 /* [BS3CG1DST_R15L] = */ 1,
379
380 /* [BS3CG1DST_AX] = */ 2,
381 /* [BS3CG1DST_CX] = */ 2,
382 /* [BS3CG1DST_DX] = */ 2,
383 /* [BS3CG1DST_BX] = */ 2,
384 /* [BS3CG1DST_SP] = */ 2,
385 /* [BS3CG1DST_BP] = */ 2,
386 /* [BS3CG1DST_SI] = */ 2,
387 /* [BS3CG1DST_DI] = */ 2,
388 /* [BS3CG1DST_R8W] = */ 2,
389 /* [BS3CG1DST_R9W] = */ 2,
390 /* [BS3CG1DST_R10W] = */ 2,
391 /* [BS3CG1DST_R11W] = */ 2,
392 /* [BS3CG1DST_R12W] = */ 2,
393 /* [BS3CG1DST_R13W] = */ 2,
394 /* [BS3CG1DST_R14W] = */ 2,
395 /* [BS3CG1DST_R15W] = */ 2,
396
397 /* [BS3CG1DST_EAX] = */ 4,
398 /* [BS3CG1DST_ECX] = */ 4,
399 /* [BS3CG1DST_EDX] = */ 4,
400 /* [BS3CG1DST_EBX] = */ 4,
401 /* [BS3CG1DST_ESP] = */ 4,
402 /* [BS3CG1DST_EBP] = */ 4,
403 /* [BS3CG1DST_ESI] = */ 4,
404 /* [BS3CG1DST_EDI] = */ 4,
405 /* [BS3CG1DST_R8D] = */ 4,
406 /* [BS3CG1DST_R9D] = */ 4,
407 /* [BS3CG1DST_R10D] = */ 4,
408 /* [BS3CG1DST_R11D] = */ 4,
409 /* [BS3CG1DST_R12D] = */ 4,
410 /* [BS3CG1DST_R13D] = */ 4,
411 /* [BS3CG1DST_R14D] = */ 4,
412 /* [BS3CG1DST_R15D] = */ 4,
413
414 /* [BS3CG1DST_RAX] = */ 8,
415 /* [BS3CG1DST_RCX] = */ 8,
416 /* [BS3CG1DST_RDX] = */ 8,
417 /* [BS3CG1DST_RBX] = */ 8,
418 /* [BS3CG1DST_RSP] = */ 8,
419 /* [BS3CG1DST_RBP] = */ 8,
420 /* [BS3CG1DST_RSI] = */ 8,
421 /* [BS3CG1DST_RDI] = */ 8,
422 /* [BS3CG1DST_R8] = */ 8,
423 /* [BS3CG1DST_R9] = */ 8,
424 /* [BS3CG1DST_R10] = */ 8,
425 /* [BS3CG1DST_R11] = */ 8,
426 /* [BS3CG1DST_R12] = */ 8,
427 /* [BS3CG1DST_R13] = */ 8,
428 /* [BS3CG1DST_R14] = */ 8,
429 /* [BS3CG1DST_R15] = */ 8,
430
431 /* [BS3CG1DST_OZ_RAX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
432 /* [BS3CG1DST_OZ_RCX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
433 /* [BS3CG1DST_OZ_RDX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
434 /* [BS3CG1DST_OZ_RBX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
435 /* [BS3CG1DST_OZ_RSP] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
436 /* [BS3CG1DST_OZ_RBP] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
437 /* [BS3CG1DST_OZ_RSI] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
438 /* [BS3CG1DST_OZ_RDI] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
439 /* [BS3CG1DST_OZ_R8] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
440 /* [BS3CG1DST_OZ_R9] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
441 /* [BS3CG1DST_OZ_R10] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
442 /* [BS3CG1DST_OZ_R11] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
443 /* [BS3CG1DST_OZ_R12] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
444 /* [BS3CG1DST_OZ_R13] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
445 /* [BS3CG1DST_OZ_R14] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
446 /* [BS3CG1DST_OZ_R15] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
447
448 /* [BS3CG1DST_CR0] = */ 4,
449 /* [BS3CG1DST_CR4] = */ 4,
450 /* [BS3CG1DST_XCR0] = */ 8,
451
452 /* [BS3CG1DST_FCW] = */ 2,
453 /* [BS3CG1DST_FSW] = */ 2,
454 /* [BS3CG1DST_FTW] = */ 2,
455 /* [BS3CG1DST_FOP] = */ 2,
456 /* [BS3CG1DST_FPUIP] = */ 2,
457 /* [BS3CG1DST_FPUCS] = */ 2,
458 /* [BS3CG1DST_FPUDP] = */ 2,
459 /* [BS3CG1DST_FPUDS] = */ 2,
460 /* [BS3CG1DST_MXCSR] = */ 4,
461 /* [BS3CG1DST_ST0] = */ 12,
462 /* [BS3CG1DST_ST1] = */ 12,
463 /* [BS3CG1DST_ST2] = */ 12,
464 /* [BS3CG1DST_ST3] = */ 12,
465 /* [BS3CG1DST_ST4] = */ 12,
466 /* [BS3CG1DST_ST5] = */ 12,
467 /* [BS3CG1DST_ST6] = */ 12,
468 /* [BS3CG1DST_ST7] = */ 12,
469 /* [BS3CG1DST_MM0] = */ 8,
470 /* [BS3CG1DST_MM1] = */ 8,
471 /* [BS3CG1DST_MM2] = */ 8,
472 /* [BS3CG1DST_MM3] = */ 8,
473 /* [BS3CG1DST_MM4] = */ 8,
474 /* [BS3CG1DST_MM5] = */ 8,
475 /* [BS3CG1DST_MM6] = */ 8,
476 /* [BS3CG1DST_MM7] = */ 8,
477 /* [BS3CG1DST_MM0_LO_ZX] = */ 4,
478 /* [BS3CG1DST_MM1_LO_ZX] = */ 4,
479 /* [BS3CG1DST_MM2_LO_ZX] = */ 4,
480 /* [BS3CG1DST_MM3_LO_ZX] = */ 4,
481 /* [BS3CG1DST_MM4_LO_ZX] = */ 4,
482 /* [BS3CG1DST_MM5_LO_ZX] = */ 4,
483 /* [BS3CG1DST_MM6_LO_ZX] = */ 4,
484 /* [BS3CG1DST_MM7_LO_ZX] = */ 4,
485 /* [BS3CG1DST_XMM0] = */ 16,
486 /* [BS3CG1DST_XMM1] = */ 16,
487 /* [BS3CG1DST_XMM2] = */ 16,
488 /* [BS3CG1DST_XMM3] = */ 16,
489 /* [BS3CG1DST_XMM4] = */ 16,
490 /* [BS3CG1DST_XMM5] = */ 16,
491 /* [BS3CG1DST_XMM6] = */ 16,
492 /* [BS3CG1DST_XMM7] = */ 16,
493 /* [BS3CG1DST_XMM8] = */ 16,
494 /* [BS3CG1DST_XMM9] = */ 16,
495 /* [BS3CG1DST_XMM10] = */ 16,
496 /* [BS3CG1DST_XMM11] = */ 16,
497 /* [BS3CG1DST_XMM12] = */ 16,
498 /* [BS3CG1DST_XMM13] = */ 16,
499 /* [BS3CG1DST_XMM14] = */ 16,
500 /* [BS3CG1DST_XMM15] = */ 16,
501 /* [BS3CG1DST_XMM0_LO] = */ 8,
502 /* [BS3CG1DST_XMM1_LO] = */ 8,
503 /* [BS3CG1DST_XMM2_LO] = */ 8,
504 /* [BS3CG1DST_XMM3_LO] = */ 8,
505 /* [BS3CG1DST_XMM4_LO] = */ 8,
506 /* [BS3CG1DST_XMM5_LO] = */ 8,
507 /* [BS3CG1DST_XMM6_LO] = */ 8,
508 /* [BS3CG1DST_XMM7_LO] = */ 8,
509 /* [BS3CG1DST_XMM8_LO] = */ 8,
510 /* [BS3CG1DST_XMM9_LO] = */ 8,
511 /* [BS3CG1DST_XMM10_LO] = */ 8,
512 /* [BS3CG1DST_XMM11_LO] = */ 8,
513 /* [BS3CG1DST_XMM12_LO] = */ 8,
514 /* [BS3CG1DST_XMM13_LO] = */ 8,
515 /* [BS3CG1DST_XMM14_LO] = */ 8,
516 /* [BS3CG1DST_XMM15_LO] = */ 8,
517 /* [BS3CG1DST_XMM0_HI] = */ 8,
518 /* [BS3CG1DST_XMM1_HI] = */ 8,
519 /* [BS3CG1DST_XMM2_HI] = */ 8,
520 /* [BS3CG1DST_XMM3_HI] = */ 8,
521 /* [BS3CG1DST_XMM4_HI] = */ 8,
522 /* [BS3CG1DST_XMM5_HI] = */ 8,
523 /* [BS3CG1DST_XMM6_HI] = */ 8,
524 /* [BS3CG1DST_XMM7_HI] = */ 8,
525 /* [BS3CG1DST_XMM8_HI] = */ 8,
526 /* [BS3CG1DST_XMM9_HI] = */ 8,
527 /* [BS3CG1DST_XMM10_HI] = */ 8,
528 /* [BS3CG1DST_XMM11_HI] = */ 8,
529 /* [BS3CG1DST_XMM12_HI] = */ 8,
530 /* [BS3CG1DST_XMM13_HI] = */ 8,
531 /* [BS3CG1DST_XMM14_HI] = */ 8,
532 /* [BS3CG1DST_XMM15_HI] = */ 8,
533 /* [BS3CG1DST_XMM0_LO_ZX] = */ 8,
534 /* [BS3CG1DST_XMM1_LO_ZX] = */ 8,
535 /* [BS3CG1DST_XMM2_LO_ZX] = */ 8,
536 /* [BS3CG1DST_XMM3_LO_ZX] = */ 8,
537 /* [BS3CG1DST_XMM4_LO_ZX] = */ 8,
538 /* [BS3CG1DST_XMM5_LO_ZX] = */ 8,
539 /* [BS3CG1DST_XMM6_LO_ZX] = */ 8,
540 /* [BS3CG1DST_XMM7_LO_ZX] = */ 8,
541 /* [BS3CG1DST_XMM8_LO_ZX] = */ 8,
542 /* [BS3CG1DST_XMM9_LO_ZX] = */ 8,
543 /* [BS3CG1DST_XMM10_LO_ZX] = */ 8,
544 /* [BS3CG1DST_XMM11_LO_ZX] = */ 8,
545 /* [BS3CG1DST_XMM12_LO_ZX] = */ 8,
546 /* [BS3CG1DST_XMM13_LO_ZX] = */ 8,
547 /* [BS3CG1DST_XMM14_LO_ZX] = */ 8,
548 /* [BS3CG1DST_XMM15_LO_ZX] = */ 8,
549 /* [BS3CG1DST_XMM0_DW0] = */ 4,
550 /* [BS3CG1DST_XMM1_DW0] = */ 4,
551 /* [BS3CG1DST_XMM2_DW0] = */ 4,
552 /* [BS3CG1DST_XMM3_DW0] = */ 4,
553 /* [BS3CG1DST_XMM4_DW0] = */ 4,
554 /* [BS3CG1DST_XMM5_DW0] = */ 4,
555 /* [BS3CG1DST_XMM6_DW0] = */ 4,
556 /* [BS3CG1DST_XMM7_DW0] = */ 4,
557 /* [BS3CG1DST_XMM8_DW0] = */ 4,
558 /* [BS3CG1DST_XMM9_DW0] = */ 4,
559 /* [BS3CG1DST_XMM10_DW0] = */ 4,
560 /* [BS3CG1DST_XMM11_DW0] = */ 4,
561 /* [BS3CG1DST_XMM12_DW0] = */ 4,
562 /* [BS3CG1DST_XMM13_DW0] = */ 4,
563 /* [BS3CG1DST_XMM14_DW0] = */ 4,
564 /* [BS3CG1DST_XMM15_DW0] = */ 4,
565 /* [BS3CG1DST_XMM0_DW0_ZX] = */ 4,
566 /* [BS3CG1DST_XMM1_DW0_ZX] = */ 4,
567 /* [BS3CG1DST_XMM2_DW0_ZX] = */ 4,
568 /* [BS3CG1DST_XMM3_DW0_ZX] = */ 4,
569 /* [BS3CG1DST_XMM4_DW0_ZX] = */ 4,
570 /* [BS3CG1DST_XMM5_DW0_ZX] = */ 4,
571 /* [BS3CG1DST_XMM6_DW0_ZX] = */ 4,
572 /* [BS3CG1DST_XMM7_DW0_ZX] = */ 4,
573 /* [BS3CG1DST_XMM8_DW0_ZX] = */ 4,
574 /* [BS3CG1DST_XMM9_DW0_ZX] = */ 4,
575 /* [BS3CG1DST_XMM10_DW0_ZX] =*/ 4,
576 /* [BS3CG1DST_XMM11_DW0_ZX] =*/ 4,
577 /* [BS3CG1DST_XMM12_DW0_ZX] =*/ 4,
578 /* [BS3CG1DST_XMM13_DW0_ZX] =*/ 4,
579 /* [BS3CG1DST_XMM14_DW0_ZX] =*/ 4,
580 /* [BS3CG1DST_XMM15_DW0_ZX] =*/ 4,
581 /* [BS3CG1DST_XMM0_HI96] = */ 12,
582 /* [BS3CG1DST_XMM1_HI96] = */ 12,
583 /* [BS3CG1DST_XMM2_HI96] = */ 12,
584 /* [BS3CG1DST_XMM3_HI96] = */ 12,
585 /* [BS3CG1DST_XMM4_HI96] = */ 12,
586 /* [BS3CG1DST_XMM5_HI96] = */ 12,
587 /* [BS3CG1DST_XMM6_HI96] = */ 12,
588 /* [BS3CG1DST_XMM7_HI96] = */ 12,
589 /* [BS3CG1DST_XMM8_HI96] = */ 12,
590 /* [BS3CG1DST_XMM9_HI96] = */ 12,
591 /* [BS3CG1DST_XMM10_HI96] =*/ 12,
592 /* [BS3CG1DST_XMM11_HI96] =*/ 12,
593 /* [BS3CG1DST_XMM12_HI96] =*/ 12,
594 /* [BS3CG1DST_XMM13_HI96] =*/ 12,
595 /* [BS3CG1DST_XMM14_HI96] =*/ 12,
596 /* [BS3CG1DST_XMM15_HI96] =*/ 12,
597 /* [BS3CG1DST_YMM0] = */ 32,
598 /* [BS3CG1DST_YMM1] = */ 32,
599 /* [BS3CG1DST_YMM2] = */ 32,
600 /* [BS3CG1DST_YMM3] = */ 32,
601 /* [BS3CG1DST_YMM4] = */ 32,
602 /* [BS3CG1DST_YMM5] = */ 32,
603 /* [BS3CG1DST_YMM6] = */ 32,
604 /* [BS3CG1DST_YMM7] = */ 32,
605 /* [BS3CG1DST_YMM8] = */ 32,
606 /* [BS3CG1DST_YMM9] = */ 32,
607 /* [BS3CG1DST_YMM10] = */ 32,
608 /* [BS3CG1DST_YMM11] = */ 32,
609 /* [BS3CG1DST_YMM12] = */ 32,
610 /* [BS3CG1DST_YMM13] = */ 32,
611 /* [BS3CG1DST_YMM14] = */ 32,
612 /* [BS3CG1DST_YMM15] = */ 32,
613
614 /* [BS3CG1DST_VALUE_XCPT] = */ 1,
615};
616AssertCompile(RT_ELEMENTS(g_acbBs3Cg1DstFields) == BS3CG1DST_END);
617
618/** Destination field offset indexed by bBS3CG1DST.
619 * Zero means operand size sized. */
620static const unsigned g_aoffBs3Cg1DstFields[] =
621{
622 /* [BS3CG1DST_INVALID] = */ ~0U,
623 /* [BS3CG1DST_OP1] = */ ~0U,
624 /* [BS3CG1DST_OP2] = */ ~0U,
625 /* [BS3CG1DST_OP3] = */ ~0U,
626 /* [BS3CG1DST_OP4] = */ ~0U,
627 /* [BS3CG1DST_EFL] = */ RT_OFFSETOF(BS3REGCTX, rflags),
628 /* [BS3CG1DST_EFL_UNDEF]=*/ ~0, /* special field */
629
630 /* [BS3CG1DST_AL] = */ RT_OFFSETOF(BS3REGCTX, rax.u8),
631 /* [BS3CG1DST_CL] = */ RT_OFFSETOF(BS3REGCTX, rcx.u8),
632 /* [BS3CG1DST_DL] = */ RT_OFFSETOF(BS3REGCTX, rdx.u8),
633 /* [BS3CG1DST_BL] = */ RT_OFFSETOF(BS3REGCTX, rbx.u8),
634 /* [BS3CG1DST_AH] = */ RT_OFFSETOF(BS3REGCTX, rax.b.bHi),
635 /* [BS3CG1DST_CH] = */ RT_OFFSETOF(BS3REGCTX, rcx.b.bHi),
636 /* [BS3CG1DST_DH] = */ RT_OFFSETOF(BS3REGCTX, rdx.b.bHi),
637 /* [BS3CG1DST_BH] = */ RT_OFFSETOF(BS3REGCTX, rbx.b.bHi),
638 /* [BS3CG1DST_SPL] = */ RT_OFFSETOF(BS3REGCTX, rsp.u8),
639 /* [BS3CG1DST_BPL] = */ RT_OFFSETOF(BS3REGCTX, rbp.u8),
640 /* [BS3CG1DST_SIL] = */ RT_OFFSETOF(BS3REGCTX, rsi.u8),
641 /* [BS3CG1DST_DIL] = */ RT_OFFSETOF(BS3REGCTX, rdi.u8),
642 /* [BS3CG1DST_R8L] = */ RT_OFFSETOF(BS3REGCTX, r8.u8),
643 /* [BS3CG1DST_R9L] = */ RT_OFFSETOF(BS3REGCTX, r9.u8),
644 /* [BS3CG1DST_R10L] = */ RT_OFFSETOF(BS3REGCTX, r10.u8),
645 /* [BS3CG1DST_R11L] = */ RT_OFFSETOF(BS3REGCTX, r11.u8),
646 /* [BS3CG1DST_R12L] = */ RT_OFFSETOF(BS3REGCTX, r12.u8),
647 /* [BS3CG1DST_R13L] = */ RT_OFFSETOF(BS3REGCTX, r13.u8),
648 /* [BS3CG1DST_R14L] = */ RT_OFFSETOF(BS3REGCTX, r14.u8),
649 /* [BS3CG1DST_R15L] = */ RT_OFFSETOF(BS3REGCTX, r15.u8),
650
651 /* [BS3CG1DST_AX] = */ RT_OFFSETOF(BS3REGCTX, rax.u16),
652 /* [BS3CG1DST_CX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u16),
653 /* [BS3CG1DST_DX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u16),
654 /* [BS3CG1DST_BX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u16),
655 /* [BS3CG1DST_SP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u16),
656 /* [BS3CG1DST_BP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u16),
657 /* [BS3CG1DST_SI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u16),
658 /* [BS3CG1DST_DI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u16),
659 /* [BS3CG1DST_R8W] = */ RT_OFFSETOF(BS3REGCTX, r8.u16),
660 /* [BS3CG1DST_R9W] = */ RT_OFFSETOF(BS3REGCTX, r9.u16),
661 /* [BS3CG1DST_R10W] = */ RT_OFFSETOF(BS3REGCTX, r10.u16),
662 /* [BS3CG1DST_R11W] = */ RT_OFFSETOF(BS3REGCTX, r11.u16),
663 /* [BS3CG1DST_R12W] = */ RT_OFFSETOF(BS3REGCTX, r12.u16),
664 /* [BS3CG1DST_R13W] = */ RT_OFFSETOF(BS3REGCTX, r13.u16),
665 /* [BS3CG1DST_R14W] = */ RT_OFFSETOF(BS3REGCTX, r14.u16),
666 /* [BS3CG1DST_R15W] = */ RT_OFFSETOF(BS3REGCTX, r15.u16),
667
668 /* [BS3CG1DST_EAX] = */ RT_OFFSETOF(BS3REGCTX, rax.u32),
669 /* [BS3CG1DST_ECX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u32),
670 /* [BS3CG1DST_EDX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u32),
671 /* [BS3CG1DST_EBX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u32),
672 /* [BS3CG1DST_ESP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u32),
673 /* [BS3CG1DST_EBP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u32),
674 /* [BS3CG1DST_ESI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u32),
675 /* [BS3CG1DST_EDI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u32),
676 /* [BS3CG1DST_R8D] = */ RT_OFFSETOF(BS3REGCTX, r8.u32),
677 /* [BS3CG1DST_R9D] = */ RT_OFFSETOF(BS3REGCTX, r9.u32),
678 /* [BS3CG1DST_R10D] = */ RT_OFFSETOF(BS3REGCTX, r10.u32),
679 /* [BS3CG1DST_R11D] = */ RT_OFFSETOF(BS3REGCTX, r11.u32),
680 /* [BS3CG1DST_R12D] = */ RT_OFFSETOF(BS3REGCTX, r12.u32),
681 /* [BS3CG1DST_R13D] = */ RT_OFFSETOF(BS3REGCTX, r13.u32),
682 /* [BS3CG1DST_R14D] = */ RT_OFFSETOF(BS3REGCTX, r14.u32),
683 /* [BS3CG1DST_R15D] = */ RT_OFFSETOF(BS3REGCTX, r15.u32),
684
685 /* [BS3CG1DST_RAX] = */ RT_OFFSETOF(BS3REGCTX, rax.u64),
686 /* [BS3CG1DST_RCX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u64),
687 /* [BS3CG1DST_RDX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u64),
688 /* [BS3CG1DST_RBX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u64),
689 /* [BS3CG1DST_RSP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u64),
690 /* [BS3CG1DST_RBP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u64),
691 /* [BS3CG1DST_RSI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u64),
692 /* [BS3CG1DST_RDI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u64),
693 /* [BS3CG1DST_R8] = */ RT_OFFSETOF(BS3REGCTX, r8.u64),
694 /* [BS3CG1DST_R9] = */ RT_OFFSETOF(BS3REGCTX, r9.u64),
695 /* [BS3CG1DST_R10] = */ RT_OFFSETOF(BS3REGCTX, r10.u64),
696 /* [BS3CG1DST_R11] = */ RT_OFFSETOF(BS3REGCTX, r11.u64),
697 /* [BS3CG1DST_R12] = */ RT_OFFSETOF(BS3REGCTX, r12.u64),
698 /* [BS3CG1DST_R13] = */ RT_OFFSETOF(BS3REGCTX, r13.u64),
699 /* [BS3CG1DST_R14] = */ RT_OFFSETOF(BS3REGCTX, r14.u64),
700 /* [BS3CG1DST_R15] = */ RT_OFFSETOF(BS3REGCTX, r15.u64),
701
702 /* [BS3CG1DST_OZ_RAX] = */ RT_OFFSETOF(BS3REGCTX, rax),
703 /* [BS3CG1DST_OZ_RCX] = */ RT_OFFSETOF(BS3REGCTX, rcx),
704 /* [BS3CG1DST_OZ_RDX] = */ RT_OFFSETOF(BS3REGCTX, rdx),
705 /* [BS3CG1DST_OZ_RBX] = */ RT_OFFSETOF(BS3REGCTX, rbx),
706 /* [BS3CG1DST_OZ_RSP] = */ RT_OFFSETOF(BS3REGCTX, rsp),
707 /* [BS3CG1DST_OZ_RBP] = */ RT_OFFSETOF(BS3REGCTX, rbp),
708 /* [BS3CG1DST_OZ_RSI] = */ RT_OFFSETOF(BS3REGCTX, rsi),
709 /* [BS3CG1DST_OZ_RDI] = */ RT_OFFSETOF(BS3REGCTX, rdi),
710 /* [BS3CG1DST_OZ_R8] = */ RT_OFFSETOF(BS3REGCTX, r8),
711 /* [BS3CG1DST_OZ_R9] = */ RT_OFFSETOF(BS3REGCTX, r9),
712 /* [BS3CG1DST_OZ_R10] = */ RT_OFFSETOF(BS3REGCTX, r10),
713 /* [BS3CG1DST_OZ_R11] = */ RT_OFFSETOF(BS3REGCTX, r11),
714 /* [BS3CG1DST_OZ_R12] = */ RT_OFFSETOF(BS3REGCTX, r12),
715 /* [BS3CG1DST_OZ_R13] = */ RT_OFFSETOF(BS3REGCTX, r13),
716 /* [BS3CG1DST_OZ_R14] = */ RT_OFFSETOF(BS3REGCTX, r14),
717 /* [BS3CG1DST_OZ_R15] = */ RT_OFFSETOF(BS3REGCTX, r15),
718
719 /* [BS3CG1DST_CR0] = */ RT_OFFSETOF(BS3REGCTX, cr0),
720 /* [BS3CG1DST_CR4] = */ RT_OFFSETOF(BS3REGCTX, cr4),
721 /* [BS3CG1DST_XCR0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, fXcr0Saved),
722
723 /* [BS3CG1DST_FCW] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FCW),
724 /* [BS3CG1DST_FSW] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FSW),
725 /* [BS3CG1DST_FTW] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FTW),
726 /* [BS3CG1DST_FOP] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FOP),
727 /* [BS3CG1DST_FPUIP] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FPUIP),
728 /* [BS3CG1DST_FPUCS] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.CS),
729 /* [BS3CG1DST_FPUDP] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FPUDP),
730 /* [BS3CG1DST_FPUDS] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.DS),
731 /* [BS3CG1DST_MXCSR] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.MXCSR),
732 /* [BS3CG1DST_ST0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[0]),
733 /* [BS3CG1DST_ST1] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[1]),
734 /* [BS3CG1DST_ST2] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[2]),
735 /* [BS3CG1DST_ST3] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[3]),
736 /* [BS3CG1DST_ST4] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[4]),
737 /* [BS3CG1DST_ST5] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[5]),
738 /* [BS3CG1DST_ST6] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[6]),
739 /* [BS3CG1DST_ST7] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[7]),
740 /* [BS3CG1DST_MM0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[0]),
741 /* [BS3CG1DST_MM1] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[1]),
742 /* [BS3CG1DST_MM2] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[2]),
743 /* [BS3CG1DST_MM3] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[3]),
744 /* [BS3CG1DST_MM4] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[4]),
745 /* [BS3CG1DST_MM5] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[5]),
746 /* [BS3CG1DST_MM6] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[6]),
747 /* [BS3CG1DST_MM7] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[7]),
748 /* [BS3CG1DST_MM0_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[0]),
749 /* [BS3CG1DST_MM1_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[1]),
750 /* [BS3CG1DST_MM2_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[2]),
751 /* [BS3CG1DST_MM3_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[3]),
752 /* [BS3CG1DST_MM4_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[4]),
753 /* [BS3CG1DST_MM5_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[5]),
754 /* [BS3CG1DST_MM6_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[6]),
755 /* [BS3CG1DST_MM7_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[7]),
756
757 /* [BS3CG1DST_XMM0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
758 /* [BS3CG1DST_XMM1] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
759 /* [BS3CG1DST_XMM2] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
760 /* [BS3CG1DST_XMM3] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
761 /* [BS3CG1DST_XMM4] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
762 /* [BS3CG1DST_XMM5] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
763 /* [BS3CG1DST_XMM6] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
764 /* [BS3CG1DST_XMM7] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
765 /* [BS3CG1DST_XMM8] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
766 /* [BS3CG1DST_XMM9] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
767 /* [BS3CG1DST_XMM10] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
768 /* [BS3CG1DST_XMM11] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
769 /* [BS3CG1DST_XMM12] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
770 /* [BS3CG1DST_XMM13] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
771 /* [BS3CG1DST_XMM14] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
772 /* [BS3CG1DST_XMM15] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
773 /* [BS3CG1DST_XMM0_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
774 /* [BS3CG1DST_XMM1_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
775 /* [BS3CG1DST_XMM2_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
776 /* [BS3CG1DST_XMM3_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
777 /* [BS3CG1DST_XMM4_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
778 /* [BS3CG1DST_XMM5_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
779 /* [BS3CG1DST_XMM6_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
780 /* [BS3CG1DST_XMM7_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
781 /* [BS3CG1DST_XMM8_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
782 /* [BS3CG1DST_XMM9_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
783 /* [BS3CG1DST_XMM10_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
784 /* [BS3CG1DST_XMM11_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
785 /* [BS3CG1DST_XMM12_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
786 /* [BS3CG1DST_XMM13_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
787 /* [BS3CG1DST_XMM14_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
788 /* [BS3CG1DST_XMM15_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
789 /* [BS3CG1DST_XMM0_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]) + sizeof(uint64_t),
790 /* [BS3CG1DST_XMM1_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]) + sizeof(uint64_t),
791 /* [BS3CG1DST_XMM2_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]) + sizeof(uint64_t),
792 /* [BS3CG1DST_XMM3_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]) + sizeof(uint64_t),
793 /* [BS3CG1DST_XMM4_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]) + sizeof(uint64_t),
794 /* [BS3CG1DST_XMM5_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]) + sizeof(uint64_t),
795 /* [BS3CG1DST_XMM6_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]) + sizeof(uint64_t),
796 /* [BS3CG1DST_XMM7_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]) + sizeof(uint64_t),
797 /* [BS3CG1DST_XMM8_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]) + sizeof(uint64_t),
798 /* [BS3CG1DST_XMM9_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]) + sizeof(uint64_t),
799 /* [BS3CG1DST_XMM10_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]) + sizeof(uint64_t),
800 /* [BS3CG1DST_XMM11_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]) + sizeof(uint64_t),
801 /* [BS3CG1DST_XMM12_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]) + sizeof(uint64_t),
802 /* [BS3CG1DST_XMM13_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]) + sizeof(uint64_t),
803 /* [BS3CG1DST_XMM14_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]) + sizeof(uint64_t),
804 /* [BS3CG1DST_XMM15_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]) + sizeof(uint64_t),
805 /* [BS3CG1DST_XMM0_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
806 /* [BS3CG1DST_XMM1_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
807 /* [BS3CG1DST_XMM2_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
808 /* [BS3CG1DST_XMM3_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
809 /* [BS3CG1DST_XMM4_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
810 /* [BS3CG1DST_XMM5_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
811 /* [BS3CG1DST_XMM6_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
812 /* [BS3CG1DST_XMM7_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
813 /* [BS3CG1DST_XMM8_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
814 /* [BS3CG1DST_XMM9_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
815 /* [BS3CG1DST_XMM10_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
816 /* [BS3CG1DST_XMM11_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
817 /* [BS3CG1DST_XMM12_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
818 /* [BS3CG1DST_XMM13_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
819 /* [BS3CG1DST_XMM14_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
820 /* [BS3CG1DST_XMM15_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
821 /* [BS3CG1DST_XMM0_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
822 /* [BS3CG1DST_XMM1_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
823 /* [BS3CG1DST_XMM2_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
824 /* [BS3CG1DST_XMM3_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
825 /* [BS3CG1DST_XMM4_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
826 /* [BS3CG1DST_XMM5_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
827 /* [BS3CG1DST_XMM6_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
828 /* [BS3CG1DST_XMM7_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
829 /* [BS3CG1DST_XMM8_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
830 /* [BS3CG1DST_XMM9_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
831 /* [BS3CG1DST_XMM10_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
832 /* [BS3CG1DST_XMM11_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
833 /* [BS3CG1DST_XMM12_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
834 /* [BS3CG1DST_XMM13_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
835 /* [BS3CG1DST_XMM14_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
836 /* [BS3CG1DST_XMM15_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
837 /* [BS3CG1DST_XMM0_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
838 /* [BS3CG1DST_XMM1_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
839 /* [BS3CG1DST_XMM2_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
840 /* [BS3CG1DST_XMM3_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
841 /* [BS3CG1DST_XMM4_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
842 /* [BS3CG1DST_XMM5_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
843 /* [BS3CG1DST_XMM6_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
844 /* [BS3CG1DST_XMM7_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
845 /* [BS3CG1DST_XMM8_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
846 /* [BS3CG1DST_XMM9_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
847 /* [BS3CG1DST_XMM10_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
848 /* [BS3CG1DST_XMM11_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
849 /* [BS3CG1DST_XMM12_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
850 /* [BS3CG1DST_XMM13_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
851 /* [BS3CG1DST_XMM14_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
852 /* [BS3CG1DST_XMM15_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
853 /* [BS3CG1DST_XMM0_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0].au32[1]),
854 /* [BS3CG1DST_XMM1_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1].au32[1]),
855 /* [BS3CG1DST_XMM2_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2].au32[1]),
856 /* [BS3CG1DST_XMM3_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3].au32[1]),
857 /* [BS3CG1DST_XMM4_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4].au32[1]),
858 /* [BS3CG1DST_XMM5_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5].au32[1]),
859 /* [BS3CG1DST_XMM6_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6].au32[1]),
860 /* [BS3CG1DST_XMM7_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7].au32[1]),
861 /* [BS3CG1DST_XMM8_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8].au32[1]),
862 /* [BS3CG1DST_XMM9_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9].au32[1]),
863 /* [BS3CG1DST_XMM10_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10].au32[1]),
864 /* [BS3CG1DST_XMM11_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11].au32[1]),
865 /* [BS3CG1DST_XMM12_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12].au32[1]),
866 /* [BS3CG1DST_XMM13_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13].au32[1]),
867 /* [BS3CG1DST_XMM14_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14].au32[1]),
868 /* [BS3CG1DST_XMM15_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15].au32[1]),
869
870 /* [BS3CG1DST_YMM0] = */ ~0U,
871 /* [BS3CG1DST_YMM1] = */ ~0U,
872 /* [BS3CG1DST_YMM2] = */ ~0U,
873 /* [BS3CG1DST_YMM3] = */ ~0U,
874 /* [BS3CG1DST_YMM4] = */ ~0U,
875 /* [BS3CG1DST_YMM5] = */ ~0U,
876 /* [BS3CG1DST_YMM6] = */ ~0U,
877 /* [BS3CG1DST_YMM7] = */ ~0U,
878 /* [BS3CG1DST_YMM8] = */ ~0U,
879 /* [BS3CG1DST_YMM9] = */ ~0U,
880 /* [BS3CG1DST_YMM10] = */ ~0U,
881 /* [BS3CG1DST_YMM11] = */ ~0U,
882 /* [BS3CG1DST_YMM12] = */ ~0U,
883 /* [BS3CG1DST_YMM13] = */ ~0U,
884 /* [BS3CG1DST_YMM14] = */ ~0U,
885 /* [BS3CG1DST_YMM15] = */ ~0U,
886
887 /* [BS3CG1DST_VALUE_XCPT] = */ ~0U,
888};
889AssertCompile(RT_ELEMENTS(g_aoffBs3Cg1DstFields) == BS3CG1DST_END);
890
891/** Destination field names. */
892static const struct { char sz[12]; } g_aszBs3Cg1DstFields[] =
893{
894 { "INVALID" },
895 { "OP1" },
896 { "OP2" },
897 { "OP3" },
898 { "OP4" },
899 { "EFL" },
900 { "EFL_UND" },
901
902 { "AL" },
903 { "CL" },
904 { "DL" },
905 { "BL" },
906 { "AH" },
907 { "CH" },
908 { "DH" },
909 { "BH" },
910 { "SPL" },
911 { "BPL" },
912 { "SIL" },
913 { "DIL" },
914 { "R8L" },
915 { "R9L" },
916 { "R10L" },
917 { "R11L" },
918 { "R12L" },
919 { "R13L" },
920 { "R14L" },
921 { "R15L" },
922
923 { "AX" },
924 { "CX" },
925 { "DX" },
926 { "BX" },
927 { "SP" },
928 { "BP" },
929 { "SI" },
930 { "DI" },
931 { "R8W" },
932 { "R9W" },
933 { "R10W" },
934 { "R11W" },
935 { "R12W" },
936 { "R13W" },
937 { "R14W" },
938 { "R15W" },
939
940 { "EAX" },
941 { "ECX" },
942 { "EDX" },
943 { "EBX" },
944 { "ESP" },
945 { "EBP" },
946 { "ESI" },
947 { "EDI" },
948 { "R8D" },
949 { "R9D" },
950 { "R10D" },
951 { "R11D" },
952 { "R12D" },
953 { "R13D" },
954 { "R14D" },
955 { "R15D" },
956
957 { "RAX" },
958 { "RCX" },
959 { "RDX" },
960 { "RBX" },
961 { "RSP" },
962 { "RBP" },
963 { "RSI" },
964 { "RDI" },
965 { "R8" },
966 { "R9" },
967 { "R10" },
968 { "R11" },
969 { "R12" },
970 { "R13" },
971 { "R14" },
972 { "R15" },
973
974 { "OZ_RAX" },
975 { "OZ_RCX" },
976 { "OZ_RDX" },
977 { "OZ_RBX" },
978 { "OZ_RSP" },
979 { "OZ_RBP" },
980 { "OZ_RSI" },
981 { "OZ_RDI" },
982 { "OZ_R8" },
983 { "OZ_R9" },
984 { "OZ_R10" },
985 { "OZ_R11" },
986 { "OZ_R12" },
987 { "OZ_R13" },
988 { "OZ_R14" },
989 { "OZ_R15" },
990
991 { "CR0" },
992 { "CR4" },
993 { "XCR0" },
994
995 { "FCW" },
996 { "FSW" },
997 { "FTW" },
998 { "FOP" },
999 { "FPUIP" },
1000 { "FPUCS" },
1001 { "FPUDP" },
1002 { "FPUDS" },
1003 { "MXCSR" },
1004 { "ST0" },
1005 { "ST1" },
1006 { "ST2" },
1007 { "ST3" },
1008 { "ST4" },
1009 { "ST5" },
1010 { "ST6" },
1011 { "ST7" },
1012 { "MM0" },
1013 { "MM1" },
1014 { "MM2" },
1015 { "MM3" },
1016 { "MM4" },
1017 { "MM5" },
1018 { "MM6" },
1019 { "MM7" },
1020 { "MM0_LO_ZX" },
1021 { "MM1_LO_ZX" },
1022 { "MM2_LO_ZX" },
1023 { "MM3_LO_ZX" },
1024 { "MM4_LO_ZX" },
1025 { "MM5_LO_ZX" },
1026 { "MM6_LO_ZX" },
1027 { "MM7_LO_ZX" },
1028 { "XMM0" },
1029 { "XMM1" },
1030 { "XMM2" },
1031 { "XMM3" },
1032 { "XMM4" },
1033 { "XMM5" },
1034 { "XMM6" },
1035 { "XMM7" },
1036 { "XMM8" },
1037 { "XMM9" },
1038 { "XMM10" },
1039 { "XMM11" },
1040 { "XMM12" },
1041 { "XMM13" },
1042 { "XMM14" },
1043 { "XMM15" },
1044 { "XMM0_LO" },
1045 { "XMM1_LO" },
1046 { "XMM2_LO" },
1047 { "XMM3_LO" },
1048 { "XMM4_LO" },
1049 { "XMM5_LO" },
1050 { "XMM6_LO" },
1051 { "XMM7_LO" },
1052 { "XMM8_LO" },
1053 { "XMM9_LO" },
1054 { "XMM10_LO" },
1055 { "XMM11_LO" },
1056 { "XMM12_LO" },
1057 { "XMM13_LO" },
1058 { "XMM14_LO" },
1059 { "XMM15_LO" },
1060 { "XMM0_HI" },
1061 { "XMM1_HI" },
1062 { "XMM2_HI" },
1063 { "XMM3_HI" },
1064 { "XMM4_HI" },
1065 { "XMM5_HI" },
1066 { "XMM6_HI" },
1067 { "XMM7_HI" },
1068 { "XMM8_HI" },
1069 { "XMM9_HI" },
1070 { "XMM10_HI" },
1071 { "XMM11_HI" },
1072 { "XMM12_HI" },
1073 { "XMM13_HI" },
1074 { "XMM14_HI" },
1075 { "XMM15_HI" },
1076 { "XMM0_LO_ZX" },
1077 { "XMM1_LO_ZX" },
1078 { "XMM2_LO_ZX" },
1079 { "XMM3_LO_ZX" },
1080 { "XMM4_LO_ZX" },
1081 { "XMM5_LO_ZX" },
1082 { "XMM6_LO_ZX" },
1083 { "XMM7_LO_ZX" },
1084 { "XMM8_LO_ZX" },
1085 { "XMM9_LO_ZX" },
1086 { "XMM10_LO_ZX" },
1087 { "XMM11_LO_ZX" },
1088 { "XMM12_LO_ZX" },
1089 { "XMM13_LO_ZX" },
1090 { "XMM14_LO_ZX" },
1091 { "XMM15_LO_ZX" },
1092 { "XMM0_DW0" },
1093 { "XMM1_DW0" },
1094 { "XMM2_DW0" },
1095 { "XMM3_DW0" },
1096 { "XMM4_DW0" },
1097 { "XMM5_DW0" },
1098 { "XMM6_DW0" },
1099 { "XMM7_DW0" },
1100 { "XMM8_DW0" },
1101 { "XMM9_DW0" },
1102 { "XMM10_DW0" },
1103 { "XMM11_DW0" },
1104 { "XMM12_DW0" },
1105 { "XMM13_DW0" },
1106 { "XMM14_DW0" },
1107 { "XMM15_DW0" },
1108 { "XMM0_DW0_ZX" },
1109 { "XMM1_DW0_ZX" },
1110 { "XMM2_DW0_ZX" },
1111 { "XMM3_DW0_ZX" },
1112 { "XMM4_DW0_ZX" },
1113 { "XMM5_DW0_ZX" },
1114 { "XMM6_DW0_ZX" },
1115 { "XMM7_DW0_ZX" },
1116 { "XMM8_DW0_ZX" },
1117 { "XMM9_DW0_ZX" },
1118 { "XMM10_DW0_ZX" },
1119 { "XMM11_DW0_ZX" },
1120 { "XMM12_DW0_ZX" },
1121 { "XMM13_DW0_ZX" },
1122 { "XMM14_DW0_ZX" },
1123 { "XMM15_DW0_ZX" },
1124 { "XMM0_HI96" },
1125 { "XMM1_HI96" },
1126 { "XMM2_HI96" },
1127 { "XMM3_HI96" },
1128 { "XMM4_HI96" },
1129 { "XMM5_HI96" },
1130 { "XMM6_HI96" },
1131 { "XMM7_HI96" },
1132 { "XMM8_HI96" },
1133 { "XMM9_HI96" },
1134 { "XMM10_HI96" },
1135 { "XMM11_HI96" },
1136 { "XMM12_HI96" },
1137 { "XMM13_HI96" },
1138 { "XMM14_HI96" },
1139 { "XMM15_HI96" },
1140 { "YMM0" },
1141 { "YMM1" },
1142 { "YMM2" },
1143 { "YMM3" },
1144 { "YMM4" },
1145 { "YMM5" },
1146 { "YMM6" },
1147 { "YMM7" },
1148 { "YMM8" },
1149 { "YMM9" },
1150 { "YMM10" },
1151 { "YMM11" },
1152 { "YMM12" },
1153 { "YMM13" },
1154 { "YMM14" },
1155 { "YMM15" },
1156
1157 { "VALXCPT" },
1158};
1159AssertCompile(RT_ELEMENTS(g_aszBs3Cg1DstFields) >= BS3CG1DST_END);
1160AssertCompile(RT_ELEMENTS(g_aszBs3Cg1DstFields) == BS3CG1DST_END);
1161
1162
1163#if 0
1164static const struct
1165{
1166 uint8_t cbPrefixes;
1167 uint8_t abPrefixes[14];
1168 uint16_t fEffective;
1169} g_aPrefixVariations[] =
1170{
1171 { 0, { 0x00 }, BS3CG1_PF_NONE },
1172
1173 { 1, { P_OZ }, BS3CG1_PF_OZ },
1174 { 1, { P_CS }, BS3CG1_PF_CS },
1175 { 1, { P_DS }, BS3CG1_PF_DS },
1176 { 1, { P_ES }, BS3CG1_PF_ES },
1177 { 1, { P_FS }, BS3CG1_PF_FS },
1178 { 1, { P_GS }, BS3CG1_PF_GS },
1179 { 1, { P_SS }, BS3CG1_PF_SS },
1180 { 1, { P_LK }, BS3CG1_PF_LK },
1181
1182 { 2, { P_CS, P_OZ, }, BS3CG1_PF_CS | BS3CFG1_PF_OZ },
1183 { 2, { P_DS, P_OZ, }, BS3CG1_PF_DS | BS3CFG1_PF_OZ },
1184 { 2, { P_ES, P_OZ, }, BS3CG1_PF_ES | BS3CFG1_PF_OZ },
1185 { 2, { P_FS, P_OZ, }, BS3CG1_PF_FS | BS3CFG1_PF_OZ },
1186 { 2, { P_GS, P_OZ, }, BS3CG1_PF_GS | BS3CFG1_PF_OZ },
1187 { 2, { P_GS, P_OZ, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1188 { 2, { P_SS, P_OZ, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1189
1190 { 2, { P_OZ, P_CS, }, BS3CG1_PF_CS | BS3CFG1_PF_OZ },
1191 { 2, { P_OZ, P_DS, }, BS3CG1_PF_DS | BS3CFG1_PF_OZ },
1192 { 2, { P_OZ, P_ES, }, BS3CG1_PF_ES | BS3CFG1_PF_OZ },
1193 { 2, { P_OZ, P_FS, }, BS3CG1_PF_FS | BS3CFG1_PF_OZ },
1194 { 2, { P_OZ, P_GS, }, BS3CG1_PF_GS | BS3CFG1_PF_OZ },
1195 { 2, { P_OZ, P_GS, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1196 { 2, { P_OZ, P_SS, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1197};
1198
1199static const uint16_t g_afPfxKindToIgnoredFlags[BS3CG1PFXKIND_END] =
1200{
1201 /* [BS3CG1PFXKIND_INVALID] = */ UINT16_MAX,
1202 /* [BS3CG1PFXKIND_MODRM] = */ 0,
1203 /* [BS3CG1PFXKIND_MODRM_NO_OP_SIZES] = */ BS3CG1_PF_OZ | BS3CG1_PF_W,
1204};
1205
1206#endif
1207
1208
1209/**
1210 * Checks if >= 16 byte SSE alignment are exempted for the exception type.
1211 *
1212 * @returns true / false.
1213 * @param enmXcptType The type to check.
1214 */
1215static bool BS3_NEAR_CODE Bs3Cg1XcptTypeIsUnaligned(BS3CG1XCPTTYPE enmXcptType)
1216{
1217 switch (enmXcptType)
1218 {
1219 case BS3CG1XCPTTYPE_1:
1220 case BS3CG1XCPTTYPE_2:
1221 case BS3CG1XCPTTYPE_4:
1222 return false;
1223 case BS3CG1XCPTTYPE_NONE:
1224 case BS3CG1XCPTTYPE_3:
1225 case BS3CG1XCPTTYPE_4UA:
1226 case BS3CG1XCPTTYPE_5:
1227 return true;
1228 default:
1229 return false;
1230 }
1231}
1232
1233
1234/**
1235 * Checks if >= 16 byte AVX alignment are exempted for the exception type.
1236 *
1237 * @returns true / false.
1238 * @param enmXcptType The type to check.
1239 */
1240static bool BS3_NEAR_CODE Bs3Cg1XcptTypeIsVexUnaligned(BS3CG1XCPTTYPE enmXcptType)
1241{
1242 switch (enmXcptType)
1243 {
1244 case BS3CG1XCPTTYPE_1:
1245 return false;
1246
1247 case BS3CG1XCPTTYPE_NONE:
1248 case BS3CG1XCPTTYPE_2:
1249 case BS3CG1XCPTTYPE_3:
1250 case BS3CG1XCPTTYPE_4:
1251 case BS3CG1XCPTTYPE_4UA:
1252 case BS3CG1XCPTTYPE_5:
1253 case BS3CG1XCPTTYPE_6:
1254 case BS3CG1XCPTTYPE_11:
1255 case BS3CG1XCPTTYPE_12:
1256 return true;
1257
1258 default:
1259 return false;
1260 }
1261}
1262
1263
1264DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertReqPrefix(PBS3CG1STATE pThis, unsigned offDst)
1265{
1266 switch (pThis->enmPrefixKind)
1267 {
1268 case BS3CG1PFXKIND_REQ_66:
1269 pThis->abCurInstr[offDst] = 0x66;
1270 break;
1271 case BS3CG1PFXKIND_REQ_F2:
1272 pThis->abCurInstr[offDst] = 0xf2;
1273 break;
1274 case BS3CG1PFXKIND_REQ_F3:
1275 pThis->abCurInstr[offDst] = 0xf3;
1276 break;
1277 default:
1278 return offDst;
1279 }
1280 return offDst + 1;
1281}
1282
1283
1284DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertOpcodes(PBS3CG1STATE pThis, unsigned offDst)
1285{
1286 switch (pThis->cbOpcodes)
1287 {
1288 case 4: pThis->abCurInstr[offDst + 3] = pThis->abOpcodes[3];
1289 case 3: pThis->abCurInstr[offDst + 2] = pThis->abOpcodes[2];
1290 case 2: pThis->abCurInstr[offDst + 1] = pThis->abOpcodes[1];
1291 case 1: pThis->abCurInstr[offDst] = pThis->abOpcodes[0];
1292 return offDst + pThis->cbOpcodes;
1293
1294 default:
1295 BS3_ASSERT(0);
1296 return 0;
1297 }
1298}
1299
1300
1301/**
1302 * Cleans up state and context changes made by the encoder.
1303 *
1304 * @param pThis The state.
1305 */
1306static void BS3_NEAR_CODE Bs3Cg1EncodeCleanup(PBS3CG1STATE pThis)
1307{
1308 /* Restore the DS registers in the contexts. */
1309 unsigned iRing = 4;
1310 while (iRing-- > 0)
1311 pThis->aInitialCtxs[iRing].ds = pThis->aSavedSegRegs[iRing].ds;
1312
1313 switch (pThis->enmEncoding)
1314 {
1315 /* Most encodings currently doesn't need any special cleaning up. */
1316 default:
1317 return;
1318 }
1319}
1320
1321
1322static unsigned BS3_NEAR_CODE Bs3Cfg1EncodeMemMod0Disp(PBS3CG1STATE pThis, bool fAddrOverride, unsigned off, uint8_t iReg,
1323 uint8_t cbOp, uint8_t cbMisalign, BS3CG1OPLOC enmLocation)
1324{
1325 pThis->aOperands[pThis->iRmOp].idxField = BS3CG1DST_INVALID;
1326 pThis->aOperands[pThis->iRmOp].enmLocation = enmLocation;
1327 pThis->aOperands[pThis->iRmOp].cbOp = cbOp;
1328 pThis->aOperands[pThis->iRmOp].off = cbOp + cbMisalign;
1329
1330 if ( BS3_MODE_IS_16BIT_CODE(pThis->bMode)
1331 || (fAddrOverride && BS3_MODE_IS_32BIT_CODE(pThis->bMode)) )
1332 {
1333 /*
1334 * 16-bit code doing 16-bit or 32-bit addressing,
1335 * or 32-bit code doing 16-bit addressing.
1336 */
1337 unsigned iRing = 4;
1338 if (BS3_MODE_IS_RM_OR_V86(pThis->bMode))
1339 while (iRing-- > 0)
1340 pThis->aInitialCtxs[iRing].ds = pThis->DataPgFar.sel;
1341 else
1342 while (iRing-- > 0)
1343 pThis->aInitialCtxs[iRing].ds = pThis->DataPgFar.sel | iRing;
1344 if (!fAddrOverride || BS3_MODE_IS_32BIT_CODE(pThis->bMode))
1345 {
1346 pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, iReg, 6 /*disp16*/);
1347 *(uint16_t *)&pThis->abCurInstr[off] = pThis->DataPgFar.off + X86_PAGE_SIZE - cbOp - cbMisalign;
1348 off += 2;
1349 }
1350 else
1351 {
1352 pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, iReg, 5 /*disp32*/);
1353 *(uint32_t *)&pThis->abCurInstr[off] = pThis->DataPgFar.off + X86_PAGE_SIZE - cbOp - cbMisalign;
1354 off += 4;
1355 }
1356 }
1357 else
1358 {
1359 /*
1360 * 32-bit code doing 32-bit addressing,
1361 * or 64-bit code doing either 64-bit or 32-bit addressing.
1362 */
1363 pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, iReg, 5 /*disp32*/);
1364 *(uint32_t *)&pThis->abCurInstr[off] = BS3_FP_OFF(pThis->pbDataPg) + X86_PAGE_SIZE - cbOp - cbMisalign;
1365
1366#if ARCH_BITS == 64
1367 /* In 64-bit mode we always have a rip relative encoding regardless of fAddrOverride. */
1368 if (BS3CG1_IS_64BIT_TARGET(pThis))
1369 *(uint32_t *)&pThis->abCurInstr[off] -= BS3_FP_OFF(&pThis->pbCodePg[X86_PAGE_SIZE]);
1370#endif
1371 off += 4;
1372 }
1373
1374 /*
1375 * Fill the memory with 0xcc.
1376 */
1377 switch (cbOp + cbMisalign)
1378 {
1379 case 8: pThis->pbDataPg[X86_PAGE_SIZE - 8] = 0xcc; /* fall thru */
1380 case 7: pThis->pbDataPg[X86_PAGE_SIZE - 7] = 0xcc; /* fall thru */
1381 case 6: pThis->pbDataPg[X86_PAGE_SIZE - 6] = 0xcc; /* fall thru */
1382 case 5: pThis->pbDataPg[X86_PAGE_SIZE - 5] = 0xcc; /* fall thru */
1383 case 4: pThis->pbDataPg[X86_PAGE_SIZE - 4] = 0xcc; /* fall thru */
1384 case 3: pThis->pbDataPg[X86_PAGE_SIZE - 3] = 0xcc; /* fall thru */
1385 case 2: pThis->pbDataPg[X86_PAGE_SIZE - 2] = 0xcc; /* fall thru */
1386 case 1: pThis->pbDataPg[X86_PAGE_SIZE - 1] = 0xcc; /* fall thru */
1387 case 0: break;
1388 default:
1389 {
1390 BS3CG1_DPRINTF(("Bs3MemSet(%p,%#x,%#x)\n", &pThis->pbDataPg[X86_PAGE_SIZE - cbOp - cbMisalign], 0xcc, cbOp - cbMisalign));
1391 Bs3MemSet(&pThis->pbDataPg[X86_PAGE_SIZE - cbOp - cbMisalign], 0xcc, cbOp - cbMisalign);
1392 break;
1393 }
1394 }
1395
1396 return off;
1397}
1398
1399
1400#if 0 /* unused */
1401/** Also encodes idxField of the register operand using idxFieldBase. */
1402static unsigned BS3_NEAR_CODE
1403Bs3Cfg1EncodeMemMod0DispWithRegField(PBS3CG1STATE pThis, bool fAddrOverride, unsigned off, uint8_t iReg,
1404 uint8_t cbOp, uint8_t cbMisalign, BS3CG1OPLOC enmLocation)
1405{
1406 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1407 return Bs3Cfg1EncodeMemMod0Disp(pThis, fAddrOverride, off, iReg & 7, cbOp, cbMisalign, enmLocation);
1408}
1409#endif
1410
1411/** Also encodes idxField of the register operand using idxFieldBase. */
1412static unsigned BS3_NEAR_CODE
1413Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(PBS3CG1STATE pThis, unsigned off, uint8_t iReg)
1414{
1415 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1416 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off, iReg & 7,
1417 pThis->aOperands[pThis->iRmOp].cbOp,
1418 0 /*cbMisalign*/,
1419 pThis->aOperands[pThis->iRmOp].enmLocation);
1420}
1421
1422
1423/** Also encodes idxField of the register operand using idxFieldBase. */
1424static unsigned BS3_NEAR_CODE
1425Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(PBS3CG1STATE pThis, unsigned off, uint8_t iReg, uint8_t cbMisalign)
1426{
1427 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1428 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off, iReg & 7,
1429 pThis->aOperands[pThis->iRmOp].cbOp,
1430 cbMisalign,
1431 pThis->aOperands[pThis->iRmOp].enmLocation);
1432}
1433
1434
1435/** Also encodes idxField of the register operand using idxFieldBase. */
1436static unsigned BS3_NEAR_CODE
1437Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(PBS3CG1STATE pThis, unsigned off, uint8_t iReg, uint8_t cbOp)
1438{
1439 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1440 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off, iReg & 7, cbOp, 0 /*cbMisalign*/,
1441 pThis->aOperands[pThis->iRmOp].enmLocation);
1442}
1443
1444/** Also encodes idxField of the register operand using idxFieldBase. */
1445static unsigned BS3_NEAR_CODE
1446Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(PBS3CG1STATE pThis, unsigned off, uint8_t iReg, uint8_t cbOp)
1447{
1448 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1449 return Bs3Cfg1EncodeMemMod0Disp(pThis, true /*fAddrOverride*/, off, iReg & 7, cbOp, 0 /*cbMisalign*/,
1450 pThis->aOperands[pThis->iRmOp].enmLocation);
1451}
1452
1453
1454/** The modrm.reg value is taken from the instruction byte at @a off. */
1455static unsigned BS3_NEAR_CODE
1456Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(PBS3CG1STATE pThis, unsigned off)
1457{
1458 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off,
1459 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
1460 pThis->aOperands[pThis->iRmOp].cbOp,
1461 0 /*cbMisalign*/,
1462 pThis->aOperands[pThis->iRmOp].enmLocation);
1463}
1464
1465
1466
1467static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Eb_Gb(PBS3CG1STATE pThis, unsigned iEncoding)
1468{
1469 unsigned off;
1470 /* Start by reg,reg encoding. */
1471 if (iEncoding == 0)
1472 {
1473 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1474 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
1475 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
1476 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
1477 }
1478 else if (iEncoding == 1)
1479 {
1480 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
1481 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1482 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM_RW);
1483 }
1484 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
1485 {
1486 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
1487 pThis->abCurInstr[0] = P_AZ;
1488 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1489 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM_RW);
1490 }
1491 else
1492 return 0;
1493 pThis->cbCurInstr = off;
1494 return iEncoding + 1;
1495}
1496
1497
1498static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Gb_Eb(PBS3CG1STATE pThis, unsigned iEncoding)
1499{
1500 unsigned off;
1501 /* Start by reg,reg encoding. */
1502 if (iEncoding == 0)
1503 {
1504 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1505 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
1506 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
1507 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
1508 }
1509 else if (iEncoding == 1)
1510 {
1511 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
1512 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1513 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM);
1514 }
1515 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
1516 {
1517 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
1518 pThis->abCurInstr[0] = P_AZ;
1519 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1520 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM);
1521 }
1522 else
1523 return 0;
1524 pThis->cbCurInstr = off;
1525 return iEncoding + 1;
1526}
1527
1528
1529static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Gv_Ev__OR__MODRM_Ev_Gv(PBS3CG1STATE pThis,
1530 unsigned iEncoding)
1531{
1532 unsigned off;
1533 unsigned cbOp;
1534 if (iEncoding == 0)
1535 {
1536 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
1537 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1538 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
1539 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBX;
1540 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_OZ_RDX;
1541 }
1542 else if (iEncoding == 1)
1543 {
1544 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
1545 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBP;
1546 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1547 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, cbOp, 0,
1548 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_WO);
1549 }
1550 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
1551 {
1552 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
1553 pThis->abCurInstr[0] = P_OZ;
1554 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1555 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
1556 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBX;
1557 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_OZ_RDX;
1558 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
1559 }
1560 else if (iEncoding == 3)
1561 {
1562 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
1563 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RSI;
1564 pThis->abCurInstr[0] = P_OZ;
1565 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1566 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xSI, cbOp, 0,
1567 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_WO);
1568 }
1569 else if (iEncoding == 4)
1570 {
1571 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
1572 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RDI;
1573 pThis->abCurInstr[0] = P_AZ;
1574 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1575 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, cbOp, 0,
1576 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_WO);
1577 }
1578 else if (iEncoding == 5)
1579 {
1580 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
1581 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RSI;
1582 pThis->abCurInstr[0] = P_OZ;
1583 pThis->abCurInstr[1] = P_AZ;
1584 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
1585 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xSI, cbOp, 0,
1586 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_WO);
1587 }
1588 else if (iEncoding == 6 && BS3CG1_IS_64BIT_TARGET(pThis))
1589 {
1590 cbOp = 8;
1591 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1592 pThis->abCurInstr[off++] = REX_W___;
1593 off = Bs3Cg1InsertOpcodes(pThis, off);
1594 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
1595 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_RBX;
1596 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_RDX;
1597 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
1598 }
1599 else
1600 return 0;
1601 pThis->aOperands[0].cbOp = cbOp;
1602 pThis->aOperands[1].cbOp = cbOp;
1603 pThis->cbOperand = cbOp;
1604 pThis->cbCurInstr = off;
1605 return iEncoding + 1;
1606}
1607
1608
1609static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Wss_WO_Vss(PBS3CG1STATE pThis, unsigned iEncoding)
1610{
1611 unsigned off;
1612 if (iEncoding == 0)
1613 {
1614 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1615 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1616 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_DW0;
1617 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_DW0;
1618 }
1619 else if (iEncoding == 1)
1620 {
1621 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_DW0;
1622 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1623 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 4, 0, BS3CG1OPLOC_MEM_WO);
1624 }
1625 else if (iEncoding == 2)
1626 {
1627 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3_DW0;
1628 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1629 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 4, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM_WO);
1630 }
1631 else
1632 return 0;
1633 pThis->cbCurInstr = off;
1634 return iEncoding + 1;
1635}
1636
1637
1638static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Wsd_WO_Vsd(PBS3CG1STATE pThis, unsigned iEncoding)
1639{
1640 unsigned off;
1641 if (iEncoding == 0)
1642 {
1643 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1644 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1645 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_LO;
1646 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_LO;
1647 }
1648 else if (iEncoding == 1)
1649 {
1650 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_LO;
1651 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1652 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 8, 0, BS3CG1OPLOC_MEM_WO);
1653 }
1654 else if (iEncoding == 2)
1655 {
1656 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3_LO;
1657 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1658 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 8, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM_WO);
1659 }
1660 else
1661 return 0;
1662 pThis->cbCurInstr = off;
1663 return iEncoding + 1;
1664}
1665
1666
1667static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Wps_WO_Vps__OR__MODRM_Wpd_WO_Vpd(PBS3CG1STATE pThis, unsigned iEncoding)
1668{
1669 unsigned off;
1670 if (iEncoding == 0)
1671 {
1672 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1673 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1674 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0;
1675 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1;
1676 }
1677 else if (iEncoding == 1)
1678 {
1679 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2;
1680 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1681 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 16, 0, BS3CG1OPLOC_MEM_WO);
1682 }
1683 else if (iEncoding == 2)
1684 {
1685 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3;
1686 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1687 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 16, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM_WO);
1688 if (!Bs3Cg1XcptTypeIsUnaligned(pThis->enmXcptType))
1689 pThis->bAlignmentXcpt = X86_XCPT_GP;
1690 }
1691 else
1692 return 0;
1693 pThis->cbCurInstr = off;
1694 return iEncoding + 1;
1695}
1696
1697
1698static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_WqZxReg_WO_Vq(PBS3CG1STATE pThis, unsigned iEncoding)
1699{
1700 unsigned off;
1701 if (iEncoding == 0)
1702 {
1703 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1704 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1705 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_LO_ZX;
1706 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_LO;
1707 }
1708 else if (iEncoding == 1)
1709 {
1710 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_LO;
1711 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1712 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 8, 0, BS3CG1OPLOC_MEM_WO);
1713 }
1714 else if (iEncoding == 2)
1715 {
1716 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3_LO;
1717 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1718 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 8, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM_WO);
1719 }
1720 else
1721 return 0;
1722 pThis->cbCurInstr = off;
1723 return iEncoding + 1;
1724}
1725
1726
1727static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Pq_WO_Qq(PBS3CG1STATE pThis, unsigned iEncoding)
1728{
1729 unsigned off;
1730 switch (iEncoding)
1731 {
1732 case 0:
1733 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1734 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1735 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1736 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
1737 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
1738 break;
1739 case 1:
1740 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1741 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1742 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 7);
1743 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 7;
1744 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
1745 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1746 break;
1747#if ARCH_BITS == 64
1748 case 2:
1749 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1750 pThis->abCurInstr[off++] = REX__RBX;
1751 off = Bs3Cg1InsertOpcodes(pThis, off);
1752 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1753 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2; /* no +8*/
1754 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6; /* no +8*/
1755 break;
1756#endif
1757 case 3:
1758 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1759 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1760 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1761 break;
1762 case 4:
1763 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1764 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1765 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1766 break;
1767#if ARCH_BITS == 64
1768 case 5:
1769 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1770 pThis->abCurInstr[off++] = REX__RBX;
1771 off = Bs3Cg1InsertOpcodes(pThis, off);
1772 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg - no +8*/);
1773 break;
1774#endif
1775
1776 default:
1777 return 0;
1778 }
1779
1780 pThis->cbCurInstr = off;
1781 return iEncoding + 1;
1782}
1783
1784
1785static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Pq_WO_Uq(PBS3CG1STATE pThis, unsigned iEncoding)
1786{
1787 unsigned off;
1788 if (iEncoding == 0)
1789 {
1790 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1791 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1792 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_LO;
1793 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_MM1;
1794 }
1795 else if (iEncoding == 1)
1796 {
1797 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1798 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1799 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM2_LO;
1800 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_MM6;
1801 }
1802 else
1803 return 0;
1804 pThis->cbCurInstr = off;
1805 return iEncoding + 1;
1806}
1807
1808
1809static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ(PBS3CG1STATE pThis, unsigned iEncoding)
1810{
1811 unsigned off;
1812 switch (iEncoding)
1813 {
1814 case 0:
1815 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1816 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1817 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1818 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
1819 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
1820 break;
1821 case 1:
1822 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1823 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1824 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
1825 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
1826 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1827 break;
1828#if ARCH_BITS == 64
1829 case 2:
1830 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1831 pThis->abCurInstr[off++] = REX__RBX;
1832 off = Bs3Cg1InsertOpcodes(pThis, off);
1833 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1834 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2 + 8;
1835 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6; /* no +8*/
1836 break;
1837#endif
1838 case 3:
1839 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1840 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1841 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1842 break;
1843 case 4:
1844 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1845 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1846 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1847 break;
1848#if ARCH_BITS == 64
1849 case 5:
1850 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1851 pThis->abCurInstr[off++] = REX__RBX;
1852 off = Bs3Cg1InsertOpcodes(pThis, off);
1853 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg*/);
1854 break;
1855#endif
1856
1857 default:
1858 return 0;
1859 }
1860 pThis->cbCurInstr = off;
1861 return iEncoding + 1;
1862}
1863
1864
1865static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ(PBS3CG1STATE pThis, unsigned iEncoding)
1866{
1867#if ARCH_BITS == 64
1868 if (BS3CG1_IS_64BIT_TARGET(pThis))
1869 {
1870 unsigned off;
1871 switch (iEncoding)
1872 {
1873 case 0:
1874 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1875 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1876 pThis->abCurInstr[off++] = REX_W___;
1877 off = Bs3Cg1InsertOpcodes(pThis, off);
1878 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1879 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
1880 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
1881 break;
1882 case 1:
1883 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1884 pThis->abCurInstr[off++] = REX_W___;
1885 off = Bs3Cg1InsertOpcodes(pThis, off);
1886 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1887 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
1888 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
1889 break;
1890 case 2:
1891 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1892 pThis->abCurInstr[off++] = REX_WRBX;
1893 off = Bs3Cg1InsertOpcodes(pThis, off);
1894 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1895 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2 + 8;
1896 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6; /* no +8*/
1897 break;
1898 case 3:
1899 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1900 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1901 pThis->abCurInstr[off++] = REX_W___;
1902 off = Bs3Cg1InsertOpcodes(pThis, off);
1903 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1904 break;
1905 case 4:
1906 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1907 pThis->abCurInstr[off++] = REX_W___;
1908 off = Bs3Cg1InsertOpcodes(pThis, off);
1909 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1910 break;
1911 case 5:
1912 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1913 pThis->abCurInstr[off++] = REX_WRBX;
1914 off = Bs3Cg1InsertOpcodes(pThis, off);
1915 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg*/);
1916 break;
1917
1918 default:
1919 return 0;
1920 }
1921 pThis->cbCurInstr = off;
1922 return iEncoding + 1;
1923 }
1924#endif
1925 return 0;
1926}
1927
1928
1929/* Differs from Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ in that REX.R isn't ignored. */
1930static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vd_WO_Ed_WZ(PBS3CG1STATE pThis, unsigned iEncoding)
1931{
1932 unsigned off;
1933 switch (iEncoding)
1934 {
1935 case 0:
1936 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1937 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1938 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
1939 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
1940 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
1941 break;
1942 case 1:
1943 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1944 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1945 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
1946 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
1947 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1948 break;
1949#if ARCH_BITS == 64
1950 case 2:
1951 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1952 pThis->abCurInstr[off++] = REX__RBX;
1953 off = Bs3Cg1InsertOpcodes(pThis, off);
1954 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
1955 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2 + 8;
1956 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6 + 8;
1957 break;
1958#endif
1959 case 3:
1960 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1961 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1962 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1963 break;
1964 case 4:
1965 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1966 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1967 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1968 break;
1969#if ARCH_BITS == 64
1970 case 5:
1971 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1972 pThis->abCurInstr[off++] = REX__RBX;
1973 off = Bs3Cg1InsertOpcodes(pThis, off);
1974 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7+8 /*iReg*/);
1975 break;
1976#endif
1977
1978 default:
1979 return 0;
1980 }
1981 pThis->cbCurInstr = off;
1982 return iEncoding + 1;
1983}
1984
1985
1986/* Differs from Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ in that REX.R isn't ignored. */
1987static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vq_WO_Eq_WNZ(PBS3CG1STATE pThis, unsigned iEncoding)
1988{
1989#if ARCH_BITS == 64
1990 if (BS3CG1_IS_64BIT_TARGET(pThis))
1991 {
1992 unsigned off;
1993 switch (iEncoding)
1994 {
1995 case 0:
1996 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1997 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1998 pThis->abCurInstr[off++] = REX_W___;
1999 off = Bs3Cg1InsertOpcodes(pThis, off);
2000 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2001 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
2002 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
2003 break;
2004 case 1:
2005 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2006 pThis->abCurInstr[off++] = REX_W___;
2007 off = Bs3Cg1InsertOpcodes(pThis, off);
2008 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2009 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2010 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
2011 break;
2012 case 2:
2013 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2014 pThis->abCurInstr[off++] = REX_WRBX;
2015 off = Bs3Cg1InsertOpcodes(pThis, off);
2016 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2017 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2 + 8;
2018 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6 + 8;
2019 break;
2020 case 4:
2021 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
2022 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2023 pThis->abCurInstr[off++] = REX_W___;
2024 off = Bs3Cg1InsertOpcodes(pThis, off);
2025 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2026 break;
2027 case 5:
2028 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2029 pThis->abCurInstr[off++] = REX_W___;
2030 off = Bs3Cg1InsertOpcodes(pThis, off);
2031 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
2032 break;
2033 case 6:
2034 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2035 pThis->abCurInstr[off++] = REX_WRBX;
2036 off = Bs3Cg1InsertOpcodes(pThis, off);
2037 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7+8 /*iReg*/);
2038 break;
2039
2040 default:
2041 return 0;
2042 }
2043 pThis->cbCurInstr = off;
2044 return iEncoding + 1;
2045 }
2046#endif
2047 return 0;
2048}
2049
2050
2051static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vq_WO_UqHi(PBS3CG1STATE pThis, unsigned iEncoding)
2052{
2053 unsigned off;
2054 if (iEncoding == 0)
2055 {
2056 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2057 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2058 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_HI;
2059 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_LO;
2060 }
2061 else if (iEncoding == 1)
2062 {
2063 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2064 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 2);
2065 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM2_HI;
2066 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_LO;
2067 }
2068 else
2069 return 0;
2070 pThis->cbCurInstr = off;
2071 return iEncoding + 1;
2072}
2073
2074
2075static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vq_WO_Mq(PBS3CG1STATE pThis, unsigned iEncoding)
2076{
2077 unsigned off;
2078 if (iEncoding == 0)
2079 {
2080 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_LO;
2081 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2082 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 8, 0, BS3CG1OPLOC_MEM);
2083 }
2084 else if (iEncoding == 1)
2085 {
2086 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3_LO;
2087 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2088 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 8, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM);
2089 }
2090 else
2091 return 0;
2092 pThis->cbCurInstr = off;
2093 return iEncoding + 1;
2094}
2095
2096
2097static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_VqHi_WO_Uq(PBS3CG1STATE pThis, unsigned iEncoding)
2098{
2099 unsigned off;
2100 if (iEncoding == 0)
2101 {
2102 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2103 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2104 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_LO;
2105 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_HI;
2106 }
2107 else if (iEncoding == 1)
2108 {
2109 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2110 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 2);
2111 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM2_LO;
2112 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_HI;
2113 }
2114 else
2115 return 0;
2116 pThis->cbCurInstr = off;
2117 return iEncoding + 1;
2118}
2119
2120
2121static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_VqHi_WO_Mq(PBS3CG1STATE pThis, unsigned iEncoding)
2122{
2123 unsigned off;
2124 if (iEncoding == 0)
2125 {
2126 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_HI;
2127 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2128 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 8, 0, BS3CG1OPLOC_MEM);
2129 }
2130 else if (iEncoding == 1)
2131 {
2132 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3_HI;
2133 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2134 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 8, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM);
2135 }
2136 else
2137 return 0;
2138 pThis->cbCurInstr = off;
2139 return iEncoding + 1;
2140}
2141
2142
2143static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vdq_WO_Wdq(PBS3CG1STATE pThis, unsigned iEncoding)
2144{
2145 unsigned off;
2146 if (iEncoding == 0)
2147 {
2148 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2149 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2150 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0;
2151 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1;
2152 }
2153 else if (iEncoding == 1)
2154 {
2155 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2;
2156 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2157 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 16, 0, BS3CG1OPLOC_MEM);
2158 }
2159 else if (iEncoding == 2)
2160 {
2161 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3;
2162 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2163 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 16, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM);
2164 if (!Bs3Cg1XcptTypeIsUnaligned(pThis->enmXcptType))
2165 pThis->bAlignmentXcpt = X86_XCPT_GP;
2166 }
2167 else
2168 return 0;
2169 pThis->cbCurInstr = off;
2170 return iEncoding + 1;
2171}
2172
2173
2174static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vps_WO_Wps__OR__MODRM_Vpd_WO_Wpd(PBS3CG1STATE pThis,
2175 unsigned iEncoding)
2176{
2177 unsigned off;
2178 if (iEncoding == 0)
2179 {
2180 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2181 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2182 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0;
2183 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1;
2184 }
2185 else if (iEncoding == 1)
2186 {
2187 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2;
2188 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2189 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 16, 0, BS3CG1OPLOC_MEM);
2190 }
2191 else if (iEncoding == 2)
2192 {
2193 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3;
2194 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2195 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 16, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM);
2196 if (!Bs3Cg1XcptTypeIsUnaligned(pThis->enmXcptType))
2197 pThis->bAlignmentXcpt = X86_XCPT_GP;
2198 }
2199 else
2200 return 0;
2201 pThis->cbCurInstr = off;
2202 return iEncoding + 1;
2203}
2204
2205
2206static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_VssZx_WO_Wss(PBS3CG1STATE pThis, unsigned iEncoding)
2207{
2208 unsigned off;
2209 if (iEncoding == 0)
2210 {
2211 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2212 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2213 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_LO;
2214 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_DW0_ZX;
2215 }
2216 else if (iEncoding == 1)
2217 {
2218 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_DW0_ZX;
2219 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2220 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 4, 0, BS3CG1OPLOC_MEM);
2221 }
2222 else if (iEncoding == 2)
2223 {
2224 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3_DW0_ZX;
2225 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2226 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 4, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM);
2227 }
2228 else
2229 return 0;
2230 pThis->cbCurInstr = off;
2231 return iEncoding + 1;
2232}
2233
2234
2235static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_VsdZx_WO_Wsd__OR__MODRM_VqZx_WO_Wq(PBS3CG1STATE pThis,
2236 unsigned iEncoding)
2237{
2238 unsigned off;
2239 if (iEncoding == 0)
2240 {
2241 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2242 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2243 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_XMM0_LO;
2244 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_LO_ZX;
2245 }
2246 else if (iEncoding == 1)
2247 {
2248 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM2_LO_ZX;
2249 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2250 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 2 /*iReg*/, 8, 0, BS3CG1OPLOC_MEM);
2251 }
2252 else if (iEncoding == 2)
2253 {
2254 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM3_LO_ZX;
2255 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2256 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 3 /*iReg*/, 8, 1 /*cbMisalign*/, BS3CG1OPLOC_MEM);
2257 }
2258 else
2259 return 0;
2260 pThis->cbCurInstr = off;
2261 return iEncoding + 1;
2262}
2263
2264
2265static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_VqZx_WO_Nq(PBS3CG1STATE pThis, unsigned iEncoding)
2266{
2267 unsigned off;
2268 if (iEncoding == 0)
2269 {
2270 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2271 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2272 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_MM0;
2273 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM1_LO_ZX;
2274 }
2275 else if (iEncoding == 1)
2276 {
2277 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2278 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 7);
2279 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_MM7;
2280 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_XMM6_LO_ZX;
2281 }
2282 else
2283 return 0;
2284 pThis->cbCurInstr = off;
2285 return iEncoding + 1;
2286}
2287
2288
2289static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Gv_RO_Ma(PBS3CG1STATE pThis, unsigned iEncoding)
2290{
2291 unsigned off;
2292 unsigned cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
2293 switch (iEncoding)
2294 {
2295 case 0:
2296 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2297 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(pThis, off, X86_GREG_xBP, cbOp * 2);
2298 break;
2299 case 1:
2300 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) < BS3CPU_80386)
2301 return 0;
2302 cbOp = cbOp == 2 ? 4 : 2;
2303 pThis->abCurInstr[0] = P_OZ;
2304 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
2305 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(pThis, off, X86_GREG_xBP, cbOp * 2);
2306 break;
2307 case 2:
2308 pThis->abCurInstr[0] = P_AZ;
2309 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
2310 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(pThis, off, X86_GREG_xBP, cbOp * 2);
2311 break;
2312 case 3:
2313 cbOp = cbOp == 2 ? 4 : 2;
2314 pThis->abCurInstr[0] = P_AZ;
2315 pThis->abCurInstr[1] = P_OZ;
2316 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
2317 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(pThis, off, X86_GREG_xBP, cbOp * 2);
2318 break;
2319 default:
2320 return 0;
2321 }
2322 pThis->aOperands[pThis->iRegOp].cbOp = cbOp;
2323 pThis->cbOperand = cbOp;
2324 pThis->cbCurInstr = off;
2325 return iEncoding + 1;
2326}
2327
2328
2329static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Msomething(PBS3CG1STATE pThis, unsigned iEncoding)
2330{
2331 unsigned off;
2332 switch (iEncoding)
2333 {
2334 case 0:
2335 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)) - 1;
2336 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
2337 break;
2338 default:
2339 return 0;
2340 }
2341 pThis->cbCurInstr = off;
2342 return iEncoding + 1;
2343}
2344
2345
2346static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Mq_WO_Pq(PBS3CG1STATE pThis, unsigned iEncoding)
2347{
2348 unsigned off;
2349 switch (iEncoding)
2350 {
2351 case 0:
2352 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2353 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2354 break;
2355 case 1:
2356 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2357 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
2358 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2359 break;
2360#if ARCH_BITS == 64
2361 case 2:
2362 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2363 pThis->abCurInstr[off++] = REX__RBX;
2364 off = Bs3Cg1InsertOpcodes(pThis, off);
2365 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg - no +8*/);
2366 break;
2367#endif
2368
2369 default:
2370 return 0;
2371 }
2372
2373 pThis->cbCurInstr = off;
2374 return iEncoding + 1;
2375}
2376
2377
2378static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Msomething_WO_Vsomething(PBS3CG1STATE pThis, unsigned iEncoding)
2379{
2380 unsigned off;
2381 switch (iEncoding)
2382 {
2383 case 0:
2384 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2385 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
2386 break;
2387 case 1:
2388 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2389 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
2390 break;
2391 default:
2392 return 0;
2393 }
2394 pThis->cbCurInstr = off;
2395 return iEncoding + 1;
2396}
2397
2398
2399static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_MsomethingWO_Vsomething_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2400{
2401 unsigned off;
2402 switch (iEncoding)
2403 {
2404 case 0:
2405 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2406 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
2407 break;
2408 case 1:
2409 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2410 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 2 /*iReg*/, 1 /*cbMisalign*/ );
2411 if (!Bs3Cg1XcptTypeIsUnaligned(pThis->enmXcptType))
2412 pThis->bAlignmentXcpt = X86_XCPT_GP;
2413 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2414 break;
2415 case 2:
2416 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2417 pThis->abCurInstr[off++] = REX__R__;
2418 off = Bs3Cg1InsertOpcodes(pThis, off);
2419 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2+8 /*iReg*/);
2420 break;
2421 default:
2422 return 0;
2423 }
2424 pThis->cbCurInstr = off;
2425 return iEncoding + 1;
2426}
2427
2428
2429static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_FIXED(PBS3CG1STATE pThis, unsigned iEncoding)
2430{
2431 unsigned off;
2432 if (iEncoding == 0)
2433 {
2434 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2435 pThis->cbCurInstr = off;
2436 }
2437 else
2438 return 0;
2439 return iEncoding + 1;
2440}
2441
2442
2443static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_FIXED_AL_Ib(PBS3CG1STATE pThis, unsigned iEncoding)
2444{
2445 unsigned off;
2446 if (iEncoding == 0)
2447 {
2448 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2449 pThis->aOperands[1].off = (uint8_t)off;
2450 pThis->abCurInstr[off++] = 0xff;
2451 pThis->cbCurInstr = off;
2452 }
2453 else
2454 return 0;
2455 return iEncoding + 1;
2456}
2457
2458
2459static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_FIXED_rAX_Iz(PBS3CG1STATE pThis, unsigned iEncoding)
2460{
2461 unsigned off;
2462 if (iEncoding == 0)
2463 {
2464 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2465 pThis->aOperands[1].off = (uint8_t)off;
2466 if (BS3_MODE_IS_16BIT_CODE(pThis->bMode))
2467 {
2468 *(uint16_t *)&pThis->abCurInstr[off] = UINT16_MAX;
2469 off += 2;
2470 pThis->aOperands[0].cbOp = 2;
2471 pThis->aOperands[1].cbOp = 2;
2472 pThis->cbOperand = 2;
2473 }
2474 else
2475 {
2476 *(uint32_t *)&pThis->abCurInstr[off] = UINT32_MAX;
2477 off += 4;
2478 pThis->aOperands[0].cbOp = 4;
2479 pThis->aOperands[1].cbOp = 4;
2480 pThis->cbOperand = 4;
2481 }
2482 }
2483 else if (iEncoding == 1 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
2484 {
2485 pThis->abCurInstr[0] = P_OZ;
2486 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
2487 pThis->aOperands[1].off = (uint8_t)off;
2488 if (!BS3_MODE_IS_16BIT_CODE(pThis->bMode))
2489 {
2490 *(uint16_t *)&pThis->abCurInstr[off] = UINT16_MAX;
2491 off += 2;
2492 pThis->aOperands[0].cbOp = 2;
2493 pThis->aOperands[1].cbOp = 2;
2494 pThis->cbOperand = 2;
2495 }
2496 else
2497 {
2498 *(uint32_t *)&pThis->abCurInstr[off] = UINT32_MAX;
2499 off += 4;
2500 pThis->aOperands[0].cbOp = 4;
2501 pThis->aOperands[1].cbOp = 4;
2502 pThis->cbOperand = 4;
2503 }
2504 }
2505 else if (iEncoding == 2 && BS3CG1_IS_64BIT_TARGET(pThis))
2506 {
2507 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2508 pThis->abCurInstr[off++] = REX_W___;
2509 off = Bs3Cg1InsertOpcodes(pThis, off);
2510 pThis->aOperands[1].off = (uint8_t)off;
2511 *(uint32_t *)&pThis->abCurInstr[off] = UINT32_MAX;
2512 off += 4;
2513 pThis->aOperands[0].cbOp = 8;
2514 pThis->aOperands[1].cbOp = 4;
2515 pThis->cbOperand = 8;
2516 }
2517 else
2518 return 0;
2519 pThis->cbCurInstr = off;
2520 return iEncoding + 1;
2521}
2522
2523
2524static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_MOD_EQ_3(PBS3CG1STATE pThis, unsigned iEncoding)
2525{
2526 unsigned off;
2527 if (iEncoding < 8)
2528 {
2529 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2530 off = Bs3Cg1InsertOpcodes(pThis, off);
2531 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, iEncoding, 1);
2532 }
2533 else if (iEncoding < 16)
2534 {
2535 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2536 off = Bs3Cg1InsertOpcodes(pThis, off);
2537 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 0, iEncoding & 7);
2538 }
2539 else
2540 return 0;
2541 pThis->cbCurInstr = off;
2542
2543 return iEncoding + 1;
2544}
2545
2546
2547static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_MOD_NE_3(PBS3CG1STATE pThis, unsigned iEncoding)
2548{
2549 unsigned off;
2550 if (iEncoding < 3)
2551 {
2552 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2553 off = Bs3Cg1InsertOpcodes(pThis, off);
2554 pThis->abCurInstr[off++] = X86_MODRM_MAKE(iEncoding, 0, 1);
2555 if (iEncoding >= 1)
2556 pThis->abCurInstr[off++] = 0x7f;
2557 if (iEncoding == 2)
2558 {
2559 pThis->abCurInstr[off++] = 0x5f;
2560 if (!BS3_MODE_IS_16BIT_CODE(pThis->bMode))
2561 {
2562 pThis->abCurInstr[off++] = 0x3f;
2563 pThis->abCurInstr[off++] = 0x1f;
2564 }
2565 }
2566 }
2567 else
2568 return 0;
2569 pThis->cbCurInstr = off;
2570 return iEncoding + 1;
2571}
2572
2573
2574/*
2575 *
2576 * VEX
2577 * VEX
2578 * VEX
2579 *
2580 */
2581#ifdef BS3CG1_WITH_VEX
2582
2583/**
2584 * Inserts a 3-byte VEX prefix.
2585 *
2586 * @returns New offDst value.
2587 * @param pThis The state.
2588 * @param offDst The current instruction offset.
2589 * @param uVexL The VEX.L value.
2590 * @param uVexV The VEX.V value (caller inverted it already).
2591 * @param uVexR The VEX.R value (caller inverted it already).
2592 * @param uVexX The VEX.X value (caller inverted it already).
2593 * @param uVexB The VEX.B value (caller inverted it already).
2594 * @param uVexW The VEX.W value (straight).
2595 */
2596DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertVex3bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL,
2597 uint8_t uVexR, uint8_t uVexX, uint8_t uVexB, uint8_t uVexW)
2598{
2599 uint8_t b1;
2600 uint8_t b2;
2601 b1 = uVexR << 7;
2602 b1 |= uVexX << 6;
2603 b1 |= uVexB << 5;
2604 b1 |= pThis->uOpcodeMap;
2605 b2 = uVexV << 3;
2606 b2 |= uVexW << 7;
2607 b2 |= uVexL << 2;
2608 switch (pThis->enmPrefixKind)
2609 {
2610 case BS3CG1PFXKIND_NO_F2_F3_66: b2 |= 0; break;
2611 case BS3CG1PFXKIND_REQ_66: b2 |= 1; break;
2612 case BS3CG1PFXKIND_REQ_F3: b2 |= 2; break;
2613 case BS3CG1PFXKIND_REQ_F2: b2 |= 3; break;
2614 default:
2615 Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n", pThis->enmPrefixKind);
2616 break;
2617 }
2618
2619 pThis->abCurInstr[offDst] = 0xc4; /* vex3 */
2620 pThis->abCurInstr[offDst + 1] = b1;
2621 pThis->abCurInstr[offDst + 2] = b2;
2622 pThis->uVexL = uVexL;
2623 return offDst + 3;
2624}
2625
2626
2627/**
2628 * Inserts a 2-byte VEX prefix.
2629 *
2630 * @note Will switch to 3-byte VEX prefix if uOpcodeMap isn't one.
2631 *
2632 * @returns New offDst value.
2633 * @param pThis The state.
2634 * @param offDst The current instruction offset.
2635 * @param uVexL The VEX.L value.
2636 * @param uVexV The VEX.V value (caller inverted it already).
2637 * @param uVexR The VEX.R value (caller inverted it already).
2638 */
2639DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertVex2bPrefix(PBS3CG1STATE pThis, unsigned offDst,
2640 uint8_t uVexV, uint8_t uVexL, uint8_t uVexR)
2641{
2642 if (pThis->uOpcodeMap == 1)
2643 {
2644 uint8_t b = uVexR << 7;
2645 b |= uVexV << 3;
2646 b |= uVexL << 2;
2647 switch (pThis->enmPrefixKind)
2648 {
2649 case BS3CG1PFXKIND_NO_F2_F3_66: b |= 0; break;
2650 case BS3CG1PFXKIND_REQ_66: b |= 1; break;
2651 case BS3CG1PFXKIND_REQ_F3: b |= 2; break;
2652 case BS3CG1PFXKIND_REQ_F2: b |= 3; break;
2653 default:
2654 Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n");
2655 break;
2656 }
2657
2658 pThis->abCurInstr[offDst] = 0xc5; /* vex2 */
2659 pThis->abCurInstr[offDst + 1] = b;
2660 pThis->uVexL = uVexL;
2661 return offDst + 2;
2662 }
2663 return Bs3Cg1InsertVex3bPrefix(pThis, offDst, uVexV, uVexL, uVexR, 1 /*uVexX*/, 1 /*uVexB*/, 0/*uVexW*/);
2664}
2665
2666
2667static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_Vd_WO_Ed_WZ(PBS3CG1STATE pThis, unsigned iEncoding)
2668{
2669 unsigned off;
2670 switch (iEncoding)
2671 {
2672 case 0:
2673 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
2674 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2675 off = Bs3Cg1InsertOpcodes(pThis, off);
2676 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
2677 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
2678 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
2679 break;
2680 case 1:
2681 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2682 off = Bs3Cg1InsertOpcodes(pThis, off);
2683 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2684 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2685 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
2686 break;
2687 case 2:
2688 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-invalid*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2689 off = Bs3Cg1InsertOpcodes(pThis, off);
2690 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2691 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2692 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
2693 pThis->fInvalidEncoding = true;
2694 break;
2695 case 3:
2696 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xe /*~V-invalid*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2697 off = Bs3Cg1InsertOpcodes(pThis, off);
2698 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2699 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2700 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
2701 pThis->fInvalidEncoding = true;
2702 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2703 break;
2704#if ARCH_BITS == 64
2705 case 4:
2706 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 0 /*~B*/, 0 /*W*/);
2707 off = Bs3Cg1InsertOpcodes(pThis, off);
2708 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2709 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2 + 8;
2710 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6 + 8;
2711 break;
2712#endif
2713 case 5:
2714 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
2715 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2716 off = Bs3Cg1InsertOpcodes(pThis, off);
2717 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2718 break;
2719 case 6:
2720 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2721 off = Bs3Cg1InsertOpcodes(pThis, off);
2722 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2723 break;
2724 case 7:
2725 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2726 off = Bs3Cg1InsertOpcodes(pThis, off);
2727 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 4 /*iReg*/, 1 /*cbMisalign*/);
2728 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 : 0;
2729 break;
2730#if ARCH_BITS == 64
2731 case 8:
2732 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2733 off = Bs3Cg1InsertOpcodes(pThis, off);
2734 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4+8 /*iReg*/);
2735 break;
2736 case 9:
2737 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/);
2738 off = Bs3Cg1InsertOpcodes(pThis, off);
2739 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8 /*iReg*/);
2740 iEncoding += 2;
2741 break;
2742#endif
2743 case 10: /* VEX.W is ignored in 32-bit mode. flag? */
2744 BS3_ASSERT(!BS3CG1_IS_64BIT_TARGET(pThis));
2745 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2746 off = Bs3Cg1InsertOpcodes(pThis, off);
2747 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2748 break;
2749
2750 default:
2751 return 0;
2752 }
2753 pThis->cbCurInstr = off;
2754 return iEncoding + 1;
2755}
2756
2757
2758/* Differs from Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ in that REX.R isn't ignored. */
2759static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_Vq_WO_Eq_WNZ(PBS3CG1STATE pThis, unsigned iEncoding)
2760{
2761#if ARCH_BITS == 64
2762 if (BS3CG1_IS_64BIT_TARGET(pThis))
2763 {
2764 unsigned off;
2765 switch (iEncoding)
2766 {
2767 case 0:
2768 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
2769 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2770 off = Bs3Cg1InsertOpcodes(pThis, off);
2771 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2772 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2773 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
2774 break;
2775 case 1:
2776 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-invalid*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2777 off = Bs3Cg1InsertOpcodes(pThis, off);
2778 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2779 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2780 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
2781 pThis->fInvalidEncoding = true;
2782 break;
2783 case 2:
2784 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xe /*~V-invalid*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2785 off = Bs3Cg1InsertOpcodes(pThis, off);
2786 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2787 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2788 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6;
2789 pThis->fInvalidEncoding = true;
2790 break;
2791 case 3:
2792 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 0 /*~B*/, 1 /*W*/);
2793 off = Bs3Cg1InsertOpcodes(pThis, off);
2794 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 6, 2);
2795 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2 + 8;
2796 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 6 + 8;
2797 break;
2798 case 4:
2799 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
2800 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2801 off = Bs3Cg1InsertOpcodes(pThis, off);
2802 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2803 break;
2804 case 5:
2805 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2806 off = Bs3Cg1InsertOpcodes(pThis, off);
2807 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 4 /*iReg*/, 1 /*cbMisalign*/);
2808 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 : 0;
2809 break;
2810 case 6:
2811 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2812 off = Bs3Cg1InsertOpcodes(pThis, off);
2813 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4+8 /*iReg*/);
2814 break;
2815
2816 default:
2817 return 0;
2818 }
2819 pThis->cbCurInstr = off;
2820 return iEncoding + 1;
2821 }
2822#endif
2823 return 0;
2824}
2825
2826
2827/**
2828 * Wip - VEX.W ignored.
2829 * Lig - VEX.L ignored.
2830 */
2831static unsigned BS3_NEAR_CODE
2832Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2833{
2834 unsigned off;
2835 switch (iEncoding)
2836 {
2837 case 0:
2838 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2839 off = Bs3Cg1InsertOpcodes(pThis, off);
2840 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2841 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2842 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 0;
2843 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2844 break;
2845 case 1:
2846 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0x8 /*~V*/, 1 /*L-ignored*/, 1 /*~R*/);
2847 off = Bs3Cg1InsertOpcodes(pThis, off);
2848 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 3, 1);
2849 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 3;
2850 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 7;
2851 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2852 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2853 break;
2854 case 2:
2855#if ARCH_BITS == 64
2856 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 0 /*~R*/);
2857 off = Bs3Cg1InsertOpcodes(pThis, off);
2858 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 3, 2);
2859 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 11;
2860 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 15;
2861 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2862 break;
2863#endif
2864 case 3:
2865 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2866 off = Bs3Cg1InsertOpcodes(pThis, off);
2867 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2868 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2869 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 0;
2870 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2871 break;
2872 case 4:
2873 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2874 off = Bs3Cg1InsertOpcodes(pThis, off);
2875 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2876 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2877 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 0;
2878 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2879 break;
2880 case 5:
2881 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xc /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2882 off = Bs3Cg1InsertOpcodes(pThis, off);
2883 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2884 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2885 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 3;
2886 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2887 break;
2888 case 6:
2889 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2890 off = Bs3Cg1InsertOpcodes(pThis, off);
2891 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2892 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2893 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + (BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2894 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2895 break;
2896 case 7:
2897 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2898 off = Bs3Cg1InsertOpcodes(pThis, off);
2899 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2900 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2901 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + (BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2902 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2903 break;
2904 default:
2905 return 0;
2906 }
2907 pThis->cbCurInstr = off;
2908 return iEncoding + 1;
2909}
2910
2911
2912/**
2913 * Wip - VEX.W ignored.
2914 */
2915static unsigned BS3_NEAR_CODE
2916Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_HdqCsomething_Usomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2917{
2918 unsigned off;
2919 switch (iEncoding)
2920 {
2921 case 0:
2922 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2923 off = Bs3Cg1InsertOpcodes(pThis, off);
2924 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2925 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2926 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 0;
2927 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2928 break;
2929 case 1:
2930 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0x8 /*~V*/, 1 /*L-ignored*/, 1 /*~R*/);
2931 off = Bs3Cg1InsertOpcodes(pThis, off);
2932 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 3, 1);
2933 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 3;
2934 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 7;
2935 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2936 pThis->fInvalidEncoding = true;
2937 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2938 break;
2939 case 2:
2940#if ARCH_BITS == 64
2941 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 0 /*~R*/);
2942 off = Bs3Cg1InsertOpcodes(pThis, off);
2943 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 3, 2);
2944 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 11;
2945 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 15;
2946 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 2;
2947 break;
2948#endif
2949 case 3:
2950 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2951 off = Bs3Cg1InsertOpcodes(pThis, off);
2952 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2953 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2954 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 0;
2955 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2956 break;
2957 case 4:
2958 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2959 off = Bs3Cg1InsertOpcodes(pThis, off);
2960 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2961 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2962 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 0;
2963 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2964 pThis->fInvalidEncoding = true;
2965 break;
2966 case 5:
2967 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xc /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2968 off = Bs3Cg1InsertOpcodes(pThis, off);
2969 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2970 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2971 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + 3;
2972 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2973 break;
2974 case 6:
2975 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2976 off = Bs3Cg1InsertOpcodes(pThis, off);
2977 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2978 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2979 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + (BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2980 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2981 break;
2982 case 7:
2983 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2984 off = Bs3Cg1InsertOpcodes(pThis, off);
2985 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 2, 1);
2986 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 2;
2987 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + (BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2988 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 1;
2989 break;
2990 default:
2991 return 0;
2992 }
2993 pThis->cbCurInstr = off;
2994 return iEncoding + 1;
2995}
2996
2997
2998/**
2999 * Wip - VEX.W ignored.
3000 */
3001static unsigned BS3_NEAR_CODE
3002Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3003{
3004 unsigned off;
3005 switch (iEncoding)
3006 {
3007 case 20: /* Switch to 256-bit operands. */
3008 pThis->aOperands[pThis->iRegOp].idxFieldBase = BS3CG1DST_YMM0;
3009 pThis->aOperands[pThis->iRegOp].cbOp = 32;
3010 pThis->aOperands[pThis->iRmOp ].cbOp = 32;
3011 /* fall thru */
3012 case 0:
3013 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3014 off = Bs3Cg1InsertOpcodes(pThis, off);
3015 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3016 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
3017 break;
3018#if ARCH_BITS == 64
3019 case 1:
3020 case 21:
3021 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/);
3022 off = Bs3Cg1InsertOpcodes(pThis, off);
3023 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
3024 break;
3025#endif
3026 case 2:
3027 case 22:
3028 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3029 off = Bs3Cg1InsertOpcodes(pThis, off);
3030 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3031 pThis->fInvalidEncoding = true;
3032 break;
3033 case 3:
3034 case 23:
3035 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3036 off = Bs3Cg1InsertOpcodes(pThis, off);
3037 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3038 break;
3039 case 4:
3040 case 24:
3041 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
3042 off = Bs3Cg1InsertOpcodes(pThis, off);
3043 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3044 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
3045 break;
3046#if ARCH_BITS == 64
3047 case 5:
3048 case 25:
3049 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3050 off = Bs3Cg1InsertOpcodes(pThis, off);
3051 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
3052 break;
3053 case 6:
3054 case 26:
3055 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
3056 off = Bs3Cg1InsertOpcodes(pThis, off);
3057 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3058 break;
3059 case 7:
3060 case 27:
3061 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
3062 off = Bs3Cg1InsertOpcodes(pThis, off);
3063 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3064 break;
3065#endif
3066 case 8:
3067 case 28:
3068 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3069 off = Bs3Cg1InsertOpcodes(pThis, off);
3070 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3071 pThis->fInvalidEncoding = true;
3072 break;
3073 case 9:
3074 case 29:
3075 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3076 off = Bs3Cg1InsertOpcodes(pThis, off);
3077 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3078 pThis->fInvalidEncoding = true;
3079 iEncoding += 10;
3080 break;
3081
3082 default:
3083 return 0;
3084 }
3085 pThis->cbCurInstr = off;
3086 return iEncoding + 1;
3087}
3088
3089
3090
3091/**
3092 * Wip - VEX.W ignored.
3093 * Lig - VEX.L ignored.
3094 */
3095static unsigned BS3_NEAR_CODE
3096Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3097{
3098 unsigned off;
3099 switch (iEncoding)
3100 {
3101 case 0:
3102 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3103 off = Bs3Cg1InsertOpcodes(pThis, off);
3104 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3105 break;
3106 case 1:
3107 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 1 /*~R*/);
3108 off = Bs3Cg1InsertOpcodes(pThis, off);
3109 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7);
3110 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
3111 break;
3112#if ARCH_BITS == 64
3113 case 2:
3114 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 0 /*~R*/);
3115 off = Bs3Cg1InsertOpcodes(pThis, off);
3116 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
3117 break;
3118#endif
3119 case 3:
3120 iEncoding = 3;
3121 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/);
3122 off = Bs3Cg1InsertOpcodes(pThis, off);
3123 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3124 pThis->fInvalidEncoding = true;
3125 break;
3126 case 4:
3127 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3128 off = Bs3Cg1InsertOpcodes(pThis, off);
3129 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3130 break;
3131 case 5:
3132 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3133 off = Bs3Cg1InsertOpcodes(pThis, off);
3134 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3135 break;
3136 case 6:
3137 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
3138 off = Bs3Cg1InsertOpcodes(pThis, off);
3139 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3140 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
3141 break;
3142#if ARCH_BITS == 64
3143 case 7:
3144 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3145 off = Bs3Cg1InsertOpcodes(pThis, off);
3146 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
3147 break;
3148 case 8:
3149 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
3150 off = Bs3Cg1InsertOpcodes(pThis, off);
3151 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3152 break;
3153 case 9:
3154 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
3155 off = Bs3Cg1InsertOpcodes(pThis, off);
3156 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3157 break;
3158#endif
3159 case 10:
3160 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3161 off = Bs3Cg1InsertOpcodes(pThis, off);
3162 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3163 pThis->fInvalidEncoding = true;
3164 break;
3165 case 11:
3166 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3167 off = Bs3Cg1InsertOpcodes(pThis, off);
3168 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3169 pThis->fInvalidEncoding = true;
3170 break;
3171 default:
3172 return 0;
3173 }
3174 pThis->cbCurInstr = off;
3175 return iEncoding + 1;
3176}
3177
3178
3179/**
3180 * Wip - VEX.W ignored.
3181 * L0 - VEX.L must be zero.
3182 */
3183static unsigned BS3_NEAR_CODE
3184Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lmbz_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3185{
3186 unsigned off;
3187 switch (iEncoding)
3188 {
3189 case 0:
3190 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3191 off = Bs3Cg1InsertOpcodes(pThis, off);
3192 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3193 break;
3194 case 1:
3195 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - invalid*/, 1 /*~R*/);
3196 off = Bs3Cg1InsertOpcodes(pThis, off);
3197 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7);
3198 pThis->fInvalidEncoding = true;
3199 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 : 0;
3200 break;
3201#if ARCH_BITS == 64
3202 case 2:
3203 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/);
3204 off = Bs3Cg1InsertOpcodes(pThis, off);
3205 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
3206 break;
3207 case 3:
3208 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - invalid*/, 0 /*~R*/);
3209 off = Bs3Cg1InsertOpcodes(pThis, off);
3210 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5 + 8);
3211 pThis->fInvalidEncoding = true;
3212 break;
3213#endif
3214 case 4:
3215 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/);
3216 off = Bs3Cg1InsertOpcodes(pThis, off);
3217 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3218 pThis->fInvalidEncoding = true;
3219 break;
3220 case 5:
3221 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3222 off = Bs3Cg1InsertOpcodes(pThis, off);
3223 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3224 break;
3225 case 6:
3226 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - invalid*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3227 off = Bs3Cg1InsertOpcodes(pThis, off);
3228 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3229 pThis->fInvalidEncoding = true;
3230 break;
3231 case 7:
3232 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
3233 off = Bs3Cg1InsertOpcodes(pThis, off);
3234 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3235 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
3236 break;
3237#if ARCH_BITS == 64
3238 case 8:
3239 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3240 off = Bs3Cg1InsertOpcodes(pThis, off);
3241 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
3242 break;
3243 case 9:
3244 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
3245 off = Bs3Cg1InsertOpcodes(pThis, off);
3246 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3247 break;
3248 case 10:
3249 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
3250 off = Bs3Cg1InsertOpcodes(pThis, off);
3251 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3252 break;
3253#endif
3254 case 11:
3255 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3256 off = Bs3Cg1InsertOpcodes(pThis, off);
3257 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3258 pThis->fInvalidEncoding = true;
3259 break;
3260 case 12:
3261 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3262 off = Bs3Cg1InsertOpcodes(pThis, off);
3263 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3264 pThis->fInvalidEncoding = true;
3265 break;
3266 default:
3267 return 0;
3268 }
3269 pThis->cbCurInstr = off;
3270 return iEncoding + 1;
3271}
3272
3273
3274/**
3275 * Wip - VEX.W ignored.
3276 */
3277static unsigned BS3_NEAR_CODE
3278Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lxx_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding, uint8_t uVexL)
3279{
3280 unsigned off;
3281 switch (iEncoding)
3282 {
3283 case 0:
3284 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/);
3285 off = Bs3Cg1InsertOpcodes(pThis, off);
3286 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3287 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
3288 break;
3289#if ARCH_BITS == 64
3290 case 1:
3291 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 0 /*~R*/);
3292 off = Bs3Cg1InsertOpcodes(pThis, off);
3293 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
3294 break;
3295#endif
3296 case 2:
3297 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, uVexL, 1 /*~R*/);
3298 off = Bs3Cg1InsertOpcodes(pThis, off);
3299 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3300 pThis->fInvalidEncoding = true;
3301 break;
3302 case 3:
3303 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3304 off = Bs3Cg1InsertOpcodes(pThis, off);
3305 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3306 break;
3307 case 4:
3308 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
3309 off = Bs3Cg1InsertOpcodes(pThis, off);
3310 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3311 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
3312 break;
3313#if ARCH_BITS == 64
3314 case 5:
3315 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3316 off = Bs3Cg1InsertOpcodes(pThis, off);
3317 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
3318 break;
3319 case 6:
3320 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
3321 off = Bs3Cg1InsertOpcodes(pThis, off);
3322 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3323 break;
3324 case 7:
3325 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
3326 off = Bs3Cg1InsertOpcodes(pThis, off);
3327 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3328 break;
3329#endif
3330 case 8:
3331 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3332 off = Bs3Cg1InsertOpcodes(pThis, off);
3333 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3334 pThis->fInvalidEncoding = true;
3335 break;
3336 case 9:
3337 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3338 off = Bs3Cg1InsertOpcodes(pThis, off);
3339 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3340 pThis->fInvalidEncoding = true;
3341 break;
3342 default:
3343 return 0;
3344 }
3345 pThis->cbCurInstr = off;
3346 return iEncoding + 1;
3347}
3348
3349
3350/**
3351 * Wip - VEX.W ignored.
3352 * L0 - VEX.L is zero (encoding may exist where it isn't).
3353 */
3354static unsigned BS3_NEAR_CODE
3355Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L0_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3356{
3357 return Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lxx_OR_ViceVersa(pThis, iEncoding, 0 /*uVexL*/);
3358}
3359
3360
3361/**
3362 * Wip - VEX.W ignored.
3363 * L1 - VEX.L is one (encoding may exist where it isn't).
3364 */
3365static unsigned BS3_NEAR_CODE
3366Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L1_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3367{
3368 return Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lxx_OR_ViceVersa(pThis, iEncoding, 1 /*uVexL*/);
3369}
3370
3371
3372
3373/**
3374 * Wip - VEX.W ignored.
3375 */
3376static unsigned BS3_NEAR_CODE
3377Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Msomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3378{
3379 unsigned off;
3380 switch (iEncoding)
3381 {
3382 case 0:
3383 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xc /*~V*/, 0 /*L*/, 1 /*~R*/);
3384 off = Bs3Cg1InsertOpcodes(pThis, off);
3385 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3386 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 3;
3387 break;
3388 case 1:
3389 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/);
3390 off = Bs3Cg1InsertOpcodes(pThis, off);
3391 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7);
3392 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3393 pThis->fInvalidEncoding = true;
3394 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
3395 break;
3396#if ARCH_BITS == 64
3397 case 2:
3398 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0x1 /*~V*/, 0 /*L*/, 0 /*~R*/);
3399 off = Bs3Cg1InsertOpcodes(pThis, off);
3400 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
3401 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 14;
3402 break;
3403#endif
3404 case 3:
3405 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/);
3406 off = Bs3Cg1InsertOpcodes(pThis, off);
3407 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3408 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 1;
3409 break;
3410 case 4:
3411 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3412 off = Bs3Cg1InsertOpcodes(pThis, off);
3413 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3414 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3415 break;
3416 case 5:
3417 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3418 off = Bs3Cg1InsertOpcodes(pThis, off);
3419 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3420 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3421 pThis->fInvalidEncoding = true;
3422 break;
3423 case 6:
3424 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
3425 off = Bs3Cg1InsertOpcodes(pThis, off);
3426 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3427 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3428 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
3429 break;
3430#if ARCH_BITS == 64
3431 case 7:
3432 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3433 off = Bs3Cg1InsertOpcodes(pThis, off);
3434 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
3435 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3436 break;
3437 case 8:
3438 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
3439 off = Bs3Cg1InsertOpcodes(pThis, off);
3440 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3441 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3442 break;
3443 case 9:
3444 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
3445 off = Bs3Cg1InsertOpcodes(pThis, off);
3446 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3447 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3448 break;
3449#endif
3450 case 10:
3451 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3452 off = Bs3Cg1InsertOpcodes(pThis, off);
3453 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3454 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + (BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
3455 pThis->fInvalidEncoding = true;
3456 break;
3457 default:
3458 return 0;
3459 }
3460 pThis->cbCurInstr = off;
3461 return iEncoding + 1;
3462}
3463
3464
3465static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_Md_WO(PBS3CG1STATE pThis, unsigned iEncoding)
3466{
3467 unsigned off;
3468 switch (iEncoding)
3469 {
3470 case 0:
3471 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3472 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3473 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3474 break;
3475 case 1:
3476 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3477 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3478 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3479 break;
3480 case 2:
3481 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0x7 /*~V-invalid*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3482 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3483 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3484 pThis->fInvalidEncoding = true;
3485 break;
3486 case 3:
3487 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3488 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3489 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3490 pThis->fInvalidEncoding = true;
3491 break;
3492 case 4:
3493 pThis->abCurInstr[0] = P_OZ;
3494 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3495 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3496 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3497 pThis->fInvalidEncoding = true;
3498 break;
3499 case 5:
3500 pThis->abCurInstr[0] = P_RZ;
3501 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3502 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3503 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3504 pThis->fInvalidEncoding = true;
3505 break;
3506 case 6:
3507 pThis->abCurInstr[0] = P_RN;
3508 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3509 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3510 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3511 pThis->fInvalidEncoding = true;
3512 break;
3513 case 7:
3514 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
3515 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3516 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3517 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
3518 break;
3519#if ARCH_BITS == 64
3520 case 8:
3521 pThis->abCurInstr[0] = REX_____;
3522 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3523 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3524 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3525 pThis->fInvalidEncoding = true;
3526 break;
3527#endif
3528 default:
3529 return 0;
3530 }
3531
3532 pThis->cbCurInstr = off;
3533 return iEncoding + 1;
3534}
3535
3536
3537/**
3538 * Wip = VEX.W ignored.
3539 * Lmbz = VEX.L must be zero.
3540 */
3541static unsigned BS3_NEAR_CODE
3542Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_Lmbz_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3543{
3544 unsigned off;
3545 switch (iEncoding)
3546 {
3547 /* 128-bit wide stuff goes first, then we'll update the operand widths afterwards. */
3548 case 0:
3549 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3550 off = Bs3Cg1InsertOpcodes(pThis, off);
3551 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
3552 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3553 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
3554 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
3555 break;
3556
3557 case 1:
3558 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3559 off = Bs3Cg1InsertOpcodes(pThis, off);
3560 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3561 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3562 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3563 break;
3564 case 2:
3565 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored*/);
3566 off = Bs3Cg1InsertOpcodes(pThis, off);
3567 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 5, 4);
3568 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 4;
3569 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 5;
3570 break;
3571 case 3:
3572 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
3573 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3574 off = Bs3Cg1InsertOpcodes(pThis, off);
3575 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
3576 break;
3577 case 4:
3578 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3579 off = Bs3Cg1InsertOpcodes(pThis, off);
3580 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3581 break;
3582 case 5:
3583 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored */);
3584 off = Bs3Cg1InsertOpcodes(pThis, off);
3585 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3586 break;
3587 case 6:
3588 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3589 off = Bs3Cg1InsertOpcodes(pThis, off);
3590 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3591 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3592 pThis->bAlignmentXcpt = X86_XCPT_GP;
3593 break;
3594 case 7:
3595 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3596 off = Bs3Cg1InsertOpcodes(pThis, off);
3597 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3598 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3599 pThis->bAlignmentXcpt = X86_XCPT_GP;
3600 break;
3601 /* 128-bit invalid encodings: */
3602 case 8:
3603 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/); /* Bad V value */
3604 off = Bs3Cg1InsertOpcodes(pThis, off);
3605 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
3606 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3607 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
3608 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
3609 pThis->fInvalidEncoding = true;
3610 break;
3611 case 9:
3612 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3613 off = Bs3Cg1InsertOpcodes(pThis, off);
3614 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3615 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3616 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3617 pThis->fInvalidEncoding = true;
3618 iEncoding = 20-1;
3619 break;
3620
3621 default:
3622 return 0;
3623 }
3624
3625 pThis->cbCurInstr = off;
3626 return iEncoding + 1;
3627}
3628
3629
3630/**
3631 * Wip = VEX.W ignored.
3632 */
3633static unsigned BS3_NEAR_CODE
3634Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3635{
3636 unsigned off;
3637
3638 switch (iEncoding)
3639 {
3640 case 20: /* switch to 256-bit */
3641 pThis->aOperands[pThis->iRmOp ].cbOp = 32;
3642 pThis->aOperands[pThis->iRmOp ].idxFieldBase = BS3CG1DST_YMM0;
3643 pThis->aOperands[pThis->iRegOp].cbOp = 32;
3644 pThis->aOperands[pThis->iRegOp].idxFieldBase = BS3CG1DST_YMM0;
3645 /* fall thru */
3646 case 0:
3647 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3648 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3649 off = Bs3Cg1InsertOpcodes(pThis, off);
3650 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
3651 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
3652 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
3653 break;
3654
3655 case 1:
3656 case 21:
3657 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3658 off = Bs3Cg1InsertOpcodes(pThis, off);
3659 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3660 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3661 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3662 break;
3663 case 2:
3664 case 22:
3665 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored*/);
3666 off = Bs3Cg1InsertOpcodes(pThis, off);
3667 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 5, 4);
3668 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 4;
3669 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 5;
3670 break;
3671 case 3:
3672 case 23:
3673 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
3674 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3675 off = Bs3Cg1InsertOpcodes(pThis, off);
3676 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
3677 break;
3678 case 4:
3679 case 24:
3680 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3681 off = Bs3Cg1InsertOpcodes(pThis, off);
3682 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3683 break;
3684 case 5:
3685 case 25:
3686 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored */);
3687 off = Bs3Cg1InsertOpcodes(pThis, off);
3688 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3689 break;
3690 case 6:
3691 case 26:
3692 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3693 off = Bs3Cg1InsertOpcodes(pThis, off);
3694 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3695 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3696 pThis->bAlignmentXcpt = X86_XCPT_GP;
3697 break;
3698 case 7:
3699 case 27:
3700 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3701 off = Bs3Cg1InsertOpcodes(pThis, off);
3702 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3703 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3704 pThis->bAlignmentXcpt = X86_XCPT_GP;
3705 break;
3706 /* invalid encodings: */
3707 case 8:
3708 case 28:
3709 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/); /* Bad V value */
3710 off = Bs3Cg1InsertOpcodes(pThis, off);
3711 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 0);
3712 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3713 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 0;
3714 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 1;
3715 pThis->fInvalidEncoding = true;
3716 break;
3717 case 9:
3718 case 29:
3719 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3720 off = Bs3Cg1InsertOpcodes(pThis, off);
3721 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3722 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3723 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3724 pThis->fInvalidEncoding = true;
3725 break;
3726
3727 case 10:
3728 case 30:
3729 pThis->abCurInstr[0] = P_RN;
3730 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3731 off = Bs3Cg1InsertOpcodes(pThis, off);
3732 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3733 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3734 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3735 pThis->fInvalidEncoding = true;
3736 break;
3737 case 11:
3738 case 31:
3739 pThis->abCurInstr[0] = P_RZ;
3740 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3741 off = Bs3Cg1InsertOpcodes(pThis, off);
3742 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3743 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3744 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3745 pThis->fInvalidEncoding = true;
3746 break;
3747 case 12:
3748 case 32:
3749 pThis->abCurInstr[0] = P_OZ;
3750 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3751 off = Bs3Cg1InsertOpcodes(pThis, off);
3752 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3753 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3754 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3755 pThis->fInvalidEncoding = true;
3756 break;
3757 case 13:
3758 case 33:
3759 pThis->abCurInstr[0] = P_LK;
3760 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3761 off = Bs3Cg1InsertOpcodes(pThis, off);
3762 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 4, 5);
3763 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 5;
3764 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 4;
3765 pThis->fInvalidEncoding = true;
3766 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 + 4 : 0;
3767 break;
3768
3769#if ARCH_BITS == 64
3770 /* 64-bit mode registers */
3771 case 14:
3772 case 34:
3773 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/);
3774 off = Bs3Cg1InsertOpcodes(pThis, off);
3775 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 3, 4);
3776 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 4;
3777 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 11;
3778 break;
3779 case 15:
3780 case 35:
3781 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/, 1 /*~X*/, 0 /*~B*/, 0 /*W*/);
3782 off = Bs3Cg1InsertOpcodes(pThis, off);
3783 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 1, 4);
3784 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + 12;
3785 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + 9;
3786 iEncoding += 4;
3787 break;
3788#endif
3789 default:
3790 return 0;
3791 }
3792
3793 pThis->cbCurInstr = off;
3794 return iEncoding + 1;
3795}
3796
3797
3798//static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_FIXED(PBS3CG1STATE pThis, unsigned iEncoding)
3799//{
3800// unsigned off;
3801// if (iEncoding == 0)
3802// off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3803// else if (iEncoding == 0)
3804// off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3805// else
3806// return 0;
3807// pThis->cbCurInstr = off;
3808// return iEncoding + 1;
3809//}
3810
3811
3812static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_MOD_EQ_3(PBS3CG1STATE pThis, unsigned iEncoding)
3813{
3814 unsigned off;
3815 if (iEncoding < 8)
3816 {
3817 if (iEncoding & 1)
3818 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3819 else
3820 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3821 off = Bs3Cg1InsertOpcodes(pThis, off);
3822 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, iEncoding, 1);
3823 }
3824 else if (iEncoding < 16)
3825 {
3826 if (iEncoding & 1)
3827 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/);
3828 else
3829 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3830 off = Bs3Cg1InsertOpcodes(pThis, off);
3831 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, iEncoding & 7, 1);
3832 }
3833 else if (iEncoding < 24)
3834 {
3835 if (iEncoding & 1)
3836 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3837 else
3838 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3839 off = Bs3Cg1InsertOpcodes(pThis, off);
3840 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 0, iEncoding & 7);
3841 }
3842 else if (iEncoding < 32)
3843 {
3844 if (iEncoding & 1)
3845 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 3) != 0 /*L*/, 1 /*~R*/);
3846 else
3847 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 2) != 0 /*L*/, 1 /*~R*/, 1 /*~X*/,
3848 1 /*~B*/, (iEncoding & 4) != 0 /*W*/);
3849 off = Bs3Cg1InsertOpcodes(pThis, off);
3850 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 0, iEncoding & 7);
3851 }
3852 else
3853 return 0;
3854 pThis->cbCurInstr = off;
3855
3856 return iEncoding + 1;
3857}
3858
3859
3860static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_MOD_NE_3(PBS3CG1STATE pThis, unsigned iEncoding)
3861{
3862 unsigned off;
3863 if (iEncoding < 8)
3864 {
3865 unsigned iMod = iEncoding % 3;
3866 if (iEncoding & 1)
3867 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 2) != 0 /*L*/, 1 /*~R*/);
3868 else
3869 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 2) != 0 /*L*/, 1 /*~R*/,
3870 1 /*~X*/, 1 /*~B*/, (iEncoding & 4) != 0 /*W*/);
3871 off = Bs3Cg1InsertOpcodes(pThis, off);
3872 pThis->abCurInstr[off++] = X86_MODRM_MAKE(iMod, 0, 1);
3873 if (iMod >= 1)
3874 pThis->abCurInstr[off++] = 0x7f;
3875 if (iMod == 2)
3876 {
3877 pThis->abCurInstr[off++] = 0x5f;
3878 if (!BS3_MODE_IS_16BIT_CODE(pThis->bMode))
3879 {
3880 pThis->abCurInstr[off++] = 0x3f;
3881 pThis->abCurInstr[off++] = 0x1f;
3882 }
3883 }
3884 }
3885 else
3886 return 0;
3887 pThis->cbCurInstr = off;
3888 return iEncoding + 1;
3889}
3890
3891
3892static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM(PBS3CG1STATE pThis, unsigned iEncoding)
3893{
3894 const unsigned cFirstEncodings = 32;
3895 if (iEncoding < cFirstEncodings)
3896 {
3897 unsigned iRet = Bs3Cg1EncodeNext_VEX_MODRM_MOD_EQ_3(pThis, iEncoding);
3898 BS3_ASSERT(iRet > iEncoding);
3899 return iRet;
3900 }
3901 return Bs3Cg1EncodeNext_VEX_MODRM_MOD_NE_3(pThis, iEncoding - cFirstEncodings) + cFirstEncodings;
3902}
3903
3904#endif /* BS3CG1_WITH_VEX */
3905
3906
3907/**
3908 * Encodes the next instruction.
3909 *
3910 * @returns Next iEncoding value. Returns @a iEncoding unchanged to indicate
3911 * that there are no more encodings to test.
3912 * @param pThis The state.
3913 * @param iEncoding The encoding to produce. Meaning is specific to
3914 * each BS3CG1ENC_XXX value and should be considered
3915 * internal.
3916 */
3917static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding)
3918{
3919 pThis->bAlignmentXcpt = UINT8_MAX;
3920 pThis->uVexL = UINT8_MAX;
3921 if (pThis->pfnEncoder)
3922 return pThis->pfnEncoder(pThis, iEncoding);
3923
3924 switch (pThis->enmEncoding)
3925 {
3926 case BS3CG1ENC_MODRM_Eb_Gb:
3927 return Bs3Cg1EncodeNext_MODRM_Eb_Gb(pThis, iEncoding);
3928 case BS3CG1ENC_MODRM_Gb_Eb:
3929 return Bs3Cg1EncodeNext_MODRM_Gb_Eb(pThis, iEncoding);
3930 case BS3CG1ENC_MODRM_Gv_Ev:
3931 case BS3CG1ENC_MODRM_Ev_Gv:
3932 return Bs3Cg1EncodeNext_MODRM_Gv_Ev__OR__MODRM_Ev_Gv(pThis, iEncoding);
3933
3934 case BS3CG1ENC_MODRM_Wss_WO_Vss:
3935 return Bs3Cg1EncodeNext_MODRM_Wss_WO_Vss(pThis, iEncoding);
3936 case BS3CG1ENC_MODRM_Wsd_WO_Vsd:
3937 return Bs3Cg1EncodeNext_MODRM_Wsd_WO_Vsd(pThis, iEncoding);
3938 case BS3CG1ENC_MODRM_Wps_WO_Vps:
3939 case BS3CG1ENC_MODRM_Wpd_WO_Vpd:
3940 return Bs3Cg1EncodeNext_MODRM_Wps_WO_Vps__OR__MODRM_Wpd_WO_Vpd(pThis, iEncoding);
3941 case BS3CG1ENC_MODRM_WqZxReg_WO_Vq:
3942 return Bs3Cg1EncodeNext_MODRM_WqZxReg_WO_Vq(pThis, iEncoding);
3943
3944 case BS3CG1ENC_MODRM_Vq_WO_UqHi:
3945 return Bs3Cg1EncodeNext_MODRM_Vq_WO_UqHi(pThis, iEncoding);
3946 case BS3CG1ENC_MODRM_Vq_WO_Mq:
3947 return Bs3Cg1EncodeNext_MODRM_Vq_WO_Mq(pThis, iEncoding);
3948 case BS3CG1ENC_MODRM_VqHi_WO_Uq:
3949 return Bs3Cg1EncodeNext_MODRM_VqHi_WO_Uq(pThis, iEncoding);
3950 case BS3CG1ENC_MODRM_VqHi_WO_Mq:
3951 return Bs3Cg1EncodeNext_MODRM_VqHi_WO_Mq(pThis, iEncoding);
3952 case BS3CG1ENC_MODRM_Vpd_WO_Wpd:
3953 case BS3CG1ENC_MODRM_Vps_WO_Wps:
3954 return Bs3Cg1EncodeNext_MODRM_Vps_WO_Wps__OR__MODRM_Vpd_WO_Wpd(pThis, iEncoding);
3955 case BS3CG1ENC_MODRM_VssZx_WO_Wss:
3956 return Bs3Cg1EncodeNext_MODRM_VssZx_WO_Wss(pThis, iEncoding);
3957 case BS3CG1ENC_MODRM_VsdZx_WO_Wsd:
3958 case BS3CG1ENC_MODRM_VqZx_WO_Wq:
3959 return Bs3Cg1EncodeNext_MODRM_VsdZx_WO_Wsd__OR__MODRM_VqZx_WO_Wq(pThis, iEncoding);
3960 case BS3CG1ENC_MODRM_VqZx_WO_Nq:
3961 return Bs3Cg1EncodeNext_MODRM_VqZx_WO_Nq(pThis, iEncoding);
3962
3963 case BS3CG1ENC_FIXED:
3964 return Bs3Cg1EncodeNext_FIXED(pThis, iEncoding);
3965 case BS3CG1ENC_FIXED_AL_Ib:
3966 return Bs3Cg1EncodeNext_FIXED_AL_Ib(pThis, iEncoding);
3967 case BS3CG1ENC_FIXED_rAX_Iz:
3968 return Bs3Cg1EncodeNext_FIXED_rAX_Iz(pThis, iEncoding);
3969
3970 /*
3971 * VEX stuff
3972 */
3973#ifdef BS3CG1_WITH_VEX
3974 case BS3CG1ENC_VEX_MODRM_VssZx_WO_Md:
3975 return Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa(pThis, iEncoding);
3976
3977#endif /* BS3CG1_WITH_VEX */
3978
3979 default:
3980 Bs3TestFailedF("Internal error! BS3CG1ENC_XXX = %u not implemented", pThis->enmEncoding);
3981 break;
3982 }
3983
3984
3985 return iEncoding;
3986}
3987
3988
3989/**
3990 * Prepares doing instruction encodings.
3991 *
3992 * This is in part specific to how the instruction is encoded, but generally it
3993 * sets up basic operand values that doesn't change (much) when Bs3Cg1EncodeNext
3994 * is called from within the loop.
3995 *
3996 * @returns Success indicator (true/false).
3997 * @param pThis The state.
3998 */
3999#define Bs3Cg1EncodePrep BS3_CMN_NM(Bs3Cg1EncodePrep)
4000bool BS3_NEAR_CODE Bs3Cg1EncodePrep(PBS3CG1STATE pThis)
4001{
4002 unsigned i = 4;
4003 while (i-- > 0)
4004 pThis->aSavedSegRegs[i].ds = pThis->aInitialCtxs[i].ds;
4005
4006 i = RT_ELEMENTS(pThis->aOperands);
4007 while (i-- > 0)
4008 {
4009 pThis->aOperands[i].enmLocationReg = BS3CG1OPLOC_INVALID;
4010 pThis->aOperands[i].enmLocationMem = BS3CG1OPLOC_INVALID;
4011 pThis->aOperands[i].idxFieldBase = BS3CG1DST_INVALID;
4012 }
4013
4014 pThis->iRmOp = RT_ELEMENTS(pThis->aOperands) - 1;
4015 pThis->iRegOp = RT_ELEMENTS(pThis->aOperands) - 1;
4016 pThis->fSameRingNotOkay = false;
4017 pThis->cbOperand = 0;
4018 pThis->pfnEncoder = NULL;
4019
4020 switch (pThis->enmEncoding)
4021 {
4022 case BS3CG1ENC_MODRM_Eb_Gb:
4023 pThis->iRmOp = 0;
4024 pThis->iRegOp = 1;
4025 pThis->aOperands[0].cbOp = 1;
4026 pThis->aOperands[1].cbOp = 1;
4027 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4028 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4029 break;
4030
4031 case BS3CG1ENC_MODRM_Ev_Gv:
4032 pThis->iRmOp = 0;
4033 pThis->iRegOp = 1;
4034 pThis->cbOperand = 2;
4035 pThis->aOperands[0].cbOp = 2;
4036 pThis->aOperands[1].cbOp = 2;
4037 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4038 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4039 break;
4040
4041 case BS3CG1ENC_MODRM_Ed_WO_Pd_WZ:
4042 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ;
4043 pThis->iRmOp = 0;
4044 pThis->iRegOp = 1;
4045 pThis->aOperands[0].cbOp = 4;
4046 pThis->aOperands[1].cbOp = 4;
4047 pThis->aOperands[0].idxFieldBase = BS3CG1DST_EAX;
4048 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
4049 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4050 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
4051 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4052 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4053 break;
4054
4055 case BS3CG1ENC_MODRM_Eq_WO_Pq_WNZ:
4056 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ;
4057 pThis->iRmOp = 0;
4058 pThis->iRegOp = 1;
4059 pThis->aOperands[0].cbOp = 8;
4060 pThis->aOperands[1].cbOp = 8;
4061 pThis->aOperands[0].idxFieldBase = BS3CG1DST_RAX;
4062 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
4063 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4064 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
4065 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4066 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4067 break;
4068
4069 case BS3CG1ENC_MODRM_Ed_WO_Vd_WZ:
4070 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vd_WO_Ed_WZ;
4071 pThis->iRmOp = 0;
4072 pThis->iRegOp = 1;
4073 pThis->aOperands[0].cbOp = 4;
4074 pThis->aOperands[1].cbOp = 4;
4075 pThis->aOperands[0].idxFieldBase = BS3CG1DST_EAX;
4076 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4077 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4078 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
4079 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4080 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4081 break;
4082
4083 case BS3CG1ENC_MODRM_Eq_WO_Vq_WNZ:
4084 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vq_WO_Eq_WNZ;
4085 pThis->iRmOp = 0;
4086 pThis->iRegOp = 1;
4087 pThis->aOperands[0].cbOp = 8;
4088 pThis->aOperands[1].cbOp = 8;
4089 pThis->aOperands[0].idxFieldBase = BS3CG1DST_RAX;
4090 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4091 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4092 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
4093 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4094 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4095 break;
4096
4097 case BS3CG1ENC_MODRM_Gb_Eb:
4098 pThis->iRmOp = 1;
4099 pThis->iRegOp = 0;
4100 pThis->aOperands[0].cbOp = 1;
4101 pThis->aOperands[1].cbOp = 1;
4102 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4103 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4104 break;
4105
4106 case BS3CG1ENC_MODRM_Gv_Ev:
4107 pThis->iRmOp = 1;
4108 pThis->iRegOp = 0;
4109 pThis->cbOperand = 2;
4110 pThis->aOperands[0].cbOp = 2;
4111 pThis->aOperands[1].cbOp = 2;
4112 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4113 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4114 break;
4115
4116 case BS3CG1ENC_MODRM_Gv_RO_Ma:
4117 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Gv_RO_Ma;
4118 pThis->iRmOp = 1;
4119 pThis->iRegOp = 0;
4120 pThis->cbOperand = 2;
4121 pThis->aOperands[0].cbOp = 2;
4122 pThis->aOperands[1].cbOp = 4;
4123 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4124 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4125 pThis->aOperands[0].idxFieldBase = BS3CG1DST_OZ_RAX;
4126 break;
4127
4128 case BS3CG1ENC_MODRM_Wss_WO_Vss:
4129 pThis->iRmOp = 0;
4130 pThis->iRegOp = 1;
4131 pThis->aOperands[0].cbOp = 4;
4132 pThis->aOperands[1].cbOp = 4;
4133 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4134 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4135 break;
4136
4137 case BS3CG1ENC_MODRM_Wsd_WO_Vsd:
4138 case BS3CG1ENC_MODRM_WqZxReg_WO_Vq:
4139 pThis->iRmOp = 0;
4140 pThis->iRegOp = 1;
4141 pThis->aOperands[0].cbOp = 8;
4142 pThis->aOperands[1].cbOp = 8;
4143 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4144 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4145 break;
4146
4147 case BS3CG1ENC_MODRM_Wps_WO_Vps:
4148 case BS3CG1ENC_MODRM_Wpd_WO_Vpd:
4149 pThis->iRmOp = 0;
4150 pThis->iRegOp = 1;
4151 pThis->aOperands[0].cbOp = 16;
4152 pThis->aOperands[1].cbOp = 16;
4153 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4154 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4155 break;
4156
4157 case BS3CG1ENC_MODRM_Vdq_WO_Mdq:
4158 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_MsomethingWO_Vsomething_OR_ViceVersa;
4159 pThis->iRegOp = 0;
4160 pThis->iRmOp = 1;
4161 pThis->aOperands[0].cbOp = 16;
4162 pThis->aOperands[1].cbOp = 16;
4163 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4164 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4165 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4166 break;
4167
4168 case BS3CG1ENC_MODRM_Vdq_WO_Wdq:
4169 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vdq_WO_Wdq;
4170 pThis->iRmOp = 1;
4171 pThis->iRegOp = 0;
4172 pThis->aOperands[0].cbOp = 16;
4173 pThis->aOperands[1].cbOp = 16;
4174 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4175 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4176 break;
4177
4178 case BS3CG1ENC_MODRM_Vpd_WO_Wpd:
4179 case BS3CG1ENC_MODRM_Vps_WO_Wps:
4180 pThis->iRmOp = 1;
4181 pThis->iRegOp = 0;
4182 pThis->aOperands[0].cbOp = 16;
4183 pThis->aOperands[1].cbOp = 16;
4184 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4185 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4186 break;
4187
4188 case BS3CG1ENC_MODRM_Pq_WO_Qq:
4189 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Qq;
4190 pThis->iRegOp = 0;
4191 pThis->iRmOp = 1;
4192 pThis->aOperands[0].cbOp = 8;
4193 pThis->aOperands[1].cbOp = 8;
4194 pThis->aOperands[0].idxFieldBase = BS3CG1DST_MM0;
4195 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
4196 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4197 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4198 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4199 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4200 break;
4201
4202 case BS3CG1ENC_MODRM_Pq_WO_Uq:
4203 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Uq;
4204 pThis->iRmOp = 1;
4205 pThis->iRegOp = 0;
4206 pThis->aOperands[0].cbOp = 8;
4207 pThis->aOperands[1].cbOp = 8;
4208 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4209 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4210 break;
4211
4212 case BS3CG1ENC_MODRM_PdZx_WO_Ed_WZ:
4213 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ;
4214 pThis->iRegOp = 0;
4215 pThis->iRmOp = 1;
4216 pThis->aOperands[0].cbOp = 4;
4217 pThis->aOperands[1].cbOp = 4;
4218 pThis->aOperands[0].idxFieldBase = BS3CG1DST_MM0_LO_ZX;
4219 pThis->aOperands[1].idxFieldBase = BS3CG1DST_EAX;
4220 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4221 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4222 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4223 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4224 break;
4225
4226 case BS3CG1ENC_MODRM_Pq_WO_Eq_WNZ:
4227 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ;
4228 pThis->iRegOp = 0;
4229 pThis->iRmOp = 1;
4230 pThis->aOperands[0].cbOp = 8;
4231 pThis->aOperands[1].cbOp = 8;
4232 pThis->aOperands[0].idxFieldBase = BS3CG1DST_MM0;
4233 pThis->aOperands[1].idxFieldBase = BS3CG1DST_RAX;
4234 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4235 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4236 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4237 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4238 break;
4239
4240 case BS3CG1ENC_MODRM_VdZx_WO_Ed_WZ:
4241 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vd_WO_Ed_WZ;
4242 pThis->iRegOp = 0;
4243 pThis->iRmOp = 1;
4244 pThis->aOperands[0].cbOp = 4;
4245 pThis->aOperands[1].cbOp = 4;
4246 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0_ZX;
4247 pThis->aOperands[1].idxFieldBase = BS3CG1DST_EAX;
4248 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4249 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4250 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4251 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4252 break;
4253
4254 case BS3CG1ENC_MODRM_VqZx_WO_Eq_WNZ:
4255 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vq_WO_Eq_WNZ;
4256 pThis->iRegOp = 0;
4257 pThis->iRmOp = 1;
4258 pThis->aOperands[0].cbOp = 8;
4259 pThis->aOperands[1].cbOp = 8;
4260 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
4261 pThis->aOperands[1].idxFieldBase = BS3CG1DST_RAX;
4262 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4263 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4264 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4265 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4266 break;
4267
4268 case BS3CG1ENC_MODRM_Vq_WO_UqHi:
4269 case BS3CG1ENC_MODRM_VqHi_WO_Uq:
4270 pThis->iRmOp = 1;
4271 pThis->iRegOp = 0;
4272 pThis->aOperands[0].cbOp = 8;
4273 pThis->aOperands[1].cbOp = 8;
4274 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4275 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4276 break;
4277
4278 case BS3CG1ENC_MODRM_Vq_WO_Mq:
4279 case BS3CG1ENC_MODRM_VqHi_WO_Mq:
4280 pThis->iRmOp = 1;
4281 pThis->iRegOp = 0;
4282 pThis->aOperands[0].cbOp = 8;
4283 pThis->aOperands[1].cbOp = 8;
4284 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4285 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4286 break;
4287
4288 case BS3CG1ENC_MODRM_VssZx_WO_Wss:
4289 pThis->iRmOp = 1;
4290 pThis->iRegOp = 0;
4291 pThis->aOperands[0].cbOp = 4;
4292 pThis->aOperands[1].cbOp = 4;
4293 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4294 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4295 break;
4296
4297 case BS3CG1ENC_MODRM_VsdZx_WO_Wsd:
4298 case BS3CG1ENC_MODRM_VqZx_WO_Wq:
4299 case BS3CG1ENC_MODRM_VqZx_WO_Nq:
4300 pThis->iRmOp = 1;
4301 pThis->iRegOp = 0;
4302 pThis->aOperands[0].cbOp = 8;
4303 pThis->aOperands[1].cbOp = 8;
4304 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4305 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4306 break;
4307
4308 case BS3CG1ENC_MODRM_Mb_RO:
4309 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething;
4310 pThis->iRmOp = 0;
4311 pThis->aOperands[0].cbOp = 1;
4312 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM;
4313 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM;
4314 break;
4315
4316 case BS3CG1ENC_MODRM_Md_RO:
4317 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething;
4318 pThis->iRmOp = 0;
4319 pThis->aOperands[0].cbOp = 4;
4320 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM;
4321 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM;
4322 break;
4323
4324 case BS3CG1ENC_MODRM_Md_WO:
4325 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething;
4326 pThis->iRmOp = 0;
4327 pThis->aOperands[0].cbOp = 4;
4328 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4329 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4330 break;
4331
4332 case BS3CG1ENC_MODRM_Mdq_WO_Vdq:
4333 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_MsomethingWO_Vsomething_OR_ViceVersa;
4334 pThis->iRmOp = 0;
4335 pThis->iRegOp = 1;
4336 pThis->aOperands[0].cbOp = 16;
4337 pThis->aOperands[1].cbOp = 16;
4338 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4339 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4340 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4341 break;
4342
4343 case BS3CG1ENC_MODRM_Mq_WO_Pq:
4344 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Mq_WO_Pq;
4345 pThis->iRmOp = 0;
4346 pThis->iRegOp = 1;
4347 pThis->aOperands[0].cbOp = 8;
4348 pThis->aOperands[1].cbOp = 8;
4349 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
4350 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4351 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4352 break;
4353
4354 case BS3CG1ENC_MODRM_Mq_WO_Vq:
4355 case BS3CG1ENC_MODRM_Mq_WO_VqHi:
4356 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_WO_Vsomething;
4357 pThis->iRmOp = 0;
4358 pThis->iRegOp = 1;
4359 pThis->aOperands[0].cbOp = 8;
4360 pThis->aOperands[1].cbOp = 8;
4361 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4362 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4363 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4364 pThis->aOperands[1].idxFieldBase = pThis->enmEncoding == BS3CG1ENC_MODRM_Mq_WO_Vq
4365 ? BS3CG1DST_XMM0_LO : BS3CG1DST_XMM0_HI;
4366 break;
4367
4368 case BS3CG1ENC_MODRM_Mps_WO_Vps:
4369 case BS3CG1ENC_MODRM_Mpd_WO_Vpd:
4370 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_MsomethingWO_Vsomething_OR_ViceVersa;
4371 pThis->iRmOp = 0;
4372 pThis->iRegOp = 1;
4373 pThis->aOperands[0].cbOp = 16;
4374 pThis->aOperands[1].cbOp = 16;
4375 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4376 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4377 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4378 break;
4379
4380 case BS3CG1ENC_FIXED:
4381 /* nothing to do here */
4382 break;
4383
4384 case BS3CG1ENC_FIXED_AL_Ib:
4385 pThis->aOperands[0].cbOp = 1;
4386 pThis->aOperands[1].cbOp = 1;
4387 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4388 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_IMM;
4389 pThis->aOperands[0].idxField = BS3CG1DST_AL;
4390 pThis->aOperands[1].idxField = BS3CG1DST_INVALID;
4391 break;
4392
4393 case BS3CG1ENC_FIXED_rAX_Iz:
4394 pThis->aOperands[0].cbOp = 2;
4395 pThis->aOperands[1].cbOp = 2;
4396 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4397 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_IMM;
4398 pThis->aOperands[0].idxField = BS3CG1DST_OZ_RAX;
4399 pThis->aOperands[1].idxField = BS3CG1DST_INVALID;
4400 break;
4401
4402 /* Unused or invalid instructions mostly. */
4403 case BS3CG1ENC_MODRM_MOD_EQ_3:
4404 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_MOD_EQ_3;
4405 break;
4406 case BS3CG1ENC_MODRM_MOD_NE_3:
4407 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_MOD_NE_3;
4408 break;
4409
4410#ifdef BS3CG1_WITH_VEX
4411
4412 case BS3CG1ENC_VEX_MODRM_Vd_WO_Ed_WZ:
4413 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_Vd_WO_Ed_WZ;
4414 pThis->iRegOp = 0;
4415 pThis->iRmOp = 1;
4416 pThis->aOperands[0].cbOp = 4;
4417 pThis->aOperands[1].cbOp = 4;
4418 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0_ZX;
4419 pThis->aOperands[1].idxFieldBase = BS3CG1DST_EAX;
4420 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4421 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4422 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4423 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4424 break;
4425
4426 case BS3CG1ENC_VEX_MODRM_Vq_WO_Eq_WNZ:
4427 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_Vq_WO_Eq_WNZ;
4428 pThis->iRegOp = 0;
4429 pThis->iRmOp = 1;
4430 pThis->aOperands[0].cbOp = 8;
4431 pThis->aOperands[1].cbOp = 8;
4432 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
4433 pThis->aOperands[1].idxFieldBase = BS3CG1DST_RAX;
4434 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4435 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4436 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4437 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4438 break;
4439
4440 case BS3CG1ENC_VEX_MODRM_Vps_WO_Wps:
4441 case BS3CG1ENC_VEX_MODRM_Vpd_WO_Wpd:
4442 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_OR_ViceVersa;
4443 pThis->iRegOp = 0;
4444 pThis->iRmOp = 1;
4445 pThis->aOperands[0].cbOp = 16;
4446 pThis->aOperands[1].cbOp = 16;
4447 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4448 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4449 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4450 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4451 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4452 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4453 break;
4454
4455 case BS3CG1ENC_VEX_MODRM_VssZx_WO_Md:
4456 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa;
4457 pThis->iRmOp = 1;
4458 pThis->iRegOp = 0;
4459 pThis->aOperands[0].cbOp = 4;
4460 pThis->aOperands[1].cbOp = 4;
4461 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4462 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4463 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0;
4464 pThis->aOperands[1].idxFieldBase = BS3CG1DST_INVALID;
4465 break;
4466
4467 case BS3CG1ENC_VEX_MODRM_Vss_WO_HssHi_Uss:
4468 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa;
4469 pThis->iRegOp = 0;
4470 pThis->iRmOp = 2;
4471 pThis->aOperands[0].cbOp = 16;
4472 pThis->aOperands[1].cbOp = 12;
4473 pThis->aOperands[2].cbOp = 4;
4474 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4475 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4476 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4477 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4478 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI96;
4479 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_DW0;
4480 break;
4481
4482 case BS3CG1ENC_VEX_MODRM_VsdZx_WO_Mq:
4483 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa;
4484 pThis->iRmOp = 1;
4485 pThis->iRegOp = 0;
4486 pThis->aOperands[0].cbOp = 8;
4487 pThis->aOperands[1].cbOp = 8;
4488 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4489 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4490 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
4491 pThis->aOperands[1].idxFieldBase = BS3CG1DST_INVALID;
4492 break;
4493
4494 case BS3CG1ENC_VEX_MODRM_Vx_WO_Mx_L0:
4495 BS3_ASSERT(!(pThis->fFlags & BS3CG1INSTR_F_VEX_L_ZERO));
4496 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L0_OR_ViceVersa;
4497 pThis->iRegOp = 0;
4498 pThis->iRmOp = 1;
4499 pThis->aOperands[0].cbOp = 16;
4500 pThis->aOperands[1].cbOp = 16;
4501 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4502 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4503 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4504 break;
4505
4506 case BS3CG1ENC_VEX_MODRM_Vx_WO_Mx_L1:
4507 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L1_OR_ViceVersa;
4508 pThis->iRegOp = 0;
4509 pThis->iRmOp = 1;
4510 pThis->aOperands[0].cbOp = 32;
4511 pThis->aOperands[1].cbOp = 32;
4512 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4513 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4514 pThis->aOperands[0].idxFieldBase = BS3CG1DST_YMM0;
4515 break;
4516
4517 case BS3CG1ENC_VEX_MODRM_Vsd_WO_HsdHi_Usd:
4518 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa;
4519 pThis->iRegOp = 0;
4520 pThis->iRmOp = 2;
4521 pThis->aOperands[0].cbOp = 16;
4522 pThis->aOperands[1].cbOp = 8;
4523 pThis->aOperands[2].cbOp = 8;
4524 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4525 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4526 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4527 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4528 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
4529 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_LO;
4530 break;
4531
4532 case BS3CG1ENC_VEX_MODRM_Vq_WO_HqHi_UqHi:
4533 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_HdqCsomething_Usomething_Wip_OR_ViceVersa;
4534 pThis->iRegOp = 0;
4535 pThis->iRmOp = 2;
4536 pThis->aOperands[0].cbOp = 16;
4537 pThis->aOperands[1].cbOp = 8;
4538 pThis->aOperands[2].cbOp = 8;
4539 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4540 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4541 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4542 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4543 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
4544 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_HI;
4545 break;
4546
4547 case BS3CG1ENC_VEX_MODRM_Vq_WO_HqHi_Mq:
4548 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Msomething_Wip_OR_ViceVersa;
4549 pThis->iRegOp = 0;
4550 pThis->iRmOp = 2;
4551 pThis->aOperands[0].cbOp = 16;
4552 pThis->aOperands[1].cbOp = 8;
4553 pThis->aOperands[2].cbOp = 8;
4554 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4555 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4556 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_MEM;
4557 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4558 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
4559 pThis->aOperands[2].idxFieldBase = BS3CG1DST_INVALID;
4560 break;
4561
4562 case BS3CG1ENC_VEX_MODRM_Vq_WO_Wq:
4563 BS3_ASSERT(pThis->fFlags & BS3CG1INSTR_F_VEX_L_ZERO);
4564 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_Lmbz_OR_ViceVersa;
4565 pThis->iRegOp = 0;
4566 pThis->iRmOp = 1;
4567 pThis->aOperands[0].cbOp = 8;
4568 pThis->aOperands[1].cbOp = 8;
4569 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4570 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4571 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4572 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4573 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
4574 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
4575 break;
4576
4577 case BS3CG1ENC_VEX_MODRM_Vx_WO_Wx:
4578 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_OR_ViceVersa;
4579 pThis->iRegOp = 0;
4580 pThis->iRmOp = 1;
4581 pThis->aOperands[0].cbOp = 16;
4582 pThis->aOperands[1].cbOp = 16;
4583 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4584 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4585 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4586 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4587 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4588 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4589 break;
4590
4591 case BS3CG1ENC_VEX_MODRM_Ed_WO_Vd_WZ:
4592 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_Vd_WO_Ed_WZ;
4593 pThis->iRmOp = 0;
4594 pThis->iRegOp = 1;
4595 pThis->aOperands[0].cbOp = 4;
4596 pThis->aOperands[1].cbOp = 4;
4597 pThis->aOperands[0].idxFieldBase = BS3CG1DST_EAX;
4598 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_DW0_ZX;
4599 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4600 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
4601 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4602 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4603 break;
4604
4605 case BS3CG1ENC_VEX_MODRM_Eq_WO_Vq_WNZ:
4606 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_Vq_WO_Eq_WNZ;
4607 pThis->iRmOp = 0;
4608 pThis->iRegOp = 1;
4609 pThis->aOperands[0].cbOp = 8;
4610 pThis->aOperands[1].cbOp = 8;
4611 pThis->aOperands[0].idxFieldBase = BS3CG1DST_RAX;
4612 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
4613 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4614 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
4615 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4616 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4617 break;
4618
4619 case BS3CG1ENC_VEX_MODRM_Md_WO:
4620 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_Md_WO;
4621 pThis->iRmOp = 0;
4622 pThis->aOperands[0].cbOp = 4;
4623 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4624 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4625 break;
4626
4627 case BS3CG1ENC_VEX_MODRM_Md_WO_Vss:
4628 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa;
4629 pThis->iRmOp = 0;
4630 pThis->iRegOp = 1;
4631 pThis->aOperands[0].cbOp = 4;
4632 pThis->aOperands[1].cbOp = 4;
4633 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4634 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4635 pThis->aOperands[0].idxFieldBase = BS3CG1DST_INVALID;
4636 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_DW0;
4637 break;
4638
4639 case BS3CG1ENC_VEX_MODRM_Mq_WO_Vq:
4640 BS3_ASSERT(pThis->fFlags & (BS3CG1INSTR_F_VEX_L_ZERO | BS3CG1INSTR_F_VEX_L_IGNORED));
4641 pThis->pfnEncoder = pThis->fFlags & BS3CG1INSTR_F_VEX_L_ZERO
4642 ? Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lmbz_OR_ViceVersa
4643 : Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa;
4644 pThis->iRmOp = 0;
4645 pThis->iRegOp = 1;
4646 pThis->aOperands[0].cbOp = 8;
4647 pThis->aOperands[1].cbOp = 8;
4648 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4649 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4650 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
4651 break;
4652
4653 case BS3CG1ENC_VEX_MODRM_Mq_WO_Vsd:
4654 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa;
4655 pThis->iRmOp = 0;
4656 pThis->iRegOp = 1;
4657 pThis->aOperands[0].cbOp = 8;
4658 pThis->aOperands[1].cbOp = 8;
4659 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4660 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4661 pThis->aOperands[0].idxFieldBase = BS3CG1DST_INVALID;
4662 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
4663 break;
4664
4665 case BS3CG1ENC_VEX_MODRM_Mps_WO_Vps:
4666 case BS3CG1ENC_VEX_MODRM_Mpd_WO_Vpd:
4667 case BS3CG1ENC_VEX_MODRM_Mx_WO_Vx:
4668 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_OR_ViceVersa;
4669 pThis->iRmOp = 0;
4670 pThis->iRegOp = 1;
4671 pThis->aOperands[0].cbOp = 16;
4672 pThis->aOperands[1].cbOp = 16;
4673 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4674 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4675 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4676 break;
4677
4678 case BS3CG1ENC_VEX_MODRM_Uss_WO_HssHi_Vss:
4679 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa;
4680 pThis->iRegOp = 2;
4681 pThis->iRmOp = 0;
4682 pThis->aOperands[0].cbOp = 16;
4683 pThis->aOperands[1].cbOp = 96;
4684 pThis->aOperands[2].cbOp = 4;
4685 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4686 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4687 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4688 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4689 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI96;
4690 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_DW0;
4691 break;
4692
4693 case BS3CG1ENC_VEX_MODRM_Usd_WO_HsdHi_Vsd:
4694 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa;
4695 pThis->iRegOp = 2;
4696 pThis->iRmOp = 0;
4697 pThis->aOperands[0].cbOp = 16;
4698 pThis->aOperands[1].cbOp = 8;
4699 pThis->aOperands[2].cbOp = 8;
4700 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4701 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4702 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4703 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4704 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
4705 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_LO;
4706 break;
4707
4708 case BS3CG1ENC_VEX_MODRM_Wps_WO_Vps:
4709 case BS3CG1ENC_VEX_MODRM_Wpd_WO_Vpd:
4710 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_OR_ViceVersa;
4711 pThis->iRmOp = 0;
4712 pThis->iRegOp = 1;
4713 pThis->aOperands[0].cbOp = 16;
4714 pThis->aOperands[1].cbOp = 16;
4715 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4716 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX_ZX_VLMAX;
4717 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4718 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4719 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4720 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4721 break;
4722
4723 case BS3CG1ENC_VEX_MODRM_Wq_WO_Vq:
4724 BS3_ASSERT(pThis->fFlags & BS3CG1INSTR_F_VEX_L_ZERO);
4725 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_Lmbz_OR_ViceVersa;
4726 pThis->iRegOp = 1;
4727 pThis->iRmOp = 0;
4728 pThis->aOperands[0].cbOp = 8;
4729 pThis->aOperands[1].cbOp = 8;
4730 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4731 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX_ZX_VLMAX;
4732 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4733 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4734 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
4735 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
4736 break;
4737
4738 case BS3CG1ENC_VEX_MODRM_Wx_WO_Vx:
4739 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_OR_ViceVersa;
4740 pThis->iRmOp = 0;
4741 pThis->iRegOp = 1;
4742 pThis->aOperands[0].cbOp = 16;
4743 pThis->aOperands[1].cbOp = 16;
4744 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4745 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX_ZX_VLMAX;
4746 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4747 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4748 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4749 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4750 break;
4751
4752
4753 /* Unused or invalid instructions mostly. */
4754 //case BS3CG1ENC_VEX_FIXED:
4755 // pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_FIXED;
4756 // break;
4757 case BS3CG1ENC_VEX_MODRM_MOD_EQ_3:
4758 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_MOD_EQ_3;
4759 break;
4760 case BS3CG1ENC_VEX_MODRM_MOD_NE_3:
4761 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_MOD_NE_3;
4762 break;
4763 case BS3CG1ENC_VEX_MODRM:
4764 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM;
4765 break;
4766
4767#endif /* BS3CG1_WITH_VEX */
4768
4769 default:
4770 Bs3TestFailedF("Invalid/unimplemented enmEncoding for instruction #%RU32 (%.*s): %d",
4771 pThis->iInstr, pThis->cchMnemonic, pThis->pchMnemonic, pThis->enmEncoding);
4772 return false;
4773 }
4774 return true;
4775}
4776
4777
4778/**
4779 * Calculates the appropriate non-intel invalid instruction encoding.
4780 *
4781 * @returns the encoding to use instead.
4782 * @param enmEncoding The intel invalid instruction encoding.
4783 */
4784static BS3CG1ENC Bs3Cg1CalcNoneIntelInvalidEncoding(BS3CG1ENC enmEncoding)
4785{
4786 switch (enmEncoding)
4787 {
4788 case BS3CG1ENC_MODRM_Gb_Eb:
4789 case BS3CG1ENC_MODRM_Gv_RO_Ma:
4790 case BS3CG1ENC_FIXED:
4791 return BS3CG1ENC_FIXED;
4792 default:
4793 Bs3TestFailedF("Bs3Cg1CalcNoneIntelInvalidEncoding: Unsupported encoding: %d\n", enmEncoding);
4794 return BS3CG1ENC_FIXED;
4795 }
4796}
4797
4798
4799/**
4800 * Sets up SSE and maybe AVX.
4801 *
4802 * @returns true (if successful, false if not and the SSE instructions ends up
4803 * being invalid).
4804 * @param pThis The state.
4805 */
4806static bool BS3_NEAR_CODE Bs3Cg3SetupSseAndAvx(PBS3CG1STATE pThis)
4807{
4808 if (!pThis->fWorkExtCtx)
4809 {
4810 unsigned i;
4811 uint32_t cr0 = ASMGetCR0();
4812 uint32_t cr4 = ASMGetCR4();
4813
4814 cr0 &= ~(X86_CR0_TS | X86_CR0_MP | X86_CR0_EM);
4815 cr0 |= X86_CR0_NE;
4816 ASMSetCR0(cr0);
4817 if (pThis->pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE)
4818 {
4819 cr4 |= X86_CR4_OSFXSR | X86_CR4_OSXMMEEXCPT | X86_CR4_OSXSAVE;
4820 ASMSetCR4(cr4);
4821 ASMSetXcr0(pThis->pExtCtx->fXcr0Nominal);
4822 }
4823 else
4824 {
4825 cr4 |= X86_CR4_OSFXSR | X86_CR4_OSXMMEEXCPT;
4826 ASMSetCR4(cr4);
4827 }
4828
4829 for (i = 0; i < RT_ELEMENTS(pThis->aInitialCtxs); i++)
4830 {
4831 pThis->aInitialCtxs[i].cr0.u32 = cr0;
4832 pThis->aInitialCtxs[i].cr4.u32 = cr4;
4833 }
4834 pThis->fWorkExtCtx = true;
4835 }
4836
4837 return true;
4838}
4839
4840
4841/**
4842 * Next CPU configuration to test the current instruction in.
4843 *
4844 * This is for testing FPU, SSE and AVX instructions with the various lazy state
4845 * load and enable bits in different configurations to ensure we're getting the
4846 * right response.
4847 *
4848 * This also cleans up the CPU and test driver state.
4849 *
4850 * @returns true if we're to do another round, false if we're done.
4851 * @param pThis The state.
4852 * @param iCpuSetup The current CPU setup number.
4853 * @param pfInvalidInstr Where to indicate whether the setup causes an
4854 * invalid instruction or not. This is also used as
4855 * input to avoid unnecessary CPUID work.
4856 */
4857static bool BS3_NEAR_CODE Bs3Cg1CpuSetupNext(PBS3CG1STATE pThis, unsigned iCpuSetup, bool BS3_FAR *pfInvalidInstr)
4858{
4859 if ( (pThis->fFlags & BS3CG1INSTR_F_INVALID_64BIT)
4860 && BS3CG1_IS_64BIT_TARGET(pThis))
4861 return false;
4862
4863 switch (pThis->enmCpuTest)
4864 {
4865 case BS3CG1CPU_ANY:
4866 case BS3CG1CPU_GE_80186:
4867 case BS3CG1CPU_GE_80286:
4868 case BS3CG1CPU_GE_80386:
4869 case BS3CG1CPU_GE_80486:
4870 case BS3CG1CPU_GE_Pentium:
4871 case BS3CG1CPU_CLFSH:
4872 case BS3CG1CPU_CLFLUSHOPT:
4873 return false;
4874
4875 case BS3CG1CPU_MMX:
4876 return false;
4877
4878 case BS3CG1CPU_SSE:
4879 case BS3CG1CPU_SSE2:
4880 case BS3CG1CPU_SSE3:
4881 case BS3CG1CPU_SSE4_1:
4882 case BS3CG1CPU_AVX:
4883 case BS3CG1CPU_AVX2:
4884 if (iCpuSetup > 0 || *pfInvalidInstr)
4885 {
4886 /** @todo do more configs here. */
4887 pThis->fWorkExtCtx = false;
4888 ASMSetCR0(ASMGetCR0() | X86_CR0_EM | X86_CR0_MP);
4889 ASMSetCR4(ASMGetCR4() & ~(X86_CR4_OSFXSR | X86_CR4_OSXMMEEXCPT | X86_CR4_OSXSAVE));
4890 return false;
4891 }
4892 return false;
4893
4894 default:
4895 Bs3TestFailedF("Invalid enmCpuTest value: %d", pThis->enmCpuTest);
4896 return false;
4897 }
4898}
4899
4900
4901/**
4902 * Check if the instruction is supported by the CPU, possibly making state
4903 * adjustments to enable support for it.
4904 *
4905 * @returns true if supported, false if not.
4906 * @param pThis The state.
4907 */
4908static bool BS3_NEAR_CODE Bs3Cg1CpuSetupFirst(PBS3CG1STATE pThis)
4909{
4910 uint32_t fEax;
4911 uint32_t fEbx;
4912 uint32_t fEcx;
4913 uint32_t fEdx;
4914
4915 if ( (pThis->fFlags & BS3CG1INSTR_F_INVALID_64BIT)
4916 && BS3CG1_IS_64BIT_TARGET(pThis))
4917 return false;
4918
4919 switch (pThis->enmCpuTest)
4920 {
4921 case BS3CG1CPU_ANY:
4922 return true;
4923
4924 case BS3CG1CPU_GE_80186:
4925 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80186)
4926 return true;
4927 return false;
4928
4929 case BS3CG1CPU_GE_80286:
4930 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80286)
4931 return true;
4932 return false;
4933
4934 case BS3CG1CPU_GE_80386:
4935 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
4936 return true;
4937 return false;
4938
4939 case BS3CG1CPU_GE_80486:
4940 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486)
4941 return true;
4942 return false;
4943
4944 case BS3CG1CPU_GE_Pentium:
4945 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_Pentium)
4946 return true;
4947 return false;
4948
4949 case BS3CG1CPU_MMX:
4950 if (g_uBs3CpuDetected & BS3CPU_F_CPUID)
4951 {
4952 ASMCpuIdExSlow(1, 0, 0, 0, NULL, NULL, NULL, &fEdx);
4953 if (fEdx & X86_CPUID_FEATURE_EDX_MMX)
4954 return Bs3Cg3SetupSseAndAvx(pThis); /** @todo only do FNSAVE/FXSAVE here? */
4955 }
4956 return false;
4957
4958 case BS3CG1CPU_SSE:
4959 case BS3CG1CPU_SSE2:
4960 case BS3CG1CPU_SSE3:
4961 case BS3CG1CPU_SSE4_1:
4962 case BS3CG1CPU_AVX:
4963 if (g_uBs3CpuDetected & BS3CPU_F_CPUID)
4964 {
4965 ASMCpuIdExSlow(1, 0, 0, 0, NULL, NULL, &fEcx, &fEdx);
4966 switch (pThis->enmCpuTest)
4967 {
4968 case BS3CG1CPU_SSE:
4969 if (fEdx & X86_CPUID_FEATURE_EDX_SSE)
4970 return Bs3Cg3SetupSseAndAvx(pThis);
4971 return false;
4972 case BS3CG1CPU_SSE2:
4973 if (fEdx & X86_CPUID_FEATURE_EDX_SSE2)
4974 return Bs3Cg3SetupSseAndAvx(pThis);
4975 return false;
4976 case BS3CG1CPU_SSE3:
4977 if (fEcx & X86_CPUID_FEATURE_ECX_SSE3)
4978 return Bs3Cg3SetupSseAndAvx(pThis);
4979 return false;
4980 case BS3CG1CPU_SSE4_1:
4981 if (fEcx & X86_CPUID_FEATURE_ECX_SSE4_1)
4982 return Bs3Cg3SetupSseAndAvx(pThis);
4983 return false;
4984 case BS3CG1CPU_AVX:
4985 if (fEcx & X86_CPUID_FEATURE_ECX_AVX)
4986 return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode);
4987 return false;
4988 default: BS3_ASSERT(0); /* impossible */
4989 }
4990 }
4991 return false;
4992
4993 case BS3CG1CPU_AVX2:
4994 if (g_uBs3CpuDetected & BS3CPU_F_CPUID)
4995 {
4996 ASMCpuIdExSlow(7, 0, 0/*leaf*/, 0, &fEax, &fEbx, &fEcx, &fEdx);
4997 switch (pThis->enmCpuTest)
4998 {
4999 case BS3CG1CPU_AVX2:
5000 if (fEbx & X86_CPUID_STEXT_FEATURE_EBX_AVX2)
5001 return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode);
5002 return false;
5003 default: BS3_ASSERT(0); return false; /* impossible */
5004 }
5005 }
5006 return false;
5007
5008 case BS3CG1CPU_CLFSH:
5009 if (g_uBs3CpuDetected & BS3CPU_F_CPUID)
5010 {
5011 ASMCpuIdExSlow(1, 0, 0, 0, NULL, NULL, NULL, &fEdx);
5012 if (fEdx & X86_CPUID_FEATURE_EDX_CLFSH)
5013 return true;
5014 }
5015 return false;
5016
5017 case BS3CG1CPU_CLFLUSHOPT:
5018 if (g_uBs3CpuDetected & BS3CPU_F_CPUID)
5019 {
5020 ASMCpuIdExSlow(7, 0, 0/*leaf*/, 0, NULL, &fEbx, NULL, NULL);
5021 if (fEbx & X86_CPUID_STEXT_FEATURE_EBX_CLFLUSHOPT)
5022 return true;
5023 }
5024 return false;
5025
5026 default:
5027 Bs3TestFailedF("Invalid enmCpuTest value: %d", pThis->enmCpuTest);
5028 return false;
5029 }
5030}
5031
5032
5033
5034/**
5035 * Checks the preconditions for a test.
5036 *
5037 * @returns true if the test be executed, false if not.
5038 * @param pThis The state.
5039 * @param pHdr The test header.
5040 */
5041static bool BS3_NEAR_CODE Bs3Cg1RunSelector(PBS3CG1STATE pThis, PCBS3CG1TESTHDR pHdr)
5042{
5043
5044 uint8_t const BS3_FAR *pbCode = (uint8_t const BS3_FAR *)(pHdr + 1);
5045 unsigned cbLeft = pHdr->cbSelector;
5046 while (cbLeft-- > 0)
5047 {
5048 switch (*pbCode++)
5049 {
5050#define CASE_PRED(a_Pred, a_Expr) \
5051 case ((a_Pred) << BS3CG1SEL_OP_KIND_MASK) | BS3CG1SEL_OP_IS_TRUE: \
5052 if (!(a_Expr)) return false; \
5053 break; \
5054 case ((a_Pred) << BS3CG1SEL_OP_KIND_MASK) | BS3CG1SEL_OP_IS_FALSE: \
5055 if (a_Expr) return false; \
5056 break
5057 CASE_PRED(BS3CG1PRED_SIZE_O16, pThis->cbOperand == 2);
5058 CASE_PRED(BS3CG1PRED_SIZE_O32, pThis->cbOperand == 4);
5059 CASE_PRED(BS3CG1PRED_SIZE_O64, pThis->cbOperand == 8);
5060 CASE_PRED(BS3CG1PRED_VEXL_0, pThis->uVexL == 0);
5061 CASE_PRED(BS3CG1PRED_VEXL_1, pThis->uVexL == 1);
5062 CASE_PRED(BS3CG1PRED_RING_0, pThis->uCpl == 0);
5063 CASE_PRED(BS3CG1PRED_RING_1, pThis->uCpl == 1);
5064 CASE_PRED(BS3CG1PRED_RING_2, pThis->uCpl == 2);
5065 CASE_PRED(BS3CG1PRED_RING_3, pThis->uCpl == 3);
5066 CASE_PRED(BS3CG1PRED_RING_0_THRU_2, pThis->uCpl <= 2);
5067 CASE_PRED(BS3CG1PRED_RING_1_THRU_3, pThis->uCpl >= 1);
5068 CASE_PRED(BS3CG1PRED_CODE_64BIT, BS3CG1_IS_64BIT_TARGET(pThis));
5069 CASE_PRED(BS3CG1PRED_CODE_32BIT, BS3_MODE_IS_32BIT_CODE(pThis->bMode));
5070 CASE_PRED(BS3CG1PRED_CODE_16BIT, BS3_MODE_IS_16BIT_CODE(pThis->bMode));
5071 CASE_PRED(BS3CG1PRED_MODE_REAL, BS3_MODE_IS_RM_SYS(pThis->bMode));
5072 CASE_PRED(BS3CG1PRED_MODE_PROT, BS3_MODE_IS_PM_SYS(pThis->bMode));
5073 CASE_PRED(BS3CG1PRED_MODE_LONG, BS3_MODE_IS_64BIT_SYS(pThis->bMode));
5074 CASE_PRED(BS3CG1PRED_MODE_SMM, false);
5075 CASE_PRED(BS3CG1PRED_MODE_VMX, false);
5076 CASE_PRED(BS3CG1PRED_MODE_SVM, false);
5077 CASE_PRED(BS3CG1PRED_PAGING_ON, BS3_MODE_IS_PAGED(pThis->bMode));
5078 CASE_PRED(BS3CG1PRED_PAGING_OFF, !BS3_MODE_IS_PAGED(pThis->bMode));
5079 CASE_PRED(BS3CG1PRED_VENDOR_AMD, pThis->bCpuVendor == BS3CPUVENDOR_AMD);
5080 CASE_PRED(BS3CG1PRED_VENDOR_INTEL, pThis->bCpuVendor == BS3CPUVENDOR_INTEL);
5081 CASE_PRED(BS3CG1PRED_VENDOR_VIA, pThis->bCpuVendor == BS3CPUVENDOR_VIA);
5082
5083#undef CASE_PRED
5084 default:
5085 return Bs3TestFailedF("Invalid selector opcode %#x!", pbCode[-1]);
5086 }
5087 }
5088
5089 return true;
5090}
5091
5092
5093#ifdef BS3CG1_DEBUG_CTX_MOD
5094/**
5095 * Translates the operator into a string.
5096 *
5097 * @returns Read-only string pointer.
5098 * @param bOpcode The context modifier program opcode.
5099 */
5100static const char BS3_FAR * BS3_NEAR_CODE Bs3Cg1CtxOpToString(uint8_t bOpcode)
5101{
5102 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5103 {
5104 case BS3CG1_CTXOP_ASSIGN: return "=";
5105 case BS3CG1_CTXOP_OR: return "|=";
5106 case BS3CG1_CTXOP_AND: return "&=";
5107 case BS3CG1_CTXOP_AND_INV: return "&~=";
5108 default: return "?WTF?";
5109 }
5110}
5111#endif
5112
5113
5114/**
5115 * Runs a context modifier program.
5116 *
5117 * @returns Success indicator (true/false).
5118 * @param pThis The state.
5119 * @param pCtx The context.
5120 * @param pHdr The program header.
5121 * @param off The program offset relative to the end of the header.
5122 * @param cb The program size.
5123 * @param pEflCtx The context to take undefined EFLAGS from. (This is NULL
5124 * if we're processing a input context modifier program.)
5125 * @param pbInstr Points to the first instruction byte. For storing
5126 * immediate operands during input context modification.
5127 * NULL for output contexts.
5128 */
5129static bool BS3_NEAR_CODE Bs3Cg1RunContextModifier(PBS3CG1STATE pThis, PBS3REGCTX pCtx, PCBS3CG1TESTHDR pHdr,
5130 unsigned off, unsigned cb,
5131 PCBS3REGCTX pEflCtx, uint8_t BS3_FAR *pbInstr)
5132{
5133 uint8_t const BS3_FAR *pbCode = (uint8_t const BS3_FAR *)(pHdr + 1) + off;
5134 int cbLeft = cb;
5135 while (cbLeft-- > 0)
5136 {
5137 /*
5138 * Decode the instruction.
5139 */
5140 uint8_t const bOpcode = *pbCode++;
5141 unsigned cbValue;
5142 unsigned cbDst;
5143 BS3CG1DST idxField;
5144 BS3PTRUNION PtrField;
5145 uint8_t BS3_FAR *pbMemCopy = NULL;
5146 bool fZxVlMax;
5147
5148 /* Expand the destiation field (can be escaped). Set fZxVlMax. */
5149 switch (bOpcode & BS3CG1_CTXOP_DST_MASK)
5150 {
5151 case BS3CG1_CTXOP_OP1:
5152 idxField = pThis->aOperands[0].idxField;
5153 if (idxField == BS3CG1DST_INVALID)
5154 idxField = BS3CG1DST_OP1;
5155 fZxVlMax = pEflCtx != NULL && pThis->aOperands[0].enmLocation == BS3CG1OPLOC_CTX_ZX_VLMAX;
5156 break;
5157
5158 case BS3CG1_CTXOP_OP2:
5159 idxField = pThis->aOperands[1].idxField;
5160 if (idxField == BS3CG1DST_INVALID)
5161 idxField = BS3CG1DST_OP2;
5162 fZxVlMax = pEflCtx != NULL && pThis->aOperands[1].enmLocation == BS3CG1OPLOC_CTX_ZX_VLMAX;
5163 break;
5164
5165 case BS3CG1_CTXOP_EFL:
5166 idxField = BS3CG1DST_EFL;
5167 fZxVlMax = false;
5168 break;
5169
5170 case BS3CG1_CTXOP_DST_ESC:
5171 if (cbLeft-- > 0)
5172 {
5173 idxField = (BS3CG1DST)*pbCode++;
5174 if (idxField <= BS3CG1DST_OP4)
5175 {
5176 if (idxField > BS3CG1DST_INVALID)
5177 {
5178 unsigned idxOp = idxField - BS3CG1DST_OP1;
5179 uint8_t idxField2 = pThis->aOperands[idxOp].idxField;
5180 if (idxField2 != BS3CG1DST_INVALID)
5181 idxField = idxField2;
5182 fZxVlMax = pEflCtx != NULL && pThis->aOperands[idxOp].enmLocation == BS3CG1OPLOC_CTX_ZX_VLMAX;
5183 break;
5184 }
5185 }
5186 else if (idxField < BS3CG1DST_END)
5187 {
5188 fZxVlMax = false;
5189 break;
5190 }
5191 return Bs3TestFailedF("Malformed context instruction: idxField=%d", idxField);
5192 }
5193 /* fall thru */
5194 default:
5195 return Bs3TestFailed("Malformed context instruction: Destination");
5196 }
5197
5198 /* Expand value size (can be escaped). */
5199 switch (bOpcode & BS3CG1_CTXOP_SIZE_MASK)
5200 {
5201 case BS3CG1_CTXOP_1_BYTE: cbValue = 1; break;
5202 case BS3CG1_CTXOP_2_BYTES: cbValue = 2; break;
5203 case BS3CG1_CTXOP_4_BYTES: cbValue = 4; break;
5204 case BS3CG1_CTXOP_8_BYTES: cbValue = 8; break;
5205 case BS3CG1_CTXOP_16_BYTES: cbValue = 16; break;
5206 case BS3CG1_CTXOP_32_BYTES: cbValue = 32; break;
5207 case BS3CG1_CTXOP_12_BYTES: cbValue = 12; break;
5208 case BS3CG1_CTXOP_SIZE_ESC:
5209 if (cbLeft-- > 0)
5210 {
5211 cbValue = *pbCode++;
5212 if (cbValue)
5213 break;
5214 }
5215 /* fall thru */
5216 default:
5217 return Bs3TestFailed("Malformed context instruction: size");
5218 }
5219
5220 /* Make sure there is enough instruction bytes for the value. */
5221 if (cbValue <= cbLeft)
5222 { /* likely */ }
5223 else
5224 return Bs3TestFailedF("Malformed context instruction: %u bytes value, %u bytes left", cbValue, cbLeft);
5225
5226 /*
5227 * Do value processing specific to the target field size.
5228 */
5229 cbDst = g_acbBs3Cg1DstFields[idxField];
5230 if (cbDst == BS3CG1DSTSIZE_OPERAND)
5231 cbDst = pThis->aOperands[idxField - BS3CG1DST_OP1].cbOp;
5232 else if (cbDst == BS3CG1DSTSIZE_OPERAND_SIZE_GRP)
5233 cbDst = pThis->cbOperand;
5234 if (cbDst <= 8)
5235 {
5236 unsigned const offField = g_aoffBs3Cg1DstFields[idxField];
5237
5238 /*
5239 * Deal with fields up to 8-byte wide.
5240 */
5241
5242 /* Get the value. */
5243 uint64_t uValue;
5244 if ((bOpcode & BS3CG1_CTXOP_SIGN_EXT))
5245 switch (cbValue)
5246 {
5247 case 1: uValue = *(int8_t const BS3_FAR *)pbCode; break;
5248 case 2: uValue = *(int16_t const BS3_FAR *)pbCode; break;
5249 case 4: uValue = *(int32_t const BS3_FAR *)pbCode; break;
5250 default:
5251 if (cbValue >= 8)
5252 {
5253 uValue = *(uint64_t const BS3_FAR *)pbCode;
5254 break;
5255 }
5256 return Bs3TestFailedF("Malformed context instruction: %u bytes value (%u dst)", cbValue, cbDst);
5257 }
5258 else
5259 switch (cbValue)
5260 {
5261 case 1: uValue = *(uint8_t const BS3_FAR *)pbCode; break;
5262 case 2: uValue = *(uint16_t const BS3_FAR *)pbCode; break;
5263 case 4: uValue = *(uint32_t const BS3_FAR *)pbCode; break;
5264 default:
5265 if (cbValue >= 8)
5266 {
5267 uValue = *(uint64_t const BS3_FAR *)pbCode;
5268 break;
5269 }
5270 return Bs3TestFailedF("Malformed context instruction: %u bytes value (%u dst)", cbValue, cbDst);
5271 }
5272
5273 /* Find the field. */
5274 if (offField < sizeof(BS3REGCTX))
5275 PtrField.pu8 = (uint8_t BS3_FAR *)pCtx + offField;
5276 /* Non-register operands: */
5277 else if ((unsigned)(idxField - BS3CG1DST_OP1) < 4U)
5278 {
5279 unsigned const idxOp = idxField - BS3CG1DST_OP1;
5280
5281 switch (pThis->aOperands[idxOp].enmLocation)
5282 {
5283 case BS3CG1OPLOC_IMM:
5284 if (pbInstr)
5285 PtrField.pu8 = &pbInstr[pThis->aOperands[idxOp].off];
5286 else
5287 return Bs3TestFailedF("Immediate operand referenced in output context!");
5288 break;
5289
5290 case BS3CG1OPLOC_MEM:
5291 if (!pbInstr)
5292 return Bs3TestFailedF("Read only operand specified in output!");
5293 PtrField.pu8 = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[idxOp].off];
5294 break;
5295
5296 case BS3CG1OPLOC_MEM_RW:
5297 case BS3CG1OPLOC_MEM_WO:
5298 if (pbInstr)
5299 {
5300 PtrField.pu8 = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[idxOp].off];
5301 pbMemCopy = pThis->MemOp.ab;
5302 }
5303 else
5304 PtrField.pu8 = pThis->MemOp.ab;
5305 break;
5306
5307 default:
5308 if (pThis->enmEncoding != pThis->enmEncodingNonInvalid)
5309 goto l_advance_to_next;
5310 return Bs3TestFailedF("Internal error: cbDst=%u idxField=%d (%d) offField=%#x: enmLocation=%u off=%#x idxField=%u",
5311 cbDst, idxField, idxOp, offField, pThis->aOperands[idxOp].enmLocation,
5312 pThis->aOperands[idxOp].off, pThis->aOperands[idxOp].idxField);
5313 }
5314 }
5315 /* Special field: Copying in undefined EFLAGS from the result context. */
5316 else if (idxField == BS3CG1DST_EFL_UNDEF)
5317 {
5318 if (!pEflCtx || (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK) != BS3CG1_CTXOP_ASSIGN)
5319 return Bs3TestFailed("Invalid BS3CG1DST_EFL_UNDEF usage");
5320 PtrField.pu32 = &pCtx->rflags.u32;
5321 uValue = (*PtrField.pu32 & ~(uint32_t)uValue) | (pEflCtx->rflags.u32 & (uint32_t)uValue);
5322 }
5323 /* Special field: Expected value (in/result) exception. */
5324 else if (idxField == BS3CG1DST_VALUE_XCPT)
5325 {
5326 if (!pEflCtx || (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK) != BS3CG1_CTXOP_ASSIGN || cbDst != 1)
5327 return Bs3TestFailed("Invalid BS3CG1DST_VALUE_XCPT usage");
5328 PtrField.pu8 = &pThis->bValueXcpt;
5329 }
5330 /* FPU and FXSAVE format. */
5331 else if ( pThis->pExtCtx->enmMethod != BS3EXTCTXMETHOD_ANCIENT
5332 && offField - sizeof(BS3REGCTX) < RT_UOFFSET_AFTER(BS3EXTCTX, Ctx.x87.aXMM[15]))
5333 {
5334 if (pThis->fWorkExtCtx)
5335 PtrField.pb = (uint8_t *)pThis->pExtCtx + offField - sizeof(BS3REGCTX);
5336 else if (!pThis->fCpuSetupFirstResult)
5337 {
5338 BS3CG1_DPRINTF(("dbg: Extended context disabled: skipping modification (<=8)\n"));
5339 goto l_advance_to_next;
5340 }
5341 else
5342 return Bs3TestFailedF("Extended context disabled: Field %d (%s) @ %#x LB %u\n",
5343 idxField, g_aszBs3Cg1DstFields[idxField].sz, offField, cbDst);
5344 }
5345 /** @todo other FPU fields and FPU state formats. */
5346 else
5347 return Bs3TestFailedF("Todo implement me: cbDst=%u idxField=%d %s offField=%#x (<= 8)",
5348 cbDst, idxField, g_aszBs3Cg1DstFields[idxField].sz, offField);
5349
5350#ifdef BS3CG1_DEBUG_CTX_MOD
5351 switch (cbDst)
5352 {
5353 case 1:
5354 BS3CG1_DPRINTF(("dbg: modify %s: %#04RX8 (LB %u) %s %#RX64 (LB %u)\n", g_aszBs3Cg1DstFields[idxField].sz,
5355 *PtrField.pu8, cbDst, Bs3Cg1CtxOpToString(bOpcode), uValue, cbValue));
5356 break;
5357 case 2:
5358 BS3CG1_DPRINTF(("dbg: modify %s: %#06RX16 (LB %u) %s %#RX64 (LB %u)\n", g_aszBs3Cg1DstFields[idxField].sz,
5359 *PtrField.pu16, cbDst, Bs3Cg1CtxOpToString(bOpcode), uValue, cbValue));
5360 break;
5361 case 4:
5362 BS3CG1_DPRINTF(("dbg: modify %s: %#010RX32 (LB %u) %s %#RX64 (LB %u)\n", g_aszBs3Cg1DstFields[idxField].sz,
5363 *PtrField.pu32, cbDst, Bs3Cg1CtxOpToString(bOpcode), uValue, cbValue));
5364 break;
5365 default:
5366 BS3CG1_DPRINTF(("dbg: modify %s: %#018RX64 (LB %u) %s %#RX64 (LB %u)\n", g_aszBs3Cg1DstFields[idxField].sz,
5367 *PtrField.pu64, cbDst, Bs3Cg1CtxOpToString(bOpcode), uValue, cbValue));
5368 break;
5369 }
5370#endif
5371
5372 /* Modify the field. */
5373 switch (cbDst)
5374 {
5375 case 1:
5376 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5377 {
5378 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu8 = (uint8_t)uValue; break;
5379 case BS3CG1_CTXOP_OR: *PtrField.pu8 |= (uint8_t)uValue; break;
5380 case BS3CG1_CTXOP_AND: *PtrField.pu8 &= (uint8_t)uValue; break;
5381 case BS3CG1_CTXOP_AND_INV: *PtrField.pu8 &= ~(uint8_t)uValue; break;
5382 }
5383 break;
5384
5385 case 2:
5386 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5387 {
5388 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu16 = (uint16_t)uValue; break;
5389 case BS3CG1_CTXOP_OR: *PtrField.pu16 |= (uint16_t)uValue; break;
5390 case BS3CG1_CTXOP_AND: *PtrField.pu16 &= (uint16_t)uValue; break;
5391 case BS3CG1_CTXOP_AND_INV: *PtrField.pu16 &= ~(uint16_t)uValue; break;
5392 }
5393 break;
5394
5395 case 4:
5396 if ( (unsigned)(idxField - BS3CG1DST_XMM0_DW0_ZX) <= (unsigned)(BS3CG1DST_XMM15_DW0_ZX - BS3CG1DST_XMM0_DW0_ZX)
5397 || fZxVlMax)
5398 {
5399 PtrField.pu32[1] = 0;
5400 PtrField.pu64[1] = 0;
5401 }
5402 else if (offField <= RT_OFFSETOF(BS3REGCTX, r15) /* Clear the top dword. */)
5403 PtrField.pu32[1] = 0;
5404 else if ((unsigned)(idxField - BS3CG1DST_MM0_LO_ZX) <= (unsigned)(BS3CG1DST_MM7_LO_ZX - BS3CG1DST_MM0_LO_ZX))
5405 {
5406 PtrField.pu32[1] = 0;
5407 PtrField.pu32[2] = 0xffff; /* observed on skylake */
5408 }
5409 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5410 {
5411 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu32 = (uint32_t)uValue; break;
5412 case BS3CG1_CTXOP_OR: *PtrField.pu32 |= (uint32_t)uValue; break;
5413 case BS3CG1_CTXOP_AND: *PtrField.pu32 &= (uint32_t)uValue; break;
5414 case BS3CG1_CTXOP_AND_INV: *PtrField.pu32 &= ~(uint32_t)uValue; break;
5415 }
5416 break;
5417
5418 case 8:
5419 if ( (unsigned)(idxField - BS3CG1DST_XMM0_LO_ZX) <= (unsigned)(BS3CG1DST_XMM15_LO_ZX - BS3CG1DST_XMM0_LO_ZX)
5420 || fZxVlMax)
5421 PtrField.pu64[1] = 0;
5422 else if ((unsigned)(idxField - BS3CG1DST_MM0) <= (unsigned)(BS3CG1DST_MM7 - BS3CG1DST_MM0))
5423 PtrField.pu32[2] = 0xffff; /* observed on skylake */
5424
5425 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5426 {
5427 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu64 = (uint64_t)uValue; break;
5428 case BS3CG1_CTXOP_OR: *PtrField.pu64 |= (uint64_t)uValue; break;
5429 case BS3CG1_CTXOP_AND: *PtrField.pu64 &= (uint64_t)uValue; break;
5430 case BS3CG1_CTXOP_AND_INV: *PtrField.pu64 &= ~(uint64_t)uValue; break;
5431 }
5432 break;
5433
5434 default:
5435 return Bs3TestFailedF("Malformed context instruction: cbDst=%u, expected 1, 2, 4, or 8", cbDst);
5436 }
5437
5438#ifdef BS3CG1_DEBUG_CTX_MOD
5439 switch (cbDst)
5440 {
5441 case 1: BS3CG1_DPRINTF(("dbg: --> %s: %#04RX8\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu8)); break;
5442 case 2: BS3CG1_DPRINTF(("dbg: --> %s: %#06RX16\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu16)); break;
5443 case 4: BS3CG1_DPRINTF(("dbg: --> %s: %#010RX32\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu32)); break;
5444 default: BS3CG1_DPRINTF(("dbg: --> %s: %#018RX64\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu64)); break;
5445 }
5446#endif
5447 if (fZxVlMax)
5448 {
5449 uintptr_t iReg = ((uintptr_t)PtrField.pu8 - (uintptr_t)&pThis->pExtCtx->Ctx.x87.aXMM[0])
5450 / sizeof(pThis->pExtCtx->Ctx.x87.aXMM[0]);
5451 pThis->pExtCtx->Ctx.x.u.YmmHi.aYmmHi[iReg].au64[0] = 0;
5452 pThis->pExtCtx->Ctx.x.u.YmmHi.aYmmHi[iReg].au64[1] = 0;
5453#ifdef BS3CG1_DEBUG_CTX_MOD
5454 BS3CG1_DPRINTF(("dbg: --> cleared YMM%u_HI\n", iReg));
5455#endif
5456 }
5457 }
5458 /*
5459 * Deal with larger field (FPU, SSE, AVX, ...).
5460 */
5461 else if (pThis->fWorkExtCtx)
5462 {
5463 union
5464 {
5465 X86FPUREG FpuReg;
5466 X86XMMREG XmmReg;
5467 X86YMMREG YmmReg;
5468 X86ZMMREG ZmmReg;
5469 uint8_t ab[sizeof(X86ZMMREG)];
5470 uint32_t au32[sizeof(X86ZMMREG) / sizeof(uint32_t)];
5471 uint64_t au64[sizeof(X86ZMMREG) / sizeof(uint64_t)];
5472 } Value;
5473 unsigned const offField = g_aoffBs3Cg1DstFields[idxField];
5474 unsigned iReg;
5475
5476 /* Copy the value into the union, doing the zero padding / extending. */
5477 Bs3MemCpy(&Value, pbCode, cbValue);
5478 if (cbValue < sizeof(Value))
5479 {
5480 if ((bOpcode & BS3CG1_CTXOP_SIGN_EXT) && (Value.ab[cbValue - 1] & 0x80))
5481 Bs3MemSet(&Value.ab[cbValue], 0xff, sizeof(Value) - cbValue);
5482 else
5483 Bs3MemSet(&Value.ab[cbValue], 0x00, sizeof(Value) - cbValue);
5484 }
5485
5486 /* Optimized access to XMM and STx registers. */
5487 if ( pThis->pExtCtx->enmMethod != BS3EXTCTXMETHOD_ANCIENT
5488 && offField - sizeof(BS3REGCTX) < RT_UOFFSET_AFTER(BS3EXTCTX, Ctx.x87.aXMM[15]) )
5489 PtrField.pb = (uint8_t *)pThis->pExtCtx + offField - sizeof(BS3REGCTX);
5490 /* Non-register operands: */
5491 else if ((unsigned)(idxField - BS3CG1DST_OP1) < 4U)
5492 {
5493 unsigned const idxOp = idxField - BS3CG1DST_OP1;
5494 switch (pThis->aOperands[idxOp].enmLocation)
5495 {
5496 case BS3CG1OPLOC_MEM:
5497 if (!pbInstr)
5498 return Bs3TestFailedF("Read only operand specified in output!");
5499 PtrField.pu8 = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[idxOp].off];
5500 break;
5501
5502 case BS3CG1OPLOC_MEM_RW:
5503 case BS3CG1OPLOC_MEM_WO:
5504 if (pbInstr)
5505 {
5506 PtrField.pu8 = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[idxOp].off];
5507 pbMemCopy = pThis->MemOp.ab;
5508 }
5509 else
5510 PtrField.pu8 = pThis->MemOp.ab;
5511 break;
5512
5513 default:
5514 return Bs3TestFailedF("Internal error: Field %d (%d) @ %#x LB %u: enmLocation=%u off=%#x idxField=%u",
5515 idxField, idxOp, offField, cbDst, pThis->aOperands[idxOp].enmLocation,
5516 pThis->aOperands[idxOp].off, pThis->aOperands[idxOp].idxField);
5517 }
5518 }
5519 /* The YMM (AVX) registers have split storage in the state, so they need special handling. */
5520 else if ((iReg = idxField - BS3CG1DST_YMM0) < 16U)
5521 {
5522 /* The first 128-bits in XMM land. */
5523 PtrField.pu64 = &pThis->pExtCtx->Ctx.x87.aXMM[iReg].au64[0];
5524 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5525 {
5526 case BS3CG1_CTXOP_ASSIGN:
5527 PtrField.pu64[0] = Value.au64[0];
5528 PtrField.pu64[1] = Value.au64[1];
5529 break;
5530 case BS3CG1_CTXOP_OR:
5531 PtrField.pu64[0] |= Value.au64[0];
5532 PtrField.pu64[1] |= Value.au64[1];
5533 break;
5534 case BS3CG1_CTXOP_AND:
5535 PtrField.pu64[0] &= Value.au64[0];
5536 PtrField.pu64[1] &= Value.au64[1];
5537 break;
5538 case BS3CG1_CTXOP_AND_INV:
5539 PtrField.pu64[0] &= ~Value.au64[0];
5540 PtrField.pu64[1] &= ~Value.au64[1];
5541 break;
5542 }
5543
5544 /* The second 128-bit in YMM_HI land. */
5545 PtrField.pu64 = &pThis->pExtCtx->Ctx.x.u.YmmHi.aYmmHi[iReg].au64[0];
5546 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5547 {
5548 case BS3CG1_CTXOP_ASSIGN:
5549 PtrField.pu64[0] = Value.au64[2];
5550 PtrField.pu64[1] = Value.au64[3];
5551 break;
5552 case BS3CG1_CTXOP_OR:
5553 PtrField.pu64[0] |= Value.au64[2];
5554 PtrField.pu64[1] |= Value.au64[3];
5555 break;
5556 case BS3CG1_CTXOP_AND:
5557 PtrField.pu64[0] &= Value.au64[2];
5558 PtrField.pu64[1] &= Value.au64[3];
5559 break;
5560 case BS3CG1_CTXOP_AND_INV:
5561 PtrField.pu64[0] &= ~Value.au64[2];
5562 PtrField.pu64[1] &= ~Value.au64[3];
5563 break;
5564 }
5565 PtrField.pb = NULL;
5566 }
5567 /* AVX512 needs handling like above, but more complicated. */
5568 else
5569 return Bs3TestFailedF("TODO: implement me: cbDst=%d idxField=%d (AVX and other weird state)", cbDst, idxField);
5570
5571 if (PtrField.pb)
5572 {
5573 /* Modify the field / memory. */
5574 unsigned i;
5575 if (cbDst & 3)
5576 return Bs3TestFailedF("Malformed context instruction: cbDst=%u, multiple of 4", cbDst);
5577
5578#ifdef BS3CG1_DEBUG_CTX_MOD
5579 BS3CG1_DPRINTF(("dbg: modify %s: %.*Rhxs (LB %u) %s %.*Rhxs (LB %u)\n", g_aszBs3Cg1DstFields[idxField].sz,
5580 cbDst, PtrField.pb, cbDst, Bs3Cg1CtxOpToString(bOpcode), cbValue, Value.ab, cbValue));
5581#endif
5582
5583 i = cbDst / 4;
5584 while (i-- > 0)
5585 {
5586 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
5587 {
5588 case BS3CG1_CTXOP_ASSIGN: PtrField.pu32[i] = Value.au32[i]; break;
5589 case BS3CG1_CTXOP_OR: PtrField.pu32[i] |= Value.au32[i]; break;
5590 case BS3CG1_CTXOP_AND: PtrField.pu32[i] &= Value.au32[i]; break;
5591 case BS3CG1_CTXOP_AND_INV: PtrField.pu32[i] &= ~Value.au32[i]; break;
5592 }
5593 }
5594
5595#ifdef BS3CG1_DEBUG_CTX_MOD
5596 BS3CG1_DPRINTF(("dbg: --> %s: %.*Rhxs\n", g_aszBs3Cg1DstFields[idxField].sz, cbDst, PtrField.pb));
5597#endif
5598
5599 if (fZxVlMax)
5600 {
5601 uintptr_t iReg = ((uintptr_t)PtrField.pu8 - (uintptr_t)&pThis->pExtCtx->Ctx.x87.aXMM[0])
5602 / sizeof(pThis->pExtCtx->Ctx.x87.aXMM[0]);
5603 if (cbDst < 16)
5604 {
5605 for (i = cbDst / 4; i < 4; i++)
5606 PtrField.pu32[i++] = 0;
5607#ifdef BS3CG1_DEBUG_CTX_MOD
5608 BS3CG1_DPRINTF(("dbg: --> cleared high %u bytes of XMM%u\n", 16 - cbDst, iReg));
5609#endif
5610 }
5611 pThis->pExtCtx->Ctx.x.u.YmmHi.aYmmHi[iReg].au64[0] = 0;
5612 pThis->pExtCtx->Ctx.x.u.YmmHi.aYmmHi[iReg].au64[1] = 0;
5613#ifdef BS3CG1_DEBUG_CTX_MOD
5614 BS3CG1_DPRINTF(("dbg: --> cleared YMM%u_HI\n", iReg));
5615#endif
5616 }
5617 }
5618
5619 /*
5620 * Hack! Update pThis->MemOp when setting up the inputs so we can
5621 * correctly validate value and alignment exceptions.
5622 */
5623 if (pbMemCopy && PtrField.pv)
5624 Bs3MemCpy(pbMemCopy, PtrField.pv, cbDst);
5625 }
5626 /* !pThis->fWorkExtCtx: */
5627 else if (pThis->fCpuSetupFirstResult)
5628 return Bs3TestFailedF("Extended context disabled: Field %d (%s) @ %#x LB %u\n",
5629 idxField, g_aszBs3Cg1DstFields[idxField].sz, g_aoffBs3Cg1DstFields[idxField], cbDst);
5630 else
5631 BS3CG1_DPRINTF(("dbg: Extended context disabled: skipping modification [> 8]\n"));
5632
5633 /*
5634 * Advance to the next instruction.
5635 */
5636l_advance_to_next:
5637 pbCode += cbValue;
5638 cbLeft -= cbValue;
5639 }
5640
5641 return true;
5642}
5643
5644
5645/**
5646 * Checks the result of a run.
5647 *
5648 * @returns true if successful, false if not.
5649 * @param pThis The state.
5650 * @param bTestXcptExpected The exception causing the test code to stop
5651 * executing.
5652 * @param fInvalidEncodingPgFault Set if we've cut the instruction a byte
5653 * short and is expecting a \#PF on the page
5654 * boundrary rather than a \#UD. Only set if
5655 * fInvalidEncoding is also set.
5656 * @param iEncoding For error reporting.
5657 */
5658static bool BS3_NEAR_CODE Bs3Cg1CheckResult(PBS3CG1STATE pThis, uint8_t bTestXcptExpected,
5659 bool fInvalidEncodingPgFault, unsigned iEncoding)
5660{
5661 unsigned iOperand;
5662
5663 /*
5664 * Check the exception state first.
5665 */
5666 uint8_t bExpectedXcpt;
5667 uint8_t cbAdjustPc;
5668 if (!pThis->fInvalidEncoding)
5669 {
5670 bExpectedXcpt = pThis->bAlignmentXcpt;
5671 if (bExpectedXcpt == UINT8_MAX)
5672 bExpectedXcpt = pThis->bValueXcpt;
5673 if (bExpectedXcpt == UINT8_MAX)
5674 {
5675 cbAdjustPc = pThis->cbCurInstr;
5676 bExpectedXcpt = bTestXcptExpected;
5677 if (bTestXcptExpected == X86_XCPT_PF)
5678 pThis->Ctx.cr2.u = pThis->uCodePgFlat + X86_PAGE_SIZE;
5679 }
5680 else
5681 cbAdjustPc = 0;
5682 }
5683 else
5684 {
5685 cbAdjustPc = 0;
5686 if (!fInvalidEncodingPgFault)
5687 bExpectedXcpt = X86_XCPT_UD;
5688 else
5689 {
5690 bExpectedXcpt = X86_XCPT_PF;
5691 pThis->Ctx.cr2.u = pThis->uCodePgFlat + X86_PAGE_SIZE;
5692 }
5693 }
5694 if (RT_LIKELY( pThis->TrapFrame.bXcpt == bExpectedXcpt
5695 && pThis->TrapFrame.Ctx.rip.u == pThis->Ctx.rip.u + cbAdjustPc))
5696 {
5697 /*
5698 * Check the register content.
5699 */
5700 bool fOkay = Bs3TestCheckRegCtxEx(&pThis->TrapFrame.Ctx, &pThis->Ctx,
5701 cbAdjustPc, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/,
5702 pThis->pszMode, iEncoding);
5703
5704 /*
5705 * Check memory output operands.
5706 */
5707 if (!pThis->fInvalidEncoding)
5708 {
5709 iOperand = pThis->cOperands;
5710 while (iOperand-- > 0)
5711 if ( pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW
5712 || pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_WO)
5713 {
5714 if (pThis->aOperands[iOperand].off)
5715 {
5716 BS3PTRUNION PtrUnion;
5717 PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off];
5718 switch (pThis->aOperands[iOperand].cbOp)
5719 {
5720 case 1:
5721 if (*PtrUnion.pu8 == pThis->MemOp.ab[0])
5722 continue;
5723 Bs3TestFailedF("op%u: Wrote %#04RX8, expected %#04RX8",
5724 iOperand, *PtrUnion.pu8, pThis->MemOp.ab[0]);
5725 break;
5726 case 2:
5727 if (*PtrUnion.pu16 == pThis->MemOp.au16[0])
5728 continue;
5729 Bs3TestFailedF("op%u: Wrote %#06RX16, expected %#06RX16",
5730 iOperand, *PtrUnion.pu16, pThis->MemOp.au16[0]);
5731 break;
5732 case 4:
5733 if (*PtrUnion.pu32 == pThis->MemOp.au32[0])
5734 continue;
5735 Bs3TestFailedF("op%u: Wrote %#010RX32, expected %#010RX32",
5736 iOperand, *PtrUnion.pu32, pThis->MemOp.au32[0]);
5737 break;
5738 case 8:
5739 if (*PtrUnion.pu64 == pThis->MemOp.au64[0])
5740 continue;
5741 Bs3TestFailedF("op%u: Wrote %#018RX64, expected %#018RX64",
5742 iOperand, *PtrUnion.pu64, pThis->MemOp.au64[0]);
5743 break;
5744 default:
5745 if (Bs3MemCmp(PtrUnion.pb, pThis->MemOp.ab, pThis->aOperands[iOperand].cbOp) == 0)
5746 continue;
5747 Bs3TestFailedF("op%u: Wrote %.*Rhxs, expected %.*Rhxs",
5748 iOperand,
5749 pThis->aOperands[iOperand].cbOp, PtrUnion.pb,
5750 pThis->aOperands[iOperand].cbOp, pThis->MemOp.ab);
5751 break;
5752 }
5753 }
5754 else
5755 Bs3TestFailedF("op%u: off is zero\n", iOperand);
5756 fOkay = false;
5757 }
5758 }
5759
5760 /*
5761 * Check extended context if enabled.
5762 */
5763 if (pThis->fWorkExtCtx)
5764 {
5765 PBS3EXTCTX pExpect = pThis->pExtCtx;
5766 PBS3EXTCTX pResult = pThis->pResultExtCtx;
5767 unsigned i;
5768 if ( pExpect->enmMethod == BS3EXTCTXMETHOD_XSAVE
5769 || pExpect->enmMethod == BS3EXTCTXMETHOD_FXSAVE)
5770 {
5771 /* Compare the x87 state, ASSUMING XCR0 bit 1 is set. */
5772#define CHECK_FIELD(a_Field, a_szFmt) \
5773 if (pResult->Ctx.a_Field != pExpect->Ctx.a_Field) fOkay = Bs3TestFailedF(a_szFmt, pResult->Ctx.a_Field, pExpect->Ctx.a_Field)
5774 CHECK_FIELD(x87.FCW, "FCW: %#06x, expected %#06x");
5775 CHECK_FIELD(x87.FSW, "FSW: %#06x, expected %#06x");
5776 CHECK_FIELD(x87.FTW, "FTW: %#06x, expected %#06x");
5777 //CHECK_FIELD(x87.FOP, "FOP: %#06x, expected %#06x");
5778 //CHECK_FIELD(x87.FPUIP, "FPUIP: %#010RX32, expected %#010RX32");
5779 //CHECK_FIELD(x87.CS, "FPUCS: %#06x, expected %#06x");
5780 //CHECK_FIELD(x87.Rsrvd1, "Rsrvd1: %#06x, expected %#06x");
5781 //CHECK_FIELD(x87.DP, "FPUDP: %#010RX32, expected %#010RX32");
5782 //CHECK_FIELD(x87.DS, "FPUDS: %#06x, expected %#06x");
5783 //CHECK_FIELD(x87.Rsrvd2, "Rsrvd2: %#06x, expected %#06x");
5784 CHECK_FIELD(x87.MXCSR, "MXCSR: %#010RX32, expected %#010RX32");
5785#undef CHECK_FIELD
5786 for (i = 0; i < RT_ELEMENTS(pExpect->Ctx.x87.aRegs); i++)
5787 if ( pResult->Ctx.x87.aRegs[i].au64[0] != pExpect->Ctx.x87.aRegs[i].au64[0]
5788 || pResult->Ctx.x87.aRegs[i].au16[4] != pExpect->Ctx.x87.aRegs[i].au16[4])
5789 fOkay = Bs3TestFailedF("ST[%u]: %c m=%#RX64 e=%d, expected %c m=%#RX64 e=%d", i,
5790 pResult->Ctx.x87.aRegs[i].r80Ex.s.fSign ? '-' : '+',
5791 pResult->Ctx.x87.aRegs[i].r80Ex.s.u64Mantissa,
5792 pResult->Ctx.x87.aRegs[i].r80Ex.s.uExponent,
5793 pExpect->Ctx.x87.aRegs[i].r80Ex.s.fSign ? '-' : '+',
5794 pExpect->Ctx.x87.aRegs[i].r80Ex.s.u64Mantissa,
5795 pExpect->Ctx.x87.aRegs[i].r80Ex.s.uExponent);
5796 for (i = 0; i < (ARCH_BITS == 64 ? 16 : 8); i++)
5797 if ( pResult->Ctx.x87.aXMM[i].au64[0] != pExpect->Ctx.x87.aXMM[i].au64[0]
5798 || pResult->Ctx.x87.aXMM[i].au64[1] != pExpect->Ctx.x87.aXMM[i].au64[1])
5799 fOkay = Bs3TestFailedF("XMM%u: %#010RX64'%016RX64, expected %#010RX64'%08RX64", i,
5800 pResult->Ctx.x87.aXMM[i].au64[1],
5801 pResult->Ctx.x87.aXMM[i].au64[0],
5802 pExpect->Ctx.x87.aXMM[i].au64[1],
5803 pExpect->Ctx.x87.aXMM[i].au64[0]);
5804 if (pExpect->fXcr0Saved & XSAVE_C_YMM)
5805 for (i = 0; i < (ARCH_BITS == 64 ? 16 : 8); i++)
5806 if ( pResult->Ctx.x.u.YmmHi.aYmmHi[i].au64[0] != pExpect->Ctx.x.u.YmmHi.aYmmHi[i].au64[0]
5807 || pResult->Ctx.x.u.YmmHi.aYmmHi[i].au64[1] != pExpect->Ctx.x.u.YmmHi.aYmmHi[i].au64[1])
5808 fOkay = Bs3TestFailedF("YMM%u_HI: %#010RX64'%016RX64, expected %#010RX64'%08RX64", i,
5809 pResult->Ctx.x.u.YmmHi.aYmmHi[i].au64[1],
5810 pResult->Ctx.x.u.YmmHi.aYmmHi[i].au64[0],
5811 pExpect->Ctx.x.u.YmmHi.aYmmHi[i].au64[1],
5812 pExpect->Ctx.x.u.YmmHi.aYmmHi[i].au64[0]);
5813 }
5814 else
5815 fOkay = Bs3TestFailedF("Unsupported extended CPU context method: %d", pExpect->enmMethod);
5816 }
5817
5818 /*
5819 * Done.
5820 */
5821 if (fOkay)
5822 return true;
5823
5824 /*
5825 * Report failure.
5826 */
5827 Bs3TestFailedF("ins#%RU32/test#%u: encoding #%u: %.*Rhxs%s",
5828 pThis->iInstr, pThis->iTest, iEncoding, pThis->cbCurInstr, pThis->abCurInstr,
5829 fInvalidEncodingPgFault ? " (cut short)" : "");
5830 }
5831 else
5832 Bs3TestFailedF("ins#%RU32/test#%u: bXcpt=%#x expected %#x; rip=%RX64 expected %RX64; encoding#%u: %.*Rhxs%s",
5833 pThis->iInstr, pThis->iTest,
5834 pThis->TrapFrame.bXcpt, bExpectedXcpt,
5835 pThis->TrapFrame.Ctx.rip.u, pThis->Ctx.rip.u + cbAdjustPc,
5836 iEncoding, pThis->cbCurInstr, pThis->abCurInstr, fInvalidEncodingPgFault ? " (cut short)" : "");
5837 Bs3TestPrintf("cpl=%u cbOperands=%u\n", pThis->uCpl, pThis->cbOperand);
5838
5839 /*
5840 * Display memory operands.
5841 */
5842 for (iOperand = 0; iOperand < pThis->cOperands; iOperand++)
5843 {
5844 BS3PTRUNION PtrUnion;
5845 switch (pThis->aOperands[iOperand].enmLocation)
5846 {
5847 case BS3CG1OPLOC_CTX:
5848 {
5849 uint8_t idxField = pThis->aOperands[iOperand].idxField;
5850 unsigned offField = g_aoffBs3Cg1DstFields[idxField];
5851 if (offField <= sizeof(BS3REGCTX))
5852 PtrUnion.pb = (uint8_t BS3_FAR *)&pThis->Ctx + offField;
5853 else
5854 {
5855 Bs3TestPrintf("op%u: ctx%u: xxxx\n", iOperand, pThis->aOperands[iOperand].cbOp * 8);
5856 break;
5857 }
5858 switch (pThis->aOperands[iOperand].cbOp)
5859 {
5860 case 1: Bs3TestPrintf("op%u: ctx08: %#04RX8\n", iOperand, *PtrUnion.pu8); break;
5861 case 2: Bs3TestPrintf("op%u: ctx16: %#06RX16\n", iOperand, *PtrUnion.pu16); break;
5862 case 4: Bs3TestPrintf("op%u: ctx32: %#010RX32\n", iOperand, *PtrUnion.pu32); break;
5863 case 8: Bs3TestPrintf("op%u: ctx64: %#018RX64\n", iOperand, *PtrUnion.pu64); break;
5864 default:
5865 Bs3TestPrintf("op%u: ctx%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
5866 pThis->aOperands[iOperand].cbOp, PtrUnion.pb);
5867 break;
5868 }
5869 break;
5870 }
5871
5872 case BS3CG1OPLOC_IMM:
5873 PtrUnion.pb = &pThis->pbCodePg[pThis->aOperands[iOperand].off];
5874 switch (pThis->aOperands[iOperand].cbOp)
5875 {
5876 case 1: Bs3TestPrintf("op%u: imm08: %#04RX8\n", iOperand, *PtrUnion.pu8); break;
5877 case 2: Bs3TestPrintf("op%u: imm16: %#06RX16\n", iOperand, *PtrUnion.pu16); break;
5878 case 4: Bs3TestPrintf("op%u: imm32: %#010RX32\n", iOperand, *PtrUnion.pu32); break;
5879 case 8: Bs3TestPrintf("op%u: imm64: %#018RX64\n", iOperand, *PtrUnion.pu64); break;
5880 default:
5881 Bs3TestPrintf("op%u: imm%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
5882 pThis->aOperands[iOperand].cbOp, PtrUnion.pb);
5883 break;
5884 }
5885 break;
5886
5887 case BS3CG1OPLOC_MEM:
5888 case BS3CG1OPLOC_MEM_RW:
5889 case BS3CG1OPLOC_MEM_WO:
5890 if (pThis->aOperands[iOperand].off)
5891 {
5892 PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off];
5893 switch (pThis->aOperands[iOperand].cbOp)
5894 {
5895 case 1: Bs3TestPrintf("op%u: result mem08: %#04RX8\n", iOperand, *PtrUnion.pu8); break;
5896 case 2: Bs3TestPrintf("op%u: result mem16: %#06RX16\n", iOperand, *PtrUnion.pu16); break;
5897 case 4: Bs3TestPrintf("op%u: result mem32: %#010RX32\n", iOperand, *PtrUnion.pu32); break;
5898 case 8: Bs3TestPrintf("op%u: result mem64: %#018RX64\n", iOperand, *PtrUnion.pu64); break;
5899 default:
5900 Bs3TestPrintf("op%u: result mem%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
5901 pThis->aOperands[iOperand].cbOp, PtrUnion.pb);
5902 break;
5903 }
5904 if ( pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_WO
5905 || pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW)
5906 {
5907 PtrUnion.pb = pThis->MemOp.ab;
5908 switch (pThis->aOperands[iOperand].cbOp)
5909 {
5910 case 1: Bs3TestPrintf("op%u: expect mem08: %#04RX8\n", iOperand, *PtrUnion.pu8); break;
5911 case 2: Bs3TestPrintf("op%u: expect mem16: %#06RX16\n", iOperand, *PtrUnion.pu16); break;
5912 case 4: Bs3TestPrintf("op%u: expect mem32: %#010RX32\n", iOperand, *PtrUnion.pu32); break;
5913 case 8: Bs3TestPrintf("op%u: expect mem64: %#018RX64\n", iOperand, *PtrUnion.pu64); break;
5914 default:
5915 Bs3TestPrintf("op%u: expect mem%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
5916 pThis->aOperands[iOperand].cbOp, PtrUnion.pb);
5917 break;
5918 }
5919 }
5920 }
5921 else
5922 Bs3TestPrintf("op%u: mem%u: zero off value!!\n", iOperand, pThis->aOperands[iOperand].cbOp * 8);
5923 break;
5924 }
5925 }
5926
5927 /*
5928 * Display contexts.
5929 */
5930 Bs3TestPrintf("-- Expected context:\n");
5931 Bs3RegCtxPrint(&pThis->Ctx);
5932 if (pThis->fWorkExtCtx)
5933 Bs3TestPrintf("xcr0=%RX64\n", pThis->pExtCtx->fXcr0Saved);
5934 Bs3TestPrintf("-- Actual context:\n");
5935 Bs3TrapPrintFrame(&pThis->TrapFrame);
5936 if (pThis->fWorkExtCtx)
5937 Bs3TestPrintf("xcr0=%RX64\n", pThis->pResultExtCtx->fXcr0Saved);
5938 Bs3TestPrintf("\n");
5939ASMHalt();
5940 return false;
5941}
5942
5943
5944/**
5945 * Destroys the state, freeing all allocations and such.
5946 *
5947 * @param pThis The state.
5948 */
5949static void BS3_NEAR_CODE Bs3Cg1Destroy(PBS3CG1STATE pThis)
5950{
5951 if (BS3_MODE_IS_PAGED(pThis->bMode))
5952 {
5953#if ARCH_BITS != 16
5954 Bs3MemGuardedTestPageFree(pThis->pbCodePg);
5955 Bs3MemGuardedTestPageFree(pThis->pbDataPg);
5956#endif
5957 }
5958 else
5959 {
5960 Bs3MemFree(pThis->pbCodePg, X86_PAGE_SIZE);
5961 Bs3MemFree(pThis->pbDataPg, X86_PAGE_SIZE);
5962 }
5963
5964 if (pThis->pExtCtx)
5965 Bs3MemFree(pThis->pExtCtx, pThis->pExtCtx->cb * 3);
5966
5967 pThis->pbCodePg = NULL;
5968 pThis->pbDataPg = NULL;
5969 pThis->pExtCtx = NULL;
5970 pThis->pResultExtCtx = NULL;
5971 pThis->pInitialExtCtx = NULL;
5972}
5973
5974
5975/**
5976 * Initializes the state.
5977 *
5978 * @returns Success indicator (true/false)
5979 * @param pThis The state.
5980 * @param bMode The mode being tested.
5981 */
5982bool BS3_NEAR_CODE BS3_CMN_NM(Bs3Cg1Init)(PBS3CG1STATE pThis, uint8_t bMode)
5983{
5984 BS3MEMKIND const enmMemKind = BS3_MODE_IS_RM_OR_V86(bMode) ? BS3MEMKIND_REAL
5985 : !BS3_MODE_IS_64BIT_CODE(bMode) ? BS3MEMKIND_TILED : BS3MEMKIND_FLAT32;
5986 unsigned iRing;
5987 unsigned cb;
5988 unsigned i;
5989 uint64_t fFlags;
5990 PBS3EXTCTX pExtCtx;
5991
5992 Bs3MemSet(pThis, 0, sizeof(*pThis));
5993
5994 pThis->iFirstRing = BS3_MODE_IS_V86(bMode) ? 3 : 0;
5995 pThis->iEndRing = BS3_MODE_IS_RM_SYS(bMode) ? 1 : 4;
5996 pThis->bMode = bMode;
5997 pThis->pszMode = Bs3GetModeName(bMode);
5998 pThis->pszModeShort = Bs3GetModeNameShortLower(bMode);
5999 pThis->bCpuVendor = Bs3GetCpuVendor();
6000 pThis->pchMnemonic = g_achBs3Cg1Mnemonics;
6001 pThis->pabOperands = g_abBs3Cg1Operands;
6002 pThis->pabOpcodes = g_abBs3Cg1Opcodes;
6003 pThis->fAdvanceMnemonic = 1;
6004
6005 /* Allocate extended context structures. */
6006 cb = Bs3ExtCtxGetSize(&fFlags);
6007 pExtCtx = Bs3MemAlloc(BS3MEMKIND_TILED, cb * 3);
6008 if (!pExtCtx)
6009 return Bs3TestFailedF("Bs3MemAlloc(tiled,%#x)", cb * 3);
6010 pThis->pExtCtx = pExtCtx;
6011 pThis->pResultExtCtx = (PBS3EXTCTX)((uint8_t BS3_FAR *)pExtCtx + cb);
6012 pThis->pInitialExtCtx = (PBS3EXTCTX)((uint8_t BS3_FAR *)pExtCtx + cb + cb);
6013
6014 Bs3ExtCtxInit(pThis->pExtCtx, cb, fFlags);
6015 Bs3ExtCtxInit(pThis->pResultExtCtx, cb, fFlags);
6016 Bs3ExtCtxInit(pThis->pInitialExtCtx, cb, fFlags);
6017 //Bs3TestPrintf("fCR0=%RX64 cbExtCtx=%#x method=%d\n", fFlags, cb, pExtCtx->enmMethod);
6018
6019 /* Allocate guarded exectuable and data memory. */
6020 if (BS3_MODE_IS_PAGED(bMode))
6021 {
6022#if ARCH_BITS != 16
6023 pThis->pbCodePg = Bs3MemGuardedTestPageAlloc(enmMemKind);
6024 pThis->pbDataPg = Bs3MemGuardedTestPageAlloc(enmMemKind);
6025 if (!pThis->pbCodePg || !pThis->pbDataPg)
6026 {
6027 Bs3TestFailedF("Bs3MemGuardedTestPageAlloc(%d) failed", enmMemKind);
6028 Bs3MemPrintInfo();
6029 Bs3Shutdown();
6030 return Bs3TestFailedF("Bs3MemGuardedTestPageAlloc(%d) failed", enmMemKind);
6031 }
6032 if ( BS3_MODE_IS_64BIT_CODE(bMode)
6033 && (uintptr_t)pThis->pbDataPg >= _2G)
6034 return Bs3TestFailedF("pbDataPg=%p is above 2GB and not simple to address from 64-bit code", pThis->pbDataPg);
6035#else
6036 return Bs3TestFailed("WTF?! #1");
6037#endif
6038 }
6039 else
6040 {
6041 pThis->pbCodePg = Bs3MemAlloc(enmMemKind, X86_PAGE_SIZE);
6042 pThis->pbDataPg = Bs3MemAlloc(enmMemKind, X86_PAGE_SIZE);
6043 if (!pThis->pbCodePg || !pThis->pbDataPg)
6044 {
6045 Bs3MemPrintInfo();
6046 return Bs3TestFailedF("Bs3MemAlloc(%d,Pg) failed", enmMemKind);
6047 }
6048 }
6049 pThis->uCodePgFlat = Bs3SelPtrToFlat(pThis->pbCodePg);
6050 pThis->uDataPgFlat = Bs3SelPtrToFlat(pThis->pbDataPg);
6051#if ARCH_BITS == 16
6052 pThis->CodePgFar.sel = BS3_FP_SEG(pThis->pbCodePg);
6053 pThis->CodePgFar.off = BS3_FP_OFF(pThis->pbCodePg);
6054 pThis->CodePgRip = BS3_FP_OFF(pThis->pbCodePg);
6055 pThis->DataPgFar.sel = BS3_FP_SEG(pThis->pbDataPg);
6056 pThis->DataPgFar.off = BS3_FP_OFF(pThis->pbDataPg);
6057#else
6058 if (BS3_MODE_IS_RM_OR_V86(bMode))
6059 {
6060 *(uint32_t *)&pThis->DataPgFar = Bs3SelFlatDataToRealMode(pThis->uDataPgFlat);
6061 ASMCompilerBarrier();
6062 pThis->CodePgFar.off = 0;
6063 pThis->CodePgFar.sel = pThis->uCodePgFlat >> 4;
6064 pThis->CodePgRip = pThis->CodePgFar.off;
6065 }
6066 else if (BS3_MODE_IS_16BIT_CODE(bMode))
6067 {
6068 *(uint32_t *)&pThis->DataPgFar = Bs3SelFlatDataToProtFar16(pThis->uDataPgFlat);
6069 ASMCompilerBarrier();
6070 pThis->CodePgFar.sel = BS3_SEL_SPARE_00;
6071 pThis->CodePgFar.off = 0;
6072 pThis->CodePgRip = 0;
6073 }
6074 else if (BS3_MODE_IS_32BIT_CODE(bMode))
6075 {
6076 *(uint32_t *)&pThis->DataPgFar = Bs3SelFlatDataToProtFar16(pThis->uDataPgFlat);
6077 ASMCompilerBarrier();
6078 pThis->CodePgFar.sel = 0;
6079 pThis->CodePgFar.off = 0;
6080 pThis->CodePgRip = (uintptr_t)pThis->pbCodePg;
6081 }
6082 else
6083 {
6084 pThis->DataPgFar.off = 0;
6085 pThis->DataPgFar.sel = 0;
6086 pThis->CodePgFar.off = 0;
6087 pThis->CodePgFar.sel = 0;
6088 pThis->CodePgRip = (uintptr_t)pThis->pbCodePg;
6089 }
6090#endif
6091 BS3CG1_DPRINTF(("pbDataPg=%p %04x:%04x pbCodePg=%p %04x:%04x\n",
6092 pThis->pbDataPg, pThis->DataPgFar.sel, pThis->DataPgFar.off,
6093 pThis->pbCodePg, pThis->CodePgFar.sel, pThis->CodePgFar.off));
6094
6095 /*
6096 * Create basic context for each target ring.
6097 *
6098 * In protected 16-bit code we need set up code selectors that can access
6099 * pbCodePg.
6100 *
6101 * In long mode we make sure the high 32-bits of GPRs (sans RSP) have some
6102 * bits set so we can check that the implicit clearing is tested.
6103 */
6104 Bs3RegCtxSaveEx(&pThis->aInitialCtxs[pThis->iFirstRing], bMode, 1024 * 3);
6105#if ARCH_BITS == 64
6106 pThis->aInitialCtxs[pThis->iFirstRing].rax.u |= UINT64_C(0x0101010100000000);
6107 pThis->aInitialCtxs[pThis->iFirstRing].rbx.u |= UINT64_C(0x0202020200000000);
6108 pThis->aInitialCtxs[pThis->iFirstRing].rcx.u |= UINT64_C(0x0303030300000000);
6109 pThis->aInitialCtxs[pThis->iFirstRing].rdx.u |= UINT64_C(0x0404040400000000);
6110 pThis->aInitialCtxs[pThis->iFirstRing].rbp.u |= UINT64_C(0x0505050500000000);
6111 pThis->aInitialCtxs[pThis->iFirstRing].rdi.u |= UINT64_C(0x0606060600000000);
6112 pThis->aInitialCtxs[pThis->iFirstRing].rsi.u |= UINT64_C(0x0707070700000000);
6113 pThis->aInitialCtxs[pThis->iFirstRing].r8.u |= UINT64_C(0x0808080800000000);
6114 pThis->aInitialCtxs[pThis->iFirstRing].r9.u |= UINT64_C(0x0909090900000000);
6115 pThis->aInitialCtxs[pThis->iFirstRing].r10.u |= UINT64_C(0x1010101000000000);
6116 pThis->aInitialCtxs[pThis->iFirstRing].r11.u |= UINT64_C(0x1111111100000000);
6117 pThis->aInitialCtxs[pThis->iFirstRing].r12.u |= UINT64_C(0x1212121200000000);
6118 pThis->aInitialCtxs[pThis->iFirstRing].r13.u |= UINT64_C(0x1313131300000000);
6119 pThis->aInitialCtxs[pThis->iFirstRing].r14.u |= UINT64_C(0x1414141400000000);
6120 pThis->aInitialCtxs[pThis->iFirstRing].r15.u |= UINT64_C(0x1515151500000000);
6121#endif
6122
6123 if (BS3_MODE_IS_RM_OR_V86(bMode))
6124 {
6125 pThis->aInitialCtxs[pThis->iFirstRing].cs = pThis->CodePgFar.sel;
6126 BS3_ASSERT(pThis->iFirstRing + 1 == pThis->iEndRing);
6127 }
6128 else if (BS3_MODE_IS_16BIT_CODE(bMode))
6129 {
6130#if ARCH_BITS == 16
6131 uintptr_t const uFlatCodePgSeg = Bs3SelPtrToFlat(BS3_FP_MAKE(BS3_FP_SEG(pThis->pbCodePg), 0));
6132#else
6133 uintptr_t const uFlatCodePgSeg = (uintptr_t)pThis->pbCodePg;
6134#endif
6135 for (iRing = pThis->iFirstRing + 1; iRing < pThis->iEndRing; iRing++)
6136 {
6137 Bs3MemCpy(&pThis->aInitialCtxs[iRing], &pThis->aInitialCtxs[pThis->iFirstRing], sizeof(pThis->aInitialCtxs[iRing]));
6138 Bs3RegCtxConvertToRingX(&pThis->aInitialCtxs[iRing], iRing);
6139 }
6140 for (iRing = pThis->iFirstRing; iRing < pThis->iEndRing; iRing++)
6141 {
6142 pThis->aInitialCtxs[iRing].cs = BS3_SEL_SPARE_00 + iRing * 8 + iRing;
6143 Bs3SelSetup16BitCode(&Bs3GdteSpare00 + iRing, uFlatCodePgSeg, iRing);
6144 }
6145 }
6146 else
6147 {
6148 Bs3RegCtxSetRipCsFromCurPtr(&pThis->aInitialCtxs[pThis->iFirstRing], (FPFNBS3FAR)pThis->pbCodePg);
6149 for (iRing = pThis->iFirstRing + 1; iRing < pThis->iEndRing; iRing++)
6150 {
6151 Bs3MemCpy(&pThis->aInitialCtxs[iRing], &pThis->aInitialCtxs[pThis->iFirstRing], sizeof(pThis->aInitialCtxs[iRing]));
6152 Bs3RegCtxConvertToRingX(&pThis->aInitialCtxs[iRing], iRing);
6153 }
6154 }
6155
6156 /*
6157 * Create an initial extended CPU context.
6158 */
6159 pExtCtx = pThis->pInitialExtCtx;
6160 if ( pExtCtx->enmMethod == BS3EXTCTXMETHOD_FXSAVE
6161 || pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE)
6162 {
6163 pExtCtx->Ctx.x87.FCW = X86_FCW_MASK_ALL | X86_FCW_PC_64 | X86_FCW_RC_NEAREST;
6164 pExtCtx->Ctx.x87.FSW = 0;
6165 pExtCtx->Ctx.x87.MXCSR = X86_MXCSR_IM | X86_MXCSR_DM | X86_MXCSR_RC_NEAREST;
6166 pExtCtx->Ctx.x87.MXCSR_MASK = 0;
6167 for (i = 0; i < RT_ELEMENTS(pExtCtx->Ctx.x87.aRegs); i++)
6168 {
6169 pExtCtx->Ctx.x87.aRegs[i].au16[0] = i << 4;
6170 pExtCtx->Ctx.x87.aRegs[i].au16[1] = i << 4;
6171 pExtCtx->Ctx.x87.aRegs[i].au16[2] = i << 4;
6172 pExtCtx->Ctx.x87.aRegs[i].au16[3] = i << 4;
6173 }
6174 for (i = 0; i < RT_ELEMENTS(pExtCtx->Ctx.x87.aXMM); i++)
6175 {
6176 pExtCtx->Ctx.x87.aXMM[i].au16[0] = i | UINT16_C(0x8f00);
6177 pExtCtx->Ctx.x87.aXMM[i].au16[1] = i | UINT16_C(0x8e00);
6178 pExtCtx->Ctx.x87.aXMM[i].au16[2] = i | UINT16_C(0x8d00);
6179 pExtCtx->Ctx.x87.aXMM[i].au16[3] = i | UINT16_C(0x8c00);
6180 pExtCtx->Ctx.x87.aXMM[i].au16[4] = i | UINT16_C(0x8b00);
6181 pExtCtx->Ctx.x87.aXMM[i].au16[5] = i | UINT16_C(0x8a00);
6182 pExtCtx->Ctx.x87.aXMM[i].au16[6] = i | UINT16_C(0x8900);
6183 pExtCtx->Ctx.x87.aXMM[i].au16[7] = i | UINT16_C(0x8800);
6184 }
6185 if (pExtCtx->fXcr0Nominal & XSAVE_C_YMM)
6186 for (i = 0; i < RT_ELEMENTS(pExtCtx->Ctx.x.u.YmmHi.aYmmHi); i++)
6187 {
6188 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[0] = (i << 8) | (i << 12) | 0xff;
6189 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[1] = (i << 8) | (i << 12) | 0xfe;
6190 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[2] = (i << 8) | (i << 12) | 0xfd;
6191 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[3] = (i << 8) | (i << 12) | 0xfc;
6192 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[4] = (i << 8) | (i << 12) | 0xfb;
6193 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[5] = (i << 8) | (i << 12) | 0xfa;
6194 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[6] = (i << 8) | (i << 12) | 0xf9;
6195 pExtCtx->Ctx.x.u.YmmHi.aYmmHi[i].au16[7] = (i << 8) | (i << 12) | 0xf8;
6196 }
6197
6198 }
6199 //else if (pExtCtx->enmMethod == BS3EXTCTXMETHOD_ANCIENT)
6200 else
6201 return Bs3TestFailedF("Unsupported extended CPU context method: %d", pExtCtx->enmMethod);
6202
6203 return true;
6204}
6205
6206
6207static uint8_t BS3_NEAR_CODE BS3_CMN_NM(Bs3Cg1WorkerInner)(PBS3CG1STATE pThis)
6208{
6209 uint8_t iRing;
6210 unsigned iInstr;
6211
6212 /*
6213 * Test the instructions.
6214 */
6215 for (iInstr = 0; iInstr < g_cBs3Cg1Instructions;
6216 iInstr++,
6217 pThis->pchMnemonic += pThis->fAdvanceMnemonic * pThis->cchMnemonic,
6218 pThis->pabOperands += pThis->cOperands,
6219 pThis->pabOpcodes += pThis->cbOpcodes)
6220 {
6221 uint8_t const bTestXcptExpected = BS3_MODE_IS_PAGED(pThis->bMode) ? X86_XCPT_PF : X86_XCPT_UD;
6222 bool fOuterInvalidInstr = false;
6223 unsigned iCpuSetup;
6224
6225 /*
6226 * Expand the instruction information into the state.
6227 * Note! 16-bit will switch to a two level test header lookup once we exceed 64KB.
6228 */
6229 PCBS3CG1INSTR pInstr = &g_aBs3Cg1Instructions[iInstr];
6230 pThis->iInstr = iInstr;
6231 pThis->pTestHdr = (PCBS3CG1TESTHDR)&g_abBs3Cg1Tests[pInstr->offTests];
6232 pThis->fFlags = pInstr->fFlags;
6233 pThis->enmEncoding = (BS3CG1ENC)pInstr->enmEncoding;
6234 pThis->enmEncodingNonInvalid = (BS3CG1ENC)pInstr->enmEncoding;
6235 pThis->enmCpuTest = (BS3CG1CPU)pInstr->enmCpuTest;
6236 pThis->enmPrefixKind = (BS3CG1PFXKIND)pInstr->enmPrefixKind;
6237 pThis->enmXcptType = (BS3CG1XCPTTYPE)pInstr->enmXcptType;
6238 pThis->cchMnemonic = pInstr->cchMnemonic;
6239 if (pThis->fAdvanceMnemonic)
6240 Bs3TestSubF("%s / %.*s", pThis->pszModeShort, pThis->cchMnemonic, pThis->pchMnemonic);
6241 pThis->fAdvanceMnemonic = pInstr->fAdvanceMnemonic;
6242 pThis->uOpcodeMap = pInstr->uOpcodeMap;
6243 pThis->cOperands = pInstr->cOperands;
6244 pThis->cbOpcodes = pInstr->cbOpcodes;
6245 switch (pThis->cOperands)
6246 {
6247 case 4: pThis->aenmOperands[3] = (BS3CG1OP)pThis->pabOperands[3];
6248 case 3: pThis->aenmOperands[2] = (BS3CG1OP)pThis->pabOperands[2];
6249 case 2: pThis->aenmOperands[1] = (BS3CG1OP)pThis->pabOperands[1];
6250 case 1: pThis->aenmOperands[0] = (BS3CG1OP)pThis->pabOperands[0];
6251 }
6252 switch (pThis->cbOpcodes)
6253 {
6254 case 4: pThis->abOpcodes[3] = pThis->pabOpcodes[3];
6255 case 3: pThis->abOpcodes[2] = pThis->pabOpcodes[2];
6256 case 2: pThis->abOpcodes[1] = pThis->pabOpcodes[1];
6257 case 1: pThis->abOpcodes[0] = pThis->pabOpcodes[0];
6258 }
6259
6260 /*
6261 * Check if the CPU supports the instruction.
6262 */
6263 pThis->fCpuSetupFirstResult = Bs3Cg1CpuSetupFirst(pThis);
6264 if ( !pThis->fCpuSetupFirstResult
6265 || (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID)))
6266 fOuterInvalidInstr = true;
6267
6268 /* Switch the encoder for some of the invalid instructions on non-intel CPUs. */
6269 if ( (pThis->fFlags & BS3CG1INSTR_F_INTEL_DECODES_INVALID)
6270 && pThis->bCpuVendor != BS3CPUVENDOR_INTEL
6271 && ( (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID))
6272 || (BS3CG1_IS_64BIT_TARGET(pThis) && (pThis->fFlags & BS3CG1INSTR_F_INVALID_64BIT))
6273 || fOuterInvalidInstr ) )
6274 pThis->enmEncoding = Bs3Cg1CalcNoneIntelInvalidEncoding(pThis->enmEncoding);
6275
6276 for (iCpuSetup = 0;; iCpuSetup++)
6277 {
6278 unsigned iEncoding;
6279 unsigned iEncodingNext;
6280
6281 /*
6282 * Prep the operands and encoding handling.
6283 */
6284 if (!Bs3Cg1EncodePrep(pThis))
6285 break;
6286
6287 /*
6288 * Encode the instruction in various ways and check out the test values.
6289 */
6290 for (iEncoding = 0;; iEncoding = iEncodingNext)
6291 {
6292 /*
6293 * Encode the next instruction variation.
6294 */
6295 pThis->fInvalidEncoding = fOuterInvalidInstr;
6296 iEncodingNext = Bs3Cg1EncodeNext(pThis, iEncoding);
6297 if (iEncodingNext <= iEncoding)
6298 break;
6299 BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u: %.*Rhxs fInvalidEncoding=%d\n",
6300 iEncoding, pThis->cbCurInstr, pThis->cbCurInstr, pThis->abCurInstr, pThis->fInvalidEncoding));
6301
6302 /*
6303 * Do the rings.
6304 */
6305 for (iRing = pThis->iFirstRing + pThis->fSameRingNotOkay; iRing < pThis->iEndRing; iRing++)
6306 {
6307 PCBS3CG1TESTHDR pHdr;
6308
6309 pThis->uCpl = iRing;
6310 BS3CG1_DPRINTF(("dbg: Ring %u\n", iRing));
6311
6312 /*
6313 * Do the tests one by one.
6314 */
6315 pHdr = pThis->pTestHdr;
6316 for (pThis->iTest = 0;; pThis->iTest++)
6317 {
6318 if (Bs3Cg1RunSelector(pThis, pHdr))
6319 {
6320 /* Okay, set up the execution context. */
6321 unsigned offCode;
6322 uint8_t BS3_FAR *pbCode;
6323
6324 Bs3MemCpy(&pThis->Ctx, &pThis->aInitialCtxs[iRing], sizeof(pThis->Ctx));
6325 if (pThis->fWorkExtCtx)
6326 Bs3ExtCtxCopy(pThis->pExtCtx, pThis->pInitialExtCtx);
6327 if (BS3_MODE_IS_PAGED(pThis->bMode))
6328 {
6329 offCode = X86_PAGE_SIZE - pThis->cbCurInstr;
6330 pbCode = &pThis->pbCodePg[offCode];
6331 //if (iEncoding > 0) { pbCode[-1] = 0xf4; offCode--; }
6332 }
6333 else
6334 {
6335 pbCode = pThis->pbCodePg;
6336 pbCode[pThis->cbCurInstr] = 0x0f; /* UD2 */
6337 pbCode[pThis->cbCurInstr + 1] = 0x0b;
6338 offCode = 0;
6339 }
6340 pThis->Ctx.rip.u = pThis->CodePgRip + offCode;
6341 Bs3MemCpy(pbCode, pThis->abCurInstr, pThis->cbCurInstr);
6342
6343 if (Bs3Cg1RunContextModifier(pThis, &pThis->Ctx, pHdr, pHdr->cbSelector, pHdr->cbInput, NULL, pbCode))
6344 {
6345 /* Run the instruction. */
6346 BS3CG1_DPRINTF(("dbg: Running test #%u\n", pThis->iTest));
6347 //Bs3RegCtxPrint(&pThis->Ctx);
6348 if (pThis->fWorkExtCtx)
6349 Bs3ExtCtxRestore(pThis->pExtCtx);
6350 Bs3TrapSetJmpAndRestore(&pThis->Ctx, &pThis->TrapFrame);
6351 if (pThis->fWorkExtCtx)
6352 Bs3ExtCtxSave(pThis->pResultExtCtx);
6353 BS3CG1_DPRINTF(("dbg: bXcpt=%#x rip=%RX64 -> %RX64\n",
6354 pThis->TrapFrame.bXcpt, pThis->Ctx.rip.u, pThis->TrapFrame.Ctx.rip.u));
6355
6356 /*
6357 * Apply the output modification program to the context.
6358 */
6359 pThis->Ctx.rflags.u32 &= ~X86_EFL_RF;
6360 pThis->Ctx.rflags.u32 |= pThis->TrapFrame.Ctx.rflags.u32 & X86_EFL_RF;
6361 pThis->bValueXcpt = UINT8_MAX; //???
6362 if ( pThis->fInvalidEncoding
6363 || pThis->bAlignmentXcpt != UINT8_MAX
6364 || pThis->bValueXcpt != UINT8_MAX
6365 || Bs3Cg1RunContextModifier(pThis, &pThis->Ctx, pHdr,
6366 pHdr->cbSelector + pHdr->cbInput, pHdr->cbOutput,
6367 &pThis->TrapFrame.Ctx, NULL /*pbCode*/))
6368 Bs3Cg1CheckResult(pThis, bTestXcptExpected, false /*fInvalidEncodingPgFault*/, iEncoding);
6369 else
6370 {
6371 Bs3TestPrintf("Bs3Cg1RunContextModifier(out): iEncoding=%u iTest=%RU32 iInstr=%u %.*s\n",
6372 iEncoding, pThis->iTest, pThis->iInstr, pThis->cchMnemonic, pThis->pchMnemonic);
6373 ASMHalt();
6374 }
6375
6376 /*
6377 * If this is an invalid encoding or instruction, check that we
6378 * get a page fault when shortening it by one byte.
6379 * (Since we didn't execute the output context modifier, we don't
6380 * need to re-initialize the start context.)
6381 */
6382 if ( pThis->fInvalidEncoding
6383 && BS3_MODE_IS_PAGED(pThis->bMode)
6384 && pThis->cbCurInstr)
6385 {
6386 pbCode += 1;
6387 offCode += 1;
6388 pThis->Ctx.rip.u = pThis->CodePgRip + offCode;
6389 Bs3MemCpy(pbCode, pThis->abCurInstr, pThis->cbCurInstr - 1);
6390
6391 /* Run the instruction. */
6392 BS3CG1_DPRINTF(("dbg: Running test #%u (cut short #PF)\n", pThis->iTest));
6393 //Bs3RegCtxPrint(&pThis->Ctx);
6394 if (pThis->fWorkExtCtx)
6395 Bs3ExtCtxRestore(pThis->pExtCtx);
6396 Bs3TrapSetJmpAndRestore(&pThis->Ctx, &pThis->TrapFrame);
6397 if (pThis->fWorkExtCtx)
6398 Bs3ExtCtxSave(pThis->pResultExtCtx);
6399 BS3CG1_DPRINTF(("dbg: bXcpt=%#x rip=%RX64 -> %RX64 (cut short #PF)\n",
6400 pThis->TrapFrame.bXcpt, pThis->Ctx.rip.u, pThis->TrapFrame.Ctx.rip.u));
6401
6402 /* Check it */
6403 pThis->Ctx.rflags.u32 &= ~X86_EFL_RF;
6404 pThis->Ctx.rflags.u32 |= pThis->TrapFrame.Ctx.rflags.u32 & X86_EFL_RF;
6405 Bs3Cg1CheckResult(pThis, X86_XCPT_PF, true /*fInvalidEncodingPgFault*/, iEncoding);
6406 }
6407 }
6408 else
6409 {
6410 Bs3TestPrintf("Bs3Cg1RunContextModifier(in): iEncoding=%u iTest=%u iInstr=%RU32 %.*s\n",
6411 iEncoding, pThis->iTest, pThis->iInstr, pThis->cchMnemonic, pThis->pchMnemonic);
6412 ASMHalt();
6413 }
6414 }
6415 else
6416 BS3CG1_DPRINTF(("dbg: Skipping #%u\n", pThis->iTest));
6417
6418 /* advance */
6419 if (pHdr->fLast)
6420 {
6421 BS3CG1_DPRINTF(("dbg: Last\n\n"));
6422 break;
6423 }
6424 pHdr = (PCBS3CG1TESTHDR)((uint8_t BS3_FAR *)(pHdr + 1) + pHdr->cbInput + pHdr->cbOutput + pHdr->cbSelector);
6425 }
6426 }
6427 }
6428
6429 /*
6430 * Clean up (segment registers, etc) and get the next CPU config.
6431 */
6432 Bs3Cg1EncodeCleanup(pThis);
6433 if (!Bs3Cg1CpuSetupNext(pThis, iCpuSetup, &fOuterInvalidInstr))
6434 break;
6435 if (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID))
6436 fOuterInvalidInstr = true;
6437 }
6438 }
6439
6440 return 0;
6441}
6442
6443
6444BS3_DECL_FAR(uint8_t) BS3_CMN_NM(Bs3Cg1Worker)(uint8_t bMode)
6445{
6446 uint8_t bRet = 1;
6447 BS3CG1STATE This;
6448
6449#if 0
6450 /* (for debugging) */
6451 if (bMode != BS3_MODE_PP32)
6452 return BS3TESTDOMODE_SKIPPED;
6453#endif
6454
6455 if (BS3_CMN_NM(Bs3Cg1Init)(&This, bMode))
6456 {
6457 bRet = BS3_CMN_NM(Bs3Cg1WorkerInner)(&This);
6458 Bs3TestSubDone();
6459 }
6460 Bs3Cg1Destroy(&This);
6461
6462#if 0
6463 /* (for debugging) */
6464 if (bMode == BS3_MODE_PPV86)
6465 {
6466 Bs3TestTerm();
6467 Bs3Shutdown();
6468 }
6469#endif
6470 return bRet;
6471}
6472
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette