VirtualBox

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

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

bs3-cpu-generated-1: cleanups

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

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