VirtualBox

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

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

bs3-cpu-generated-1,IEM: updates.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 48.9 KB
Line 
1/* $Id: bs3-cpu-generated-1-template.c 66113 2017-03-15 14:32:28Z 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 P_CS X86_OP_PRF_CS
45#define P_SS X86_OP_PRF_SS
46#define P_DS X86_OP_PRF_DS
47#define P_ES X86_OP_PRF_ES
48#define P_FS X86_OP_PRF_FS
49#define P_GS X86_OP_PRF_GS
50#define P_OZ X86_OP_PRF_SIZE_OP
51#define P_AZ X86_OP_PRF_SIZE_ADDR
52#define P_LK X86_OP_PRF_LOCK
53#define P_RN X86_OP_PRF_REPNZ
54#define P_RZ X86_OP_PRF_REPZ
55
56#define REX_WRBX (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B | X86_OP_REX_X)
57#define REX_W___ (X86_OP_REX_W)
58#define REX_WR__ (X86_OP_REX_W | X86_OP_REX_R)
59#define REX_W_B_ (X86_OP_REX_W | X86_OP_REX_B)
60#define REX_W__X (X86_OP_REX_W | X86_OP_REX_X)
61#define REX_WRB_ (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B)
62#define REX_WR_X (X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_X)
63#define REX_W_BX (X86_OP_REX_W | X86_OP_REX_B | X86_OP_REX_X)
64#define REX__R__ (X86_OP_REX_R)
65#define REX__RB_ (X86_OP_REX_R | X86_OP_REX_B)
66#define REX__R_X (X86_OP_REX_R | X86_OP_REX_X)
67#define REX__RBX (X86_OP_REX_R | X86_OP_REX_B | X86_OP_REX_X)
68#define REX___B_ (X86_OP_REX_B)
69#define REX___BX (X86_OP_REX_B | X86_OP_REX_X)
70#define REX____X (X86_OP_REX_X)
71#define REX_____ (0x40)
72
73
74/** @def BS3CG1_DPRINTF
75 * Debug print macro.
76 */
77#if 1
78# define BS3CG1_DPRINTF(a_ArgList) Bs3TestPrintf a_ArgList
79#else
80# define BS3CG1_DPRINTF(a_ArgList) do { } while (0)
81#endif
82
83#define BS3CG1_DEBUG_CTX_MOD
84
85
86/*********************************************************************************************************************************
87* Structures and Typedefs *
88*********************************************************************************************************************************/
89/**
90 * The state.
91 */
92typedef struct BS3CG1STATE
93{
94 /** @name Instruction details (expanded from BS3CG1INSTR).
95 * @{ */
96 /** Pointer to the mnemonic string (not terminated) (g_achBs3Cg1Mnemonics). */
97 const char BS3_FAR *pchMnemonic;
98 /** Pointer to the test header. */
99 PCBS3CG1TESTHDR pTestHdr;
100 /** Pointer to the per operand flags (g_abBs3Cg1Operands). */
101 const uint8_t BS3_FAR *pabOperands;
102 /** Opcode bytes (g_abBs3Cg1Opcodes). */
103 const uint8_t BS3_FAR *pabOpcodes;
104 /** The current instruction number in the input array (for error reporting). */
105 uint32_t iInstr;
106
107 /** The instruction flags. */
108 uint32_t fFlags;
109 /** The encoding. */
110 BS3CG1ENC enmEncoding;
111#if ARCH_BITS == 16
112 uint16_t u16Padding0;
113#endif
114 /** Per operand flags. */
115 BS3CG1OP aenmOperands[4];
116 /** Opcode bytes. */
117 uint8_t abOpcodes[4];
118
119 /** The length of the mnemonic. */
120 uint8_t cchMnemonic;
121 /** Whether to advance the mnemonic pointer or not. */
122 uint8_t fAdvanceMnemonic;
123 /** The number of opcode bytes. */
124 uint8_t cbOpcodes;
125 /** Number of operands. */
126 uint8_t cOperands;
127 /** @} */
128
129 /** Operand size (16, 32, 64, or 0). */
130 uint8_t cBitsOp;
131 /** Target ring (0..3). */
132 uint8_t uCpl;
133
134 /** The current test number. */
135 uint8_t iTest;
136
137 /** Target mode (g_bBs3CurrentMode). */
138 uint8_t bMode;
139
140
141 /** @name Current encoded instruction.
142 * @{ */
143 /** The size of the current instruction that we're testing. */
144 uint8_t cbCurInstr;
145 /** The size the prefixes. */
146 uint8_t cbCurPrefix;
147 /** The offset into abCurInstr of the immediate. */
148 uint8_t offCurImm;
149 /** Buffer for assembling the current instruction. */
150 uint8_t abCurInstr[27];
151
152 /** Set if the encoding can't be tested in the same ring as this test code.
153 * This is used to deal with encodings modifying SP/ESP/RSP. */
154 bool fSameRingNotOkay;
155 /** The aOperands index of the modrm.reg operand (if applicable). */
156 uint8_t iRegOp;
157 /** The aOperands index of the modrm.rm operand (if applicable). */
158 uint8_t iRmOp;
159
160 /** Operands details. */
161 struct
162 {
163 uint8_t cbOp;
164 bool fMem;
165 /** The BS3CG1DST value for this field.
166 * Set to BS3CG1DST_INVALID if memory. */
167 uint8_t idxField;
168 } aOperands[4];
169 /** @} */
170
171 /** Page to put code in. When paging is enabled, the page before and after
172 * are marked not-present. */
173 uint8_t BS3_FAR *pbCodePg;
174 /** The flat address corresponding to pbCodePg. */
175 uintptr_t uCodePgFlat;
176 /** Page for placing data operands in. When paging is enabled, the page before
177 * and after are marked not-present. */
178 uint8_t BS3_FAR *pbDataPg;
179
180 /** The context we're working on. */
181 BS3REGCTX Ctx;
182 /** The trap context and frame. */
183 BS3TRAPFRAME TrapFrame;
184 /** Initial contexts, one for each ring. */
185 BS3REGCTX aInitialCtxs[4];
186
187 /** Memory operand scratch space. */
188 union
189 {
190 uint8_t ab[128];
191 uint16_t au16[128 / sizeof(uint16_t)];
192 uint32_t au32[128 / sizeof(uint32_t)];
193 uint64_t au64[128 / sizeof(uint64_t)];
194 } MemOp;
195} BS3CG1STATE;
196/** Pointer to the generated test state. */
197typedef BS3CG1STATE *PBS3CG1STATE;
198
199
200#define BS3CG1_PF_OZ UINT16_C(0x0001)
201#define BS3CG1_PF_AZ UINT16_C(0x0002)
202#define BS3CG1_PF_CS UINT16_C(0x0004)
203#define BS3CG1_PF_DS UINT16_C(0x0008)
204#define BS3CG1_PF_ES UINT16_C(0x0010)
205#define BS3CG1_PF_FS UINT16_C(0x0020)
206#define BS3CG1_PF_GS UINT16_C(0x0040)
207#define BS3CG1_PF_SS UINT16_C(0x0080)
208#define BS3CG1_PF_SEGS (BS3CG1_PF_CS | BS3CG1_PF_DS | BS3CG1_PF_ES | BS3CG1_PF_FS | BS3CG1_PF_GS | BS3CG1_PF_SS)
209#define BS3CG1_PF_MEM (BS3CG1_PF_SEGS | BS3CG1_PF_AZ)
210#define BS3CG1_PF_LK UINT16_C(0x0100)
211#define BS3CG1_PF_RN UINT16_C(0x0200)
212#define BS3CG1_PF_RZ UINT16_C(0x0400)
213#define BS3CG1_PF_W UINT16_C(0x0800) /**< REX.W */
214#define BS3CG1_PF_R UINT16_C(0x1000) /**< REX.R */
215#define BS3CG1_PF_B UINT16_C(0x2000) /**< REX.B */
216#define BS3CG1_PF_X UINT16_C(0x4000) /**< REX.X */
217
218
219/** Used in g_cbBs3Cg1DstFields to indicate that it's one of the 4 operands. */
220#define BS3CG1DSTSIZE_OPERAND UINT8_C(255)
221/** Used in g_cbBs3Cg1DstFields to indicate that the operand size determins
222 * the field size (2, 4, or 8). */
223#define BS3CG1DSTSIZE_OPERAND_SIZE_GRP UINT8_C(254)
224
225
226
227/*********************************************************************************************************************************
228* Global Variables *
229*********************************************************************************************************************************/
230/** Destination field sizes indexed by bBS3CG1DST.
231 * Zero means operand size sized. */
232static const uint8_t g_acbBs3Cg1DstFields[] =
233{
234 /* [BS3CG1DST_INVALID] = */ BS3CG1DSTSIZE_OPERAND,
235
236 /* [BS3CG1DST_OP1] = */ BS3CG1DSTSIZE_OPERAND,
237 /* [BS3CG1DST_OP2] = */ BS3CG1DSTSIZE_OPERAND,
238 /* [BS3CG1DST_OP3] = */ BS3CG1DSTSIZE_OPERAND,
239 /* [BS3CG1DST_OP4] = */ BS3CG1DSTSIZE_OPERAND,
240 /* [BS3CG1DST_EFL] = */ 4,
241 /* [BS3CG1DST_EFL_UNDEF]=*/ 4,
242
243 /* [BS3CG1DST_AL] = */ 1,
244 /* [BS3CG1DST_CL] = */ 1,
245 /* [BS3CG1DST_DL] = */ 1,
246 /* [BS3CG1DST_BL] = */ 1,
247 /* [BS3CG1DST_AH] = */ 1,
248 /* [BS3CG1DST_CH] = */ 1,
249 /* [BS3CG1DST_DH] = */ 1,
250 /* [BS3CG1DST_BH] = */ 1,
251 /* [BS3CG1DST_SPL] = */ 1,
252 /* [BS3CG1DST_BPL] = */ 1,
253 /* [BS3CG1DST_SIL] = */ 1,
254 /* [BS3CG1DST_DIL] = */ 1,
255 /* [BS3CG1DST_R8L] = */ 1,
256 /* [BS3CG1DST_R9L] = */ 1,
257 /* [BS3CG1DST_R10L] = */ 1,
258 /* [BS3CG1DST_R11L] = */ 1,
259 /* [BS3CG1DST_R12L] = */ 1,
260 /* [BS3CG1DST_R13L] = */ 1,
261 /* [BS3CG1DST_R14L] = */ 1,
262 /* [BS3CG1DST_R15L] = */ 1,
263
264 /* [BS3CG1DST_AX] = */ 2,
265 /* [BS3CG1DST_CX] = */ 2,
266 /* [BS3CG1DST_DX] = */ 2,
267 /* [BS3CG1DST_BX] = */ 2,
268 /* [BS3CG1DST_SP] = */ 2,
269 /* [BS3CG1DST_BP] = */ 2,
270 /* [BS3CG1DST_SI] = */ 2,
271 /* [BS3CG1DST_DI] = */ 2,
272 /* [BS3CG1DST_R8W] = */ 2,
273 /* [BS3CG1DST_R9W] = */ 2,
274 /* [BS3CG1DST_R10W] = */ 2,
275 /* [BS3CG1DST_R11W] = */ 2,
276 /* [BS3CG1DST_R12W] = */ 2,
277 /* [BS3CG1DST_R13W] = */ 2,
278 /* [BS3CG1DST_R14W] = */ 2,
279 /* [BS3CG1DST_R15W] = */ 2,
280
281 /* [BS3CG1DST_EAX] = */ 4,
282 /* [BS3CG1DST_ECX] = */ 4,
283 /* [BS3CG1DST_EDX] = */ 4,
284 /* [BS3CG1DST_EBX] = */ 4,
285 /* [BS3CG1DST_ESP] = */ 4,
286 /* [BS3CG1DST_EBP] = */ 4,
287 /* [BS3CG1DST_ESI] = */ 4,
288 /* [BS3CG1DST_EDI] = */ 4,
289 /* [BS3CG1DST_R8D] = */ 4,
290 /* [BS3CG1DST_R9D] = */ 4,
291 /* [BS3CG1DST_R10D] = */ 4,
292 /* [BS3CG1DST_R11D] = */ 4,
293 /* [BS3CG1DST_R12D] = */ 4,
294 /* [BS3CG1DST_R13D] = */ 4,
295 /* [BS3CG1DST_R14D] = */ 4,
296 /* [BS3CG1DST_R15D] = */ 4,
297
298 /* [BS3CG1DST_RAX] = */ 8,
299 /* [BS3CG1DST_RCX] = */ 8,
300 /* [BS3CG1DST_RDX] = */ 8,
301 /* [BS3CG1DST_RBX] = */ 8,
302 /* [BS3CG1DST_RSP] = */ 8,
303 /* [BS3CG1DST_RBP] = */ 8,
304 /* [BS3CG1DST_RSI] = */ 8,
305 /* [BS3CG1DST_RDI] = */ 8,
306 /* [BS3CG1DST_R8] = */ 8,
307 /* [BS3CG1DST_R9] = */ 8,
308 /* [BS3CG1DST_R10] = */ 8,
309 /* [BS3CG1DST_R11] = */ 8,
310 /* [BS3CG1DST_R12] = */ 8,
311 /* [BS3CG1DST_R13] = */ 8,
312 /* [BS3CG1DST_R14] = */ 8,
313 /* [BS3CG1DST_R15] = */ 8,
314
315 /* [BS3CG1DST_OZ_RAX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
316 /* [BS3CG1DST_OZ_RCX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
317 /* [BS3CG1DST_OZ_RDX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
318 /* [BS3CG1DST_OZ_RBX] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
319 /* [BS3CG1DST_OZ_RSP] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
320 /* [BS3CG1DST_OZ_RBP] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
321 /* [BS3CG1DST_OZ_RSI] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
322 /* [BS3CG1DST_OZ_RDI] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
323 /* [BS3CG1DST_OZ_R8] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
324 /* [BS3CG1DST_OZ_R9] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
325 /* [BS3CG1DST_OZ_R10] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
326 /* [BS3CG1DST_OZ_R11] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
327 /* [BS3CG1DST_OZ_R12] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
328 /* [BS3CG1DST_OZ_R13] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
329 /* [BS3CG1DST_OZ_R14] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
330 /* [BS3CG1DST_OZ_R15] = */ BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
331};
332
333/** Destination field offset indexed by bBS3CG1DST.
334 * Zero means operand size sized. */
335static const unsigned g_aoffBs3Cg1DstFields[] =
336{
337 /* [BS3CG1DST_INVALID] = */ ~0U,
338 /* [BS3CG1DST_OP1] = */ ~0U,
339 /* [BS3CG1DST_OP2] = */ ~0U,
340 /* [BS3CG1DST_OP3] = */ ~0U,
341 /* [BS3CG1DST_OP4] = */ ~0U,
342 /* [BS3CG1DST_EFL] = */ RT_OFFSETOF(BS3REGCTX, rflags),
343 /* [BS3CG1DST_EFL_UNDEF]=*/ ~0, /* special field */
344
345 /* [BS3CG1DST_AL] = */ RT_OFFSETOF(BS3REGCTX, rax.u8),
346 /* [BS3CG1DST_CL] = */ RT_OFFSETOF(BS3REGCTX, rcx.u8),
347 /* [BS3CG1DST_DL] = */ RT_OFFSETOF(BS3REGCTX, rdx.u8),
348 /* [BS3CG1DST_BL] = */ RT_OFFSETOF(BS3REGCTX, rbx.u8),
349 /* [BS3CG1DST_AH] = */ RT_OFFSETOF(BS3REGCTX, rax.b.bHi),
350 /* [BS3CG1DST_CH] = */ RT_OFFSETOF(BS3REGCTX, rcx.b.bHi),
351 /* [BS3CG1DST_DH] = */ RT_OFFSETOF(BS3REGCTX, rdx.b.bHi),
352 /* [BS3CG1DST_BH] = */ RT_OFFSETOF(BS3REGCTX, rbx.b.bHi),
353 /* [BS3CG1DST_SPL] = */ RT_OFFSETOF(BS3REGCTX, rsp.u8),
354 /* [BS3CG1DST_BPL] = */ RT_OFFSETOF(BS3REGCTX, rbp.u8),
355 /* [BS3CG1DST_SIL] = */ RT_OFFSETOF(BS3REGCTX, rsi.u8),
356 /* [BS3CG1DST_DIL] = */ RT_OFFSETOF(BS3REGCTX, rdi.u8),
357 /* [BS3CG1DST_R8L] = */ RT_OFFSETOF(BS3REGCTX, r8.u8),
358 /* [BS3CG1DST_R9L] = */ RT_OFFSETOF(BS3REGCTX, r9.u8),
359 /* [BS3CG1DST_R10L] = */ RT_OFFSETOF(BS3REGCTX, r10.u8),
360 /* [BS3CG1DST_R11L] = */ RT_OFFSETOF(BS3REGCTX, r11.u8),
361 /* [BS3CG1DST_R12L] = */ RT_OFFSETOF(BS3REGCTX, r12.u8),
362 /* [BS3CG1DST_R13L] = */ RT_OFFSETOF(BS3REGCTX, r13.u8),
363 /* [BS3CG1DST_R14L] = */ RT_OFFSETOF(BS3REGCTX, r14.u8),
364 /* [BS3CG1DST_R15L] = */ RT_OFFSETOF(BS3REGCTX, r15.u8),
365
366 /* [BS3CG1DST_AX] = */ RT_OFFSETOF(BS3REGCTX, rax.u16),
367 /* [BS3CG1DST_CX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u16),
368 /* [BS3CG1DST_DX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u16),
369 /* [BS3CG1DST_BX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u16),
370 /* [BS3CG1DST_SP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u16),
371 /* [BS3CG1DST_BP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u16),
372 /* [BS3CG1DST_SI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u16),
373 /* [BS3CG1DST_DI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u16),
374 /* [BS3CG1DST_R8W] = */ RT_OFFSETOF(BS3REGCTX, r8.u16),
375 /* [BS3CG1DST_R9W] = */ RT_OFFSETOF(BS3REGCTX, r9.u16),
376 /* [BS3CG1DST_R10W] = */ RT_OFFSETOF(BS3REGCTX, r10.u16),
377 /* [BS3CG1DST_R11W] = */ RT_OFFSETOF(BS3REGCTX, r11.u16),
378 /* [BS3CG1DST_R12W] = */ RT_OFFSETOF(BS3REGCTX, r12.u16),
379 /* [BS3CG1DST_R13W] = */ RT_OFFSETOF(BS3REGCTX, r13.u16),
380 /* [BS3CG1DST_R14W] = */ RT_OFFSETOF(BS3REGCTX, r14.u16),
381 /* [BS3CG1DST_R15W] = */ RT_OFFSETOF(BS3REGCTX, r15.u16),
382
383 /* [BS3CG1DST_EAX] = */ RT_OFFSETOF(BS3REGCTX, rax.u32),
384 /* [BS3CG1DST_ECX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u32),
385 /* [BS3CG1DST_EDX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u32),
386 /* [BS3CG1DST_EBX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u32),
387 /* [BS3CG1DST_ESP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u32),
388 /* [BS3CG1DST_EBP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u32),
389 /* [BS3CG1DST_ESI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u32),
390 /* [BS3CG1DST_EDI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u32),
391 /* [BS3CG1DST_R8D] = */ RT_OFFSETOF(BS3REGCTX, r8.u32),
392 /* [BS3CG1DST_R9D] = */ RT_OFFSETOF(BS3REGCTX, r9.u32),
393 /* [BS3CG1DST_R10D] = */ RT_OFFSETOF(BS3REGCTX, r10.u32),
394 /* [BS3CG1DST_R11D] = */ RT_OFFSETOF(BS3REGCTX, r11.u32),
395 /* [BS3CG1DST_R12D] = */ RT_OFFSETOF(BS3REGCTX, r12.u32),
396 /* [BS3CG1DST_R13D] = */ RT_OFFSETOF(BS3REGCTX, r13.u32),
397 /* [BS3CG1DST_R14D] = */ RT_OFFSETOF(BS3REGCTX, r14.u32),
398 /* [BS3CG1DST_R15D] = */ RT_OFFSETOF(BS3REGCTX, r15.u32),
399
400 /* [BS3CG1DST_RAX] = */ RT_OFFSETOF(BS3REGCTX, rax.u64),
401 /* [BS3CG1DST_RCX] = */ RT_OFFSETOF(BS3REGCTX, rcx.u64),
402 /* [BS3CG1DST_RDX] = */ RT_OFFSETOF(BS3REGCTX, rdx.u64),
403 /* [BS3CG1DST_RBX] = */ RT_OFFSETOF(BS3REGCTX, rbx.u64),
404 /* [BS3CG1DST_RSP] = */ RT_OFFSETOF(BS3REGCTX, rsp.u64),
405 /* [BS3CG1DST_RBP] = */ RT_OFFSETOF(BS3REGCTX, rbp.u64),
406 /* [BS3CG1DST_RSI] = */ RT_OFFSETOF(BS3REGCTX, rsi.u64),
407 /* [BS3CG1DST_RDI] = */ RT_OFFSETOF(BS3REGCTX, rdi.u64),
408 /* [BS3CG1DST_R8] = */ RT_OFFSETOF(BS3REGCTX, r8.u64),
409 /* [BS3CG1DST_R9] = */ RT_OFFSETOF(BS3REGCTX, r9.u64),
410 /* [BS3CG1DST_R10] = */ RT_OFFSETOF(BS3REGCTX, r10.u64),
411 /* [BS3CG1DST_R11] = */ RT_OFFSETOF(BS3REGCTX, r11.u64),
412 /* [BS3CG1DST_R12] = */ RT_OFFSETOF(BS3REGCTX, r12.u64),
413 /* [BS3CG1DST_R13] = */ RT_OFFSETOF(BS3REGCTX, r13.u64),
414 /* [BS3CG1DST_R14] = */ RT_OFFSETOF(BS3REGCTX, r14.u64),
415 /* [BS3CG1DST_R15] = */ RT_OFFSETOF(BS3REGCTX, r15.u64),
416
417 /* [BS3CG1DST_OZ_RAX] = */ RT_OFFSETOF(BS3REGCTX, rax),
418 /* [BS3CG1DST_OZ_RCX] = */ RT_OFFSETOF(BS3REGCTX, rcx),
419 /* [BS3CG1DST_OZ_RDX] = */ RT_OFFSETOF(BS3REGCTX, rdx),
420 /* [BS3CG1DST_OZ_RBX] = */ RT_OFFSETOF(BS3REGCTX, rbx),
421 /* [BS3CG1DST_OZ_RSP] = */ RT_OFFSETOF(BS3REGCTX, rsp),
422 /* [BS3CG1DST_OZ_RBP] = */ RT_OFFSETOF(BS3REGCTX, rbp),
423 /* [BS3CG1DST_OZ_RSI] = */ RT_OFFSETOF(BS3REGCTX, rsi),
424 /* [BS3CG1DST_OZ_RDI] = */ RT_OFFSETOF(BS3REGCTX, rdi),
425 /* [BS3CG1DST_OZ_R8] = */ RT_OFFSETOF(BS3REGCTX, r8),
426 /* [BS3CG1DST_OZ_R9] = */ RT_OFFSETOF(BS3REGCTX, r9),
427 /* [BS3CG1DST_OZ_R10] = */ RT_OFFSETOF(BS3REGCTX, r10),
428 /* [BS3CG1DST_OZ_R11] = */ RT_OFFSETOF(BS3REGCTX, r11),
429 /* [BS3CG1DST_OZ_R12] = */ RT_OFFSETOF(BS3REGCTX, r12),
430 /* [BS3CG1DST_OZ_R13] = */ RT_OFFSETOF(BS3REGCTX, r13),
431 /* [BS3CG1DST_OZ_R14] = */ RT_OFFSETOF(BS3REGCTX, r14),
432 /* [BS3CG1DST_OZ_R15] = */ RT_OFFSETOF(BS3REGCTX, r15),
433};
434
435#ifdef BS3CG1_DEBUG_CTX_MOD
436/** Destination field names. */
437static const struct { char sz[8]; } g_aszBs3Cg1DstFields[] =
438{
439 { "INVALID" },
440 { "OP1" },
441 { "OP2" },
442 { "OP3" },
443 { "OP4" },
444 { "EFL" },
445 { "EFL_UND" },
446
447 { "AL" },
448 { "CL" },
449 { "DL" },
450 { "BL" },
451 { "AH" },
452 { "CH" },
453 { "DH" },
454 { "BH" },
455 { "SPL" },
456 { "BPL" },
457 { "SIL" },
458 { "DIL" },
459 { "R8L" },
460 { "R9L" },
461 { "R10L" },
462 { "R11L" },
463 { "R12L" },
464 { "R13L" },
465 { "R14L" },
466 { "R15L" },
467
468 { "AX" },
469 { "CX" },
470 { "DX" },
471 { "BX" },
472 { "SP" },
473 { "BP" },
474 { "SI" },
475 { "DI" },
476 { "R8W" },
477 { "R9W" },
478 { "R10W" },
479 { "R11W" },
480 { "R12W" },
481 { "R13W" },
482 { "R14W" },
483 { "R15W" },
484
485 { "EAX" },
486 { "ECX" },
487 { "EDX" },
488 { "EBX" },
489 { "ESP" },
490 { "EBP" },
491 { "ESI" },
492 { "EDI" },
493 { "R8D" },
494 { "R9D" },
495 { "R10D" },
496 { "R11D" },
497 { "R12D" },
498 { "R13D" },
499 { "R14D" },
500 { "R15D" },
501
502 { "RAX" },
503 { "RCX" },
504 { "RDX" },
505 { "RBX" },
506 { "RSP" },
507 { "RBP" },
508 { "RSI" },
509 { "RDI" },
510 { "R8" },
511 { "R9" },
512 { "R10" },
513 { "R11" },
514 { "R12" },
515 { "R13" },
516 { "R14" },
517 { "R15" },
518
519 { "OZ_RAX" },
520 { "OZ_RCX" },
521 { "OZ_RDX" },
522 { "OZ_RBX" },
523 { "OZ_RSP" },
524 { "OZ_RBP" },
525 { "OZ_RSI" },
526 { "OZ_RDI" },
527 { "OZ_R8" },
528 { "OZ_R9" },
529 { "OZ_R10" },
530 { "OZ_R11" },
531 { "OZ_R12" },
532 { "OZ_R13" },
533 { "OZ_R14" },
534 { "OZ_R15" },
535};
536
537#endif
538
539#if 0
540static const struct
541{
542 uint8_t cbPrefixes;
543 uint8_t abPrefixes[14];
544 uint16_t fEffective;
545} g_aPrefixVariations[] =
546{
547 { 0, { 0x00 }, BS3CG1_PF_NONE },
548
549 { 1, { P_OZ }, BS3CG1_PF_OZ },
550 { 1, { P_CS }, BS3CG1_PF_CS },
551 { 1, { P_DS }, BS3CG1_PF_DS },
552 { 1, { P_ES }, BS3CG1_PF_ES },
553 { 1, { P_FS }, BS3CG1_PF_FS },
554 { 1, { P_GS }, BS3CG1_PF_GS },
555 { 1, { P_SS }, BS3CG1_PF_SS },
556 { 1, { P_LK }, BS3CG1_PF_LK },
557
558 { 2, { P_CS, P_OZ, }, BS3CG1_PF_CS | BS3CFG1_PF_OZ },
559 { 2, { P_DS, P_OZ, }, BS3CG1_PF_DS | BS3CFG1_PF_OZ },
560 { 2, { P_ES, P_OZ, }, BS3CG1_PF_ES | BS3CFG1_PF_OZ },
561 { 2, { P_FS, P_OZ, }, BS3CG1_PF_FS | BS3CFG1_PF_OZ },
562 { 2, { P_GS, P_OZ, }, BS3CG1_PF_GS | BS3CFG1_PF_OZ },
563 { 2, { P_GS, P_OZ, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
564 { 2, { P_SS, P_OZ, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
565
566 { 2, { P_OZ, P_CS, }, BS3CG1_PF_CS | BS3CFG1_PF_OZ },
567 { 2, { P_OZ, P_DS, }, BS3CG1_PF_DS | BS3CFG1_PF_OZ },
568 { 2, { P_OZ, P_ES, }, BS3CG1_PF_ES | BS3CFG1_PF_OZ },
569 { 2, { P_OZ, P_FS, }, BS3CG1_PF_FS | BS3CFG1_PF_OZ },
570 { 2, { P_OZ, P_GS, }, BS3CG1_PF_GS | BS3CFG1_PF_OZ },
571 { 2, { P_OZ, P_GS, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
572 { 2, { P_OZ, P_SS, }, BS3CG1_PF_SS | BS3CFG1_PF_OZ },
573};
574
575static const uint16_t g_afPfxKindToIgnoredFlags[BS3CGPFXKIND_END] =
576{
577 /* [BS3CGPFXKIND_INVALID] = */ UINT16_MAX,
578 /* [BS3CGPFXKIND_MODRM] = */ 0,
579 /* [BS3CGPFXKIND_MODRM_NO_OP_SIZES] = */ BS3CG1_PF_OZ | BS3CG1_PF_W,
580};
581
582#endif
583
584
585DECLINLINE(unsigned) Bs3Cg1InsertOpcodes(PBS3CG1STATE pThis, unsigned offDst)
586{
587 switch (pThis->cbOpcodes)
588 {
589 case 4: pThis->abCurInstr[offDst + 3] = pThis->abOpcodes[3];
590 case 3: pThis->abCurInstr[offDst + 2] = pThis->abOpcodes[2];
591 case 2: pThis->abCurInstr[offDst + 1] = pThis->abOpcodes[1];
592 case 1: pThis->abCurInstr[offDst] = pThis->abOpcodes[0];
593 return offDst + pThis->cbOpcodes;
594
595 default:
596 BS3_ASSERT(0);
597 return 0;
598 }
599}
600
601
602static unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding)
603{
604 unsigned off;
605 switch (pThis->enmEncoding)
606 {
607 case BS3CG1ENC_MODRM_Eb_Gb:
608 /* Start by reg,reg encoding. */
609 if (iEncoding == 0)
610 {
611 off = Bs3Cg1InsertOpcodes(pThis, 0);
612 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
613 pThis->cbCurInstr = off;
614 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
615 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
616 iEncoding++;
617 }
618 break;
619
620 case BS3CG1ENC_MODRM_Ev_Gv:
621 case BS3CG1ENC_FIXED_AL_Ib:
622 case BS3CG1ENC_FIXED_rAX_Iz:
623 break;
624
625 case BS3CG1ENC_END:
626 case BS3CG1ENC_INVALID:
627 /* Impossible; to shut up gcc. */
628 break;
629 }
630
631
632 return iEncoding;
633}
634
635
636/**
637 * Prepares doing instruction encodings.
638 *
639 * This is in part specific to how the instruction is encoded, but generally it
640 * sets up basic operand values that doesn't change (much) when Bs3Cg1EncodeNext
641 * is called from within the loop.
642 *
643 * @returns Success indicator (true/false).
644 * @param pThis The state.
645 */
646static bool Bs3Cg1EncodePrep(PBS3CG1STATE pThis)
647{
648 pThis->iRmOp = RT_ELEMENTS(pThis->aOperands) - 1;
649 pThis->iRegOp = RT_ELEMENTS(pThis->aOperands) - 1;
650 pThis->fSameRingNotOkay = false;
651
652 switch (pThis->enmEncoding)
653 {
654 case BS3CG1ENC_MODRM_Eb_Gb:
655 pThis->iRmOp = 0;
656 pThis->iRegOp = 1;
657 pThis->aOperands[0].cbOp = 1;
658 pThis->aOperands[1].cbOp = 1;
659 pThis->aOperands[0].fMem = false;
660 pThis->aOperands[1].fMem = false;
661 break;
662
663 case BS3CG1ENC_MODRM_Ev_Gv:
664 pThis->iRmOp = 0;
665 pThis->iRegOp = 1;
666 pThis->aOperands[0].cbOp = 2;
667 pThis->aOperands[1].cbOp = 2;
668 pThis->aOperands[0].fMem = false;
669 pThis->aOperands[1].fMem = false;
670 break;
671
672 case BS3CG1ENC_FIXED_AL_Ib:
673 break;
674 case BS3CG1ENC_FIXED_rAX_Iz:
675 break;
676
677 default:
678 Bs3TestFailedF("Invalid enmEncoding for instruction #%u (%.*s): %d",
679 pThis->iInstr, pThis->cchMnemonic, pThis->pchMnemonic, pThis->enmEncoding);
680 return false;
681 }
682 return true;
683}
684
685
686/**
687 * Checks the preconditions for a test.
688 *
689 * @returns true if the test be executed, false if not.
690 * @param pThis The state.
691 * @param pHdr The test header.
692 */
693static bool Bs3Cg1RunSelector(PBS3CG1STATE pThis, PCBS3CG1TESTHDR pHdr)
694{
695
696 uint8_t const BS3_FAR *pbCode = (uint8_t const BS3_FAR *)(pHdr + 1);
697 unsigned cbLeft = pHdr->cbSelector;
698 while (cbLeft-- > 0)
699 {
700 switch (*pbCode++)
701 {
702#define CASE_PRED(a_Pred, a_Expr) \
703 case ((a_Pred) << BS3CG1SEL_OP_KIND_MASK) | BS3CG1SEL_OP_IS_TRUE: \
704 if (!(a_Expr)) return false; \
705 break; \
706 case ((a_Pred) << BS3CG1SEL_OP_KIND_MASK) | BS3CG1SEL_OP_IS_FALSE: \
707 if (a_Expr) return false; \
708 break
709 CASE_PRED(BS3CG1PRED_SIZE_O16, pThis->cBitsOp == 16);
710 CASE_PRED(BS3CG1PRED_SIZE_O32, pThis->cBitsOp == 32);
711 CASE_PRED(BS3CG1PRED_SIZE_O64, pThis->cBitsOp == 64);
712 CASE_PRED(BS3CG1PRED_RING_0, pThis->uCpl == 0);
713 CASE_PRED(BS3CG1PRED_RING_1, pThis->uCpl == 1);
714 CASE_PRED(BS3CG1PRED_RING_2, pThis->uCpl == 2);
715 CASE_PRED(BS3CG1PRED_RING_3, pThis->uCpl == 3);
716 CASE_PRED(BS3CG1PRED_RING_0_THRU_2, pThis->uCpl <= 2);
717 CASE_PRED(BS3CG1PRED_RING_1_THRU_3, pThis->uCpl >= 1);
718 CASE_PRED(BS3CG1PRED_CODE_64BIT, BS3_MODE_IS_64BIT_CODE(pThis->bMode));
719 CASE_PRED(BS3CG1PRED_CODE_32BIT, BS3_MODE_IS_32BIT_CODE(pThis->bMode));
720 CASE_PRED(BS3CG1PRED_CODE_16BIT, BS3_MODE_IS_16BIT_CODE(pThis->bMode));
721 CASE_PRED(BS3CG1PRED_MODE_REAL, BS3_MODE_IS_RM_SYS(pThis->bMode));
722 CASE_PRED(BS3CG1PRED_MODE_PROT, BS3_MODE_IS_PM_SYS(pThis->bMode));
723 CASE_PRED(BS3CG1PRED_MODE_LONG, BS3_MODE_IS_64BIT_SYS(pThis->bMode));
724 CASE_PRED(BS3CG1PRED_MODE_SMM, false);
725 CASE_PRED(BS3CG1PRED_MODE_VMX, false);
726 CASE_PRED(BS3CG1PRED_MODE_SVM, false);
727 CASE_PRED(BS3CG1PRED_PAGING_ON, BS3_MODE_IS_PAGED(pThis->bMode));
728 CASE_PRED(BS3CG1PRED_PAGING_OFF, !BS3_MODE_IS_PAGED(pThis->bMode));
729
730#undef CASE_PRED
731 default:
732 Bs3TestFailedF("Invalid selector opcode %#x!", pbCode[-1]);
733 return false;
734 }
735 }
736
737 return true;
738}
739
740
741/**
742 * Runs a context modifier program.
743 *
744 * @returns Success indicator (true/false).
745 * @param pThis The state.
746 * @param pCtx The context.
747 * @param pHdr The program header.
748 * @param off The program offset relative to the end of the header.
749 * @param cb The program size.
750 * @param pEflCtx The context to take undefined EFLAGS from. (This is NULL
751 * if we're processing a input context modifier program.)
752 */
753static bool Bs3Cg1RunContextModifier(PBS3CG1STATE pThis, PBS3REGCTX pCtx, PCBS3CG1TESTHDR pHdr, unsigned off, unsigned cb,
754 PCBS3REGCTX pEflCtx)
755{
756 uint8_t const BS3_FAR *pbCode = (uint8_t const BS3_FAR *)(pHdr + 1) + off;
757 int cbLeft = cb;
758 while (cbLeft-- > 0)
759 {
760 /*
761 * Decode the instruction.
762 */
763 uint8_t const bOpcode = *pbCode++;
764 unsigned cbValue;
765 unsigned cbDst;
766 BS3CG1DST idxField;
767
768 /* Expand the destiation field (can be escaped). */
769 switch (bOpcode & BS3CG1_CTXOP_DST_MASK)
770 {
771 case BS3CG1_CTXOP_OP1:
772 idxField = pThis->aOperands[0].idxField;
773 if (idxField == BS3CG1DST_INVALID)
774 idxField = BS3CG1DST_OP1;
775 break;
776
777 case BS3CG1_CTXOP_OP2:
778 idxField = pThis->aOperands[1].idxField;
779 if (idxField == BS3CG1DST_INVALID)
780 idxField = BS3CG1DST_OP2;
781 break;
782
783 case BS3CG1_CTXOP_EFL:
784 idxField = BS3CG1DST_EFL;
785 break;
786
787 case BS3CG1_CTXOP_DST_ESC:
788 if (cbLeft-- > 0)
789 {
790 idxField = (BS3CG1DST)*pbCode++;
791 if (idxField <= BS3CG1DST_OP4)
792 {
793 if (idxField > BS3CG1DST_INVALID)
794 {
795 uint8_t idxField2 = pThis->aOperands[idxField - BS3CG1DST_OP1].idxField;
796 if (idxField2 != BS3CG1DST_INVALID)
797 idxField = idxField2;
798 break;
799 }
800 }
801 else if (idxField < BS3CG1DST_END)
802 break;
803 Bs3TestFailedF("Malformed context instruction: idxField=%d", idxField);
804 return false;
805 }
806 /* fall thru */
807 default:
808 Bs3TestFailed("Malformed context instruction: Destination");
809 return false;
810 }
811
812
813 /* Expand value size (can be escaped). */
814 switch (bOpcode & BS3CG1_CTXOP_SIZE_MASK)
815 {
816 case BS3CG1_CTXOP_1_BYTE: cbValue = 1; break;
817 case BS3CG1_CTXOP_2_BYTES: cbValue = 2; break;
818 case BS3CG1_CTXOP_4_BYTES: cbValue = 4; break;
819 case BS3CG1_CTXOP_8_BYTES: cbValue = 8; break;
820 case BS3CG1_CTXOP_16_BYTES: cbValue = 16; break;
821 case BS3CG1_CTXOP_32_BYTES: cbValue = 32; break;
822 case BS3CG1_CTXOP_12_BYTES: cbValue = 12; break;
823 case BS3CG1_CTXOP_SIZE_ESC:
824 if (cbLeft-- > 0)
825 {
826 cbValue = *pbCode++;
827 if (cbValue)
828 break;
829 }
830 /* fall thru */
831 default:
832 Bs3TestFailed("Malformed context instruction: size");
833 return false;
834 }
835
836 /* Make sure there is enough instruction bytes for the value. */
837 if (cbValue <= cbLeft)
838 { /* likely */ }
839 else
840 {
841 Bs3TestFailedF("Malformed context instruction: %u bytes value, %u bytes left", cbValue, cbLeft);
842 return false;
843 }
844
845 /*
846 * Do value processing specific to the target field size.
847 */
848 cbDst = g_acbBs3Cg1DstFields[idxField];
849 if (cbDst == BS3CG1DSTSIZE_OPERAND)
850 cbDst = pThis->aOperands[idxField - BS3CG1DST_OP1].cbOp;
851 else if (cbDst == BS3CG1DSTSIZE_OPERAND_SIZE_GRP)
852 cbDst = pThis->cBitsOp / 8;
853 if (cbDst <= 8)
854 {
855 unsigned const offField = g_aoffBs3Cg1DstFields[idxField];
856 BS3PTRUNION PtrField;
857
858 /*
859 * Deal with fields up to 8-byte wide.
860 */
861 /* Get the value. */
862 uint64_t uValue;
863 if ((bOpcode & BS3CG1_CTXOP_SIGN_EXT))
864 switch (cbValue)
865 {
866 case 1: uValue = *(int8_t const BS3_FAR *)pbCode; break;
867 case 2: uValue = *(int16_t const BS3_FAR *)pbCode; break;
868 case 4: uValue = *(int32_t const BS3_FAR *)pbCode; break;
869 default:
870 if (cbValue >= 8)
871 {
872 uValue = *(uint64_t const BS3_FAR *)pbCode;
873 break;
874 }
875 Bs3TestFailedF("Malformed context instruction: %u bytes value (%u dst)", cbValue, cbDst);
876 return false;
877 }
878 else
879 switch (cbValue)
880 {
881 case 1: uValue = *(uint8_t const BS3_FAR *)pbCode; break;
882 case 2: uValue = *(uint16_t const BS3_FAR *)pbCode; break;
883 case 4: uValue = *(uint32_t const BS3_FAR *)pbCode; break;
884 default:
885 if (cbValue >= 8)
886 {
887 uValue = *(uint64_t const BS3_FAR *)pbCode;
888 break;
889 }
890 Bs3TestFailedF("Malformed context instruction: %u bytes value (%u dst)", cbValue, cbDst);
891 return false;
892 }
893
894 /* Find the field. */
895 if (offField < sizeof(BS3REGCTX))
896 PtrField.pu8 = (uint8_t BS3_FAR *)pCtx + offField;
897 /* Special field: Copying in undefined EFLAGS from the result context. */
898 else if (idxField == BS3CG1DST_EFL_UNDEF)
899 {
900 if (!pEflCtx || (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK) != BS3CG1_CTXOP_ASSIGN)
901 {
902 Bs3TestFailed("Invalid BS3CG1DST_EFL_UNDEF usage");
903 return false;
904 }
905 PtrField.pu32 = &pCtx->rflags.u32;
906 uValue = (*PtrField.pu32 & ~(uint32_t)uValue) | (pEflCtx->rflags.u32 & (uint32_t)uValue);
907 }
908 //@todo else if (idxField <= BS3CG1DST_OP4)
909 //@todo {
910 //@todo
911 //@todo }
912 else
913 {
914 Bs3TestFailedF("Todo implement me: cbDst=%u idxField=%d offField=%#x", cbDst, idxField, offField);
915 return false;
916 }
917
918#ifdef BS3CG1_DEBUG_CTX_MOD
919 {
920 const char BS3_FAR *pszOp;
921 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
922 {
923 case BS3CG1_CTXOP_ASSIGN: pszOp = "="; break;
924 case BS3CG1_CTXOP_OR: pszOp = "|="; break;
925 case BS3CG1_CTXOP_AND: pszOp = "&="; break;
926 case BS3CG1_CTXOP_AND_INV: pszOp = "&~="; break;
927 }
928 switch (cbDst)
929 {
930 case 1:
931 BS3CG1_DPRINTF(("dbg: modify %s: %#04RX8 (LB %u) %s %#RX64 (LB %u)\n",
932 g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu8, cbDst, pszOp, uValue, cbValue));
933 break;
934 case 2:
935 BS3CG1_DPRINTF(("dbg: modify %s: %#06RX16 (LB %u) %s %#RX64 (LB %u)\n",
936 g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu16, cbDst, pszOp, uValue, cbValue));
937 break;
938 case 4:
939 BS3CG1_DPRINTF(("dbg: modify %s: %#010RX32 (LB %u) %s %#RX64 (LB %u)\n",
940 g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu32, cbDst, pszOp, uValue, cbValue));
941 break;
942 default:
943 BS3CG1_DPRINTF(("dbg: modify %s: %#018RX64 (LB %u) %s %#RX64 (LB %u)\n",
944 g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu64, cbDst, pszOp, uValue, cbValue));
945 break;
946 }
947 }
948#endif
949
950 /* Modify the field. */
951 switch (cbDst)
952 {
953 case 1:
954 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
955 {
956 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu8 = (uint8_t)uValue; break;
957 case BS3CG1_CTXOP_OR: *PtrField.pu8 |= (uint8_t)uValue; break;
958 case BS3CG1_CTXOP_AND: *PtrField.pu8 &= (uint8_t)uValue; break;
959 case BS3CG1_CTXOP_AND_INV: *PtrField.pu8 &= ~(uint8_t)uValue; break;
960 }
961 break;
962
963 case 2:
964 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
965 {
966 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu16 = (uint16_t)uValue; break;
967 case BS3CG1_CTXOP_OR: *PtrField.pu16 |= (uint16_t)uValue; break;
968 case BS3CG1_CTXOP_AND: *PtrField.pu16 &= (uint16_t)uValue; break;
969 case BS3CG1_CTXOP_AND_INV: *PtrField.pu16 &= ~(uint16_t)uValue; break;
970 }
971 break;
972
973 case 4:
974 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
975 {
976 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu32 = (uint32_t)uValue; break;
977 case BS3CG1_CTXOP_OR: *PtrField.pu32 |= (uint32_t)uValue; break;
978 case BS3CG1_CTXOP_AND: *PtrField.pu32 &= (uint32_t)uValue; break;
979 case BS3CG1_CTXOP_AND_INV: *PtrField.pu32 &= ~(uint32_t)uValue; break;
980 }
981 break;
982
983 case 8:
984 switch (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK)
985 {
986 case BS3CG1_CTXOP_ASSIGN: *PtrField.pu64 = (uint64_t)uValue; break;
987 case BS3CG1_CTXOP_OR: *PtrField.pu64 |= (uint64_t)uValue; break;
988 case BS3CG1_CTXOP_AND: *PtrField.pu64 &= (uint64_t)uValue; break;
989 case BS3CG1_CTXOP_AND_INV: *PtrField.pu64 &= ~(uint64_t)uValue; break;
990 }
991 break;
992
993 default:
994 Bs3TestFailedF("Malformed context instruction: cbDst=%u, expected 1, 2, 4, or 8", cbDst);
995 return false;
996 }
997
998#ifdef BS3CG1_DEBUG_CTX_MOD
999 switch (cbDst)
1000 {
1001 case 1: BS3CG1_DPRINTF(("dbg: --> %s: %#04RX32\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu8)); break;
1002 case 2: BS3CG1_DPRINTF(("dbg: --> %s: %#06RX32\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu16)); break;
1003 case 4: BS3CG1_DPRINTF(("dbg: --> %s: %#010RX32\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu32)); break;
1004 default: BS3CG1_DPRINTF(("dbg: --> %s: %#018RX64\n", g_aszBs3Cg1DstFields[idxField].sz, *PtrField.pu64)); break;
1005 }
1006#endif
1007
1008 }
1009 /*
1010 * Deal with larger field (FPU, SSE, AVX, ...).
1011 */
1012 else
1013 {
1014 Bs3TestFailedF("TODO: Implement me: cbDst=%u idxField=%d", cbDst, idxField);
1015 return false;
1016 }
1017
1018 /*
1019 * Advance to the next instruction.
1020 */
1021 pbCode += cbValue;
1022 cbLeft -= cbValue;
1023 }
1024
1025 return true;
1026}
1027
1028
1029
1030BS3_DECL_FAR(uint8_t) BS3_CMN_NM(Bs3Cg1Worker)(uint8_t bMode)
1031{
1032 BS3CG1STATE This;
1033 unsigned const iFirstRing = BS3_MODE_IS_V86(bMode) ? 3 : 0;
1034 uint8_t const cRings = BS3_MODE_IS_RM_OR_V86(bMode) ? 1 : 4;
1035 uint8_t iRing;
1036 unsigned iInstr;
1037 const char BS3_FAR * const pszMode = Bs3GetModeName(bMode);
1038 BS3MEMKIND const enmMemKind = BS3_MODE_IS_RM_OR_V86(bMode) ? BS3MEMKIND_REAL
1039 : BS3_MODE_IS_16BIT_CODE(bMode) ? BS3MEMKIND_TILED : BS3MEMKIND_FLAT32;
1040
1041 /*
1042 * Initalize the state.
1043 */
1044 Bs3MemSet(&This, 0, sizeof(This));
1045
1046 This.bMode = bMode;
1047 This.pchMnemonic = g_achBs3Cg1Mnemonics;
1048 This.pabOperands = g_abBs3Cg1Operands;
1049 This.pabOpcodes = g_abBs3Cg1Opcodes;
1050 This.fAdvanceMnemonic = 1;
1051
1052 /* Allocate guarded exectuable and data memory. */
1053 if (BS3_MODE_IS_PAGED(bMode))
1054 {
1055 This.pbCodePg = Bs3MemGuardedTestPageAlloc(enmMemKind);
1056 if (!This.pbCodePg)
1057 {
1058 Bs3TestFailedF("First Bs3MemGuardedTestPageAlloc(%d) failed", enmMemKind);
1059 return 0;
1060 }
1061 This.pbDataPg = Bs3MemGuardedTestPageAlloc(enmMemKind);
1062 if (!This.pbDataPg)
1063 {
1064 Bs3MemGuardedTestPageFree(This.pbCodePg);
1065 Bs3TestFailedF("Second Bs3MemGuardedTestPageAlloc(%d) failed", enmMemKind);
1066 return 0;
1067 }
1068 }
1069 else
1070 {
1071 This.pbCodePg = Bs3MemAlloc(enmMemKind, X86_PAGE_SIZE);
1072 if (!This.pbCodePg)
1073 {
1074 Bs3TestFailedF("First Bs3MemAlloc(%d,Pg) failed", enmMemKind);
1075 return 0;
1076 }
1077 This.pbDataPg = Bs3MemAlloc(enmMemKind, X86_PAGE_SIZE);
1078 if (!This.pbDataPg)
1079 {
1080 Bs3MemFree(This.pbCodePg, X86_PAGE_SIZE);
1081 Bs3TestFailedF("Second Bs3MemAlloc(%d,Pg) failed", enmMemKind);
1082 return 0;
1083 }
1084 }
1085 This.uCodePgFlat = Bs3SelPtrToFlat(This.pbCodePg);
1086
1087 /* Create basic context for each target ring. In protected 16-bit code we need
1088 set up code selectors that can access pbCodePg. ASSUMES 16-bit driver code! */
1089 Bs3RegCtxSaveEx(&This.aInitialCtxs[iFirstRing], bMode, 512);
1090 if (BS3_MODE_IS_16BIT_CODE(bMode) && !BS3_MODE_IS_RM_OR_V86(bMode))
1091 {
1092#if ARCH_BITS == 16
1093 uintptr_t const uFlatCodePg = Bs3SelPtrToFlat(BS3_FP_MAKE(BS3_FP_SEG(This.pbCodePg), 0));
1094#else
1095 uintptr_t const uFlatCodePg = (uintptr_t)This.pbCodePg;
1096#endif
1097 BS3_ASSERT(ARCH_BITS == 16);
1098 for (iRing = iFirstRing + 1; iRing < cRings; iRing++)
1099 {
1100 Bs3MemCpy(&This.aInitialCtxs[iRing], &This.aInitialCtxs[iFirstRing], sizeof(This.aInitialCtxs[iRing]));
1101 Bs3RegCtxConvertToRingX(&This.aInitialCtxs[iRing], iRing);
1102 }
1103 for (iRing = iFirstRing; iRing < cRings; iRing++)
1104 {
1105 This.aInitialCtxs[iRing].cs = BS3_SEL_SPARE_00 + iRing * 8 + iRing;
1106 Bs3SelSetup16BitCode(&Bs3GdteSpare00 + iRing, uFlatCodePg, iRing);
1107 }
1108 }
1109 else
1110 {
1111 Bs3RegCtxSetRipCsFromCurPtr(&This.aInitialCtxs[iFirstRing], (FPFNBS3FAR)This.pbCodePg);
1112 for (iRing = iFirstRing + 1; iRing < cRings; iRing++)
1113 {
1114 Bs3MemCpy(&This.aInitialCtxs[iRing], &This.aInitialCtxs[iFirstRing], sizeof(This.aInitialCtxs[iRing]));
1115 Bs3RegCtxConvertToRingX(&This.aInitialCtxs[iRing], iRing);
1116 }
1117 }
1118
1119 /*
1120 * Test the instructions.
1121 */
1122 for (iInstr = 0; iInstr < g_cBs3Cg1Instructions;
1123 iInstr++,
1124 This.pchMnemonic += This.fAdvanceMnemonic * This.cchMnemonic,
1125 This.pabOperands += This.cOperands,
1126 This.pabOpcodes += This.cbOpcodes)
1127 {
1128 unsigned iEncoding;
1129 unsigned iEncodingNext;
1130
1131 /*
1132 * Expand the instruction information into the state.
1133 * Note! 16-bit will switch to a two level test header lookup once we exceed 64KB.
1134 */
1135 PCBS3CG1INSTR pInstr = &g_aBs3Cg1Instructions[iInstr];
1136 This.iInstr = iInstr;
1137 This.pTestHdr = (PCBS3CG1TESTHDR)&g_abBs3Cg1Tests[pInstr->offTests];
1138 This.fFlags = pInstr->fFlags;
1139 This.enmEncoding = (BS3CG1ENC)pInstr->enmEncoding;
1140 This.cchMnemonic = pInstr->cchMnemonic;
1141 if (This.fAdvanceMnemonic)
1142 Bs3TestSubF("%.*s", This.cchMnemonic, This.pchMnemonic);
1143 This.fAdvanceMnemonic = pInstr->fAdvanceMnemonic;
1144 This.cOperands = pInstr->cOperands;
1145 This.cbOpcodes = pInstr->cbOpcodes;
1146 switch (This.cOperands)
1147 {
1148 case 3: This.aenmOperands[3] = (BS3CG1OP)This.pabOperands[3];
1149 case 2: This.aenmOperands[2] = (BS3CG1OP)This.pabOperands[2];
1150 case 1: This.aenmOperands[1] = (BS3CG1OP)This.pabOperands[1];
1151 case 0: This.aenmOperands[0] = (BS3CG1OP)This.pabOperands[0];
1152 }
1153
1154 switch (This.cbOpcodes)
1155 {
1156 case 3: This.abOpcodes[3] = This.pabOpcodes[3];
1157 case 2: This.abOpcodes[2] = This.pabOpcodes[2];
1158 case 1: This.abOpcodes[1] = This.pabOpcodes[1];
1159 case 0: This.abOpcodes[0] = This.pabOpcodes[0];
1160 }
1161
1162 /*
1163 * Prep the operands and encoding handling.
1164 */
1165 if (!Bs3Cg1EncodePrep(&This))
1166 continue;
1167
1168 /*
1169 * Encode the instruction in various ways and check out the test values.
1170 */
1171 for (iEncoding = 0;; iEncoding = iEncodingNext)
1172 {
1173 /*
1174 * Encode the next instruction variation.
1175 */
1176 iEncodingNext = Bs3Cg1EncodeNext(&This, iEncoding);
1177 if (iEncodingNext <= iEncoding)
1178 break;
1179 BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u %.*Rhxs\n", iEncoding, This.cbCurInstr, This.cbCurInstr, This.abCurInstr));
1180
1181 /*
1182 * Do the rings.
1183 */
1184 for (iRing = iFirstRing + This.fSameRingNotOkay; iRing < cRings; iRing++)
1185 {
1186 PCBS3CG1TESTHDR pHdr;
1187
1188 This.uCpl = iRing;
1189 BS3CG1_DPRINTF(("dbg: Ring %u\n", iRing));
1190
1191 /*
1192 * Do the tests one by one.
1193 */
1194 pHdr = This.pTestHdr;
1195 for (This.iTest = 0;; This.iTest++)
1196 {
1197 if (Bs3Cg1RunSelector(&This, pHdr))
1198 {
1199 /* Okay, set up the execution context. */
1200 uint8_t BS3_FAR *pbCode = &This.pbCodePg[BS3_MODE_IS_PAGED(bMode) ? This.cbCurInstr : 0];
1201
1202 Bs3MemCpy(&This.Ctx, &This.aInitialCtxs[iRing], sizeof(This.Ctx));
1203 if (BS3_MODE_IS_PAGED(bMode))
1204 pbCode = &This.pbCodePg[X86_PAGE_SIZE - This.cbCurInstr];
1205 else
1206 {
1207 pbCode = This.pbCodePg;
1208 pbCode[This.cbCurInstr] = 0x0f; /* UD2 */
1209 pbCode[This.cbCurInstr + 1] = 0x0b;
1210 }
1211 Bs3MemCpy(pbCode, This.abCurInstr, This.cbCurInstr);
1212 This.Ctx.rip.u = BS3_FP_OFF(pbCode);
1213
1214 if (Bs3Cg1RunContextModifier(&This, &This.Ctx, pHdr, pHdr->cbSelector, pHdr->cbInput, NULL))
1215 {
1216 /* Run the instruction. */
1217 BS3CG1_DPRINTF(("dbg: Running test #%u\n", This.iTest));
1218 //Bs3RegCtxPrint(&This.Ctx);
1219 Bs3TrapSetJmpAndRestore(&This.Ctx, &This.TrapFrame);
1220 BS3CG1_DPRINTF(("dbg: bXcpt=%#x rip=%RX64 -> %RX64\n", This.TrapFrame.bXcpt, This.Ctx.rip.u, This.TrapFrame.Ctx.rip.u));
1221
1222 /* Check the control exception result first. */
1223 if ( This.TrapFrame.bXcpt == (BS3_MODE_IS_PAGED(bMode) ? X86_XCPT_PF : X86_XCPT_UD)
1224 && This.TrapFrame.Ctx.rip.u == This.Ctx.rip.u + This.cbCurInstr)
1225 {
1226 /* Apply output modifications and compare the contexts. */
1227 if (BS3_MODE_IS_PAGED(bMode))
1228 This.Ctx.cr2.u = This.uCodePgFlat + X86_PAGE_SIZE;
1229 This.Ctx.rflags.u32 &= ~X86_EFL_RF;
1230 This.Ctx.rflags.u32 |= X86_EFL_RF & This.TrapFrame.Ctx.rflags.u32;
1231 if (Bs3Cg1RunContextModifier(&This, &This.Ctx, pHdr,
1232 pHdr->cbSelector + pHdr->cbInput, pHdr->cbOutput,
1233 &This.TrapFrame.Ctx))
1234 {
1235 Bs3TestCheckRegCtxEx(&This.TrapFrame.Ctx, &This.Ctx, This.cbCurInstr, 0 /*cbSpAdjust*/,
1236 0 /*fExtraEfl*/, pszMode, iEncoding);
1237 }
1238 }
1239 else
1240 {
1241 Bs3TestFailedF("bXcpt=%#x expected %#x; rip=%RX64 expected %RX64; encoding: %.*Rhxs",
1242 This.TrapFrame.bXcpt, BS3_MODE_IS_PAGED(bMode) ? X86_XCPT_PF : X86_XCPT_UD,
1243 This.TrapFrame.Ctx.rip.u, This.Ctx.rip.u + This.cbCurInstr,
1244 This.cbCurInstr, This.abCurInstr);
1245 }
1246 }
1247 }
1248 else
1249 BS3CG1_DPRINTF(("dbg: Skipping #%u\n", This.iTest));
1250
1251 /* advance */
1252 if (pHdr->fLast)
1253 {
1254 BS3CG1_DPRINTF(("dbg: Last\n"));
1255 break;
1256 }
1257 pHdr = (PCBS3CG1TESTHDR)((uint8_t BS3_FAR *)(pHdr + 1) + pHdr->cbInput + pHdr->cbOutput + pHdr->cbSelector);
1258 }
1259 }
1260 }
1261
1262 }
1263
1264 /*
1265 * Clean up.
1266 */
1267 if (BS3_MODE_IS_PAGED(bMode))
1268 {
1269 Bs3MemGuardedTestPageFree(This.pbCodePg);
1270 Bs3MemGuardedTestPageFree(This.pbDataPg);
1271 }
1272 else
1273 {
1274 Bs3MemFree(This.pbCodePg, X86_PAGE_SIZE);
1275 Bs3MemFree(This.pbDataPg, X86_PAGE_SIZE);
1276 }
1277
1278 Bs3TestSubDone();
1279
1280 return 0;
1281}
1282
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