VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/utils/cpu/cidet-instr-1.cpp@ 91087

Last change on this file since 91087 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1/* $Id: cidet-instr-1.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * CPU Instruction Decoding & Execution Tests - First bunch of instructions.
4 */
5
6/*
7 * Copyright (C) 2014-2020 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/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include "cidet.h"
33#include <VBox/err.h>
34
35
36/*********************************************************************************************************************************
37* Defined Constants And Macros *
38*********************************************************************************************************************************/
39/*
40 * Shorter defines for the EFLAGS to save table space.
41 */
42#undef CF
43#undef PF
44#undef AF
45#undef ZF
46#undef SF
47#undef OF
48
49#define CF X86_EFL_CF
50#define PF X86_EFL_PF
51#define AF X86_EFL_AF
52#define ZF X86_EFL_ZF
53#define SF X86_EFL_SF
54#define OF X86_EFL_OF
55
56
57/*********************************************************************************************************************************
58* Structures and Typedefs *
59*********************************************************************************************************************************/
60typedef struct CIDET2IN1OUTWITHFLAGSU8ENTRY
61{
62 uint8_t uIn1;
63 uint8_t uIn2;
64 uint16_t fEFlagsIn;
65 uint8_t uOut;
66 uint16_t fEFlagsOut;
67} CIDET2IN1OUTWITHFLAGSU8ENTRY;
68typedef CIDET2IN1OUTWITHFLAGSU8ENTRY const *PCCIDET2IN1OUTWITHFLAGSU8ENTRY;
69
70typedef struct CIDET2IN1OUTWITHFLAGSU16ENTRY
71{
72 uint16_t uIn1;
73 uint16_t uIn2;
74 uint16_t fEFlagsIn;
75 uint16_t uOut;
76 uint16_t fEFlagsOut;
77} CIDET2IN1OUTWITHFLAGSU16ENTRY;
78typedef CIDET2IN1OUTWITHFLAGSU16ENTRY const *PCCIDET2IN1OUTWITHFLAGSU16ENTRY;
79
80typedef struct CIDET2IN1OUTWITHFLAGSU32ENTRY
81{
82 uint32_t uIn1;
83 uint32_t uIn2;
84 uint16_t fEFlagsIn;
85 uint32_t uOut;
86 uint16_t fEFlagsOut;
87} CIDET2IN1OUTWITHFLAGSU32ENTRY;
88typedef CIDET2IN1OUTWITHFLAGSU32ENTRY const *PCCIDET2IN1OUTWITHFLAGSU32ENTRY;
89
90typedef struct CIDET2IN1OUTWITHFLAGSU64ENTRY
91{
92 uint64_t uIn1;
93 uint64_t uIn2;
94 uint16_t fEFlagsIn;
95 uint64_t uOut;
96 uint16_t fEFlagsOut;
97} CIDET2IN1OUTWITHFLAGSU64ENTRY;
98typedef CIDET2IN1OUTWITHFLAGSU64ENTRY const *PCCIDET2IN1OUTWITHFLAGSU64ENTRY;
99
100typedef struct CIDET2IN1OUTWITHFLAGS
101{
102 PCCIDET2IN1OUTWITHFLAGSU8ENTRY pa8Entries;
103 PCCIDET2IN1OUTWITHFLAGSU16ENTRY pa16Entries;
104 PCCIDET2IN1OUTWITHFLAGSU32ENTRY pa32Entries;
105 PCCIDET2IN1OUTWITHFLAGSU64ENTRY pa64Entries;
106 uint16_t c8Entries;
107 uint16_t c16Entries;
108 uint16_t c32Entries;
109 uint16_t c64Entries;
110 uint32_t fRelevantEFlags;
111} CIDET2IN1OUTWITHFLAGS;
112
113#define CIDET2IN1OUTWITHFLAGS_INITIALIZER(a_fRelevantEFlags) \
114 { \
115 &s_a8Results[0], &s_a16Results[0], &s_a32Results[0], &s_a64Results[0], \
116 RT_ELEMENTS(s_a8Results), RT_ELEMENTS(s_a16Results), RT_ELEMENTS(s_a32Results), RT_ELEMENTS(s_a64Results), \
117 (a_fRelevantEFlags) \
118 }
119
120
121/**
122 * Generic worker for a FNCIDETSETUPINOUT function with two GPR/MEM registers,
123 * storing result in the first and flags.
124 *
125 * @returns See FNCIDETSETUPINOUT.
126 * @param pThis The core CIDET state structure. The InCtx
127 * and ExpectedCtx members will be modified.
128 * @param fInvalid When set, get the next invalid operands that will
129 * cause exceptions/faults.
130 * @param pResults The result collection.
131 */
132static int CidetGenericIn2Out1WithFlags(PCIDETCORE pThis, bool fInvalid, CIDET2IN1OUTWITHFLAGS const *pResults)
133{
134 int rc;
135
136 Assert(pThis->idxMrmRegOp < 2);
137 Assert(pThis->idxMrmRmOp < 2);
138 Assert(pThis->idxMrmRmOp != pThis->idxMrmRegOp);
139 AssertCompile(RT_ELEMENTS(pThis->aiInOut) >= 4);
140
141 if (!fInvalid)
142 {
143 if ( !pThis->fHasRegCollisionDirect
144 && !pThis->fHasRegCollisionMem)
145 {
146 pThis->InCtx.rfl &= ~(uint64_t)pResults->fRelevantEFlags;
147 pThis->ExpectedCtx.rfl &= ~(uint64_t)pResults->fRelevantEFlags;
148 switch (pThis->aOperands[0].cb)
149 {
150 case 1:
151 {
152 uint16_t idx = ++pThis->aiInOut[0] % pResults->c8Entries;
153 PCCIDET2IN1OUTWITHFLAGSU8ENTRY pEntry = &pResults->pa8Entries[idx];
154 rc = idx ? VINF_SUCCESS : VINF_EOF;
155
156 *pThis->aOperands[0].In.pu8 = pEntry->uIn1;
157 *pThis->aOperands[1].In.pu8 = pEntry->uIn2;
158 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
159
160 *pThis->aOperands[0].Expected.pu8 = pEntry->uOut;
161 *pThis->aOperands[1].Expected.pu8 = pEntry->uIn2;
162 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
163 break;
164 }
165
166 case 2:
167 {
168 uint16_t idx = ++pThis->aiInOut[1] % pResults->c16Entries;
169 PCCIDET2IN1OUTWITHFLAGSU16ENTRY pEntry = &pResults->pa16Entries[idx];
170 rc = idx ? VINF_SUCCESS : VINF_EOF;
171
172 *pThis->aOperands[0].In.pu16 = pEntry->uIn1;
173 *pThis->aOperands[1].In.pu16 = pEntry->uIn2;
174 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
175
176 *pThis->aOperands[0].Expected.pu16 = pEntry->uOut;
177 *pThis->aOperands[1].Expected.pu16 = pEntry->uIn2;
178 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
179 break;
180 }
181
182 case 4:
183 {
184 uint16_t idx = ++pThis->aiInOut[2] % pResults->c32Entries;
185 PCCIDET2IN1OUTWITHFLAGSU32ENTRY pEntry = &pResults->pa32Entries[idx];
186 rc = idx ? VINF_SUCCESS : VINF_EOF;
187
188 *pThis->aOperands[0].In.pu32 = pEntry->uIn1;
189 *pThis->aOperands[1].In.pu32 = pEntry->uIn2;
190 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
191
192 *pThis->aOperands[0].Expected.pu32 = pEntry->uOut;
193 if (!pThis->aOperands[0].fIsMem)
194 pThis->aOperands[0].Expected.pu32[1] = 0;
195 *pThis->aOperands[1].Expected.pu32 = pEntry->uIn2;
196 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
197 break;
198 }
199
200 case 8:
201 {
202 uint16_t idx = ++pThis->aiInOut[3] % pResults->c64Entries;
203 PCCIDET2IN1OUTWITHFLAGSU64ENTRY pEntry = &pResults->pa64Entries[idx];
204 rc = idx ? VINF_SUCCESS : VINF_EOF;
205
206 *pThis->aOperands[0].In.pu64 = pEntry->uIn1;
207 *pThis->aOperands[1].In.pu64 = pEntry->uIn2;
208 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
209
210 *pThis->aOperands[0].Expected.pu64 = pEntry->uOut;
211 *pThis->aOperands[1].Expected.pu64 = pEntry->uIn2;
212 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
213 break;
214 }
215
216 default:
217 AssertFailed();
218 rc = VERR_INTERNAL_ERROR_3;
219 }
220 }
221 else
222 rc = VERR_NOT_SUPPORTED;
223 }
224 else
225 rc = VERR_NO_DATA;
226 return rc;
227}
228
229
230static DECLCALLBACK(int) cidetInOutAdd(PCIDETCORE pThis, bool fInvalid)
231{
232 static const CIDET2IN1OUTWITHFLAGSU8ENTRY s_a8Results[] =
233 {
234 { UINT8_C(0x00), UINT8_C(0x00), 0, UINT8_C(0x00), ZF | PF },
235 { UINT8_C(0xff), UINT8_C(0x01), 0, UINT8_C(0x00), CF | ZF | AF | PF },
236 { UINT8_C(0x7f), UINT8_C(0x80), 0, UINT8_C(0xff), SF | PF },
237 { UINT8_C(0x01), UINT8_C(0x01), 0, UINT8_C(0x02), 0 },
238 };
239 static const CIDET2IN1OUTWITHFLAGSU16ENTRY s_a16Results[] =
240 {
241 { UINT16_C(0x0000), UINT16_C(0x0000), 0, UINT16_C(0x0000), ZF | PF },
242 { UINT16_C(0xfefd), UINT16_C(0x0103), 0, UINT16_C(0x0000), CF | ZF | AF | PF },
243 { UINT16_C(0x8e7d), UINT16_C(0x7182), 0, UINT16_C(0xffff), SF | PF },
244 { UINT16_C(0x0001), UINT16_C(0x0001), 0, UINT16_C(0x0002), 0 },
245 };
246 static const CIDET2IN1OUTWITHFLAGSU32ENTRY s_a32Results[] =
247 {
248 { UINT32_C(0x00000000), UINT32_C(0x00000000), 0, UINT32_C(0x00000000), ZF | PF },
249 { UINT32_C(0xfefdfcfb), UINT32_C(0x01020305), 0, UINT32_C(0x00000000), CF | ZF | AF | PF },
250 { UINT32_C(0x8efdfcfb), UINT32_C(0x71020304), 0, UINT32_C(0xffffffff), SF | PF },
251 { UINT32_C(0x00000001), UINT32_C(0x00000001), 0, UINT32_C(0x00000002), 0 },
252 };
253 static const CIDET2IN1OUTWITHFLAGSU64ENTRY s_a64Results[] =
254 {
255 { UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000), 0, UINT64_C(0x0000000000000000), ZF | PF },
256 { UINT64_C(0xfefdfcfbfaf9f8f7), UINT64_C(0x0102030405060709), 0, UINT64_C(0x0000000000000000), CF | ZF | AF | PF },
257 { UINT64_C(0x7efdfcfbfaf9f8f7), UINT64_C(0x8102030405060708), 0, UINT64_C(0xffffffffffffffff), SF | PF },
258 { UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000001), 0, UINT64_C(0x0000000000000002), 0 },
259 };
260 static const CIDET2IN1OUTWITHFLAGS s_Results = CIDET2IN1OUTWITHFLAGS_INITIALIZER(CF | PF | AF | SF | OF);
261 return CidetGenericIn2Out1WithFlags(pThis, fInvalid, &s_Results);
262}
263
264
265/** First bunch of instructions. */
266const CIDETINSTR g_aCidetInstructions1[] =
267{
268#if 1
269 {
270 "add Eb,Gb", cidetInOutAdd, 1, {0x00, 0, 0}, 0, 2,
271 { CIDET_OF_K_GPR | CIDET_OF_Z_BYTE | CIDET_OF_M_RM | CIDET_OF_A_RW,
272 CIDET_OF_K_GPR | CIDET_OF_Z_BYTE | CIDET_OF_M_REG | CIDET_OF_A_R,
273 0, 0 }, CIDET_IF_MODRM
274 },
275#endif
276#if 1
277 {
278 "add Ev,Gv", cidetInOutAdd, 1, {0x01, 0, 0}, 0, 2,
279 { CIDET_OF_K_GPR | CIDET_OF_Z_VAR_WDQ | CIDET_OF_M_RM | CIDET_OF_A_RW,
280 CIDET_OF_K_GPR | CIDET_OF_Z_VAR_WDQ | CIDET_OF_M_REG | CIDET_OF_A_R,
281 0, 0 }, CIDET_IF_MODRM
282 },
283#endif
284};
285/** Number of instruction in the g_aInstructions1 array. */
286const uint32_t g_cCidetInstructions1 = RT_ELEMENTS(g_aCidetInstructions1);
287
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