VirtualBox

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

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

bs3-cpu-generated-1: updates.

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

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