VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-decoding-1.c32@ 63574

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

bs3kit: Added a instruction test case for imul & idiv.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.2 KB
Line 
1/* $Id: bs3-cpu-decoding-1.c32 62410 2016-07-21 20:26:33Z vboxsync $ */
2/** @file
3 * BS3Kit - bs3-cpu-decoding-1, 32-bit C code.
4 */
5
6/*
7 * Copyright (C) 2007-2016 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
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <bs3kit.h>
32#include <iprt/asm-amd64-x86.h>
33
34/**
35 * Simple test.
36 */
37typedef struct CPUDECODE1TST
38{
39 uint8_t fFlags;
40 uint8_t cbUd;
41 uint8_t cbOpcodes;
42 uint8_t abOpcodes[21];
43} CPUDECODE1TST;
44typedef CPUDECODE1TST BS3_FAR *PCPUDECODE1TST;
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_RZ X86_OP_PRF_REPZ
56#define P_RN X86_OP_PRF_REPNZ
57
58#define RM_EAX_EAX ((3 << X86_MODRM_MOD_SHIFT) | (X86_GREG_xAX << X86_MODRM_REG_SHIFT) | (X86_GREG_xAX))
59#define RM_EAX_DEREF_EBX ((0 << X86_MODRM_MOD_SHIFT) | (X86_GREG_xAX << X86_MODRM_REG_SHIFT) | (X86_GREG_xBX))
60
61#define F_486 0
62#define F_SSE2 1
63#define F_SSE3 2
64#define F_SSE42 4
65#define F_MOVBE 80
66
67CPUDECODE1TST const g_aSimpleTests[] =
68{
69 /*
70 * fFlags, cbUd, cbOpcodes, abOpcodes
71 */
72#if 1
73 /* Using currently undefined 0x0f 0x7a sequences. */
74 { 0, 3, 3, { 0x0f, 0x7a, RM_EAX_EAX, } },
75 { 0, 3+1, 3+1, { P_LK, 0x0f, 0x7a, RM_EAX_EAX, } },
76 { 0, 3+1, 3+1, { P_RN, 0x0f, 0x7a, RM_EAX_EAX, } },
77 { 0, 3+1, 3+1, { P_RZ, 0x0f, 0x7a, RM_EAX_EAX, } },
78 { 0, 3+2, 3+2, { P_LK, P_LK, 0x0f, 0x7a, RM_EAX_EAX, } },
79#endif
80#if 0
81 /* The XADD instruction has empty lines for 66, f3 and f2 prefixes.
82 AMD doesn't do anything special for XADD Ev,Gv as the intel table would indicate. */
83 { F_486, 99, 3, { 0x0f, 0xc1, RM_EAX_EAX, } },
84 { F_486, 99, 4, { P_OZ, 0x0f, 0xc1, RM_EAX_EAX, } },
85 { F_486, 99, 4, { P_RN, 0x0f, 0xc1, RM_EAX_EAX, } },
86 { F_486, 99, 5, { P_OZ, P_RN, 0x0f, 0xc1, RM_EAX_EAX, } },
87 { F_486, 99, 5, { P_RN, P_OZ, 0x0f, 0xc1, RM_EAX_EAX, } },
88 { F_486, 99, 4, { P_RZ, 0x0f, 0xc1, RM_EAX_EAX, } },
89 { F_486, 99, 5, { P_OZ, P_RZ, 0x0f, 0xc1, RM_EAX_EAX, } },
90 { F_486, 99, 5, { P_RZ, P_OZ, 0x0f, 0xc1, RM_EAX_EAX, } },
91#endif
92#if 0
93 /* The movnti instruction is confined to the unprefixed lined in the intel manuals. Check how the other lines work. */
94 { F_SSE2, 3, 3, { 0x0f, 0xc3, RM_EAX_EAX, } }, /* invalid - reg,reg */
95 { F_SSE2, 99, 3, { 0x0f, 0xc3, RM_EAX_DEREF_EBX, } },
96 { F_SSE2, 4, 4, { P_OZ, 0x0f, 0xc3, RM_EAX_DEREF_EBX, } }, /* invalid */
97 { F_SSE2, 4, 4, { P_RN, 0x0f, 0xc3, RM_EAX_DEREF_EBX, } }, /* invalid */
98 { F_SSE2, 4, 4, { P_RZ, 0x0f, 0xc3, RM_EAX_DEREF_EBX, } }, /* invalid */
99 { F_SSE2, 4, 4, { P_LK, 0x0f, 0xc3, RM_EAX_DEREF_EBX, } }, /* invalid */
100 { F_SSE2, 5, 5, { P_RZ, P_LK, 0x0f, 0xc3, RM_EAX_DEREF_EBX, } }, /* invalid */
101#endif
102#if 1
103 /* The lddqu instruction requires a 0xf2 prefix, intel only lists 0x66 and empty
104 prefix for it. Check what they really mean by that*/
105 { F_SSE3, 4, 4, { P_RZ, 0x0f, 0xf0, RM_EAX_EAX, } }, /* invalid - reg, reg */
106 { F_SSE3, 99, 4, { P_RZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
107 { F_SSE3, 99, 5, { P_RZ, P_RZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
108 { F_SSE3, 3, 3, { 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
109 { F_SSE3, 4, 4, { P_RN, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
110 { F_SSE3, 4, 4, { P_OZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
111 { F_SSE3, 4, 4, { P_LK, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
112 { F_SSE3, 5, 5, { P_RZ, P_RN, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
113 { F_SSE3, 99, 5, { P_RZ, P_OZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } }, // AMD,why?
114 { F_SSE3, 5, 5, { P_RZ, P_LK, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
115 { F_SSE3, 99, 5, { P_RN, P_RZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
116 { F_SSE3, 99, 5, { P_OZ, P_RZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
117 { F_SSE3, 5, 5, { P_LK, P_RZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
118 { F_SSE3, 99, 5, { P_OZ, P_RZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
119 { F_SSE3, 99, 6,{ P_OZ, P_RN, P_RZ, 0x0f, 0xf0, RM_EAX_DEREF_EBX, } },
120#endif
121 { F_SSE2, 99, 3, { 0x0f, 0x7e, RM_EAX_EAX, } },
122 { F_SSE2, 99, 4, { P_OZ, 0x0f, 0x7e, RM_EAX_EAX, } },
123 { F_SSE2, 5, 5,{ P_RZ, P_OZ, 0x0f, 0x7e, RM_EAX_EAX, } }, // WTF?
124 { F_SSE2, 5, 5,{ P_OZ, P_RZ, 0x0f, 0x7e, RM_EAX_EAX, } },
125 { F_SSE2, 99, 5,{ P_RN, P_OZ, 0x0f, 0x7e, RM_EAX_EAX, } },
126 { F_SSE2, 99, 4, { P_RN, 0x0f, 0x7e, RM_EAX_EAX, } },
127 { F_SSE2, 4, 4, { P_RZ, 0x0f, 0x7e, RM_EAX_EAX, } },
128/** @todo crc32 / movbe */
129};
130
131void DecodeEdgeTest(void)
132{
133 /*
134 * Allocate and initialize a page pair
135 */
136 uint8_t BS3_FAR *pbPages;
137 pbPages = Bs3MemGuardedTestPageAlloc(BS3MEMKIND_FLAT32);
138 if (pbPages)
139 {
140 unsigned i;
141 BS3REGCTX Ctx;
142 BS3TRAPFRAME TrapFrame;
143
144 Bs3MemZero(&Ctx, sizeof(Ctx));
145 Bs3MemZero(&TrapFrame, sizeof(TrapFrame));
146
147 ASMSetCR0((ASMGetCR0() & ~(X86_CR0_EM | X86_CR0_TS)) | X86_CR0_MP);
148 ASMSetCR4(ASMGetCR4() | X86_CR4_OSFXSR);
149
150 Bs3RegCtxSaveEx(&Ctx, BS3_MODE_CODE_32, 512);
151 Ctx.rbx.u64 = (uintptr_t)pbPages;
152
153 for (i = 0; i < RT_ELEMENTS(g_aSimpleTests); i++)
154 {
155 unsigned cb = g_aSimpleTests[i].cbOpcodes;
156 while (cb >= 1)
157 {
158 unsigned const cErrorsBefore = Bs3TestSubErrorCount();
159 uint8_t BS3_FAR *pbRip = &pbPages[X86_PAGE_SIZE - cb];
160 Bs3MemCpy(pbRip, &g_aSimpleTests[i].abOpcodes[0], cb);
161 Bs3RegCtxSetRipCsFromFlat(&Ctx, (uintptr_t)pbRip);
162 Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
163#if 0
164 Bs3TestPrintf("\ni=%d cb=%#x (cbUd=%#x cbOpcodes=%#x)\n", i, cb, g_aSimpleTests[i].cbUd, g_aSimpleTests[i].cbOpcodes);
165 Bs3TrapPrintFrame(&TrapFrame);
166#endif
167 if (cb >= g_aSimpleTests[i].cbUd)
168 {
169 if (TrapFrame.bXcpt != X86_XCPT_UD)
170 Bs3TestFailedF("i=%d cb=%d cbUd=%d cbOp=%d: expected #UD got %#x at %RX32\n",
171 i, cb, g_aSimpleTests[i].cbUd, g_aSimpleTests[i].cbOpcodes,
172 TrapFrame.bXcpt, TrapFrame.Ctx.rip.u32);
173 }
174 else if (cb < g_aSimpleTests[i].cbOpcodes)
175 {
176 if (TrapFrame.bXcpt != X86_XCPT_PF)
177 Bs3TestFailedF("i=%d cb=%d cbUd=%d cbOp=%d: expected #PF (on) got %#x at %RX32\n",
178 i, cb, g_aSimpleTests[i].cbUd, g_aSimpleTests[i].cbOpcodes,
179 TrapFrame.bXcpt, TrapFrame.Ctx.rip.u32);
180 else if (TrapFrame.Ctx.rip.u32 != (uintptr_t)pbRip)
181 Bs3TestFailedF("i=%d cb=%d cbUd=%d cbOp=%d: expected #PF rip of %p (on) got %#RX32\n",
182 i, cb, g_aSimpleTests[i].cbUd, g_aSimpleTests[i].cbOpcodes,
183 pbRip, TrapFrame.Ctx.rip.u32);
184 }
185 else
186 {
187 if (TrapFrame.bXcpt != X86_XCPT_PF)
188 Bs3TestFailedF("i=%d cb=%d cbUd=%d cbOp=%d: expected #PF (after) got %#x at %RX32\n",
189 i, cb, g_aSimpleTests[i].cbUd, g_aSimpleTests[i].cbOpcodes,
190 TrapFrame.bXcpt, TrapFrame.Ctx.rip.u32);
191 else if (TrapFrame.Ctx.rip.u32 != (uintptr_t)&pbPages[X86_PAGE_SIZE])
192 Bs3TestFailedF("i=%d cb=%d cbUd=%d cbOp=%d: expected #PF rip of %p (after) got %#RX32\n",
193 i, cb, g_aSimpleTests[i].cbUd, g_aSimpleTests[i].cbOpcodes,
194 &pbPages[X86_PAGE_SIZE], TrapFrame.Ctx.rip.u32);
195 }
196 if (Bs3TestSubErrorCount() != cErrorsBefore)
197 {
198 Bs3TestPrintf(" %.*Rhxs", cb, &g_aSimpleTests[i].abOpcodes[0]);
199 if (cb < g_aSimpleTests[i].cbOpcodes)
200 Bs3TestPrintf("[%.*Rhxs]", g_aSimpleTests[i].cbOpcodes - cb, &g_aSimpleTests[i].abOpcodes[cb]);
201 Bs3TestPrintf("\n");
202 }
203
204 /* next */
205 cb--;
206 }
207 }
208
209 Bs3MemGuardedTestPageFree(pbPages);
210 }
211 else
212 Bs3TestFailed("Failed to allocate two pages!\n");
213
214 /*
215 * Test instruction sequences.
216 */
217
218
219}
220
221
222BS3_DECL(void) Main_pp32()
223{
224 Bs3TestInit("bs3-cpu-decoding-1");
225 Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
226
227 DecodeEdgeTest();
228
229 Bs3TestTerm();
230
231 //for (;;) ASMHalt();
232}
233
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