VirtualBox

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

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

IEM: Implemented movq Wq,Vq (VEX.66.0F d6).

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