VirtualBox

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

Last change on this file since 53579 was 53579, checked in by vboxsync, 10 years ago

cidet: More code...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1/* $Id: cidet-instr-1.cpp 53579 2014-12-19 19:24:09Z vboxsync $ */
2/** @file
3 * CPU Instruction Decoding & Execution Tests - First bunch of instructions.
4 */
5
6/*
7 * Copyright (C) 2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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
140 if (!fInvalid)
141 {
142 if ( !pThis->fHasRegCollisionDirect
143 && !pThis->fHasRegCollisionMem)
144 {
145 pThis->InCtx.rfl &= ~(uint64_t)pResults->fRelevantEFlags;
146 pThis->ExpectedCtx.rfl &= ~(uint64_t)pResults->fRelevantEFlags;
147 switch (pThis->aOperands[0].cb)
148 {
149 case 1:
150 {
151 uint16_t idx = ++pThis->iInOut % pResults->c8Entries;
152 PCCIDET2IN1OUTWITHFLAGSU8ENTRY pEntry = &pResults->pa8Entries[idx];
153 rc = idx ? VINF_SUCCESS : VINF_EOF;
154
155 *pThis->aOperands[0].In.pu8 = pEntry->uIn1;
156 *pThis->aOperands[1].In.pu8 = pEntry->uIn2;
157 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
158
159 *pThis->aOperands[0].Expected.pu8 = pEntry->uOut;
160 *pThis->aOperands[1].Expected.pu8 = pEntry->uIn2;
161 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
162 break;
163 }
164
165 case 2:
166 {
167 uint16_t idx = ++pThis->iInOut % pResults->c16Entries;
168 PCCIDET2IN1OUTWITHFLAGSU16ENTRY pEntry = &pResults->pa16Entries[idx];
169 rc = idx ? VINF_SUCCESS : VINF_EOF;
170
171 *pThis->aOperands[0].In.pu16 = pEntry->uIn1;
172 *pThis->aOperands[1].In.pu16 = pEntry->uIn2;
173 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
174
175 *pThis->aOperands[0].Expected.pu16 = pEntry->uOut;
176 *pThis->aOperands[1].Expected.pu16 = pEntry->uIn2;
177 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
178 break;
179 }
180
181 case 4:
182 {
183 uint16_t idx = ++pThis->iInOut % pResults->c32Entries;
184 PCCIDET2IN1OUTWITHFLAGSU32ENTRY pEntry = &pResults->pa32Entries[idx];
185 rc = idx ? VINF_SUCCESS : VINF_EOF;
186
187 *pThis->aOperands[0].In.pu32 = pEntry->uIn1;
188 *pThis->aOperands[1].In.pu32 = pEntry->uIn2;
189 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
190
191 *pThis->aOperands[0].Expected.pu32 = pEntry->uOut;
192 if (!pThis->aOperands[0].fIsMem)
193 pThis->aOperands[0].Expected.pu32[0] = 0;
194 *pThis->aOperands[1].Expected.pu32 = pEntry->uIn2;
195 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
196 break;
197 }
198
199 case 8:
200 {
201 uint16_t idx = ++pThis->iInOut % pResults->c64Entries;
202 PCCIDET2IN1OUTWITHFLAGSU64ENTRY pEntry = &pResults->pa64Entries[idx];
203 rc = idx ? VINF_SUCCESS : VINF_EOF;
204
205 *pThis->aOperands[0].In.pu64 = pEntry->uIn1;
206 *pThis->aOperands[1].In.pu64 = pEntry->uIn2;
207 pThis->InCtx.rfl |= pEntry->fEFlagsIn;
208
209 *pThis->aOperands[0].Expected.pu64 = pEntry->uOut;
210 *pThis->aOperands[1].Expected.pu64 = pEntry->uIn2;
211 pThis->ExpectedCtx.rfl |= pEntry->fEFlagsOut;
212 break;
213 }
214
215 default:
216 AssertFailed();
217 rc = VERR_INTERNAL_ERROR_3;
218 }
219 }
220 else
221 rc = VERR_NOT_SUPPORTED;
222 }
223 else
224 rc = VERR_NO_DATA;
225 return rc;
226}
227
228
229static DECLCALLBACK(int) cidetInOutAdd(PCIDETCORE pThis, bool fInvalid)
230{
231 static const CIDET2IN1OUTWITHFLAGSU8ENTRY s_a8Results[] =
232 {
233 { UINT8_C(0x00), UINT8_C(0x00), 0, UINT8_C(0x00), ZF | PF },
234 };
235 static const CIDET2IN1OUTWITHFLAGSU16ENTRY s_a16Results[] =
236 {
237 { UINT16_C(0x0000), UINT16_C(0x0000), 0, UINT16_C(0x0000), ZF | PF },
238 };
239 static const CIDET2IN1OUTWITHFLAGSU32ENTRY s_a32Results[] =
240 {
241 { UINT32_C(0x00000000), UINT32_C(0x00000000), 0, UINT32_C(0x00000000), ZF | PF },
242 };
243 static const CIDET2IN1OUTWITHFLAGSU64ENTRY s_a64Results[] =
244 {
245 { UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000), 0, UINT64_C(0x0000000000000000), ZF | PF },
246 };
247 static const CIDET2IN1OUTWITHFLAGS s_Results = CIDET2IN1OUTWITHFLAGS_INITIALIZER(CF | PF | AF | SF | OF);
248 return CidetGenericIn2Out1WithFlags(pThis, fInvalid, &s_Results);
249}
250
251
252/** First bunch of instructions. */
253const CIDETINSTR g_aCidetInstructions1[] =
254{
255 {
256 "add Eb,Gb", cidetInOutAdd, 1, {0x00, 0, 0}, 0, 2,
257 { CIDET_OF_K_GPR | CIDET_OF_Z_BYTE | CIDET_OF_M_RM | CIDET_OF_A_RW,
258 CIDET_OF_K_GPR | CIDET_OF_Z_BYTE | CIDET_OF_M_REG | CIDET_OF_A_R,
259 0, 0 }, CIDET_IF_MODRM
260 },
261#if 0
262 {
263 "add Ev,Gv", cidetInOutAdd, 1, {0x00, 0, 0}, 0, 2,
264 { CIDET_OF_K_GPR | CIDET_OF_Z_VAR_WDQ | CIDET_OF_M_RM,
265 CIDET_OF_K_GPR | CIDET_OF_Z_VAR_WDQ | CIDET_OF_M_REG,
266 0, 0 }, CIDET_IF_MODRM
267 },
268#endif
269};
270/** Number of instruction in the g_aInstructions1 array. */
271const uint32_t g_cCidetInstructions1 = RT_ELEMENTS(g_aCidetInstructions1);
272
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