VirtualBox

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

Last change on this file since 103131 was 98103, checked in by vboxsync, 21 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 266.0 KB
Line 
1/* $Id: bs3-cpu-generated-1-template.c 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * BS3Kit - bs3-cpu-generated-1, C code template.
4 */
5
6/*
7 * Copyright (C) 2007-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37#ifndef BS3_INSTANTIATING_CMN
38# error "BS3_INSTANTIATING_CMN not defined"
39#endif
40
41
42/*********************************************************************************************************************************
43* Header Files *
44*********************************************************************************************************************************/
45#include <iprt/asm.h>
46#include <iprt/asm-amd64-x86.h>
47
48#include "bs3-cpu-generated-1.h"
49
50
51/*********************************************************************************************************************************
52* Defined Constants And Macros *
53*********************************************************************************************************************************/
54#define BS3CG1_WITH_VEX
55
56#define P_CS X86_OP_PRF_CS
57#define P_SS X86_OP_PRF_SS
58#define P_DS X86_OP_PRF_DS
59#define P_ES X86_OP_PRF_ES
60#define P_FS X86_OP_PRF_FS
61#define P_GS X86_OP_PRF_GS
62#define P_OZ X86_OP_PRF_SIZE_OP
63#define P_AZ X86_OP_PRF_SIZE_ADDR
64#define P_LK X86_OP_PRF_LOCK
65#define P_RN X86_OP_PRF_REPNZ
66#define P_RZ X86_OP_PRF_REPZ
67
68#define REX_WRBX (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B | X86_OP_REX_X)
69#define REX_W___ (X86_OP_REX_W)
70#define REX_WR__ (X86_OP_REX_W | X86_OP_REX_R)
71#define REX_W_B_ (X86_OP_REX_W | X86_OP_REX_B)
72#define REX_W__X (X86_OP_REX_W | X86_OP_REX_X)
73#define REX_WRB_ (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B)
74#define REX_WR_X (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_X)
75#define REX_W_BX (X86_OP_REX_W | X86_OP_REX_B | X86_OP_REX_X)
76#define REX__R__ (X86_OP_REX_R)
77#define REX__RB_ (X86_OP_REX_R | X86_OP_REX_B)
78#define REX__R_X (X86_OP_REX_R | X86_OP_REX_X)
79#define REX__RBX (X86_OP_REX_R | X86_OP_REX_B | X86_OP_REX_X)
80#define REX___B_ (X86_OP_REX_B)
81#define REX___BX (X86_OP_REX_B | X86_OP_REX_X)
82#define REX____X (X86_OP_REX_X)
83#define REX_____ (0x40)
84
85
86/** @def BS3CG1_DPRINTF
87 * Debug print macro.
88 */
89#if 0
90# define BS3CG1_DPRINTF(a_ArgList) Bs3TestPrintf a_ArgList
91# define BS3CG1_DEBUG_CTX_MOD
92#else
93# define BS3CG1_DPRINTF(a_ArgList) do { } while (0)
94#endif
95
96/**
97 * Checks if this is a 64-bit test target or not.
98 * Helps avoid ifdefs or code bloat.
99 */
100#if ARCH_BITS == 64
101# define BS3CG1_IS_64BIT_TARGET(a_pThis) BS3_MODE_IS_64BIT_CODE((a_pThis)->bMode)
102#else
103# define BS3CG1_IS_64BIT_TARGET(a_pThis) (false)
104#endif
105
106
107/*********************************************************************************************************************************
108* Structures and Typedefs *
109*********************************************************************************************************************************/
110/** Operand value location. */
111typedef enum BS3CG1OPLOC
112{
113 BS3CG1OPLOC_INVALID = 0,
114 BS3CG1OPLOC_CTX,
115 BS3CG1OPLOC_CTX_ZX_VLMAX,
116 BS3CG1OPLOC_IMM,
117 BS3CG1OPLOC_MEM,
118 BS3CG1OPLOC_MEM_RW,
119 BS3CG1OPLOC_MEM_WO,
120 BS3CG1OPLOC_END
121} BS3CG1OPLOC;
122AssertCompile(BS3CG1OPLOC_END <= 16);
123
124
125/** Pointer to the generated test state. */
126typedef struct BS3CG1STATE *PBS3CG1STATE;
127
128/**
129 * Encoder callback.
130 * @returns Next encoding. If equal or less to @a iEncoding, no
131 * further encodings are available for testing.
132 * @param pThis The state.
133 * @param iEncoding The encoding.
134 */
135typedef unsigned BS3_NEAR_CODE FNBS3CG1ENCODER(PBS3CG1STATE pThis, unsigned iEncoding);
136/** Pointer to a encoder callback. */
137typedef FNBS3CG1ENCODER *PFNBS3CG1ENCODER;
138
139
140/**
141 * The state.
142 */
143typedef struct BS3CG1STATE
144{
145 /** @name Instruction details (expanded from BS3CG1INSTR).
146 * @{ */
147 /** Pointer to the mnemonic string (not terminated) (g_achBs3Cg1Mnemonics). */
148 const char BS3_FAR *pchMnemonic;
149 /** Pointer to the test header. */
150 PCBS3CG1TESTHDR pTestHdr;
151 /** Pointer to the per operand flags (g_abBs3Cg1Operands). */
152 const uint8_t BS3_FAR *pabOperands;
153 /** Opcode bytes (g_abBs3Cg1Opcodes). */
154 const uint8_t BS3_FAR *pabOpcodes;
155 /** The current instruction number in the input array (for error reporting). */
156 uint32_t iInstr;
157
158 /** The instruction flags. */
159 uint32_t fFlags;
160 /** The encoding. */
161 BS3CG1ENC enmEncoding;
162 /** The non-invalid encoding. This may differ from enmEncoding when
163 * Bs3Cg1CalcNoneIntelInvalidEncoding has been called. */
164 BS3CG1ENC enmEncodingNonInvalid;
165 /** The CPU test / CPU ID. */
166 BS3CG1CPU enmCpuTest;
167 /** Prefix sensitivity and requirements. */
168 BS3CG1PFXKIND enmPrefixKind;
169 /** Exception type (SSE, AVX). */
170 BS3CG1XCPTTYPE enmXcptType;
171 /** Per operand flags. */
172 BS3CG1OP aenmOperands[4];
173 /** Opcode bytes. */
174 uint8_t abOpcodes[4];
175 /** The instruction encoder. */
176 PFNBS3CG1ENCODER pfnEncoder;
177
178 /** The length of the mnemonic. */
179 uint8_t cchMnemonic;
180 /** Whether to advance the mnemonic pointer or not. */
181 uint8_t fAdvanceMnemonic;
182 /** The opcode map number. */
183 uint8_t uOpcodeMap;
184 /** The number of opcode bytes. */
185 uint8_t cbOpcodes;
186 /** Number of operands. */
187 uint8_t cOperands;
188 /** @} */
189
190 /** Default operand size. */
191 uint8_t cbOpDefault;
192 /** Operand size when overridden by 066h. */
193 uint8_t cbOpOvrd66;
194 /** Operand size when overridden by REX.W. */
195 uint8_t cbOpOvrdRexW;
196
197 /** Operand size in bytes (0 if not applicable). */
198 uint8_t cbOperand;
199 /** Current VEX.L value (UINT8_MAX if not applicable). */
200 uint8_t uVexL;
201 /** Current target ring (0..3). */
202 uint8_t uCpl;
203
204 /** The current test number. */
205 uint8_t iTest;
206
207 /** Target mode (g_bBs3CurrentMode). */
208 uint8_t bMode;
209 /** The CPU vendor (BS3CPUVENDOR). */
210 uint8_t bCpuVendor;
211 /** First ring being tested. */
212 uint8_t iFirstRing;
213 /** End of rings being tested. */
214 uint8_t iEndRing;
215
216 /** @name Current encoded instruction.
217 * @{ */
218 /** The size of the current instruction that we're testing. */
219 uint8_t cbCurInstr;
220 /** The size the prefixes. */
221 uint8_t cbCurPrefix;
222 /** The offset into abCurInstr of the immediate. */
223 uint8_t offCurImm;
224 /** Buffer for assembling the current instruction. */
225 uint8_t abCurInstr[23];
226
227 /** Set if the encoding can't be tested in the same ring as this test code.
228 * This is used to deal with encodings modifying SP/ESP/RSP. */
229 bool fSameRingNotOkay;
230 /** Whether to work the extended context too. */
231 bool fWorkExtCtx;
232 /** The aOperands index of the modrm.reg operand (if applicable). */
233 uint8_t iRegOp;
234 /** The aOperands index of the modrm.rm operand (if applicable). */
235 uint8_t iRmOp;
236
237 /** Operands details. */
238 struct
239 {
240 uint8_t cbOp;
241 /** BS3CG1OPLOC_XXX. */
242 uint8_t enmLocation;
243 /** BS3CG1OPLOC_XXX for memory encodings (MODRM.rm field). */
244 uint8_t enmLocationMem : 4;
245 /** BS3CG1OPLOC_XXX for register encodings (MODRM.rm field). */
246 uint8_t enmLocationReg : 4;
247 /** The BS3CG1DST value for this field.
248 * Set to BS3CG1DST_INVALID if memory or immediate. */
249 uint8_t idxField;
250 /** The base BS3CG1DST value for this field.
251 * Used only by some generalized encoders when dealing with registers. */
252 uint8_t idxFieldBase;
253 /** Depends on enmLocation.
254 * - BS3CG1OPLOC_IMM: offset relative to start of the instruction.
255 * - BS3CG1OPLOC_MEM: offset should be subtracted from &pbDataPg[_4K].
256 * - BS3CG1OPLOC_MEM_RW: offset should be subtracted from &pbDataPg[_4K].
257 * - BS3CG1OPLOC_MEM_RO: offset should be subtracted from &pbDataPg[_4K].
258 * - BS3CG1OPLOC_CTX: not used (use idxField instead).
259 */
260 uint8_t off;
261 } aOperands[4];
262 /** @} */
263
264 /** Page to put code in. When paging is enabled, the page before and after
265 * are marked not-present. */
266 uint8_t BS3_FAR *pbCodePg;
267 /** The flat address corresponding to pbCodePg. */
268 uintptr_t uCodePgFlat;
269 /** The 16-bit address corresponding to pbCodePg if relevant for bMode. */
270 RTFAR16 CodePgFar;
271 /** The IP/EIP/RIP value for pbCodePg[0] relative to CS (bMode). */
272 uintptr_t CodePgRip;
273
274 /** Page for placing data operands in. When paging is enabled, the page before
275 * and after are marked not-present. */
276 uint8_t BS3_FAR *pbDataPg;
277 /** The flat address corresponding to pbDataPg. */
278 uintptr_t uDataPgFlat;
279 /** The 16-bit address corresponding to pbDataPg. */
280 RTFAR16 DataPgFar;
281
282 /** The name corresponding to bMode. */
283 const char BS3_FAR *pszMode;
284 /** The short name corresponding to bMode. */
285 const char BS3_FAR *pszModeShort;
286
287 /** @name Expected result (modifiable by output program).
288 * @{ */
289 /** The expected exception based on operand values or result.
290 * UINT8_MAX if no special exception expected. */
291 uint8_t bValueXcpt;
292 /** @} */
293 /** Alignment exception expected by the encoder.
294 * UINT8_MAX if no special exception expected. */
295 uint8_t bAlignmentXcpt;
296 /** Set by the encoding method to indicating invalid encoding. */
297 bool fInvalidEncoding;
298 /** The result of Bs3Cg1CpuSetupFirst(). */
299 bool fCpuSetupFirstResult;
300
301 /** The context we're working on. */
302 BS3REGCTX Ctx;
303 /** The trap context and frame. */
304 BS3TRAPFRAME TrapFrame;
305 /** Initial contexts, one for each ring. */
306 BS3REGCTX aInitialCtxs[4];
307
308 /** The extended context we're working on (input, expected output). */
309 PBS3EXTCTX pExtCtx;
310 /** The extended result context (analoguous to TrapFrame). */
311 PBS3EXTCTX pResultExtCtx;
312 /** The initial extended context. */
313 PBS3EXTCTX pInitialExtCtx;
314
315 /** Memory operand scratch space. */
316 union
317 {
318 uint8_t ab[128];
319 uint16_t au16[128 / sizeof(uint16_t)];
320 uint32_t au32[128 / sizeof(uint32_t)];
321 uint64_t au64[128 / sizeof(uint64_t)];
322 } MemOp;
323
324 /** Array parallel to aInitialCtxs for saving segment registers. */
325 struct
326 {
327 RTSEL ds;
328 } aSavedSegRegs[4];
329
330} BS3CG1STATE;
331
332
333#define BS3CG1_PF_OZ UINT16_C(0x0001)
334#define BS3CG1_PF_AZ UINT16_C(0x0002)
335#define BS3CG1_PF_CS UINT16_C(0x0004)
336#define BS3CG1_PF_DS UINT16_C(0x0008)
337#define BS3CG1_PF_ES UINT16_C(0x0010)
338#define BS3CG1_PF_FS UINT16_C(0x0020)
339#define BS3CG1_PF_GS UINT16_C(0x0040)
340#define BS3CG1_PF_SS UINT16_C(0x0080)
341#define BS3CG1_PF_SEGS (BS3CG1_PF_CS | BS3CG1_PF_DS | BS3CG1_PF_ES | BS3CG1_PF_FS | BS3CG1_PF_GS | BS3CG1_PF_SS)
342#define BS3CG1_PF_MEM (BS3CG1_PF_SEGS | BS3CG1_PF_AZ)
343#define BS3CG1_PF_LK UINT16_C(0x0100)
344#define BS3CG1_PF_RN UINT16_C(0x0200)
345#define BS3CG1_PF_RZ UINT16_C(0x0400)
346#define BS3CG1_PF_W UINT16_C(0x0800) /**< REX.W */
347#define BS3CG1_PF_R UINT16_C(0x1000) /**< REX.R */
348#define BS3CG1_PF_B UINT16_C(0x2000) /**< REX.B */
349#define BS3CG1_PF_X UINT16_C(0x4000) /**< REX.X */
350
351
352/** Used in g_cbBs3Cg1DstFields to indicate that it's one of the 4 operands. */
353#define BS3CG1DSTSIZE_OPERAND UINT8_C(255)
354/** Used in g_cbBs3Cg1DstFields to indicate that the operand size determins
355 * the field size (2, 4, or 8). */
356#define BS3CG1DSTSIZE_OPERAND_SIZE_GRP UINT8_C(254)
357
358
359
360/*********************************************************************************************************************************
361* Global Variables *
362*********************************************************************************************************************************/
363/** Destination field sizes indexed by bBS3CG1DST.
364 * Zero means operand size sized. */
365static const uint8_t g_acbBs3Cg1DstFields[] =
366{
367 /* [BS3CG1DST_INVALID] = */ BS3CG1DSTSIZE_OPERAND,
368
369 /* [BS3CG1DST_OP1] = */ BS3CG1DSTSIZE_OPERAND,
370 /* [BS3CG1DST_OP2] = */ BS3CG1DSTSIZE_OPERAND,
371 /* [BS3CG1DST_OP3] = */ BS3CG1DSTSIZE_OPERAND,
372 /* [BS3CG1DST_OP4] = */ BS3CG1DSTSIZE_OPERAND,
373 /* [BS3CG1DST_EFL] = */ 4,
374 /* [BS3CG1DST_EFL_UNDEF]=*/ 4,
375
376 /* [BS3CG1DST_AL] = */ 1,
377 /* [BS3CG1DST_CL] = */ 1,
378 /* [BS3CG1DST_DL] = */ 1,
379 /* [BS3CG1DST_BL] = */ 1,
380 /* [BS3CG1DST_AH] = */ 1,
381 /* [BS3CG1DST_CH] = */ 1,
382 /* [BS3CG1DST_DH] = */ 1,
383 /* [BS3CG1DST_BH] = */ 1,
384 /* [BS3CG1DST_SPL] = */ 1,
385 /* [BS3CG1DST_BPL] = */ 1,
386 /* [BS3CG1DST_SIL] = */ 1,
387 /* [BS3CG1DST_DIL] = */ 1,
388 /* [BS3CG1DST_R8L] = */ 1,
389 /* [BS3CG1DST_R9L] = */ 1,
390 /* [BS3CG1DST_R10L] = */ 1,
391 /* [BS3CG1DST_R11L] = */ 1,
392 /* [BS3CG1DST_R12L] = */ 1,
393 /* [BS3CG1DST_R13L] = */ 1,
394 /* [BS3CG1DST_R14L] = */ 1,
395 /* [BS3CG1DST_R15L] = */ 1,
396
397 /* [BS3CG1DST_AX] = */ 2,
398 /* [BS3CG1DST_CX] = */ 2,
399 /* [BS3CG1DST_DX] = */ 2,
400 /* [BS3CG1DST_BX] = */ 2,
401 /* [BS3CG1DST_SP] = */ 2,
402 /* [BS3CG1DST_BP] = */ 2,
403 /* [BS3CG1DST_SI] = */ 2,
404 /* [BS3CG1DST_DI] = */ 2,
405 /* [BS3CG1DST_R8W] = */ 2,
406 /* [BS3CG1DST_R9W] = */ 2,
407 /* [BS3CG1DST_R10W] = */ 2,
408 /* [BS3CG1DST_R11W] = */ 2,
409 /* [BS3CG1DST_R12W] = */ 2,
410 /* [BS3CG1DST_R13W] = */ 2,
411 /* [BS3CG1DST_R14W] = */ 2,
412 /* [BS3CG1DST_R15W] = */ 2,
413
414 /* [BS3CG1DST_EAX] = */ 4,
415 /* [BS3CG1DST_ECX] = */ 4,
416 /* [BS3CG1DST_EDX] = */ 4,
417 /* [BS3CG1DST_EBX] = */ 4,
418 /* [BS3CG1DST_ESP] = */ 4,
419 /* [BS3CG1DST_EBP] = */ 4,
420 /* [BS3CG1DST_ESI] = */ 4,
421 /* [BS3CG1DST_EDI] = */ 4,
422 /* [BS3CG1DST_R8D] = */ 4,
423 /* [BS3CG1DST_R9D] = */ 4,
424 /* [BS3CG1DST_R10D] = */ 4,
425 /* [BS3CG1DST_R11D] = */ 4,
426 /* [BS3CG1DST_R12D] = */ 4,
427 /* [BS3CG1DST_R13D] = */ 4,
428 /* [BS3CG1DST_R14D] = */ 4,
429 /* [BS3CG1DST_R15D] = */ 4,
430
431 /* [BS3CG1DST_RAX] = */ 8,
432 /* [BS3CG1DST_RCX] = */ 8,
433 /* [BS3CG1DST_RDX] = */ 8,
434 /* [BS3CG1DST_RBX] = */ 8,
435 /* [BS3CG1DST_RSP] = */ 8,
436 /* [BS3CG1DST_RBP] = */ 8,
437 /* [BS3CG1DST_RSI] = */ 8,
438 /* [BS3CG1DST_RDI] = */ 8,
439 /* [BS3CG1DST_R8] = */ 8,
440 /* [BS3CG1DST_R9] = */ 8,
441 /* [BS3CG1DST_R10] = */ 8,
442 /* [BS3CG1DST_R11] = */ 8,
443 /* [BS3CG1DST_R12] = */ 8,
444 /* [BS3CG1DST_R13] = */ 8,
445 /* [BS3CG1DST_R14] = */ 8,
446 /* [BS3CG1DST_R15] = */ 8,
447
448 /* [BS3CG1DST_OZ_RAX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
449 /* [BS3CG1DST_OZ_RCX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
450 /* [BS3CG1DST_OZ_RDX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
451 /* [BS3CG1DST_OZ_RBX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
452 /* [BS3CG1DST_OZ_RSP] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
453 /* [BS3CG1DST_OZ_RBP] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
454 /* [BS3CG1DST_OZ_RSI] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
455 /* [BS3CG1DST_OZ_RDI] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
456 /* [BS3CG1DST_OZ_R8] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
457 /* [BS3CG1DST_OZ_R9] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
458 /* [BS3CG1DST_OZ_R10] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
459 /* [BS3CG1DST_OZ_R11] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
460 /* [BS3CG1DST_OZ_R12] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
461 /* [BS3CG1DST_OZ_R13] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
462 /* [BS3CG1DST_OZ_R14] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
463 /* [BS3CG1DST_OZ_R15] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
464
465 /* [BS3CG1DST_CR0] = */ 4,
466 /* [BS3CG1DST_CR4] = */ 4,
467 /* [BS3CG1DST_XCR0] = */ 8,
468
469 /* [BS3CG1DST_FCW] = */ 2,
470 /* [BS3CG1DST_FSW] = */ 2,
471 /* [BS3CG1DST_FTW] = */ 2,
472 /* [BS3CG1DST_FOP] = */ 2,
473 /* [BS3CG1DST_FPUIP] = */ 2,
474 /* [BS3CG1DST_FPUCS] = */ 2,
475 /* [BS3CG1DST_FPUDP] = */ 2,
476 /* [BS3CG1DST_FPUDS] = */ 2,
477 /* [BS3CG1DST_MXCSR] = */ 4,
478 /* [BS3CG1DST_ST0] = */ 12,
479 /* [BS3CG1DST_ST1] = */ 12,
480 /* [BS3CG1DST_ST2] = */ 12,
481 /* [BS3CG1DST_ST3] = */ 12,
482 /* [BS3CG1DST_ST4] = */ 12,
483 /* [BS3CG1DST_ST5] = */ 12,
484 /* [BS3CG1DST_ST6] = */ 12,
485 /* [BS3CG1DST_ST7] = */ 12,
486 /* [BS3CG1DST_MM0] = */ 8,
487 /* [BS3CG1DST_MM1] = */ 8,
488 /* [BS3CG1DST_MM2] = */ 8,
489 /* [BS3CG1DST_MM3] = */ 8,
490 /* [BS3CG1DST_MM4] = */ 8,
491 /* [BS3CG1DST_MM5] = */ 8,
492 /* [BS3CG1DST_MM6] = */ 8,
493 /* [BS3CG1DST_MM7] = */ 8,
494 /* [BS3CG1DST_MM0_LO_ZX] = */ 4,
495 /* [BS3CG1DST_MM1_LO_ZX] = */ 4,
496 /* [BS3CG1DST_MM2_LO_ZX] = */ 4,
497 /* [BS3CG1DST_MM3_LO_ZX] = */ 4,
498 /* [BS3CG1DST_MM4_LO_ZX] = */ 4,
499 /* [BS3CG1DST_MM5_LO_ZX] = */ 4,
500 /* [BS3CG1DST_MM6_LO_ZX] = */ 4,
501 /* [BS3CG1DST_MM7_LO_ZX] = */ 4,
502 /* [BS3CG1DST_XMM0] = */ 16,
503 /* [BS3CG1DST_XMM1] = */ 16,
504 /* [BS3CG1DST_XMM2] = */ 16,
505 /* [BS3CG1DST_XMM3] = */ 16,
506 /* [BS3CG1DST_XMM4] = */ 16,
507 /* [BS3CG1DST_XMM5] = */ 16,
508 /* [BS3CG1DST_XMM6] = */ 16,
509 /* [BS3CG1DST_XMM7] = */ 16,
510 /* [BS3CG1DST_XMM8] = */ 16,
511 /* [BS3CG1DST_XMM9] = */ 16,
512 /* [BS3CG1DST_XMM10] = */ 16,
513 /* [BS3CG1DST_XMM11] = */ 16,
514 /* [BS3CG1DST_XMM12] = */ 16,
515 /* [BS3CG1DST_XMM13] = */ 16,
516 /* [BS3CG1DST_XMM14] = */ 16,
517 /* [BS3CG1DST_XMM15] = */ 16,
518 /* [BS3CG1DST_XMM0_LO] = */ 8,
519 /* [BS3CG1DST_XMM1_LO] = */ 8,
520 /* [BS3CG1DST_XMM2_LO] = */ 8,
521 /* [BS3CG1DST_XMM3_LO] = */ 8,
522 /* [BS3CG1DST_XMM4_LO] = */ 8,
523 /* [BS3CG1DST_XMM5_LO] = */ 8,
524 /* [BS3CG1DST_XMM6_LO] = */ 8,
525 /* [BS3CG1DST_XMM7_LO] = */ 8,
526 /* [BS3CG1DST_XMM8_LO] = */ 8,
527 /* [BS3CG1DST_XMM9_LO] = */ 8,
528 /* [BS3CG1DST_XMM10_LO] = */ 8,
529 /* [BS3CG1DST_XMM11_LO] = */ 8,
530 /* [BS3CG1DST_XMM12_LO] = */ 8,
531 /* [BS3CG1DST_XMM13_LO] = */ 8,
532 /* [BS3CG1DST_XMM14_LO] = */ 8,
533 /* [BS3CG1DST_XMM15_LO] = */ 8,
534 /* [BS3CG1DST_XMM0_HI] = */ 8,
535 /* [BS3CG1DST_XMM1_HI] = */ 8,
536 /* [BS3CG1DST_XMM2_HI] = */ 8,
537 /* [BS3CG1DST_XMM3_HI] = */ 8,
538 /* [BS3CG1DST_XMM4_HI] = */ 8,
539 /* [BS3CG1DST_XMM5_HI] = */ 8,
540 /* [BS3CG1DST_XMM6_HI] = */ 8,
541 /* [BS3CG1DST_XMM7_HI] = */ 8,
542 /* [BS3CG1DST_XMM8_HI] = */ 8,
543 /* [BS3CG1DST_XMM9_HI] = */ 8,
544 /* [BS3CG1DST_XMM10_HI] = */ 8,
545 /* [BS3CG1DST_XMM11_HI] = */ 8,
546 /* [BS3CG1DST_XMM12_HI] = */ 8,
547 /* [BS3CG1DST_XMM13_HI] = */ 8,
548 /* [BS3CG1DST_XMM14_HI] = */ 8,
549 /* [BS3CG1DST_XMM15_HI] = */ 8,
550 /* [BS3CG1DST_XMM0_LO_ZX] = */ 8,
551 /* [BS3CG1DST_XMM1_LO_ZX] = */ 8,
552 /* [BS3CG1DST_XMM2_LO_ZX] = */ 8,
553 /* [BS3CG1DST_XMM3_LO_ZX] = */ 8,
554 /* [BS3CG1DST_XMM4_LO_ZX] = */ 8,
555 /* [BS3CG1DST_XMM5_LO_ZX] = */ 8,
556 /* [BS3CG1DST_XMM6_LO_ZX] = */ 8,
557 /* [BS3CG1DST_XMM7_LO_ZX] = */ 8,
558 /* [BS3CG1DST_XMM8_LO_ZX] = */ 8,
559 /* [BS3CG1DST_XMM9_LO_ZX] = */ 8,
560 /* [BS3CG1DST_XMM10_LO_ZX] = */ 8,
561 /* [BS3CG1DST_XMM11_LO_ZX] = */ 8,
562 /* [BS3CG1DST_XMM12_LO_ZX] = */ 8,
563 /* [BS3CG1DST_XMM13_LO_ZX] = */ 8,
564 /* [BS3CG1DST_XMM14_LO_ZX] = */ 8,
565 /* [BS3CG1DST_XMM15_LO_ZX] = */ 8,
566 /* [BS3CG1DST_XMM0_DW0] = */ 4,
567 /* [BS3CG1DST_XMM1_DW0] = */ 4,
568 /* [BS3CG1DST_XMM2_DW0] = */ 4,
569 /* [BS3CG1DST_XMM3_DW0] = */ 4,
570 /* [BS3CG1DST_XMM4_DW0] = */ 4,
571 /* [BS3CG1DST_XMM5_DW0] = */ 4,
572 /* [BS3CG1DST_XMM6_DW0] = */ 4,
573 /* [BS3CG1DST_XMM7_DW0] = */ 4,
574 /* [BS3CG1DST_XMM8_DW0] = */ 4,
575 /* [BS3CG1DST_XMM9_DW0] = */ 4,
576 /* [BS3CG1DST_XMM10_DW0] = */ 4,
577 /* [BS3CG1DST_XMM11_DW0] = */ 4,
578 /* [BS3CG1DST_XMM12_DW0] = */ 4,
579 /* [BS3CG1DST_XMM13_DW0] = */ 4,
580 /* [BS3CG1DST_XMM14_DW0] = */ 4,
581 /* [BS3CG1DST_XMM15_DW0] = */ 4,
582 /* [BS3CG1DST_XMM0_DW0_ZX] = */ 4,
583 /* [BS3CG1DST_XMM1_DW0_ZX] = */ 4,
584 /* [BS3CG1DST_XMM2_DW0_ZX] = */ 4,
585 /* [BS3CG1DST_XMM3_DW0_ZX] = */ 4,
586 /* [BS3CG1DST_XMM4_DW0_ZX] = */ 4,
587 /* [BS3CG1DST_XMM5_DW0_ZX] = */ 4,
588 /* [BS3CG1DST_XMM6_DW0_ZX] = */ 4,
589 /* [BS3CG1DST_XMM7_DW0_ZX] = */ 4,
590 /* [BS3CG1DST_XMM8_DW0_ZX] = */ 4,
591 /* [BS3CG1DST_XMM9_DW0_ZX] = */ 4,
592 /* [BS3CG1DST_XMM10_DW0_ZX] =*/ 4,
593 /* [BS3CG1DST_XMM11_DW0_ZX] =*/ 4,
594 /* [BS3CG1DST_XMM12_DW0_ZX] =*/ 4,
595 /* [BS3CG1DST_XMM13_DW0_ZX] =*/ 4,
596 /* [BS3CG1DST_XMM14_DW0_ZX] =*/ 4,
597 /* [BS3CG1DST_XMM15_DW0_ZX] =*/ 4,
598 /* [BS3CG1DST_XMM0_HI96] = */ 12,
599 /* [BS3CG1DST_XMM1_HI96] = */ 12,
600 /* [BS3CG1DST_XMM2_HI96] = */ 12,
601 /* [BS3CG1DST_XMM3_HI96] = */ 12,
602 /* [BS3CG1DST_XMM4_HI96] = */ 12,
603 /* [BS3CG1DST_XMM5_HI96] = */ 12,
604 /* [BS3CG1DST_XMM6_HI96] = */ 12,
605 /* [BS3CG1DST_XMM7_HI96] = */ 12,
606 /* [BS3CG1DST_XMM8_HI96] = */ 12,
607 /* [BS3CG1DST_XMM9_HI96] = */ 12,
608 /* [BS3CG1DST_XMM10_HI96] =*/ 12,
609 /* [BS3CG1DST_XMM11_HI96] =*/ 12,
610 /* [BS3CG1DST_XMM12_HI96] =*/ 12,
611 /* [BS3CG1DST_XMM13_HI96] =*/ 12,
612 /* [BS3CG1DST_XMM14_HI96] =*/ 12,
613 /* [BS3CG1DST_XMM15_HI96] =*/ 12,
614 /* [BS3CG1DST_YMM0] = */ 32,
615 /* [BS3CG1DST_YMM1] = */ 32,
616 /* [BS3CG1DST_YMM2] = */ 32,
617 /* [BS3CG1DST_YMM3] = */ 32,
618 /* [BS3CG1DST_YMM4] = */ 32,
619 /* [BS3CG1DST_YMM5] = */ 32,
620 /* [BS3CG1DST_YMM6] = */ 32,
621 /* [BS3CG1DST_YMM7] = */ 32,
622 /* [BS3CG1DST_YMM8] = */ 32,
623 /* [BS3CG1DST_YMM9] = */ 32,
624 /* [BS3CG1DST_YMM10] = */ 32,
625 /* [BS3CG1DST_YMM11] = */ 32,
626 /* [BS3CG1DST_YMM12] = */ 32,
627 /* [BS3CG1DST_YMM13] = */ 32,
628 /* [BS3CG1DST_YMM14] = */ 32,
629 /* [BS3CG1DST_YMM15] = */ 32,
630
631 /* [BS3CG1DST_VALUE_XCPT] = */ 1,
632};
633AssertCompile(RT_ELEMENTS(g_acbBs3Cg1DstFields) == BS3CG1DST_END);
634
635/** Destination field offset indexed by bBS3CG1DST.
636 * Zero means operand size sized. */
637static const unsigned g_aoffBs3Cg1DstFields[] =
638{
639 /* [BS3CG1DST_INVALID] = */ ~0U,
640 /* [BS3CG1DST_OP1] = */ ~0U,
641 /* [BS3CG1DST_OP2] = */ ~0U,
642 /* [BS3CG1DST_OP3] = */ ~0U,
643 /* [BS3CG1DST_OP4] = */ ~0U,
644 /* [BS3CG1DST_EFL] = */ RT_OFFSETOF(BS3REGCTX, rflags),
645 /* [BS3CG1DST_EFL_UNDEF]=*/ ~0, /* special field */
646
647 /* [BS3CG1DST_AL] = */ RT_OFFSETOF(BS3REGCTX, rax.u8),
648 /* [BS3CG1DST_CL] = */ RT_OFFSETOF(BS3REGCTX, rcx.u8),
649 /* [BS3CG1DST_DL] = */ RT_OFFSETOF(BS3REGCTX, rdx.u8),
650 /* [BS3CG1DST_BL] = */ RT_OFFSETOF(BS3REGCTX, rbx.u8),
651 /* [BS3CG1DST_AH] = */ RT_OFFSETOF(BS3REGCTX, rax.b.bHi),
652 /* [BS3CG1DST_CH] = */ RT_OFFSETOF(BS3REGCTX, rcx.b.bHi),
653 /* [BS3CG1DST_DH] = */ RT_OFFSETOF(BS3REGCTX, rdx.b.bHi),
654 /* [BS3CG1DST_BH] = */ RT_OFFSETOF(BS3REGCTX, rbx.b.bHi),
655 /* [BS3CG1DST_SPL] = */ RT_OFFSETOF(BS3REGCTX, rsp.u8),
656 /* [BS3CG1DST_BPL] = */ RT_OFFSETOF(BS3REGCTX, rbp.u8),
657 /* [BS3CG1DST_SIL] = */ RT_OFFSETOF(BS3REGCTX, rsi.u8),
658 /* [BS3CG1DST_DIL] = */ RT_OFFSETOF(BS3REGCTX, rdi.u8),
659 /* [BS3CG1DST_R8L] = */ RT_OFFSETOF(BS3REGCTX, r8.u8),
660 /* [BS3CG1DST_R9L] = */ RT_OFFSETOF(BS3REGCTX, r9.u8),
661 /* [BS3CG1DST_R10L] = */ RT_OFFSETOF(BS3REGCTX, r10.u8),
662 /* [BS3CG1DST_R11L] = */ RT_OFFSETOF(BS3REGCTX, r11.u8),
663 /* [BS3CG1DST_R12L] = */ RT_OFFSETOF(BS3REGCTX, r12.u8),
664 /* [BS3CG1DST_R13L] = */ RT_OFFSETOF(BS3REGCTX, r13.u8),
665 /* [BS3CG1DST_R14L] = */ RT_OFFSETOF(BS3REGCTX, r14.u8),
666 /* [BS3CG1DST_R15L] = */ RT_OFFSETOF(BS3REGCTX, r15.u8),
667
668 /* [BS3CG1DST_AX] = */ RT_OFFSETOF(BS3REGCTX, rax.u16),
669 /* [BS3CG1DST_CX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u16),
670 /* [BS3CG1DST_DX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u16),
671 /* [BS3CG1DST_BX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u16),
672 /* [BS3CG1DST_SP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u16),
673 /* [BS3CG1DST_BP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u16),
674 /* [BS3CG1DST_SI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u16),
675 /* [BS3CG1DST_DI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u16),
676 /* [BS3CG1DST_R8W] = */ RT_OFFSETOF(BS3REGCTX, r8.u16),
677 /* [BS3CG1DST_R9W] = */ RT_OFFSETOF(BS3REGCTX, r9.u16),
678 /* [BS3CG1DST_R10W] = */ RT_OFFSETOF(BS3REGCTX, r10.u16),
679 /* [BS3CG1DST_R11W] = */ RT_OFFSETOF(BS3REGCTX, r11.u16),
680 /* [BS3CG1DST_R12W] = */ RT_OFFSETOF(BS3REGCTX, r12.u16),
681 /* [BS3CG1DST_R13W] = */ RT_OFFSETOF(BS3REGCTX, r13.u16),
682 /* [BS3CG1DST_R14W] = */ RT_OFFSETOF(BS3REGCTX, r14.u16),
683 /* [BS3CG1DST_R15W] = */ RT_OFFSETOF(BS3REGCTX, r15.u16),
684
685 /* [BS3CG1DST_EAX] = */ RT_OFFSETOF(BS3REGCTX, rax.u32),
686 /* [BS3CG1DST_ECX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u32),
687 /* [BS3CG1DST_EDX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u32),
688 /* [BS3CG1DST_EBX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u32),
689 /* [BS3CG1DST_ESP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u32),
690 /* [BS3CG1DST_EBP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u32),
691 /* [BS3CG1DST_ESI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u32),
692 /* [BS3CG1DST_EDI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u32),
693 /* [BS3CG1DST_R8D] = */ RT_OFFSETOF(BS3REGCTX, r8.u32),
694 /* [BS3CG1DST_R9D] = */ RT_OFFSETOF(BS3REGCTX, r9.u32),
695 /* [BS3CG1DST_R10D] = */ RT_OFFSETOF(BS3REGCTX, r10.u32),
696 /* [BS3CG1DST_R11D] = */ RT_OFFSETOF(BS3REGCTX, r11.u32),
697 /* [BS3CG1DST_R12D] = */ RT_OFFSETOF(BS3REGCTX, r12.u32),
698 /* [BS3CG1DST_R13D] = */ RT_OFFSETOF(BS3REGCTX, r13.u32),
699 /* [BS3CG1DST_R14D] = */ RT_OFFSETOF(BS3REGCTX, r14.u32),
700 /* [BS3CG1DST_R15D] = */ RT_OFFSETOF(BS3REGCTX, r15.u32),
701
702 /* [BS3CG1DST_RAX] = */ RT_OFFSETOF(BS3REGCTX, rax.u64),
703 /* [BS3CG1DST_RCX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u64),
704 /* [BS3CG1DST_RDX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u64),
705 /* [BS3CG1DST_RBX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u64),
706 /* [BS3CG1DST_RSP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u64),
707 /* [BS3CG1DST_RBP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u64),
708 /* [BS3CG1DST_RSI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u64),
709 /* [BS3CG1DST_RDI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u64),
710 /* [BS3CG1DST_R8] = */ RT_OFFSETOF(BS3REGCTX, r8.u64),
711 /* [BS3CG1DST_R9] = */ RT_OFFSETOF(BS3REGCTX, r9.u64),
712 /* [BS3CG1DST_R10] = */ RT_OFFSETOF(BS3REGCTX, r10.u64),
713 /* [BS3CG1DST_R11] = */ RT_OFFSETOF(BS3REGCTX, r11.u64),
714 /* [BS3CG1DST_R12] = */ RT_OFFSETOF(BS3REGCTX, r12.u64),
715 /* [BS3CG1DST_R13] = */ RT_OFFSETOF(BS3REGCTX, r13.u64),
716 /* [BS3CG1DST_R14] = */ RT_OFFSETOF(BS3REGCTX, r14.u64),
717 /* [BS3CG1DST_R15] = */ RT_OFFSETOF(BS3REGCTX, r15.u64),
718
719 /* [BS3CG1DST_OZ_RAX] = */ RT_OFFSETOF(BS3REGCTX, rax),
720 /* [BS3CG1DST_OZ_RCX] = */ RT_OFFSETOF(BS3REGCTX, rcx),
721 /* [BS3CG1DST_OZ_RDX] = */ RT_OFFSETOF(BS3REGCTX, rdx),
722 /* [BS3CG1DST_OZ_RBX] = */ RT_OFFSETOF(BS3REGCTX, rbx),
723 /* [BS3CG1DST_OZ_RSP] = */ RT_OFFSETOF(BS3REGCTX, rsp),
724 /* [BS3CG1DST_OZ_RBP] = */ RT_OFFSETOF(BS3REGCTX, rbp),
725 /* [BS3CG1DST_OZ_RSI] = */ RT_OFFSETOF(BS3REGCTX, rsi),
726 /* [BS3CG1DST_OZ_RDI] = */ RT_OFFSETOF(BS3REGCTX, rdi),
727 /* [BS3CG1DST_OZ_R8] = */ RT_OFFSETOF(BS3REGCTX, r8),
728 /* [BS3CG1DST_OZ_R9] = */ RT_OFFSETOF(BS3REGCTX, r9),
729 /* [BS3CG1DST_OZ_R10] = */ RT_OFFSETOF(BS3REGCTX, r10),
730 /* [BS3CG1DST_OZ_R11] = */ RT_OFFSETOF(BS3REGCTX, r11),
731 /* [BS3CG1DST_OZ_R12] = */ RT_OFFSETOF(BS3REGCTX, r12),
732 /* [BS3CG1DST_OZ_R13] = */ RT_OFFSETOF(BS3REGCTX, r13),
733 /* [BS3CG1DST_OZ_R14] = */ RT_OFFSETOF(BS3REGCTX, r14),
734 /* [BS3CG1DST_OZ_R15] = */ RT_OFFSETOF(BS3REGCTX, r15),
735
736 /* [BS3CG1DST_CR0] = */ RT_OFFSETOF(BS3REGCTX, cr0),
737 /* [BS3CG1DST_CR4] = */ RT_OFFSETOF(BS3REGCTX, cr4),
738 /* [BS3CG1DST_XCR0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, fXcr0Saved),
739
740 /* [BS3CG1DST_FCW] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FCW),
741 /* [BS3CG1DST_FSW] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FSW),
742 /* [BS3CG1DST_FTW] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FTW),
743 /* [BS3CG1DST_FOP] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FOP),
744 /* [BS3CG1DST_FPUIP] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FPUIP),
745 /* [BS3CG1DST_FPUCS] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.CS),
746 /* [BS3CG1DST_FPUDP] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.FPUDP),
747 /* [BS3CG1DST_FPUDS] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.DS),
748 /* [BS3CG1DST_MXCSR] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.MXCSR),
749 /* [BS3CG1DST_ST0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[0]),
750 /* [BS3CG1DST_ST1] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[1]),
751 /* [BS3CG1DST_ST2] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[2]),
752 /* [BS3CG1DST_ST3] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[3]),
753 /* [BS3CG1DST_ST4] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[4]),
754 /* [BS3CG1DST_ST5] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[5]),
755 /* [BS3CG1DST_ST6] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[6]),
756 /* [BS3CG1DST_ST7] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[7]),
757 /* [BS3CG1DST_MM0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[0]),
758 /* [BS3CG1DST_MM1] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[1]),
759 /* [BS3CG1DST_MM2] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[2]),
760 /* [BS3CG1DST_MM3] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[3]),
761 /* [BS3CG1DST_MM4] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[4]),
762 /* [BS3CG1DST_MM5] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[5]),
763 /* [BS3CG1DST_MM6] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[6]),
764 /* [BS3CG1DST_MM7] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[7]),
765 /* [BS3CG1DST_MM0_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[0]),
766 /* [BS3CG1DST_MM1_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[1]),
767 /* [BS3CG1DST_MM2_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[2]),
768 /* [BS3CG1DST_MM3_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[3]),
769 /* [BS3CG1DST_MM4_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[4]),
770 /* [BS3CG1DST_MM5_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[5]),
771 /* [BS3CG1DST_MM6_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[6]),
772 /* [BS3CG1DST_MM7_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aRegs[7]),
773
774 /* [BS3CG1DST_XMM0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
775 /* [BS3CG1DST_XMM1] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
776 /* [BS3CG1DST_XMM2] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
777 /* [BS3CG1DST_XMM3] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
778 /* [BS3CG1DST_XMM4] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
779 /* [BS3CG1DST_XMM5] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
780 /* [BS3CG1DST_XMM6] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
781 /* [BS3CG1DST_XMM7] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
782 /* [BS3CG1DST_XMM8] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
783 /* [BS3CG1DST_XMM9] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
784 /* [BS3CG1DST_XMM10] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
785 /* [BS3CG1DST_XMM11] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
786 /* [BS3CG1DST_XMM12] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
787 /* [BS3CG1DST_XMM13] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
788 /* [BS3CG1DST_XMM14] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
789 /* [BS3CG1DST_XMM15] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
790 /* [BS3CG1DST_XMM0_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
791 /* [BS3CG1DST_XMM1_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
792 /* [BS3CG1DST_XMM2_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
793 /* [BS3CG1DST_XMM3_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
794 /* [BS3CG1DST_XMM4_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
795 /* [BS3CG1DST_XMM5_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
796 /* [BS3CG1DST_XMM6_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
797 /* [BS3CG1DST_XMM7_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
798 /* [BS3CG1DST_XMM8_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
799 /* [BS3CG1DST_XMM9_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
800 /* [BS3CG1DST_XMM10_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
801 /* [BS3CG1DST_XMM11_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
802 /* [BS3CG1DST_XMM12_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
803 /* [BS3CG1DST_XMM13_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
804 /* [BS3CG1DST_XMM14_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
805 /* [BS3CG1DST_XMM15_LO] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
806 /* [BS3CG1DST_XMM0_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]) + sizeof(uint64_t),
807 /* [BS3CG1DST_XMM1_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]) + sizeof(uint64_t),
808 /* [BS3CG1DST_XMM2_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]) + sizeof(uint64_t),
809 /* [BS3CG1DST_XMM3_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]) + sizeof(uint64_t),
810 /* [BS3CG1DST_XMM4_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]) + sizeof(uint64_t),
811 /* [BS3CG1DST_XMM5_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]) + sizeof(uint64_t),
812 /* [BS3CG1DST_XMM6_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]) + sizeof(uint64_t),
813 /* [BS3CG1DST_XMM7_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]) + sizeof(uint64_t),
814 /* [BS3CG1DST_XMM8_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]) + sizeof(uint64_t),
815 /* [BS3CG1DST_XMM9_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]) + sizeof(uint64_t),
816 /* [BS3CG1DST_XMM10_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]) + sizeof(uint64_t),
817 /* [BS3CG1DST_XMM11_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]) + sizeof(uint64_t),
818 /* [BS3CG1DST_XMM12_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]) + sizeof(uint64_t),
819 /* [BS3CG1DST_XMM13_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]) + sizeof(uint64_t),
820 /* [BS3CG1DST_XMM14_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]) + sizeof(uint64_t),
821 /* [BS3CG1DST_XMM15_HI] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]) + sizeof(uint64_t),
822 /* [BS3CG1DST_XMM0_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
823 /* [BS3CG1DST_XMM1_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
824 /* [BS3CG1DST_XMM2_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
825 /* [BS3CG1DST_XMM3_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
826 /* [BS3CG1DST_XMM4_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
827 /* [BS3CG1DST_XMM5_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
828 /* [BS3CG1DST_XMM6_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
829 /* [BS3CG1DST_XMM7_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
830 /* [BS3CG1DST_XMM8_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
831 /* [BS3CG1DST_XMM9_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
832 /* [BS3CG1DST_XMM10_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
833 /* [BS3CG1DST_XMM11_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
834 /* [BS3CG1DST_XMM12_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
835 /* [BS3CG1DST_XMM13_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
836 /* [BS3CG1DST_XMM14_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
837 /* [BS3CG1DST_XMM15_LO_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
838 /* [BS3CG1DST_XMM0_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
839 /* [BS3CG1DST_XMM1_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
840 /* [BS3CG1DST_XMM2_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
841 /* [BS3CG1DST_XMM3_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
842 /* [BS3CG1DST_XMM4_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
843 /* [BS3CG1DST_XMM5_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
844 /* [BS3CG1DST_XMM6_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
845 /* [BS3CG1DST_XMM7_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
846 /* [BS3CG1DST_XMM8_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
847 /* [BS3CG1DST_XMM9_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
848 /* [BS3CG1DST_XMM10_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
849 /* [BS3CG1DST_XMM11_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
850 /* [BS3CG1DST_XMM12_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
851 /* [BS3CG1DST_XMM13_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
852 /* [BS3CG1DST_XMM14_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
853 /* [BS3CG1DST_XMM15_DW0] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
854 /* [BS3CG1DST_XMM0_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0]),
855 /* [BS3CG1DST_XMM1_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1]),
856 /* [BS3CG1DST_XMM2_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2]),
857 /* [BS3CG1DST_XMM3_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3]),
858 /* [BS3CG1DST_XMM4_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4]),
859 /* [BS3CG1DST_XMM5_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5]),
860 /* [BS3CG1DST_XMM6_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6]),
861 /* [BS3CG1DST_XMM7_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7]),
862 /* [BS3CG1DST_XMM8_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8]),
863 /* [BS3CG1DST_XMM9_DW0_ZX] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9]),
864 /* [BS3CG1DST_XMM10_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10]),
865 /* [BS3CG1DST_XMM11_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11]),
866 /* [BS3CG1DST_XMM12_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12]),
867 /* [BS3CG1DST_XMM13_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13]),
868 /* [BS3CG1DST_XMM14_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14]),
869 /* [BS3CG1DST_XMM15_DW0_ZX] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15]),
870 /* [BS3CG1DST_XMM0_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[0].au32[1]),
871 /* [BS3CG1DST_XMM1_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[1].au32[1]),
872 /* [BS3CG1DST_XMM2_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[2].au32[1]),
873 /* [BS3CG1DST_XMM3_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[3].au32[1]),
874 /* [BS3CG1DST_XMM4_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[4].au32[1]),
875 /* [BS3CG1DST_XMM5_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[5].au32[1]),
876 /* [BS3CG1DST_XMM6_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[6].au32[1]),
877 /* [BS3CG1DST_XMM7_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[7].au32[1]),
878 /* [BS3CG1DST_XMM8_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[8].au32[1]),
879 /* [BS3CG1DST_XMM9_HI96] = */ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[9].au32[1]),
880 /* [BS3CG1DST_XMM10_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[10].au32[1]),
881 /* [BS3CG1DST_XMM11_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[11].au32[1]),
882 /* [BS3CG1DST_XMM12_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[12].au32[1]),
883 /* [BS3CG1DST_XMM13_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[13].au32[1]),
884 /* [BS3CG1DST_XMM14_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[14].au32[1]),
885 /* [BS3CG1DST_XMM15_HI96] =*/ sizeof(BS3REGCTX) + RT_OFFSETOF(BS3EXTCTX, Ctx.x87.aXMM[15].au32[1]),
886
887 /* [BS3CG1DST_YMM0] = */ ~0U,
888 /* [BS3CG1DST_YMM1] = */ ~0U,
889 /* [BS3CG1DST_YMM2] = */ ~0U,
890 /* [BS3CG1DST_YMM3] = */ ~0U,
891 /* [BS3CG1DST_YMM4] = */ ~0U,
892 /* [BS3CG1DST_YMM5] = */ ~0U,
893 /* [BS3CG1DST_YMM6] = */ ~0U,
894 /* [BS3CG1DST_YMM7] = */ ~0U,
895 /* [BS3CG1DST_YMM8] = */ ~0U,
896 /* [BS3CG1DST_YMM9] = */ ~0U,
897 /* [BS3CG1DST_YMM10] = */ ~0U,
898 /* [BS3CG1DST_YMM11] = */ ~0U,
899 /* [BS3CG1DST_YMM12] = */ ~0U,
900 /* [BS3CG1DST_YMM13] = */ ~0U,
901 /* [BS3CG1DST_YMM14] = */ ~0U,
902 /* [BS3CG1DST_YMM15] = */ ~0U,
903
904 /* [BS3CG1DST_VALUE_XCPT] = */ ~0U,
905};
906AssertCompile(RT_ELEMENTS(g_aoffBs3Cg1DstFields) == BS3CG1DST_END);
907
908/** Destination field names. */
909static const struct { char sz[12]; } g_aszBs3Cg1DstFields[] =
910{
911 { "INVALID" },
912 { "OP1" },
913 { "OP2" },
914 { "OP3" },
915 { "OP4" },
916 { "EFL" },
917 { "EFL_UND" },
918
919 { "AL" },
920 { "CL" },
921 { "DL" },
922 { "BL" },
923 { "AH" },
924 { "CH" },
925 { "DH" },
926 { "BH" },
927 { "SPL" },
928 { "BPL" },
929 { "SIL" },
930 { "DIL" },
931 { "R8L" },
932 { "R9L" },
933 { "R10L" },
934 { "R11L" },
935 { "R12L" },
936 { "R13L" },
937 { "R14L" },
938 { "R15L" },
939
940 { "AX" },
941 { "CX" },
942 { "DX" },
943 { "BX" },
944 { "SP" },
945 { "BP" },
946 { "SI" },
947 { "DI" },
948 { "R8W" },
949 { "R9W" },
950 { "R10W" },
951 { "R11W" },
952 { "R12W" },
953 { "R13W" },
954 { "R14W" },
955 { "R15W" },
956
957 { "EAX" },
958 { "ECX" },
959 { "EDX" },
960 { "EBX" },
961 { "ESP" },
962 { "EBP" },
963 { "ESI" },
964 { "EDI" },
965 { "R8D" },
966 { "R9D" },
967 { "R10D" },
968 { "R11D" },
969 { "R12D" },
970 { "R13D" },
971 { "R14D" },
972 { "R15D" },
973
974 { "RAX" },
975 { "RCX" },
976 { "RDX" },
977 { "RBX" },
978 { "RSP" },
979 { "RBP" },
980 { "RSI" },
981 { "RDI" },
982 { "R8" },
983 { "R9" },
984 { "R10" },
985 { "R11" },
986 { "R12" },
987 { "R13" },
988 { "R14" },
989 { "R15" },
990
991 { "OZ_RAX" },
992 { "OZ_RCX" },
993 { "OZ_RDX" },
994 { "OZ_RBX" },
995 { "OZ_RSP" },
996 { "OZ_RBP" },
997 { "OZ_RSI" },
998 { "OZ_RDI" },
999 { "OZ_R8" },
1000 { "OZ_R9" },
1001 { "OZ_R10" },
1002 { "OZ_R11" },
1003 { "OZ_R12" },
1004 { "OZ_R13" },
1005 { "OZ_R14" },
1006 { "OZ_R15" },
1007
1008 { "CR0" },
1009 { "CR4" },
1010 { "XCR0" },
1011
1012 { "FCW" },
1013 { "FSW" },
1014 { "FTW" },
1015 { "FOP" },
1016 { "FPUIP" },
1017 { "FPUCS" },
1018 { "FPUDP" },
1019 { "FPUDS" },
1020 { "MXCSR" },
1021 { "ST0" },
1022 { "ST1" },
1023 { "ST2" },
1024 { "ST3" },
1025 { "ST4" },
1026 { "ST5" },
1027 { "ST6" },
1028 { "ST7" },
1029 { "MM0" },
1030 { "MM1" },
1031 { "MM2" },
1032 { "MM3" },
1033 { "MM4" },
1034 { "MM5" },
1035 { "MM6" },
1036 { "MM7" },
1037 { "MM0_LO_ZX" },
1038 { "MM1_LO_ZX" },
1039 { "MM2_LO_ZX" },
1040 { "MM3_LO_ZX" },
1041 { "MM4_LO_ZX" },
1042 { "MM5_LO_ZX" },
1043 { "MM6_LO_ZX" },
1044 { "MM7_LO_ZX" },
1045 { "XMM0" },
1046 { "XMM1" },
1047 { "XMM2" },
1048 { "XMM3" },
1049 { "XMM4" },
1050 { "XMM5" },
1051 { "XMM6" },
1052 { "XMM7" },
1053 { "XMM8" },
1054 { "XMM9" },
1055 { "XMM10" },
1056 { "XMM11" },
1057 { "XMM12" },
1058 { "XMM13" },
1059 { "XMM14" },
1060 { "XMM15" },
1061 { "XMM0_LO" },
1062 { "XMM1_LO" },
1063 { "XMM2_LO" },
1064 { "XMM3_LO" },
1065 { "XMM4_LO" },
1066 { "XMM5_LO" },
1067 { "XMM6_LO" },
1068 { "XMM7_LO" },
1069 { "XMM8_LO" },
1070 { "XMM9_LO" },
1071 { "XMM10_LO" },
1072 { "XMM11_LO" },
1073 { "XMM12_LO" },
1074 { "XMM13_LO" },
1075 { "XMM14_LO" },
1076 { "XMM15_LO" },
1077 { "XMM0_HI" },
1078 { "XMM1_HI" },
1079 { "XMM2_HI" },
1080 { "XMM3_HI" },
1081 { "XMM4_HI" },
1082 { "XMM5_HI" },
1083 { "XMM6_HI" },
1084 { "XMM7_HI" },
1085 { "XMM8_HI" },
1086 { "XMM9_HI" },
1087 { "XMM10_HI" },
1088 { "XMM11_HI" },
1089 { "XMM12_HI" },
1090 { "XMM13_HI" },
1091 { "XMM14_HI" },
1092 { "XMM15_HI" },
1093 { "XMM0_LO_ZX" },
1094 { "XMM1_LO_ZX" },
1095 { "XMM2_LO_ZX" },
1096 { "XMM3_LO_ZX" },
1097 { "XMM4_LO_ZX" },
1098 { "XMM5_LO_ZX" },
1099 { "XMM6_LO_ZX" },
1100 { "XMM7_LO_ZX" },
1101 { "XMM8_LO_ZX" },
1102 { "XMM9_LO_ZX" },
1103 { "XMM10_LO_ZX" },
1104 { "XMM11_LO_ZX" },
1105 { "XMM12_LO_ZX" },
1106 { "XMM13_LO_ZX" },
1107 { "XMM14_LO_ZX" },
1108 { "XMM15_LO_ZX" },
1109 { "XMM0_DW0" },
1110 { "XMM1_DW0" },
1111 { "XMM2_DW0" },
1112 { "XMM3_DW0" },
1113 { "XMM4_DW0" },
1114 { "XMM5_DW0" },
1115 { "XMM6_DW0" },
1116 { "XMM7_DW0" },
1117 { "XMM8_DW0" },
1118 { "XMM9_DW0" },
1119 { "XMM10_DW0" },
1120 { "XMM11_DW0" },
1121 { "XMM12_DW0" },
1122 { "XMM13_DW0" },
1123 { "XMM14_DW0" },
1124 { "XMM15_DW0" },
1125 { "XMM0_DW0_ZX" },
1126 { "XMM1_DW0_ZX" },
1127 { "XMM2_DW0_ZX" },
1128 { "XMM3_DW0_ZX" },
1129 { "XMM4_DW0_ZX" },
1130 { "XMM5_DW0_ZX" },
1131 { "XMM6_DW0_ZX" },
1132 { "XMM7_DW0_ZX" },
1133 { "XMM8_DW0_ZX" },
1134 { "XMM9_DW0_ZX" },
1135 { "XMM10_DW0_ZX" },
1136 { "XMM11_DW0_ZX" },
1137 { "XMM12_DW0_ZX" },
1138 { "XMM13_DW0_ZX" },
1139 { "XMM14_DW0_ZX" },
1140 { "XMM15_DW0_ZX" },
1141 { "XMM0_HI96" },
1142 { "XMM1_HI96" },
1143 { "XMM2_HI96" },
1144 { "XMM3_HI96" },
1145 { "XMM4_HI96" },
1146 { "XMM5_HI96" },
1147 { "XMM6_HI96" },
1148 { "XMM7_HI96" },
1149 { "XMM8_HI96" },
1150 { "XMM9_HI96" },
1151 { "XMM10_HI96" },
1152 { "XMM11_HI96" },
1153 { "XMM12_HI96" },
1154 { "XMM13_HI96" },
1155 { "XMM14_HI96" },
1156 { "XMM15_HI96" },
1157 { "YMM0" },
1158 { "YMM1" },
1159 { "YMM2" },
1160 { "YMM3" },
1161 { "YMM4" },
1162 { "YMM5" },
1163 { "YMM6" },
1164 { "YMM7" },
1165 { "YMM8" },
1166 { "YMM9" },
1167 { "YMM10" },
1168 { "YMM11" },
1169 { "YMM12" },
1170 { "YMM13" },
1171 { "YMM14" },
1172 { "YMM15" },
1173
1174 { "VALXCPT" },
1175};
1176AssertCompile(RT_ELEMENTS(g_aszBs3Cg1DstFields) >= BS3CG1DST_END);
1177AssertCompile(RT_ELEMENTS(g_aszBs3Cg1DstFields) == BS3CG1DST_END);
1178
1179
1180#if 0
1181static const struct
1182{
1183 uint8_t cbPrefixes;
1184 uint8_t abPrefixes[14];
1185 uint16_t fEffective;
1186} g_aPrefixVariations[] =
1187{
1188 { 0, { 0x00 }, BS3CG1_PF_NONE },
1189
1190 { 1, { P_OZ }, BS3CG1_PF_OZ },
1191 { 1, { P_CS }, BS3CG1_PF_CS },
1192 { 1, { P_DS }, BS3CG1_PF_DS },
1193 { 1, { P_ES }, BS3CG1_PF_ES },
1194 { 1, { P_FS }, BS3CG1_PF_FS },
1195 { 1, { P_GS }, BS3CG1_PF_GS },
1196 { 1, { P_SS }, BS3CG1_PF_SS },
1197 { 1, { P_LK }, BS3CG1_PF_LK },
1198
1199 { 2, { P_CS, P_OZ, }, BS3CG1_PF_CS | BS3CFG1_PF_OZ },
1200 { 2, { P_DS, P_OZ, }, BS3CG1_PF_DS | BS3CFG1_PF_OZ },
1201 { 2, { P_ES, P_OZ, }, BS3CG1_PF_ES | BS3CFG1_PF_OZ },
1202 { 2, { P_FS, P_OZ, }, BS3CG1_PF_FS | BS3CFG1_PF_OZ },
1203 { 2, { P_GS, P_OZ, }, BS3CG1_PF_GS | BS3CFG1_PF_OZ },
1204 { 2, { P_GS, P_OZ, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1205 { 2, { P_SS, P_OZ, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1206
1207 { 2, { P_OZ, P_CS, }, BS3CG1_PF_CS | BS3CFG1_PF_OZ },
1208 { 2, { P_OZ, P_DS, }, BS3CG1_PF_DS | BS3CFG1_PF_OZ },
1209 { 2, { P_OZ, P_ES, }, BS3CG1_PF_ES | BS3CFG1_PF_OZ },
1210 { 2, { P_OZ, P_FS, }, BS3CG1_PF_FS | BS3CFG1_PF_OZ },
1211 { 2, { P_OZ, P_GS, }, BS3CG1_PF_GS | BS3CFG1_PF_OZ },
1212 { 2, { P_OZ, P_GS, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1213 { 2, { P_OZ, P_SS, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
1214};
1215
1216static const uint16_t g_afPfxKindToIgnoredFlags[BS3CG1PFXKIND_END] =
1217{
1218 /* [BS3CG1PFXKIND_INVALID] = */ UINT16_MAX,
1219 /* [BS3CG1PFXKIND_MODRM] = */ 0,
1220 /* [BS3CG1PFXKIND_MODRM_NO_OP_SIZES] = */ BS3CG1_PF_OZ | BS3CG1_PF_W,
1221};
1222
1223#endif
1224
1225
1226/**
1227 * Checks if >= 16 byte SSE alignment are exempted for the exception type.
1228 *
1229 * @returns true / false.
1230 * @param enmXcptType The type to check.
1231 */
1232static bool BS3_NEAR_CODE Bs3Cg1XcptTypeIsUnaligned(BS3CG1XCPTTYPE enmXcptType)
1233{
1234 switch (enmXcptType)
1235 {
1236 case BS3CG1XCPTTYPE_1:
1237 case BS3CG1XCPTTYPE_2:
1238 case BS3CG1XCPTTYPE_4:
1239 return false;
1240 case BS3CG1XCPTTYPE_NONE:
1241 case BS3CG1XCPTTYPE_3:
1242 case BS3CG1XCPTTYPE_4UA:
1243 case BS3CG1XCPTTYPE_5:
1244 return true;
1245 default:
1246 return false;
1247 }
1248}
1249
1250
1251/**
1252 * Checks if >= 16 byte AVX alignment are exempted for the exception type.
1253 *
1254 * @returns true / false.
1255 * @param enmXcptType The type to check.
1256 */
1257static bool BS3_NEAR_CODE Bs3Cg1XcptTypeIsVexUnaligned(BS3CG1XCPTTYPE enmXcptType)
1258{
1259 switch (enmXcptType)
1260 {
1261 case BS3CG1XCPTTYPE_1:
1262 return false;
1263
1264 case BS3CG1XCPTTYPE_NONE:
1265 case BS3CG1XCPTTYPE_2:
1266 case BS3CG1XCPTTYPE_3:
1267 case BS3CG1XCPTTYPE_4:
1268 case BS3CG1XCPTTYPE_4UA:
1269 case BS3CG1XCPTTYPE_5:
1270 case BS3CG1XCPTTYPE_6:
1271 case BS3CG1XCPTTYPE_11:
1272 case BS3CG1XCPTTYPE_12:
1273 return true;
1274
1275 default:
1276 return false;
1277 }
1278}
1279
1280
1281DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertReqPrefix(PBS3CG1STATE pThis, unsigned offDst)
1282{
1283 switch (pThis->enmPrefixKind)
1284 {
1285 case BS3CG1PFXKIND_REQ_66:
1286 pThis->abCurInstr[offDst] = 0x66;
1287 break;
1288 case BS3CG1PFXKIND_REQ_F2:
1289 pThis->abCurInstr[offDst] = 0xf2;
1290 break;
1291 case BS3CG1PFXKIND_REQ_F3:
1292 pThis->abCurInstr[offDst] = 0xf3;
1293 break;
1294 default:
1295 return offDst;
1296 }
1297 return offDst + 1;
1298}
1299
1300
1301DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertOpcodes(PBS3CG1STATE pThis, unsigned offDst)
1302{
1303 switch (pThis->cbOpcodes)
1304 {
1305 case 4: pThis->abCurInstr[offDst + 3] = pThis->abOpcodes[3];
1306 case 3: pThis->abCurInstr[offDst + 2] = pThis->abOpcodes[2];
1307 case 2: pThis->abCurInstr[offDst + 1] = pThis->abOpcodes[1];
1308 case 1: pThis->abCurInstr[offDst] = pThis->abOpcodes[0];
1309 return offDst + pThis->cbOpcodes;
1310
1311 default:
1312 BS3_ASSERT(0);
1313 return 0;
1314 }
1315}
1316
1317
1318/**
1319 * Inserts a ModR/M byte with mod=3 and set the two idxFields members.
1320 *
1321 * @returns off + 1.
1322 * @param pThis The state.
1323 * @param off Current instruction offset.
1324 * @param uReg Register index for ModR/M.reg.
1325 * @param uRegMem Register index for ModR/M.rm.
1326 */
1327static unsigned Bs3Cg1InsertModRmWithRegFields(PBS3CG1STATE pThis, unsigned off, uint8_t uReg, uint8_t uRegMem)
1328{
1329 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, uReg & 7, uRegMem & 7);
1330 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + uReg;
1331 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + uRegMem;
1332 return off;
1333}
1334
1335
1336
1337/**
1338 * Cleans up state and context changes made by the encoder.
1339 *
1340 * @param pThis The state.
1341 */
1342static void BS3_NEAR_CODE Bs3Cg1EncodeCleanup(PBS3CG1STATE pThis)
1343{
1344 /* Restore the DS registers in the contexts. */
1345 unsigned iRing = 4;
1346 while (iRing-- > 0)
1347 pThis->aInitialCtxs[iRing].ds = pThis->aSavedSegRegs[iRing].ds;
1348
1349 switch (pThis->enmEncoding)
1350 {
1351 /* Most encodings currently doesn't need any special cleaning up. */
1352 default:
1353 return;
1354 }
1355}
1356
1357
1358static unsigned BS3_NEAR_CODE Bs3Cfg1EncodeMemMod0Disp(PBS3CG1STATE pThis, bool fAddrOverride, unsigned off, uint8_t iReg,
1359 uint8_t cbOp, uint8_t cbMisalign, BS3CG1OPLOC enmLocation)
1360{
1361 pThis->aOperands[pThis->iRmOp].idxField = BS3CG1DST_INVALID;
1362 pThis->aOperands[pThis->iRmOp].enmLocation = enmLocation;
1363 pThis->aOperands[pThis->iRmOp].cbOp = cbOp;
1364 pThis->aOperands[pThis->iRmOp].off = cbOp + cbMisalign;
1365
1366 if ( BS3_MODE_IS_16BIT_CODE(pThis->bMode)
1367 || (fAddrOverride && BS3_MODE_IS_32BIT_CODE(pThis->bMode)) )
1368 {
1369 /*
1370 * 16-bit code doing 16-bit or 32-bit addressing,
1371 * or 32-bit code doing 16-bit addressing.
1372 */
1373 unsigned iRing = 4;
1374 if (BS3_MODE_IS_RM_OR_V86(pThis->bMode))
1375 while (iRing-- > 0)
1376 pThis->aInitialCtxs[iRing].ds = pThis->DataPgFar.sel;
1377 else
1378 while (iRing-- > 0)
1379 pThis->aInitialCtxs[iRing].ds = pThis->DataPgFar.sel | iRing;
1380 if (!fAddrOverride || BS3_MODE_IS_32BIT_CODE(pThis->bMode))
1381 {
1382 pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, iReg, 6 /*disp16*/);
1383 *(uint16_t *)&pThis->abCurInstr[off] = pThis->DataPgFar.off + X86_PAGE_SIZE - cbOp - cbMisalign;
1384 off += 2;
1385 }
1386 else
1387 {
1388 pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, iReg, 5 /*disp32*/);
1389 *(uint32_t *)&pThis->abCurInstr[off] = pThis->DataPgFar.off + X86_PAGE_SIZE - cbOp - cbMisalign;
1390 off += 4;
1391 }
1392 }
1393 else
1394 {
1395 /*
1396 * 32-bit code doing 32-bit addressing,
1397 * or 64-bit code doing either 64-bit or 32-bit addressing.
1398 */
1399 pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, iReg, 5 /*disp32*/);
1400 *(uint32_t *)&pThis->abCurInstr[off] = BS3_FP_OFF(pThis->pbDataPg) + X86_PAGE_SIZE - cbOp - cbMisalign;
1401
1402#if ARCH_BITS == 64
1403 /* In 64-bit mode we always have a rip relative encoding regardless of fAddrOverride. */
1404 if (BS3CG1_IS_64BIT_TARGET(pThis))
1405 *(uint32_t *)&pThis->abCurInstr[off] -= BS3_FP_OFF(&pThis->pbCodePg[X86_PAGE_SIZE]);
1406#endif
1407 off += 4;
1408 }
1409
1410 /*
1411 * Fill the memory with 0xcc.
1412 */
1413 switch (cbOp + cbMisalign)
1414 {
1415 case 8: pThis->pbDataPg[X86_PAGE_SIZE - 8] = 0xcc; RT_FALL_THRU();
1416 case 7: pThis->pbDataPg[X86_PAGE_SIZE - 7] = 0xcc; RT_FALL_THRU();
1417 case 6: pThis->pbDataPg[X86_PAGE_SIZE - 6] = 0xcc; RT_FALL_THRU();
1418 case 5: pThis->pbDataPg[X86_PAGE_SIZE - 5] = 0xcc; RT_FALL_THRU();
1419 case 4: pThis->pbDataPg[X86_PAGE_SIZE - 4] = 0xcc; RT_FALL_THRU();
1420 case 3: pThis->pbDataPg[X86_PAGE_SIZE - 3] = 0xcc; RT_FALL_THRU();
1421 case 2: pThis->pbDataPg[X86_PAGE_SIZE - 2] = 0xcc; RT_FALL_THRU();
1422 case 1: pThis->pbDataPg[X86_PAGE_SIZE - 1] = 0xcc; RT_FALL_THRU();
1423 case 0: break;
1424 default:
1425 {
1426 BS3CG1_DPRINTF(("Bs3MemSet(%p,%#x,%#x)\n", &pThis->pbDataPg[X86_PAGE_SIZE - cbOp - cbMisalign], 0xcc, cbOp - cbMisalign));
1427 Bs3MemSet(&pThis->pbDataPg[X86_PAGE_SIZE - cbOp - cbMisalign], 0xcc, cbOp - cbMisalign);
1428 break;
1429 }
1430 }
1431
1432 return off;
1433}
1434
1435
1436#if 0 /* unused */
1437/** Also encodes idxField of the register operand using idxFieldBase. */
1438static unsigned BS3_NEAR_CODE
1439Bs3Cfg1EncodeMemMod0DispWithRegField(PBS3CG1STATE pThis, bool fAddrOverride, unsigned off, uint8_t iReg,
1440 uint8_t cbOp, uint8_t cbMisalign, BS3CG1OPLOC enmLocation)
1441{
1442 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1443 return Bs3Cfg1EncodeMemMod0Disp(pThis, fAddrOverride, off, iReg & 7, cbOp, cbMisalign, enmLocation);
1444}
1445#endif
1446
1447/** Also encodes idxField of the register operand using idxFieldBase. */
1448static unsigned BS3_NEAR_CODE
1449Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(PBS3CG1STATE pThis, unsigned off, uint8_t iReg)
1450{
1451 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1452 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off, iReg & 7,
1453 pThis->aOperands[pThis->iRmOp].cbOp,
1454 0 /*cbMisalign*/,
1455 pThis->aOperands[pThis->iRmOp].enmLocation);
1456}
1457
1458/** Also encodes idxField of the register operand using idxFieldBase. */
1459static unsigned BS3_NEAR_CODE
1460Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsAddrOverride(PBS3CG1STATE pThis, unsigned off, uint8_t iReg)
1461{
1462 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1463 return Bs3Cfg1EncodeMemMod0Disp(pThis, true /*fAddrOverride*/, off, iReg & 7,
1464 pThis->aOperands[pThis->iRmOp].cbOp,
1465 0 /*cbMisalign*/,
1466 pThis->aOperands[pThis->iRmOp].enmLocation);
1467}
1468
1469
1470/** Also encodes idxField of the register operand using idxFieldBase. */
1471static unsigned BS3_NEAR_CODE
1472Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(PBS3CG1STATE pThis, unsigned off, uint8_t iReg, uint8_t cbMisalign)
1473{
1474 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1475 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off, iReg & 7,
1476 pThis->aOperands[pThis->iRmOp].cbOp,
1477 cbMisalign,
1478 pThis->aOperands[pThis->iRmOp].enmLocation);
1479}
1480
1481
1482/** Also encodes idxField of the register operand using idxFieldBase. */
1483static unsigned BS3_NEAR_CODE
1484Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(PBS3CG1STATE pThis, unsigned off, uint8_t iReg, uint8_t cbOp)
1485{
1486 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1487 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off, iReg & 7, cbOp, 0 /*cbMisalign*/,
1488 pThis->aOperands[pThis->iRmOp].enmLocation);
1489}
1490
1491/** Also encodes idxField of the register operand using idxFieldBase. */
1492static unsigned BS3_NEAR_CODE
1493Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(PBS3CG1STATE pThis, unsigned off, uint8_t iReg, uint8_t cbOp)
1494{
1495 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + iReg;
1496 return Bs3Cfg1EncodeMemMod0Disp(pThis, true /*fAddrOverride*/, off, iReg & 7, cbOp, 0 /*cbMisalign*/,
1497 pThis->aOperands[pThis->iRmOp].enmLocation);
1498}
1499
1500
1501/** The modrm.reg value is taken from the instruction byte at @a off. */
1502static unsigned BS3_NEAR_CODE
1503Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(PBS3CG1STATE pThis, unsigned off)
1504{
1505 return Bs3Cfg1EncodeMemMod0Disp(pThis, false /*fAddrOverride*/, off,
1506 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
1507 pThis->aOperands[pThis->iRmOp].cbOp,
1508 0 /*cbMisalign*/,
1509 pThis->aOperands[pThis->iRmOp].enmLocation);
1510}
1511
1512
1513
1514static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Eb_Gb_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
1515{
1516 unsigned off;
1517 switch (iEncoding)
1518 {
1519 /* Start by reg,reg encoding. */
1520 case 0:
1521 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1522 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1523 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, X86_GREG_xAX, X86_GREG_xCX);
1524 break;
1525 case 1:
1526 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1527 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1528 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5 /*CH*/);
1529 break;
1530 case 2:
1531 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) < BS3CPU_80386)
1532 return 0;
1533 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1534 pThis->abCurInstr[0] = P_OZ;
1535 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1536 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 6 /*DH*/);
1537 break;
1538 /* Tests with address overrides go last! */
1539 case 3:
1540 pThis->abCurInstr[0] = P_AZ;
1541 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1542 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsAddrOverride(pThis, off, 7 /*BH*/);
1543 break;
1544
1545 default:
1546 return 0;
1547 }
1548 pThis->cbCurInstr = off;
1549 return iEncoding + 1;
1550}
1551
1552
1553static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Gv_Ev__OR__MODRM_Ev_Gv(PBS3CG1STATE pThis, unsigned iEncoding)
1554{
1555 unsigned off;
1556 unsigned cbOp;
1557 switch (iEncoding)
1558 {
1559 case 0:
1560 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1561 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1562 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, X86_GREG_xBX, X86_GREG_xDX);
1563 cbOp = pThis->cbOpDefault;
1564 break;
1565 case 1:
1566 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1567 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1568 cbOp = pThis->cbOpDefault;
1569 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(pThis, off, X86_GREG_xBP, cbOp);
1570 break;
1571 case 2:
1572 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) < BS3CPU_80386)
1573 return 0;
1574 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1575 pThis->abCurInstr[0] = P_OZ;
1576 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1577 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, X86_GREG_xAX, X86_GREG_xCX);
1578 cbOp = pThis->cbOpOvrd66;
1579 break;
1580 case 3:
1581 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1582 pThis->abCurInstr[0] = P_OZ;
1583 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1584 cbOp = pThis->cbOpOvrd66;
1585 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(pThis, off, X86_GREG_xSI, cbOp);
1586 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 : 0;
1587 break;
1588 case 4:
1589 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1590 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1591 pThis->abCurInstr[off++] = REX_W___;
1592 off = Bs3Cg1InsertOpcodes(pThis, off);
1593 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, X86_GREG_xBX, X86_GREG_xDX);
1594 cbOp = pThis->cbOpOvrdRexW;
1595 break;
1596 case 5:
1597 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1598 pThis->abCurInstr[off++] = REX__RB_;
1599 off = Bs3Cg1InsertOpcodes(pThis, off);
1600 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, X86_GREG_x14, X86_GREG_x12);
1601 cbOp = pThis->cbOpDefault;
1602 break;
1603 /* Tests with address overrides go last!*/
1604 case 6:
1605 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1606 pThis->abCurInstr[0] = P_AZ;
1607 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
1608 cbOp = pThis->cbOpDefault;
1609 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(pThis, off, X86_GREG_xDI, cbOp);
1610 break;
1611 case 7:
1612 pThis->abCurInstr[0] = P_OZ;
1613 pThis->abCurInstr[1] = P_AZ;
1614 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
1615 cbOp = pThis->cbOpOvrd66;
1616 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(pThis, off, X86_GREG_xDI, cbOp);
1617 break;
1618 default:
1619 return 0;
1620 }
1621 pThis->aOperands[0].cbOp = cbOp;
1622 pThis->aOperands[1].cbOp = cbOp;
1623 pThis->cbOperand = cbOp;
1624 pThis->cbCurInstr = off;
1625 return iEncoding + 1;
1626}
1627
1628
1629static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Pq_WO_Qq(PBS3CG1STATE pThis, unsigned iEncoding)
1630{
1631 unsigned off;
1632 switch (iEncoding)
1633 {
1634 case 0:
1635 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1636 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1637 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1638 break;
1639 case 1:
1640 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1641 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1642 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 7);
1643 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1644 break;
1645#if ARCH_BITS == 64
1646 case 2:
1647 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1648 pThis->abCurInstr[off++] = REX__RBX;
1649 off = Bs3Cg1InsertOpcodes(pThis, off);
1650 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6 /*no +8*/, 2 /*no +8*/);
1651 break;
1652#endif
1653 case 3:
1654 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1655 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1656 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1657 break;
1658 case 4:
1659 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1660 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1661 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1662 break;
1663#if ARCH_BITS == 64
1664 case 5:
1665 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1666 pThis->abCurInstr[off++] = REX__RBX;
1667 off = Bs3Cg1InsertOpcodes(pThis, off);
1668 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg - no +8*/);
1669 break;
1670#endif
1671
1672 default:
1673 return 0;
1674 }
1675
1676 pThis->cbCurInstr = off;
1677 return iEncoding + 1;
1678}
1679
1680
1681static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Pq_WO_Uq(PBS3CG1STATE pThis, unsigned iEncoding)
1682{
1683 unsigned off;
1684 switch (iEncoding)
1685 {
1686 case 0:
1687 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1688 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1689 break;
1690 case 1:
1691 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1692 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
1693 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1694 break;
1695 case 2:
1696 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1697 pThis->abCurInstr[off++] = REX__RBX;
1698 off = Bs3Cg1InsertOpcodes(pThis, off);
1699 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6 /*no+8*/, 2 + 8);
1700 break;
1701 default:
1702 return 0;
1703 }
1704 pThis->cbCurInstr = off;
1705 return iEncoding + 1;
1706}
1707
1708
1709static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ(PBS3CG1STATE pThis, unsigned iEncoding)
1710{
1711 unsigned off;
1712 switch (iEncoding)
1713 {
1714 case 0:
1715 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1716 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1717 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1718 break;
1719 case 1:
1720 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1721 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
1722 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1723 break;
1724#if ARCH_BITS == 64
1725 case 2:
1726 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1727 pThis->abCurInstr[off++] = REX__RBX;
1728 off = Bs3Cg1InsertOpcodes(pThis, off);
1729 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6 /*no +8*/, 2+8);
1730 break;
1731#endif
1732 case 3:
1733 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1734 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1735 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1736 break;
1737 case 4:
1738 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1739 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1740 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1741 break;
1742#if ARCH_BITS == 64
1743 case 5:
1744 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1745 pThis->abCurInstr[off++] = REX__RBX;
1746 off = Bs3Cg1InsertOpcodes(pThis, off);
1747 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg*/);
1748 break;
1749#endif
1750
1751 default:
1752 return 0;
1753 }
1754 pThis->cbCurInstr = off;
1755 return iEncoding + 1;
1756}
1757
1758
1759static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ(PBS3CG1STATE pThis, unsigned iEncoding)
1760{
1761#if ARCH_BITS == 64
1762 if (BS3CG1_IS_64BIT_TARGET(pThis))
1763 {
1764 unsigned off;
1765 switch (iEncoding)
1766 {
1767 case 0:
1768 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1769 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1770 pThis->abCurInstr[off++] = REX_W___;
1771 off = Bs3Cg1InsertOpcodes(pThis, off);
1772 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1773 break;
1774 case 1:
1775 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1776 pThis->abCurInstr[off++] = REX_W___;
1777 off = Bs3Cg1InsertOpcodes(pThis, off);
1778 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
1779 break;
1780 case 2:
1781 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1782 pThis->abCurInstr[off++] = REX_WRBX;
1783 off = Bs3Cg1InsertOpcodes(pThis, off);
1784 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6 /*no +8*/, 2+8);
1785 break;
1786 case 3:
1787 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1788 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1789 pThis->abCurInstr[off++] = REX_W___;
1790 off = Bs3Cg1InsertOpcodes(pThis, off);
1791 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1792 break;
1793 case 4:
1794 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1795 pThis->abCurInstr[off++] = REX_W___;
1796 off = Bs3Cg1InsertOpcodes(pThis, off);
1797 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1798 break;
1799 case 5:
1800 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1801 pThis->abCurInstr[off++] = REX_WRBX;
1802 off = Bs3Cg1InsertOpcodes(pThis, off);
1803 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg*/);
1804 break;
1805
1806 default:
1807 return 0;
1808 }
1809 pThis->cbCurInstr = off;
1810 return iEncoding + 1;
1811 }
1812#endif
1813 return 0;
1814}
1815
1816
1817/* Differs from Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ in that REX.R isn't ignored. */
1818static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vd_WO_Ed_WZ(PBS3CG1STATE pThis, unsigned iEncoding)
1819{
1820 unsigned off;
1821 switch (iEncoding)
1822 {
1823 case 0:
1824 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1825 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1826 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1827 break;
1828 case 1:
1829 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1830 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
1831 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1832 break;
1833#if ARCH_BITS == 64
1834 case 2:
1835 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1836 pThis->abCurInstr[off++] = REX__RBX;
1837 off = Bs3Cg1InsertOpcodes(pThis, off);
1838 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6+8, 2+8);
1839 break;
1840#endif
1841 case 3:
1842 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1843 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1844 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1845 break;
1846 case 4:
1847 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1848 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1849 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1850 break;
1851#if ARCH_BITS == 64
1852 case 5:
1853 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1854 pThis->abCurInstr[off++] = REX__RBX;
1855 off = Bs3Cg1InsertOpcodes(pThis, off);
1856 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7+8 /*iReg*/);
1857 break;
1858#endif
1859
1860 default:
1861 return 0;
1862 }
1863 pThis->cbCurInstr = off;
1864 return iEncoding + 1;
1865}
1866
1867
1868/* Differs from Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ in that REX.R isn't ignored. */
1869static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vq_WO_Eq_WNZ(PBS3CG1STATE pThis, unsigned iEncoding)
1870{
1871#if ARCH_BITS == 64
1872 if (BS3CG1_IS_64BIT_TARGET(pThis))
1873 {
1874 unsigned off;
1875 switch (iEncoding)
1876 {
1877 case 0:
1878 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1879 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1880 pThis->abCurInstr[off++] = REX_W___;
1881 off = Bs3Cg1InsertOpcodes(pThis, off);
1882 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1883 break;
1884 case 1:
1885 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1886 pThis->abCurInstr[off++] = REX_W___;
1887 off = Bs3Cg1InsertOpcodes(pThis, off);
1888 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
1889 break;
1890 case 2:
1891 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1892 pThis->abCurInstr[off++] = REX_WRBX;
1893 off = Bs3Cg1InsertOpcodes(pThis, off);
1894 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6+8, 2+8);
1895 break;
1896 case 4:
1897 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1898 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1899 pThis->abCurInstr[off++] = REX_W___;
1900 off = Bs3Cg1InsertOpcodes(pThis, off);
1901 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
1902 break;
1903 case 5:
1904 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1905 pThis->abCurInstr[off++] = REX_W___;
1906 off = Bs3Cg1InsertOpcodes(pThis, off);
1907 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
1908 break;
1909 case 6:
1910 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1911 pThis->abCurInstr[off++] = REX_WRBX;
1912 off = Bs3Cg1InsertOpcodes(pThis, off);
1913 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7+8 /*iReg*/);
1914 break;
1915
1916 default:
1917 return 0;
1918 }
1919 pThis->cbCurInstr = off;
1920 return iEncoding + 1;
1921 }
1922#endif
1923 return 0;
1924}
1925
1926
1927static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vsomething_Usomething_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
1928{
1929 unsigned off;
1930 switch (iEncoding)
1931 {
1932 case 0:
1933 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1934 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1935 break;
1936 case 1:
1937 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1938 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 2, 2);
1939 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1940 break;
1941 case 2:
1942 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1943 pThis->abCurInstr[off++] = REX__RBX;
1944 off = Bs3Cg1InsertOpcodes(pThis, off);
1945 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 3+8, 7+8);
1946 break;
1947 default:
1948 return 0;
1949 }
1950 pThis->cbCurInstr = off;
1951 return iEncoding + 1;
1952}
1953
1954
1955static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
1956{
1957 unsigned off;
1958 switch (iEncoding)
1959 {
1960 case 0:
1961 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
1962 off = Bs3Cg1InsertModRmWithRegFields(pThis, Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)), 1, 0);
1963 break;
1964 case 1:
1965 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
1966 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1967 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
1968 break;
1969 case 2:
1970 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1971 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
1972 if (!Bs3Cg1XcptTypeIsUnaligned(pThis->enmXcptType))
1973 pThis->bAlignmentXcpt = X86_XCPT_GP;
1974 break;
1975 default:
1976 return 0;
1977 }
1978 pThis->cbCurInstr = off;
1979 return iEncoding + 1;
1980}
1981
1982
1983static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Vsomething_Nsomething(PBS3CG1STATE pThis, unsigned iEncoding)
1984{
1985 unsigned off;
1986 switch (iEncoding)
1987 {
1988 case 0:
1989 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1990 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
1991 break;
1992 case 1:
1993 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
1994 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 7);
1995 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
1996 break;
1997 case 2:
1998 off = Bs3Cg1InsertReqPrefix(pThis, 0);
1999 pThis->abCurInstr[off++] = REX_WRBX;
2000 off = Bs3Cg1InsertOpcodes(pThis, off);
2001 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6 + 8, 7 /*no +8*/);
2002 break;
2003
2004 default:
2005 return 0;
2006 }
2007 pThis->cbCurInstr = off;
2008 return iEncoding + 1;
2009}
2010
2011
2012static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Gv_RO_Ma(PBS3CG1STATE pThis, unsigned iEncoding) /* bound instr */
2013{
2014 unsigned off;
2015 unsigned cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
2016 switch (iEncoding)
2017 {
2018 case 0:
2019 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2020 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(pThis, off, X86_GREG_xBP, cbOp * 2);
2021 break;
2022 case 1:
2023 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) < BS3CPU_80386)
2024 return 0;
2025 cbOp = cbOp == 2 ? 4 : 2;
2026 pThis->abCurInstr[0] = P_OZ;
2027 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
2028 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaults(pThis, off, X86_GREG_xBP, cbOp * 2);
2029 break;
2030 case 2:
2031 pThis->abCurInstr[0] = P_AZ;
2032 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
2033 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(pThis, off, X86_GREG_xBP, cbOp * 2);
2034 break;
2035 case 3:
2036 cbOp = cbOp == 2 ? 4 : 2;
2037 pThis->abCurInstr[0] = P_AZ;
2038 pThis->abCurInstr[1] = P_OZ;
2039 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
2040 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndSizeAndDefaultsAddrOverride(pThis, off, X86_GREG_xBP, cbOp * 2);
2041 break;
2042 default:
2043 return 0;
2044 }
2045 pThis->aOperands[pThis->iRegOp].cbOp = cbOp;
2046 pThis->cbOperand = cbOp;
2047 pThis->cbCurInstr = off;
2048 return iEncoding + 1;
2049}
2050
2051
2052static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Msomething(PBS3CG1STATE pThis, unsigned iEncoding)
2053{
2054 unsigned off;
2055 switch (iEncoding)
2056 {
2057 case 0:
2058 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)) - 1;
2059 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
2060 break;
2061 default:
2062 return 0;
2063 }
2064 pThis->cbCurInstr = off;
2065 return iEncoding + 1;
2066}
2067
2068
2069static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Msomething_Psomething(PBS3CG1STATE pThis, unsigned iEncoding)
2070{
2071 unsigned off;
2072 switch (iEncoding)
2073 {
2074 case 0:
2075 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2076 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2077 break;
2078 case 1:
2079 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2080 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 7 /*iReg*/, 1 /*cbMisalign*/);
2081 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2082 break;
2083#if ARCH_BITS == 64
2084 case 2:
2085 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2086 pThis->abCurInstr[off++] = REX__RBX;
2087 off = Bs3Cg1InsertOpcodes(pThis, off);
2088 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 /*iReg - no +8*/);
2089 break;
2090#endif
2091
2092 default:
2093 return 0;
2094 }
2095
2096 pThis->cbCurInstr = off;
2097 return iEncoding + 1;
2098}
2099
2100
2101static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_Msomething_Vsomething_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2102{
2103 unsigned off;
2104 switch (iEncoding)
2105 {
2106 case 0:
2107 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2108 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
2109 break;
2110 case 1:
2111 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2112 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 2 /*iReg*/, 1 /*cbMisalign*/ );
2113 if (!Bs3Cg1XcptTypeIsUnaligned(pThis->enmXcptType))
2114 pThis->bAlignmentXcpt = X86_XCPT_GP;
2115 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2116 break;
2117 case 2:
2118 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2119 pThis->abCurInstr[off++] = REX__R__;
2120 off = Bs3Cg1InsertOpcodes(pThis, off);
2121 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2+8 /*iReg*/);
2122 break;
2123 default:
2124 return 0;
2125 }
2126 pThis->cbCurInstr = off;
2127 return iEncoding + 1;
2128}
2129
2130
2131static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_FIXED(PBS3CG1STATE pThis, unsigned iEncoding)
2132{
2133 unsigned off;
2134 switch (iEncoding)
2135 {
2136 case 0:
2137 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2138 pThis->cbCurInstr = off;
2139 break;
2140 default:
2141 return 0;
2142 }
2143 return iEncoding + 1;
2144}
2145
2146
2147static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_FIXED_AL_Ib(PBS3CG1STATE pThis, unsigned iEncoding)
2148{
2149 unsigned off;
2150 switch (iEncoding)
2151 {
2152 case 0:
2153 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2154 pThis->aOperands[1].off = (uint8_t)off;
2155 pThis->abCurInstr[off++] = 0xff;
2156 pThis->cbCurInstr = off;
2157 break;
2158 default:
2159 return 0;
2160 }
2161 return iEncoding + 1;
2162}
2163
2164
2165static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_FIXED_rAX_Iz(PBS3CG1STATE pThis, unsigned iEncoding)
2166{
2167 unsigned off;
2168 unsigned cbOp;
2169 switch (iEncoding)
2170 {
2171 case 0:
2172 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
2173 pThis->aOperands[1].off = (uint8_t)off;
2174 cbOp = pThis->cbOpDefault;
2175 if (cbOp == 2)
2176 *(uint16_t *)&pThis->abCurInstr[off] = UINT16_MAX;
2177 else
2178 *(uint32_t *)&pThis->abCurInstr[off] = UINT32_MAX;
2179 off += cbOp;
2180 pThis->aOperands[0].cbOp = cbOp;
2181 pThis->aOperands[1].cbOp = cbOp;
2182 pThis->cbOperand = cbOp;
2183 break;
2184 case 1:
2185 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) < BS3CPU_80386)
2186 return 0;
2187 pThis->abCurInstr[0] = P_OZ;
2188 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
2189 pThis->aOperands[1].off = (uint8_t)off;
2190 cbOp = pThis->cbOpOvrd66;
2191 if (cbOp == 2)
2192 *(uint16_t *)&pThis->abCurInstr[off] = UINT16_MAX;
2193 else
2194 *(uint32_t *)&pThis->abCurInstr[off] = UINT32_MAX;
2195 off += cbOp;
2196 pThis->aOperands[0].cbOp = cbOp;
2197 pThis->aOperands[1].cbOp = cbOp;
2198 pThis->cbOperand = cbOp;
2199 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2200 break;
2201 case 2:
2202 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2203 pThis->abCurInstr[off++] = REX_W___;
2204 off = Bs3Cg1InsertOpcodes(pThis, off);
2205 pThis->aOperands[1].off = (uint8_t)off;
2206 *(uint32_t *)&pThis->abCurInstr[off] = UINT32_MAX;
2207 off += 4;
2208 pThis->aOperands[0].cbOp = 8;
2209 pThis->aOperands[1].cbOp = 4;
2210 pThis->cbOperand = 8;
2211 break;
2212 default:
2213 return 0;
2214
2215 /* IMAGE PADDING - workaround for "rd err" - remove later! */
2216 case 4:
2217 ASMHalt();
2218 ASMHalt();
2219 ASMHalt();
2220 return 0;
2221
2222 }
2223 pThis->cbCurInstr = off;
2224 return iEncoding + 1;
2225}
2226
2227
2228static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_MOD_EQ_3(PBS3CG1STATE pThis, unsigned iEncoding)
2229{
2230 unsigned off;
2231 if (iEncoding < 8)
2232 {
2233 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2234 off = Bs3Cg1InsertOpcodes(pThis, off);
2235 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, iEncoding, 1);
2236 }
2237 else if (iEncoding < 16)
2238 {
2239 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2240 off = Bs3Cg1InsertOpcodes(pThis, off);
2241 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 0, iEncoding & 7);
2242 }
2243 else
2244 return 0;
2245 pThis->cbCurInstr = off;
2246
2247 return iEncoding + 1;
2248}
2249
2250
2251static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_MODRM_MOD_NE_3(PBS3CG1STATE pThis, unsigned iEncoding)
2252{
2253 unsigned off;
2254 if (iEncoding < 3)
2255 {
2256 off = Bs3Cg1InsertReqPrefix(pThis, 0);
2257 off = Bs3Cg1InsertOpcodes(pThis, off);
2258 pThis->abCurInstr[off++] = X86_MODRM_MAKE(iEncoding, 0, 1);
2259 if (iEncoding >= 1)
2260 pThis->abCurInstr[off++] = 0x7f;
2261 if (iEncoding == 2)
2262 {
2263 pThis->abCurInstr[off++] = 0x5f;
2264 if (!BS3_MODE_IS_16BIT_CODE(pThis->bMode))
2265 {
2266 pThis->abCurInstr[off++] = 0x3f;
2267 pThis->abCurInstr[off++] = 0x1f;
2268 }
2269 }
2270 }
2271 else
2272 return 0;
2273 pThis->cbCurInstr = off;
2274 return iEncoding + 1;
2275}
2276
2277
2278/*
2279 *
2280 * VEX
2281 * VEX
2282 * VEX
2283 *
2284 */
2285#ifdef BS3CG1_WITH_VEX
2286
2287/**
2288 * Inserts a 3-byte VEX prefix.
2289 *
2290 * @returns New offDst value.
2291 * @param pThis The state.
2292 * @param offDst The current instruction offset.
2293 * @param uVexL The VEX.L value.
2294 * @param uVexV The VEX.V value (caller inverted it already).
2295 * @param uVexR The VEX.R value (caller inverted it already).
2296 * @param uVexX The VEX.X value (caller inverted it already).
2297 * @param uVexB The VEX.B value (caller inverted it already).
2298 * @param uVexW The VEX.W value (straight).
2299 */
2300DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertVex3bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL,
2301 uint8_t uVexR, uint8_t uVexX, uint8_t uVexB, uint8_t uVexW)
2302{
2303 uint8_t b1;
2304 uint8_t b2;
2305 b1 = uVexR << 7;
2306 b1 |= uVexX << 6;
2307 b1 |= uVexB << 5;
2308 b1 |= pThis->uOpcodeMap;
2309 b2 = uVexV << 3;
2310 b2 |= uVexW << 7;
2311 b2 |= uVexL << 2;
2312 switch (pThis->enmPrefixKind)
2313 {
2314 case BS3CG1PFXKIND_NO_F2_F3_66: b2 |= 0; break;
2315 case BS3CG1PFXKIND_REQ_66: b2 |= 1; break;
2316 case BS3CG1PFXKIND_REQ_F3: b2 |= 2; break;
2317 case BS3CG1PFXKIND_REQ_F2: b2 |= 3; break;
2318 default:
2319 Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n", pThis->enmPrefixKind);
2320 break;
2321 }
2322
2323 pThis->abCurInstr[offDst] = 0xc4; /* vex3 */
2324 pThis->abCurInstr[offDst + 1] = b1;
2325 pThis->abCurInstr[offDst + 2] = b2;
2326 pThis->uVexL = uVexL;
2327 return offDst + 3;
2328}
2329
2330
2331/**
2332 * Inserts a 2-byte VEX prefix.
2333 *
2334 * @note Will switch to 3-byte VEX prefix if uOpcodeMap isn't one.
2335 *
2336 * @returns New offDst value.
2337 * @param pThis The state.
2338 * @param offDst The current instruction offset.
2339 * @param uVexL The VEX.L value.
2340 * @param uVexV The VEX.V value (caller inverted it already).
2341 * @param uVexR The VEX.R value (caller inverted it already).
2342 */
2343DECLINLINE(unsigned) BS3_NEAR_CODE Bs3Cg1InsertVex2bPrefix(PBS3CG1STATE pThis, unsigned offDst,
2344 uint8_t uVexV, uint8_t uVexL, uint8_t uVexR)
2345{
2346 if (pThis->uOpcodeMap == 1)
2347 {
2348 uint8_t b = uVexR << 7;
2349 b |= uVexV << 3;
2350 b |= uVexL << 2;
2351 switch (pThis->enmPrefixKind)
2352 {
2353 case BS3CG1PFXKIND_NO_F2_F3_66: b |= 0; break;
2354 case BS3CG1PFXKIND_REQ_66: b |= 1; break;
2355 case BS3CG1PFXKIND_REQ_F3: b |= 2; break;
2356 case BS3CG1PFXKIND_REQ_F2: b |= 3; break;
2357 default:
2358 Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n");
2359 break;
2360 }
2361
2362 pThis->abCurInstr[offDst] = 0xc5; /* vex2 */
2363 pThis->abCurInstr[offDst + 1] = b;
2364 pThis->uVexL = uVexL;
2365 return offDst + 2;
2366 }
2367 return Bs3Cg1InsertVex3bPrefix(pThis, offDst, uVexV, uVexL, uVexR, 1 /*uVexX*/, 1 /*uVexB*/, 0/*uVexW*/);
2368}
2369
2370
2371/**
2372 * Inserts a ModR/M byte with mod=3 and set the two idxFields members.
2373 *
2374 * @returns off + 1.
2375 * @param pThis The state.
2376 * @param off Current instruction offset.
2377 * @param uReg Register index for ModR/M.reg.
2378 * @param uRegMem Register index for ModR/M.rm.
2379 * @param uVexVvvv The VEX.vvvv register.
2380 */
2381static unsigned Bs3Cg1InsertModRmWithRegFieldsAndVvvv(PBS3CG1STATE pThis, unsigned off,
2382 uint8_t uReg, uint8_t uRegMem, uint8_t uVexVvvv)
2383{
2384 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, uReg & 7, uRegMem & 7);
2385 pThis->aOperands[pThis->iRegOp].idxField = pThis->aOperands[pThis->iRegOp].idxFieldBase + uReg;
2386 pThis->aOperands[1 ].idxField = pThis->aOperands[1 ].idxFieldBase + uVexVvvv;
2387 pThis->aOperands[pThis->iRmOp ].idxField = pThis->aOperands[pThis->iRmOp ].idxFieldBase + uRegMem;
2388 return off;
2389}
2390
2391
2392static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_Vd_WO_Ed_WZ(PBS3CG1STATE pThis, unsigned iEncoding)
2393{
2394 unsigned off;
2395 switch (iEncoding)
2396 {
2397 case 0:
2398 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
2399 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2400 off = Bs3Cg1InsertOpcodes(pThis, off);
2401 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
2402 break;
2403 case 1:
2404 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2405 off = Bs3Cg1InsertOpcodes(pThis, off);
2406 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
2407 break;
2408 case 2:
2409 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-invalid*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2410 off = Bs3Cg1InsertOpcodes(pThis, off);
2411 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
2412 pThis->fInvalidEncoding = true;
2413 break;
2414 case 3:
2415 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xe /*~V-invalid*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2416 off = Bs3Cg1InsertOpcodes(pThis, off);
2417 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
2418 pThis->fInvalidEncoding = true;
2419 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2420 break;
2421#if ARCH_BITS == 64
2422 case 4:
2423 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 0 /*~B*/, 0 /*W*/);
2424 off = Bs3Cg1InsertOpcodes(pThis, off);
2425 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6+8, 2+8);
2426 break;
2427#endif
2428 case 5:
2429 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
2430 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2431 off = Bs3Cg1InsertOpcodes(pThis, off);
2432 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2433 break;
2434 case 6:
2435 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2436 off = Bs3Cg1InsertOpcodes(pThis, off);
2437 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2438 break;
2439 case 7:
2440 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2441 off = Bs3Cg1InsertOpcodes(pThis, off);
2442 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 4 /*iReg*/, 1 /*cbMisalign*/);
2443 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 : 0;
2444 break;
2445#if ARCH_BITS == 64
2446 case 8:
2447 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2448 off = Bs3Cg1InsertOpcodes(pThis, off);
2449 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4+8 /*iReg*/);
2450 break;
2451 case 9:
2452 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/);
2453 off = Bs3Cg1InsertOpcodes(pThis, off);
2454 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8 /*iReg*/);
2455 iEncoding += 2;
2456 break;
2457#endif
2458 case 10: /* VEX.W is ignored in 32-bit mode. flag? */
2459 BS3_ASSERT(!BS3CG1_IS_64BIT_TARGET(pThis));
2460 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2461 off = Bs3Cg1InsertOpcodes(pThis, off);
2462 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2463 break;
2464
2465 default:
2466 return 0;
2467 }
2468 pThis->cbCurInstr = off;
2469 return iEncoding + 1;
2470}
2471
2472
2473/* Differs from Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ in that REX.R isn't ignored. */
2474static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_Vq_WO_Eq_WNZ(PBS3CG1STATE pThis, unsigned iEncoding)
2475{
2476#if ARCH_BITS == 64
2477 if (BS3CG1_IS_64BIT_TARGET(pThis))
2478 {
2479 unsigned off;
2480 switch (iEncoding)
2481 {
2482 case 0:
2483 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
2484 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2485 off = Bs3Cg1InsertOpcodes(pThis, off);
2486 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
2487 break;
2488 case 1:
2489 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-invalid*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2490 off = Bs3Cg1InsertOpcodes(pThis, off);
2491 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
2492 pThis->fInvalidEncoding = true;
2493 break;
2494 case 2:
2495 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xe /*~V-invalid*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2496 off = Bs3Cg1InsertOpcodes(pThis, off);
2497 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6, 2);
2498 pThis->fInvalidEncoding = true;
2499 break;
2500 case 3:
2501 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 0 /*~B*/, 1 /*W*/);
2502 off = Bs3Cg1InsertOpcodes(pThis, off);
2503 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 6+8, 2+8);
2504 break;
2505 case 4:
2506 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
2507 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2508 off = Bs3Cg1InsertOpcodes(pThis, off);
2509 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4 /*iReg*/);
2510 break;
2511 case 5:
2512 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2513 off = Bs3Cg1InsertOpcodes(pThis, off);
2514 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 4 /*iReg*/, 1 /*cbMisalign*/);
2515 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 : 0;
2516 break;
2517 case 6:
2518 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
2519 off = Bs3Cg1InsertOpcodes(pThis, off);
2520 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 4+8 /*iReg*/);
2521 break;
2522
2523 default:
2524 return 0;
2525 }
2526 pThis->cbCurInstr = off;
2527 return iEncoding + 1;
2528 }
2529#endif
2530 return 0;
2531}
2532
2533
2534/**
2535 * Wip - VEX.W ignored.
2536 * Lig - VEX.L ignored.
2537 */
2538static unsigned BS3_NEAR_CODE
2539Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2540{
2541 unsigned off;
2542 switch (iEncoding)
2543 {
2544 case 0:
2545 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2546 off = Bs3Cg1InsertOpcodes(pThis, off);
2547 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 0);
2548 break;
2549 case 1:
2550 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0x8 /*~V*/, 1 /*L-ignored*/, 1 /*~R*/);
2551 off = Bs3Cg1InsertOpcodes(pThis, off);
2552 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 3, 1, 7);
2553 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2554 break;
2555 case 2:
2556#if ARCH_BITS == 64
2557 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 0 /*~R*/);
2558 off = Bs3Cg1InsertOpcodes(pThis, off);
2559 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 3+8, 2, 15);
2560 break;
2561#endif
2562 case 3:
2563 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2564 off = Bs3Cg1InsertOpcodes(pThis, off);
2565 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 0);
2566 break;
2567 case 4:
2568 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2569 off = Bs3Cg1InsertOpcodes(pThis, off);
2570 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 0);
2571 break;
2572 case 5:
2573 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xc /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2574 off = Bs3Cg1InsertOpcodes(pThis, off);
2575 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 3);
2576 break;
2577 case 6:
2578 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2579 off = Bs3Cg1InsertOpcodes(pThis, off);
2580 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2581 break;
2582 case 7:
2583 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2584 off = Bs3Cg1InsertOpcodes(pThis, off);
2585 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2586 break;
2587 default:
2588 return 0;
2589 }
2590 pThis->cbCurInstr = off;
2591 return iEncoding + 1;
2592}
2593
2594
2595/**
2596 * Wip - VEX.W ignored.
2597 */
2598static unsigned BS3_NEAR_CODE
2599Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_HdqCsomething_Usomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2600{
2601 unsigned off;
2602 switch (iEncoding)
2603 {
2604 case 0:
2605 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2606 off = Bs3Cg1InsertOpcodes(pThis, off);
2607 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 0);
2608 break;
2609 case 1:
2610 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0x8 /*~V*/, 1 /*L-ignored*/, 1 /*~R*/);
2611 off = Bs3Cg1InsertOpcodes(pThis, off);
2612 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 3, 1, 7);
2613 pThis->fInvalidEncoding = true;
2614 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2615 break;
2616 case 2:
2617#if ARCH_BITS == 64
2618 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 0 /*~R*/);
2619 off = Bs3Cg1InsertOpcodes(pThis, off);
2620 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 3+8, 2, 15);
2621 break;
2622#endif
2623 case 3:
2624 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2625 off = Bs3Cg1InsertOpcodes(pThis, off);
2626 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 0);
2627 break;
2628 case 4:
2629 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2630 off = Bs3Cg1InsertOpcodes(pThis, off);
2631 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 0);
2632 pThis->fInvalidEncoding = true;
2633 break;
2634 case 5:
2635 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xc /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2636 off = Bs3Cg1InsertOpcodes(pThis, off);
2637 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, 3);
2638 break;
2639 case 6:
2640 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2641 off = Bs3Cg1InsertOpcodes(pThis, off);
2642 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2643 break;
2644 case 7:
2645 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2646 off = Bs3Cg1InsertOpcodes(pThis, off);
2647 off = Bs3Cg1InsertModRmWithRegFieldsAndVvvv(pThis, off, 2, 1, BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
2648 break;
2649 default:
2650 return 0;
2651 }
2652 pThis->cbCurInstr = off;
2653 return iEncoding + 1;
2654}
2655
2656
2657/**
2658 * Wip - VEX.W ignored.
2659 */
2660static unsigned BS3_NEAR_CODE
2661Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2662{
2663 unsigned off;
2664 switch (iEncoding)
2665 {
2666 case 20: /* Switch to 256-bit operands. */
2667 pThis->aOperands[pThis->iRegOp].idxFieldBase = BS3CG1DST_YMM0;
2668 pThis->aOperands[pThis->iRegOp].cbOp = 32;
2669 pThis->aOperands[pThis->iRmOp ].cbOp = 32;
2670 RT_FALL_THRU();
2671 case 0:
2672 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
2673 off = Bs3Cg1InsertOpcodes(pThis, off);
2674 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2675 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2676 break;
2677#if ARCH_BITS == 64
2678 case 1:
2679 case 21:
2680 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/);
2681 off = Bs3Cg1InsertOpcodes(pThis, off);
2682 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
2683 break;
2684#endif
2685 case 2:
2686 case 22:
2687 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
2688 off = Bs3Cg1InsertOpcodes(pThis, off);
2689 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2690 pThis->fInvalidEncoding = true;
2691 break;
2692 case 3:
2693 case 23:
2694 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2695 off = Bs3Cg1InsertOpcodes(pThis, off);
2696 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2697 break;
2698 case 4:
2699 case 24:
2700 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2701 off = Bs3Cg1InsertOpcodes(pThis, off);
2702 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2703 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
2704 break;
2705#if ARCH_BITS == 64
2706 case 5:
2707 case 25:
2708 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2709 off = Bs3Cg1InsertOpcodes(pThis, off);
2710 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
2711 break;
2712 case 6:
2713 case 26:
2714 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
2715 off = Bs3Cg1InsertOpcodes(pThis, off);
2716 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2717 break;
2718 case 7:
2719 case 27:
2720 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
2721 off = Bs3Cg1InsertOpcodes(pThis, off);
2722 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2723 break;
2724#endif
2725 case 8:
2726 case 28:
2727 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2728 off = Bs3Cg1InsertOpcodes(pThis, off);
2729 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2730 pThis->fInvalidEncoding = true;
2731 break;
2732 case 9:
2733 case 29:
2734 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2735 off = Bs3Cg1InsertOpcodes(pThis, off);
2736 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2737 pThis->fInvalidEncoding = true;
2738 iEncoding += 10;
2739 break;
2740
2741 default:
2742 return 0;
2743 }
2744 pThis->cbCurInstr = off;
2745 return iEncoding + 1;
2746}
2747
2748
2749
2750/**
2751 * Wip - VEX.W ignored.
2752 * Lig - VEX.L ignored.
2753 */
2754static unsigned BS3_NEAR_CODE
2755Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2756{
2757 unsigned off;
2758 switch (iEncoding)
2759 {
2760 case 0:
2761 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2762 off = Bs3Cg1InsertOpcodes(pThis, off);
2763 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2764 break;
2765 case 1:
2766 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 1 /*~R*/);
2767 off = Bs3Cg1InsertOpcodes(pThis, off);
2768 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7);
2769 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2770 break;
2771#if ARCH_BITS == 64
2772 case 2:
2773 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - ignored*/, 0 /*~R*/);
2774 off = Bs3Cg1InsertOpcodes(pThis, off);
2775 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
2776 break;
2777#endif
2778 case 3:
2779 iEncoding = 3;
2780 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/);
2781 off = Bs3Cg1InsertOpcodes(pThis, off);
2782 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2783 pThis->fInvalidEncoding = true;
2784 break;
2785 case 4:
2786 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2787 off = Bs3Cg1InsertOpcodes(pThis, off);
2788 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2789 break;
2790 case 5:
2791 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2792 off = Bs3Cg1InsertOpcodes(pThis, off);
2793 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2794 break;
2795 case 6:
2796 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2797 off = Bs3Cg1InsertOpcodes(pThis, off);
2798 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2799 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
2800 break;
2801#if ARCH_BITS == 64
2802 case 7:
2803 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2804 off = Bs3Cg1InsertOpcodes(pThis, off);
2805 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
2806 break;
2807 case 8:
2808 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
2809 off = Bs3Cg1InsertOpcodes(pThis, off);
2810 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2811 break;
2812 case 9:
2813 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
2814 off = Bs3Cg1InsertOpcodes(pThis, off);
2815 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2816 break;
2817#endif
2818 case 10:
2819 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2820 off = Bs3Cg1InsertOpcodes(pThis, off);
2821 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2822 pThis->fInvalidEncoding = true;
2823 break;
2824 case 11:
2825 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2826 off = Bs3Cg1InsertOpcodes(pThis, off);
2827 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2828 pThis->fInvalidEncoding = true;
2829 break;
2830 default:
2831 return 0;
2832 }
2833 pThis->cbCurInstr = off;
2834 return iEncoding + 1;
2835}
2836
2837
2838/**
2839 * Wip - VEX.W ignored.
2840 * L0 - VEX.L must be zero.
2841 */
2842static unsigned BS3_NEAR_CODE
2843Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lmbz_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
2844{
2845 unsigned off;
2846 switch (iEncoding)
2847 {
2848 case 0:
2849 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
2850 off = Bs3Cg1InsertOpcodes(pThis, off);
2851 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2852 break;
2853 case 1:
2854 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - invalid*/, 1 /*~R*/);
2855 off = Bs3Cg1InsertOpcodes(pThis, off);
2856 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7);
2857 pThis->fInvalidEncoding = true;
2858 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 : 0;
2859 break;
2860#if ARCH_BITS == 64
2861 case 2:
2862 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/);
2863 off = Bs3Cg1InsertOpcodes(pThis, off);
2864 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
2865 break;
2866 case 3:
2867 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - invalid*/, 0 /*~R*/);
2868 off = Bs3Cg1InsertOpcodes(pThis, off);
2869 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5 + 8);
2870 pThis->fInvalidEncoding = true;
2871 break;
2872#endif
2873 case 4:
2874 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/);
2875 off = Bs3Cg1InsertOpcodes(pThis, off);
2876 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2877 pThis->fInvalidEncoding = true;
2878 break;
2879 case 5:
2880 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2881 off = Bs3Cg1InsertOpcodes(pThis, off);
2882 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2883 break;
2884 case 6:
2885 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L - invalid*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2886 off = Bs3Cg1InsertOpcodes(pThis, off);
2887 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2888 pThis->fInvalidEncoding = true;
2889 break;
2890 case 7:
2891 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2892 off = Bs3Cg1InsertOpcodes(pThis, off);
2893 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2894 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
2895 break;
2896#if ARCH_BITS == 64
2897 case 8:
2898 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2899 off = Bs3Cg1InsertOpcodes(pThis, off);
2900 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
2901 break;
2902 case 9:
2903 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
2904 off = Bs3Cg1InsertOpcodes(pThis, off);
2905 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2906 break;
2907 case 10:
2908 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
2909 off = Bs3Cg1InsertOpcodes(pThis, off);
2910 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2911 break;
2912#endif
2913 case 11:
2914 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2915 off = Bs3Cg1InsertOpcodes(pThis, off);
2916 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2917 pThis->fInvalidEncoding = true;
2918 break;
2919 case 12:
2920 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2921 off = Bs3Cg1InsertOpcodes(pThis, off);
2922 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2923 pThis->fInvalidEncoding = true;
2924 break;
2925 default:
2926 return 0;
2927 }
2928 pThis->cbCurInstr = off;
2929 return iEncoding + 1;
2930}
2931
2932
2933/**
2934 * Wip - VEX.W ignored.
2935 */
2936static unsigned BS3_NEAR_CODE
2937Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lxx_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding, uint8_t uVexL)
2938{
2939 unsigned off;
2940 switch (iEncoding)
2941 {
2942 case 0:
2943 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/);
2944 off = Bs3Cg1InsertOpcodes(pThis, off);
2945 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2946 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
2947 break;
2948#if ARCH_BITS == 64
2949 case 1:
2950 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 0 /*~R*/);
2951 off = Bs3Cg1InsertOpcodes(pThis, off);
2952 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
2953 break;
2954#endif
2955 case 2:
2956 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, uVexL, 1 /*~R*/);
2957 off = Bs3Cg1InsertOpcodes(pThis, off);
2958 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
2959 pThis->fInvalidEncoding = true;
2960 break;
2961 case 3:
2962 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2963 off = Bs3Cg1InsertOpcodes(pThis, off);
2964 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2965 break;
2966 case 4:
2967 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
2968 off = Bs3Cg1InsertOpcodes(pThis, off);
2969 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2970 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
2971 break;
2972#if ARCH_BITS == 64
2973 case 5:
2974 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2975 off = Bs3Cg1InsertOpcodes(pThis, off);
2976 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
2977 break;
2978 case 6:
2979 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
2980 off = Bs3Cg1InsertOpcodes(pThis, off);
2981 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
2982 break;
2983 case 7:
2984 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, uVexL, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
2985 off = Bs3Cg1InsertOpcodes(pThis, off);
2986 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2987 break;
2988#endif
2989 case 8:
2990 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2991 off = Bs3Cg1InsertOpcodes(pThis, off);
2992 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
2993 pThis->fInvalidEncoding = true;
2994 break;
2995 case 9:
2996 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 7 /*~V*/, uVexL, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
2997 off = Bs3Cg1InsertOpcodes(pThis, off);
2998 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
2999 pThis->fInvalidEncoding = true;
3000 break;
3001 default:
3002 return 0;
3003 }
3004 pThis->cbCurInstr = off;
3005 return iEncoding + 1;
3006}
3007
3008
3009/**
3010 * Wip - VEX.W ignored.
3011 * L0 - VEX.L is zero (encoding may exist where it isn't).
3012 */
3013static unsigned BS3_NEAR_CODE
3014Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L0_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3015{
3016 return Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lxx_OR_ViceVersa(pThis, iEncoding, 0 /*uVexL*/);
3017}
3018
3019
3020/**
3021 * Wip - VEX.W ignored.
3022 * L1 - VEX.L is one (encoding may exist where it isn't).
3023 */
3024static unsigned BS3_NEAR_CODE
3025Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L1_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3026{
3027 return Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lxx_OR_ViceVersa(pThis, iEncoding, 1 /*uVexL*/);
3028}
3029
3030
3031
3032/**
3033 * Wip - VEX.W ignored.
3034 */
3035static unsigned BS3_NEAR_CODE
3036Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Msomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3037{
3038 unsigned off;
3039 switch (iEncoding)
3040 {
3041 case 0:
3042 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xc /*~V*/, 0 /*L*/, 1 /*~R*/);
3043 off = Bs3Cg1InsertOpcodes(pThis, off);
3044 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3045 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 3;
3046 break;
3047 case 1:
3048 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/);
3049 off = Bs3Cg1InsertOpcodes(pThis, off);
3050 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7);
3051 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3052 pThis->fInvalidEncoding = true;
3053 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
3054 break;
3055#if ARCH_BITS == 64
3056 case 2:
3057 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0x1 /*~V*/, 0 /*L*/, 0 /*~R*/);
3058 off = Bs3Cg1InsertOpcodes(pThis, off);
3059 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 7 + 8);
3060 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 14;
3061 break;
3062#endif
3063 case 3:
3064 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/);
3065 off = Bs3Cg1InsertOpcodes(pThis, off);
3066 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 0);
3067 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 1;
3068 break;
3069 case 4:
3070 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3071 off = Bs3Cg1InsertOpcodes(pThis, off);
3072 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3073 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3074 break;
3075 case 5:
3076 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L-ignored*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3077 off = Bs3Cg1InsertOpcodes(pThis, off);
3078 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3079 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3080 pThis->fInvalidEncoding = true;
3081 break;
3082 case 6:
3083 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W-ignored*/);
3084 off = Bs3Cg1InsertOpcodes(pThis, off);
3085 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3086 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3087 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 3 : 0;
3088 break;
3089#if ARCH_BITS == 64
3090 case 7:
3091 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 0 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3092 off = Bs3Cg1InsertOpcodes(pThis, off);
3093 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5+8);
3094 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3095 break;
3096 case 8:
3097 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 0 /*~B-ignored*/, 0 /*W*/);
3098 off = Bs3Cg1InsertOpcodes(pThis, off);
3099 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 1);
3100 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3101 break;
3102 case 9:
3103 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 0 /*~X-ignored*/, 1 /*~B*/, 0 /*W*/);
3104 off = Bs3Cg1InsertOpcodes(pThis, off);
3105 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2);
3106 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + 0;
3107 break;
3108#endif
3109 case 10:
3110 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3111 off = Bs3Cg1InsertOpcodes(pThis, off);
3112 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 5);
3113 pThis->aOperands[1].idxField = pThis->aOperands[1].idxFieldBase + (BS3CG1_IS_64BIT_TARGET(pThis) ? 15 : 7);
3114 pThis->fInvalidEncoding = true;
3115 break;
3116 default:
3117 return 0;
3118 }
3119 pThis->cbCurInstr = off;
3120 return iEncoding + 1;
3121}
3122
3123
3124static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_Md_WO(PBS3CG1STATE pThis, unsigned iEncoding)
3125{
3126 unsigned off;
3127 switch (iEncoding)
3128 {
3129 case 0:
3130 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3131 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3132 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3133 break;
3134 case 1:
3135 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3136 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3137 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3138 break;
3139 case 2:
3140 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0x7 /*~V-invalid*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3141 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3142 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3143 pThis->fInvalidEncoding = true;
3144 break;
3145 case 3:
3146 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3147 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3148 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3149 pThis->fInvalidEncoding = true;
3150 break;
3151 case 4:
3152 pThis->abCurInstr[0] = P_OZ;
3153 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3154 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3155 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3156 pThis->fInvalidEncoding = true;
3157 break;
3158 case 5:
3159 pThis->abCurInstr[0] = P_RZ;
3160 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3161 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3162 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3163 pThis->fInvalidEncoding = true;
3164 break;
3165 case 6:
3166 pThis->abCurInstr[0] = P_RN;
3167 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3168 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3169 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3170 pThis->fInvalidEncoding = true;
3171 break;
3172 case 7:
3173 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
3174 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3175 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3176 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 1 : 0;
3177 break;
3178#if ARCH_BITS == 64
3179 case 8:
3180 pThis->abCurInstr[0] = REX_____;
3181 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3182 off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
3183 off = Bs3Cfg1EncodeMemMod0DispWithDefaultsAndNoReg(pThis, off);
3184 pThis->fInvalidEncoding = true;
3185 break;
3186#endif
3187 default:
3188 return 0;
3189 }
3190
3191 pThis->cbCurInstr = off;
3192 return iEncoding + 1;
3193}
3194
3195
3196/**
3197 * Wip = VEX.W ignored.
3198 * Lmbz = VEX.L must be zero.
3199 */
3200static unsigned BS3_NEAR_CODE
3201Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_Lmbz_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3202{
3203 unsigned off;
3204 switch (iEncoding)
3205 {
3206 /* 128-bit wide stuff goes first, then we'll update the operand widths afterwards. */
3207 case 0:
3208 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3209 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3210 off = Bs3Cg1InsertOpcodes(pThis, off);
3211 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
3212 break;
3213
3214 case 1:
3215 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3216 off = Bs3Cg1InsertOpcodes(pThis, off);
3217 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3218 break;
3219 case 2:
3220 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored*/);
3221 off = Bs3Cg1InsertOpcodes(pThis, off);
3222 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 5, 4);
3223 break;
3224 case 3:
3225 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
3226 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3227 off = Bs3Cg1InsertOpcodes(pThis, off);
3228 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
3229 break;
3230 case 4:
3231 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3232 off = Bs3Cg1InsertOpcodes(pThis, off);
3233 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3234 break;
3235 case 5:
3236 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored */);
3237 off = Bs3Cg1InsertOpcodes(pThis, off);
3238 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3239 break;
3240 case 6:
3241 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3242 off = Bs3Cg1InsertOpcodes(pThis, off);
3243 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3244 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3245 pThis->bAlignmentXcpt = X86_XCPT_GP;
3246 break;
3247 case 7:
3248 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3249 off = Bs3Cg1InsertOpcodes(pThis, off);
3250 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3251 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3252 pThis->bAlignmentXcpt = X86_XCPT_GP;
3253 break;
3254 /* 128-bit invalid encodings: */
3255 case 8:
3256 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3257 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, 0 /*L*/, 1 /*~R*/); /* Bad V value */
3258 off = Bs3Cg1InsertOpcodes(pThis, off);
3259 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
3260 pThis->fInvalidEncoding = true;
3261 break;
3262 case 9:
3263 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3264 off = Bs3Cg1InsertOpcodes(pThis, off);
3265 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3266 pThis->fInvalidEncoding = true;
3267 iEncoding = 20-1;
3268 break;
3269
3270 default:
3271 return 0;
3272 }
3273
3274 pThis->cbCurInstr = off;
3275 return iEncoding + 1;
3276}
3277
3278
3279/**
3280 * Wip = VEX.W ignored.
3281 */
3282static unsigned BS3_NEAR_CODE
3283Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_OR_ViceVersa(PBS3CG1STATE pThis, unsigned iEncoding)
3284{
3285 unsigned off;
3286
3287 switch (iEncoding)
3288 {
3289 case 20: /* switch to 256-bit */
3290 pThis->aOperands[pThis->iRmOp ].cbOp = 32;
3291 pThis->aOperands[pThis->iRmOp ].idxFieldBase = BS3CG1DST_YMM0;
3292 pThis->aOperands[pThis->iRegOp].cbOp = 32;
3293 pThis->aOperands[pThis->iRegOp].idxFieldBase = BS3CG1DST_YMM0;
3294 RT_FALL_THRU();
3295 case 0:
3296 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3297 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3298 off = Bs3Cg1InsertOpcodes(pThis, off);
3299 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
3300 break;
3301
3302 case 1:
3303 case 21:
3304 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3305 off = Bs3Cg1InsertOpcodes(pThis, off);
3306 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3307 break;
3308 case 2:
3309 case 22:
3310 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored*/);
3311 off = Bs3Cg1InsertOpcodes(pThis, off);
3312 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 5, 4);
3313 break;
3314 case 3:
3315 case 23:
3316 pThis->aOperands[pThis->iRmOp].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationMem;
3317 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3318 off = Bs3Cg1InsertOpcodes(pThis, off);
3319 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 2 /*iReg*/);
3320 break;
3321 case 4:
3322 case 24:
3323 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3324 off = Bs3Cg1InsertOpcodes(pThis, off);
3325 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3326 break;
3327 case 5:
3328 case 25:
3329 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W - ignored */);
3330 off = Bs3Cg1InsertOpcodes(pThis, off);
3331 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaults(pThis, off, 3 /*iReg*/);
3332 break;
3333 case 6:
3334 case 26:
3335 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/);
3336 off = Bs3Cg1InsertOpcodes(pThis, off);
3337 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3338 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3339 pThis->bAlignmentXcpt = X86_XCPT_GP;
3340 break;
3341 case 7:
3342 case 27:
3343 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3344 off = Bs3Cg1InsertOpcodes(pThis, off);
3345 off = Bs3Cfg1EncodeMemMod0DispWithRegFieldAndDefaultsMisaligned(pThis, off, 3 /*iReg*/, 1 /*cbMisalign*/);
3346 if (!Bs3Cg1XcptTypeIsVexUnaligned(pThis->enmXcptType))
3347 pThis->bAlignmentXcpt = X86_XCPT_GP;
3348 break;
3349 /* invalid encodings: */
3350 case 8:
3351 case 28:
3352 pThis->aOperands[pThis->iRmOp ].enmLocation = pThis->aOperands[pThis->iRmOp].enmLocationReg;
3353 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xe /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/); /* Bad V value */
3354 off = Bs3Cg1InsertOpcodes(pThis, off);
3355 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1, 0);
3356 pThis->fInvalidEncoding = true;
3357 break;
3358 case 9:
3359 case 29:
3360 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0 /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3361 off = Bs3Cg1InsertOpcodes(pThis, off);
3362 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3363 pThis->fInvalidEncoding = true;
3364 break;
3365
3366 case 10:
3367 case 30:
3368 pThis->abCurInstr[0] = P_RN;
3369 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3370 off = Bs3Cg1InsertOpcodes(pThis, off);
3371 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3372 pThis->fInvalidEncoding = true;
3373 break;
3374 case 11:
3375 case 31:
3376 pThis->abCurInstr[0] = P_RZ;
3377 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3378 off = Bs3Cg1InsertOpcodes(pThis, off);
3379 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3380 pThis->fInvalidEncoding = true;
3381 break;
3382 case 12:
3383 case 32:
3384 pThis->abCurInstr[0] = P_OZ;
3385 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3386 off = Bs3Cg1InsertOpcodes(pThis, off);
3387 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3388 pThis->fInvalidEncoding = true;
3389 break;
3390 case 13:
3391 case 33:
3392 pThis->abCurInstr[0] = P_LK;
3393 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3394 off = Bs3Cg1InsertOpcodes(pThis, off);
3395 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 4, 5);
3396 pThis->fInvalidEncoding = true;
3397 iEncoding += !BS3CG1_IS_64BIT_TARGET(pThis) ? 2 + 4 : 0;
3398 break;
3399
3400#if ARCH_BITS == 64
3401 /* 64-bit mode registers */
3402 case 14:
3403 case 34:
3404 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/);
3405 off = Bs3Cg1InsertOpcodes(pThis, off);
3406 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 3+8, 4);
3407 break;
3408 case 15:
3409 case 35:
3410 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, iEncoding >= 20 /*L*/, 0 /*~R*/, 1 /*~X*/, 0 /*~B*/, 0 /*W*/);
3411 off = Bs3Cg1InsertOpcodes(pThis, off);
3412 off = Bs3Cg1InsertModRmWithRegFields(pThis, off, 1+8, 4+8);
3413 iEncoding += 4;
3414 break;
3415#endif
3416 default:
3417 return 0;
3418 }
3419
3420 pThis->cbCurInstr = off;
3421 return iEncoding + 1;
3422}
3423
3424
3425//static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_FIXED(PBS3CG1STATE pThis, unsigned iEncoding)
3426//{
3427// unsigned off;
3428// if (iEncoding == 0)
3429// off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3430// else if (iEncoding == 0)
3431// off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3432// else
3433// return 0;
3434// pThis->cbCurInstr = off;
3435// return iEncoding + 1;
3436//}
3437
3438
3439static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_MOD_EQ_3(PBS3CG1STATE pThis, unsigned iEncoding)
3440{
3441 unsigned off;
3442 if (iEncoding < 8)
3443 {
3444 if (iEncoding & 1)
3445 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3446 else
3447 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3448 off = Bs3Cg1InsertOpcodes(pThis, off);
3449 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, iEncoding, 1);
3450 }
3451 else if (iEncoding < 16)
3452 {
3453 if (iEncoding & 1)
3454 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/);
3455 else
3456 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3457 off = Bs3Cg1InsertOpcodes(pThis, off);
3458 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, iEncoding & 7, 1);
3459 }
3460 else if (iEncoding < 24)
3461 {
3462 if (iEncoding & 1)
3463 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
3464 else
3465 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
3466 off = Bs3Cg1InsertOpcodes(pThis, off);
3467 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 0, iEncoding & 7);
3468 }
3469 else if (iEncoding < 32)
3470 {
3471 if (iEncoding & 1)
3472 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 3) != 0 /*L*/, 1 /*~R*/);
3473 else
3474 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 2) != 0 /*L*/, 1 /*~R*/, 1 /*~X*/,
3475 1 /*~B*/, (iEncoding & 4) != 0 /*W*/);
3476 off = Bs3Cg1InsertOpcodes(pThis, off);
3477 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, 0, iEncoding & 7);
3478 }
3479 else
3480 return 0;
3481 pThis->cbCurInstr = off;
3482
3483 return iEncoding + 1;
3484}
3485
3486
3487static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM_MOD_NE_3(PBS3CG1STATE pThis, unsigned iEncoding)
3488{
3489 unsigned off;
3490 if (iEncoding < 8)
3491 {
3492 unsigned iMod = iEncoding % 3;
3493 if (iEncoding & 1)
3494 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 2) != 0 /*L*/, 1 /*~R*/);
3495 else
3496 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, (iEncoding & 2) != 0 /*L*/, 1 /*~R*/,
3497 1 /*~X*/, 1 /*~B*/, (iEncoding & 4) != 0 /*W*/);
3498 off = Bs3Cg1InsertOpcodes(pThis, off);
3499 pThis->abCurInstr[off++] = X86_MODRM_MAKE(iMod, 0, 1);
3500 if (iMod >= 1)
3501 pThis->abCurInstr[off++] = 0x7f;
3502 if (iMod == 2)
3503 {
3504 pThis->abCurInstr[off++] = 0x5f;
3505 if (!BS3_MODE_IS_16BIT_CODE(pThis->bMode))
3506 {
3507 pThis->abCurInstr[off++] = 0x3f;
3508 pThis->abCurInstr[off++] = 0x1f;
3509 }
3510 }
3511 }
3512 else
3513 return 0;
3514 pThis->cbCurInstr = off;
3515 return iEncoding + 1;
3516}
3517
3518
3519static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext_VEX_MODRM(PBS3CG1STATE pThis, unsigned iEncoding)
3520{
3521 const unsigned cFirstEncodings = 32;
3522 if (iEncoding < cFirstEncodings)
3523 {
3524 unsigned iRet = Bs3Cg1EncodeNext_VEX_MODRM_MOD_EQ_3(pThis, iEncoding);
3525 BS3_ASSERT(iRet > iEncoding);
3526 return iRet;
3527 }
3528 return Bs3Cg1EncodeNext_VEX_MODRM_MOD_NE_3(pThis, iEncoding - cFirstEncodings) + cFirstEncodings;
3529}
3530
3531#endif /* BS3CG1_WITH_VEX */
3532
3533
3534/**
3535 * Encodes the next instruction.
3536 *
3537 * @returns Next iEncoding value. Returns @a iEncoding unchanged to indicate
3538 * that there are no more encodings to test.
3539 * @param pThis The state.
3540 * @param iEncoding The encoding to produce. Meaning is specific to
3541 * each BS3CG1ENC_XXX value and should be considered
3542 * internal.
3543 */
3544static unsigned BS3_NEAR_CODE Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding)
3545{
3546 pThis->bAlignmentXcpt = UINT8_MAX;
3547 pThis->uVexL = UINT8_MAX;
3548 if (pThis->pfnEncoder)
3549 return pThis->pfnEncoder(pThis, iEncoding);
3550
3551 Bs3TestFailedF("Internal error! BS3CG1ENC_XXX = %u not implemented", pThis->enmEncoding);
3552 return iEncoding;
3553}
3554
3555
3556/**
3557 * Prepares doing instruction encodings.
3558 *
3559 * This is in part specific to how the instruction is encoded, but generally it
3560 * sets up basic operand values that doesn't change (much) when Bs3Cg1EncodeNext
3561 * is called from within the loop.
3562 *
3563 * @returns Success indicator (true/false).
3564 * @param pThis The state.
3565 */
3566#define Bs3Cg1EncodePrep BS3_CMN_NM(Bs3Cg1EncodePrep)
3567bool BS3_NEAR_CODE Bs3Cg1EncodePrep(PBS3CG1STATE pThis)
3568{
3569 unsigned i = 4;
3570 while (i-- > 0)
3571 pThis->aSavedSegRegs[i].ds = pThis->aInitialCtxs[i].ds;
3572
3573 i = RT_ELEMENTS(pThis->aOperands);
3574 while (i-- > 0)
3575 {
3576 pThis->aOperands[i].enmLocationReg = BS3CG1OPLOC_INVALID;
3577 pThis->aOperands[i].enmLocationMem = BS3CG1OPLOC_INVALID;
3578 pThis->aOperands[i].idxFieldBase = BS3CG1DST_INVALID;
3579 }
3580
3581 pThis->iRmOp = RT_ELEMENTS(pThis->aOperands) - 1;
3582 pThis->iRegOp = RT_ELEMENTS(pThis->aOperands) - 1;
3583 pThis->fSameRingNotOkay = false;
3584 pThis->cbOperand = 0;
3585 pThis->pfnEncoder = NULL;
3586
3587 switch (pThis->enmEncoding)
3588 {
3589 case BS3CG1ENC_MODRM_Eb_Gb:
3590 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Eb_Gb_OR_ViceVersa;
3591 pThis->iRmOp = 0;
3592 pThis->iRegOp = 1;
3593 pThis->aOperands[0].cbOp = 1;
3594 pThis->aOperands[1].cbOp = 1;
3595 pThis->aOperands[0].idxFieldBase = BS3CG1DST_AL;
3596 pThis->aOperands[1].idxFieldBase = BS3CG1DST_AL;
3597 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3598 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_RW;
3599 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3600 break;
3601
3602 case BS3CG1ENC_MODRM_Ev_Gv:
3603 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Gv_Ev__OR__MODRM_Ev_Gv;
3604 pThis->iRmOp = 0;
3605 pThis->iRegOp = 1;
3606 pThis->cbOperand = 2;
3607 pThis->aOperands[0].idxFieldBase = BS3CG1DST_OZ_RAX;
3608 pThis->aOperands[1].idxFieldBase = BS3CG1DST_OZ_RAX;
3609 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3610 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_RW;
3611 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3612 break;
3613
3614 case BS3CG1ENC_MODRM_Ed_WO_Pd_WZ:
3615 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ;
3616 pThis->iRmOp = 0;
3617 pThis->iRegOp = 1;
3618 pThis->aOperands[0].cbOp = 4;
3619 pThis->aOperands[1].cbOp = 4;
3620 pThis->aOperands[0].idxFieldBase = BS3CG1DST_EAX;
3621 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
3622 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3623 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3624 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3625 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3626 break;
3627
3628 case BS3CG1ENC_MODRM_Eq_WO_Pq_WNZ:
3629 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ;
3630 pThis->iRmOp = 0;
3631 pThis->iRegOp = 1;
3632 pThis->aOperands[0].cbOp = 8;
3633 pThis->aOperands[1].cbOp = 8;
3634 pThis->aOperands[0].idxFieldBase = BS3CG1DST_RAX;
3635 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
3636 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3637 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3638 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3639 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3640 break;
3641
3642 case BS3CG1ENC_MODRM_Ed_WO_Vd_WZ:
3643 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vd_WO_Ed_WZ;
3644 pThis->iRmOp = 0;
3645 pThis->iRegOp = 1;
3646 pThis->aOperands[0].cbOp = 4;
3647 pThis->aOperands[1].cbOp = 4;
3648 pThis->aOperands[0].idxFieldBase = BS3CG1DST_EAX;
3649 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
3650 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3651 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3652 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3653 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3654 break;
3655
3656 case BS3CG1ENC_MODRM_Eq_WO_Vq_WNZ:
3657 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vq_WO_Eq_WNZ;
3658 pThis->iRmOp = 0;
3659 pThis->iRegOp = 1;
3660 pThis->aOperands[0].cbOp = 8;
3661 pThis->aOperands[1].cbOp = 8;
3662 pThis->aOperands[0].idxFieldBase = BS3CG1DST_RAX;
3663 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
3664 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3665 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3666 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3667 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3668 break;
3669
3670 case BS3CG1ENC_MODRM_Gb_Eb:
3671 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Eb_Gb_OR_ViceVersa;
3672 pThis->iRegOp = 0;
3673 pThis->iRmOp = 1;
3674 pThis->aOperands[0].cbOp = 1;
3675 pThis->aOperands[1].cbOp = 1;
3676 pThis->aOperands[0].idxFieldBase = BS3CG1DST_AL;
3677 pThis->aOperands[1].idxFieldBase = BS3CG1DST_AL;
3678 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3679 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3680 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3681 break;
3682
3683 case BS3CG1ENC_MODRM_Gv_Ev:
3684 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Gv_Ev__OR__MODRM_Ev_Gv;
3685 pThis->iRegOp = 0;
3686 pThis->iRmOp = 1;
3687 pThis->cbOperand = 2;
3688 pThis->aOperands[0].idxFieldBase = BS3CG1DST_OZ_RAX;
3689 pThis->aOperands[1].idxFieldBase = BS3CG1DST_OZ_RAX;
3690 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3691 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3692 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3693 break;
3694
3695 case BS3CG1ENC_MODRM_Gv_RO_Ma: /* bound instr */
3696 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Gv_RO_Ma;
3697 pThis->iRmOp = 1;
3698 pThis->iRegOp = 0;
3699 pThis->cbOperand = 2;
3700 pThis->aOperands[0].cbOp = 2;
3701 pThis->aOperands[1].cbOp = 4;
3702 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3703 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
3704 pThis->aOperands[0].idxFieldBase = BS3CG1DST_OZ_RAX;
3705 break;
3706
3707 case BS3CG1ENC_MODRM_Wss_WO_Vss:
3708 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa;
3709 pThis->iRmOp = 0;
3710 pThis->iRegOp = 1;
3711 pThis->aOperands[0].cbOp = 4;
3712 pThis->aOperands[1].cbOp = 4;
3713 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0;
3714 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_DW0;
3715 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3716 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3717 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3718 break;
3719
3720 case BS3CG1ENC_MODRM_Wsd_WO_Vsd:
3721 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa;
3722 pThis->iRmOp = 0;
3723 pThis->iRegOp = 1;
3724 pThis->aOperands[0].cbOp = 8;
3725 pThis->aOperands[1].cbOp = 8;
3726 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
3727 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
3728 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3729 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3730 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3731 break;
3732
3733 case BS3CG1ENC_MODRM_WqZxReg_WO_Vq:
3734 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa;
3735 pThis->iRmOp = 0;
3736 pThis->iRegOp = 1;
3737 pThis->aOperands[0].cbOp = 8;
3738 pThis->aOperands[1].cbOp = 8;
3739 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
3740 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
3741 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3742 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3743 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3744 break;
3745
3746 case BS3CG1ENC_MODRM_Wps_WO_Vps:
3747 case BS3CG1ENC_MODRM_Wpd_WO_Vpd:
3748 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa;
3749 pThis->iRmOp = 0;
3750 pThis->iRegOp = 1;
3751 pThis->aOperands[0].cbOp = 16;
3752 pThis->aOperands[1].cbOp = 16;
3753 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
3754 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
3755 pThis->aOperands[0].enmLocationReg = BS3CG1OPLOC_CTX;
3756 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3757 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3758 break;
3759
3760 case BS3CG1ENC_MODRM_Vdq_WO_Mdq:
3761 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_Vsomething_OR_ViceVersa;
3762 pThis->iRegOp = 0;
3763 pThis->iRmOp = 1;
3764 pThis->aOperands[0].cbOp = 16;
3765 pThis->aOperands[1].cbOp = 16;
3766 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3767 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
3768 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
3769 break;
3770
3771 case BS3CG1ENC_MODRM_Vdq_WO_Wdq:
3772 case BS3CG1ENC_MODRM_Vpd_WO_Wpd:
3773 case BS3CG1ENC_MODRM_Vps_WO_Wps:
3774 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa;
3775 pThis->iRegOp = 0;
3776 pThis->iRmOp = 1;
3777 pThis->aOperands[0].cbOp = 16;
3778 pThis->aOperands[1].cbOp = 16;
3779 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
3780 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
3781 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3782 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3783 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3784 break;
3785
3786 case BS3CG1ENC_MODRM_Pq_WO_Qq:
3787 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Qq;
3788 pThis->iRegOp = 0;
3789 pThis->iRmOp = 1;
3790 pThis->aOperands[0].cbOp = 8;
3791 pThis->aOperands[1].cbOp = 8;
3792 pThis->aOperands[0].idxFieldBase = BS3CG1DST_MM0;
3793 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
3794 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3795 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3796 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3797 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3798 break;
3799
3800 case BS3CG1ENC_MODRM_Pq_WO_Uq:
3801 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Uq;
3802 pThis->iRegOp = 0;
3803 pThis->iRmOp = 1;
3804 pThis->aOperands[0].cbOp = 8;
3805 pThis->aOperands[1].cbOp = 8;
3806 pThis->aOperands[0].idxFieldBase = BS3CG1DST_MM0;
3807 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
3808 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3809 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX; /* reg only */
3810 break;
3811
3812 case BS3CG1ENC_MODRM_PdZx_WO_Ed_WZ:
3813 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_PdZx_WO_Ed_WZ;
3814 pThis->iRegOp = 0;
3815 pThis->iRmOp = 1;
3816 pThis->aOperands[0].cbOp = 4;
3817 pThis->aOperands[1].cbOp = 4;
3818 pThis->aOperands[0].idxFieldBase = BS3CG1DST_MM0_LO_ZX;
3819 pThis->aOperands[1].idxFieldBase = BS3CG1DST_EAX;
3820 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3821 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3822 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3823 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3824 break;
3825
3826 case BS3CG1ENC_MODRM_Pq_WO_Eq_WNZ:
3827 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Pq_WO_Eq_WNZ;
3828 pThis->iRegOp = 0;
3829 pThis->iRmOp = 1;
3830 pThis->aOperands[0].cbOp = 8;
3831 pThis->aOperands[1].cbOp = 8;
3832 pThis->aOperands[0].idxFieldBase = BS3CG1DST_MM0;
3833 pThis->aOperands[1].idxFieldBase = BS3CG1DST_RAX;
3834 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3835 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3836 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3837 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3838 break;
3839
3840 case BS3CG1ENC_MODRM_VdZx_WO_Ed_WZ:
3841 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vd_WO_Ed_WZ;
3842 pThis->iRegOp = 0;
3843 pThis->iRmOp = 1;
3844 pThis->aOperands[0].cbOp = 4;
3845 pThis->aOperands[1].cbOp = 4;
3846 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0_ZX;
3847 pThis->aOperands[1].idxFieldBase = BS3CG1DST_EAX;
3848 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3849 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3850 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3851 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3852 break;
3853
3854 case BS3CG1ENC_MODRM_VqZx_WO_Eq_WNZ:
3855 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vq_WO_Eq_WNZ;
3856 pThis->iRegOp = 0;
3857 pThis->iRmOp = 1;
3858 pThis->aOperands[0].cbOp = 8;
3859 pThis->aOperands[1].cbOp = 8;
3860 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
3861 pThis->aOperands[1].idxFieldBase = BS3CG1DST_RAX;
3862 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3863 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3864 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3865 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3866 break;
3867
3868 case BS3CG1ENC_MODRM_Vq_WO_UqHi:
3869 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Usomething_OR_ViceVersa;
3870 pThis->iRegOp = 0;
3871 pThis->iRmOp = 1;
3872 pThis->aOperands[0].cbOp = 8;
3873 pThis->aOperands[1].cbOp = 8;
3874 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
3875 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
3876 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3877 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3878 break;
3879
3880 case BS3CG1ENC_MODRM_VqHi_WO_Uq:
3881 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Usomething_OR_ViceVersa;
3882 pThis->iRegOp = 0;
3883 pThis->iRmOp = 1;
3884 pThis->aOperands[0].cbOp = 8;
3885 pThis->aOperands[1].cbOp = 8;
3886 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_HI;
3887 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
3888 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3889 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3890 break;
3891
3892 case BS3CG1ENC_MODRM_VqHi_WO_Mq:
3893 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_Vsomething_OR_ViceVersa;
3894 pThis->iRegOp = 0;
3895 pThis->iRmOp = 1;
3896 pThis->aOperands[0].cbOp = 8;
3897 pThis->aOperands[1].cbOp = 8;
3898 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_HI;
3899 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3900 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
3901 break;
3902
3903 case BS3CG1ENC_MODRM_Vq_WO_Mq:
3904 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_Vsomething_OR_ViceVersa;
3905 pThis->iRegOp = 0;
3906 pThis->iRmOp = 1;
3907 pThis->aOperands[0].cbOp = 8;
3908 pThis->aOperands[1].cbOp = 8;
3909 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
3910 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3911 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
3912 break;
3913
3914 case BS3CG1ENC_MODRM_VssZx_WO_Wss:
3915 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa;
3916 pThis->iRegOp = 0;
3917 pThis->iRmOp = 1;
3918 pThis->aOperands[0].cbOp = 4;
3919 pThis->aOperands[1].cbOp = 4;
3920 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3921 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3922 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3923 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0_ZX;
3924 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
3925 break;
3926
3927 case BS3CG1ENC_MODRM_VqZx_WO_Nq:
3928 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Nsomething;
3929 pThis->iRegOp = 0;
3930 pThis->iRmOp = 1;
3931 pThis->aOperands[0].cbOp = 8;
3932 pThis->aOperands[1].cbOp = 8;
3933 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3934 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3935 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
3936 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
3937 break;
3938
3939 case BS3CG1ENC_MODRM_VsdZx_WO_Wsd:
3940 case BS3CG1ENC_MODRM_VqZx_WO_Wq:
3941 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Vsomething_Wsomething_OR_ViceVersa;
3942 pThis->iRegOp = 0;
3943 pThis->iRmOp = 1;
3944 pThis->aOperands[0].cbOp = 8;
3945 pThis->aOperands[1].cbOp = 8;
3946 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
3947 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3948 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
3949 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
3950 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
3951 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO;
3952 break;
3953
3954 case BS3CG1ENC_MODRM_Mb_RO:
3955 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething;
3956 pThis->iRmOp = 0;
3957 pThis->aOperands[0].cbOp = 1;
3958 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM;
3959 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM;
3960 break;
3961
3962 case BS3CG1ENC_MODRM_Md_RO:
3963 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething;
3964 pThis->iRmOp = 0;
3965 pThis->aOperands[0].cbOp = 4;
3966 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM;
3967 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM;
3968 break;
3969
3970 case BS3CG1ENC_MODRM_Md_WO:
3971 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething;
3972 pThis->iRmOp = 0;
3973 pThis->aOperands[0].cbOp = 4;
3974 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
3975 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
3976 break;
3977
3978 case BS3CG1ENC_MODRM_Mdq_WO_Vdq:
3979 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_Vsomething_OR_ViceVersa;
3980 pThis->iRmOp = 0;
3981 pThis->iRegOp = 1;
3982 pThis->aOperands[0].cbOp = 16;
3983 pThis->aOperands[1].cbOp = 16;
3984 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
3985 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3986 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
3987 break;
3988
3989 case BS3CG1ENC_MODRM_Mq_WO_Pq:
3990 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_Psomething;
3991 pThis->iRmOp = 0;
3992 pThis->iRegOp = 1;
3993 pThis->aOperands[0].cbOp = 8;
3994 pThis->aOperands[1].cbOp = 8;
3995 pThis->aOperands[1].idxFieldBase = BS3CG1DST_MM0;
3996 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
3997 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
3998 break;
3999
4000 case BS3CG1ENC_MODRM_Mq_WO_Vq:
4001 case BS3CG1ENC_MODRM_Mq_WO_VqHi:
4002 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_Vsomething_OR_ViceVersa;
4003 pThis->iRmOp = 0;
4004 pThis->iRegOp = 1;
4005 pThis->aOperands[0].cbOp = 8;
4006 pThis->aOperands[1].cbOp = 8;
4007 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4008 pThis->aOperands[0].enmLocationMem = BS3CG1OPLOC_MEM_WO;
4009 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4010 pThis->aOperands[1].idxFieldBase = pThis->enmEncoding == BS3CG1ENC_MODRM_Mq_WO_Vq
4011 ? BS3CG1DST_XMM0_LO : BS3CG1DST_XMM0_HI;
4012 break;
4013
4014 case BS3CG1ENC_MODRM_Mps_WO_Vps:
4015 case BS3CG1ENC_MODRM_Mpd_WO_Vpd:
4016 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_Msomething_Vsomething_OR_ViceVersa;
4017 pThis->iRmOp = 0;
4018 pThis->iRegOp = 1;
4019 pThis->aOperands[0].cbOp = 16;
4020 pThis->aOperands[1].cbOp = 16;
4021 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_MEM_WO;
4022 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4023 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4024 break;
4025
4026 case BS3CG1ENC_FIXED:
4027 pThis->pfnEncoder = Bs3Cg1EncodeNext_FIXED;
4028 break;
4029
4030 case BS3CG1ENC_FIXED_AL_Ib:
4031 pThis->pfnEncoder = Bs3Cg1EncodeNext_FIXED_AL_Ib;
4032 pThis->aOperands[0].cbOp = 1;
4033 pThis->aOperands[1].cbOp = 1;
4034 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4035 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_IMM;
4036 pThis->aOperands[0].idxField = BS3CG1DST_AL;
4037 pThis->aOperands[1].idxField = BS3CG1DST_INVALID;
4038 break;
4039
4040 case BS3CG1ENC_FIXED_rAX_Iz:
4041 pThis->pfnEncoder = Bs3Cg1EncodeNext_FIXED_rAX_Iz;
4042 pThis->aOperands[0].cbOp = 2;
4043 pThis->aOperands[1].cbOp = 2;
4044 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
4045 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_IMM;
4046 pThis->aOperands[0].idxField = BS3CG1DST_OZ_RAX;
4047 pThis->aOperands[1].idxField = BS3CG1DST_INVALID;
4048 break;
4049
4050 /* Unused or invalid instructions mostly. */
4051 case BS3CG1ENC_MODRM_MOD_EQ_3:
4052 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_MOD_EQ_3;
4053 break;
4054 case BS3CG1ENC_MODRM_MOD_NE_3:
4055 pThis->pfnEncoder = Bs3Cg1EncodeNext_MODRM_MOD_NE_3;
4056 break;
4057
4058#ifdef BS3CG1_WITH_VEX
4059
4060 case BS3CG1ENC_VEX_MODRM_Vd_WO_Ed_WZ:
4061 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_Vd_WO_Ed_WZ;
4062 pThis->iRegOp = 0;
4063 pThis->iRmOp = 1;
4064 pThis->aOperands[0].cbOp = 4;
4065 pThis->aOperands[1].cbOp = 4;
4066 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0_ZX;
4067 pThis->aOperands[1].idxFieldBase = BS3CG1DST_EAX;
4068 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4069 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4070 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4071 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4072 break;
4073
4074 case BS3CG1ENC_VEX_MODRM_Vq_WO_Eq_WNZ:
4075 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_Vq_WO_Eq_WNZ;
4076 pThis->iRegOp = 0;
4077 pThis->iRmOp = 1;
4078 pThis->aOperands[0].cbOp = 8;
4079 pThis->aOperands[1].cbOp = 8;
4080 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO_ZX;
4081 pThis->aOperands[1].idxFieldBase = BS3CG1DST_RAX;
4082 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4083 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4084 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4085 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4086 break;
4087
4088 case BS3CG1ENC_VEX_MODRM_Vps_WO_Wps:
4089 case BS3CG1ENC_VEX_MODRM_Vpd_WO_Wpd:
4090 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_OR_ViceVersa;
4091 pThis->iRegOp = 0;
4092 pThis->iRmOp = 1;
4093 pThis->aOperands[0].cbOp = 16;
4094 pThis->aOperands[1].cbOp = 16;
4095 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4096 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4097 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4098 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4099 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4100 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0;
4101 break;
4102
4103 case BS3CG1ENC_VEX_MODRM_VssZx_WO_Md:
4104 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa;
4105 pThis->iRmOp = 1;
4106 pThis->iRegOp = 0;
4107 pThis->aOperands[0].cbOp = 4;
4108 pThis->aOperands[1].cbOp = 4;
4109 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4110 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4111 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_DW0;
4112 pThis->aOperands[1].idxFieldBase = BS3CG1DST_INVALID;
4113 break;
4114
4115 case BS3CG1ENC_VEX_MODRM_Vss_WO_HssHi_Uss:
4116 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa;
4117 pThis->iRegOp = 0;
4118 pThis->iRmOp = 2;
4119 pThis->aOperands[0].cbOp = 16;
4120 pThis->aOperands[1].cbOp = 12;
4121 pThis->aOperands[2].cbOp = 4;
4122 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4123 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4124 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4125 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4126 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI96;
4127 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_DW0;
4128 break;
4129
4130 case BS3CG1ENC_VEX_MODRM_VsdZx_WO_Mq:
4131 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_Lig_OR_ViceVersa;
4132 pThis->iRmOp = 1;
4133 pThis->iRegOp = 0;
4134 pThis->aOperands[0].cbOp = 8;
4135 pThis->aOperands[1].cbOp = 8;
4136 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4137 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4138 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
4139 pThis->aOperands[1].idxFieldBase = BS3CG1DST_INVALID;
4140 break;
4141
4142 case BS3CG1ENC_VEX_MODRM_Vx_WO_Mx_L0:
4143 BS3_ASSERT(!(pThis->fFlags & BS3CG1INSTR_F_VEX_L_ZERO));
4144 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L0_OR_ViceVersa;
4145 pThis->iRegOp = 0;
4146 pThis->iRmOp = 1;
4147 pThis->aOperands[0].cbOp = 16;
4148 pThis->aOperands[1].cbOp = 16;
4149 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4150 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4151 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4152 break;
4153
4154 case BS3CG1ENC_VEX_MODRM_Vx_WO_Mx_L1:
4155 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Msomething_Wip_L1_OR_ViceVersa;
4156 pThis->iRegOp = 0;
4157 pThis->iRmOp = 1;
4158 pThis->aOperands[0].cbOp = 32;
4159 pThis->aOperands[1].cbOp = 32;
4160 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4161 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
4162 pThis->aOperands[0].idxFieldBase = BS3CG1DST_YMM0;
4163 break;
4164
4165 case BS3CG1ENC_VEX_MODRM_Vsd_WO_HsdHi_Usd:
4166 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Usomething_Lip_Wip_OR_ViceVersa;
4167 pThis->iRegOp = 0;
4168 pThis->iRmOp = 2;
4169 pThis->aOperands[0].cbOp = 16;
4170 pThis->aOperands[1].cbOp = 8;
4171 pThis->aOperands[2].cbOp = 8;
4172 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4173 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4174 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4175 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4176 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
4177 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_LO;
4178 break;
4179
4180 case BS3CG1ENC_VEX_MODRM_Vq_WO_HqHi_UqHi:
4181 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_HdqCsomething_Usomething_Wip_OR_ViceVersa;
4182 pThis->iRegOp = 0;
4183 pThis->iRmOp = 2;
4184 pThis->aOperands[0].cbOp = 16;
4185 pThis->aOperands[1].cbOp = 8;
4186 pThis->aOperands[2].cbOp = 8;
4187 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4188 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4189 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_CTX;
4190 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4191 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
4192 pThis->aOperands[2].idxFieldBase = BS3CG1DST_XMM0_HI;
4193 break;
4194
4195 case BS3CG1ENC_VEX_MODRM_Vq_WO_HqHi_Mq:
4196 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_VsomethingWO_Hsomething_Msomething_Wip_OR_ViceVersa;
4197 pThis->iRegOp = 0;
4198 pThis->iRmOp = 2;
4199 pThis->aOperands[0].cbOp = 16;
4200 pThis->aOperands[1].cbOp = 8;
4201 pThis->aOperands[2].cbOp = 8;
4202 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4203 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4204 pThis->aOperands[2].enmLocation = BS3CG1OPLOC_MEM;
4205 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0;
4206 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_HI;
4207 pThis->aOperands[2].idxFieldBase = BS3CG1DST_INVALID;
4208 break;
4209
4210 case BS3CG1ENC_VEX_MODRM_Vq_WO_Wq:
4211 BS3_ASSERT(pThis->fFlags & BS3CG1INSTR_F_VEX_L_ZERO);
4212 pThis->pfnEncoder = Bs3Cg1EncodeNext_VEX_MODRM_WsomethingWO_Vsomething_Wip_Lmbz_OR_ViceVersa;
4213 pThis->iRegOp = 0;
4214 pThis->iRmOp = 1;
4215 pThis->aOperands[0].cbOp = 8;
4216 pThis->aOperands[1].cbOp = 8;
4217 pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX_ZX_VLMAX;
4218 pThis->aOperands[1].enmLocation = BS3CG1OPLOC_CTX;
4219 pThis->aOperands[1].enmLocationReg = BS3CG1OPLOC_CTX;
4220 pThis->aOperands[1].enmLocationMem = BS3CG1OPLOC_MEM;
4221 pThis->aOperands[0].idxFieldBase = BS3CG1DST_XMM0_LO;
4222 pThis->aOperands[1].idxFieldBase = BS3CG1DST_XMM0_LO