1 /////////////////////////////////////////////////////////////////////////
2 // $Id: instr.h,v 1.18 2008/10/10 20:49:16 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2008 Stanislav Shwartsman
6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /////////////////////////////////////////////////////////////////////////
27 class bxInstruction_c
;
29 // <TAG-TYPE-EXECUTEPTR-START>
31 typedef void (BX_CPP_AttrRegparmN(1) *BxExecutePtr_tR
)(bxInstruction_c
*);
32 typedef bx_address (BX_CPP_AttrRegparmN(1) *BxResolvePtr_tR
)(bxInstruction_c
*);
34 typedef void (BX_CPU_C::*BxExecutePtr_tR
)(bxInstruction_c
*) BX_CPP_AttrRegparmN(1);
35 typedef bx_address (BX_CPU_C::*BxResolvePtr_tR
)(bxInstruction_c
*) BX_CPP_AttrRegparmN(1);
37 // <TAG-TYPE-EXECUTEPTR-END>
39 // <TAG-CLASS-INSTRUCTION-START>
40 class bxInstruction_c
{
42 // Function pointers; a function to resolve the modRM address
43 // given the current state of the CPU and the instruction data,
44 // and a function to execute the instruction after resolving
45 // the memory address (if any).
46 BxExecutePtr_tR execute
;
47 BxExecutePtr_tR execute2
;
48 BxResolvePtr_tR ResolveModrm
;
49 #if BX_INSTRUMENTATION
55 // 0...0 stop trace (used with trace cache)
58 // 7...0 b1 - opcode byte
70 // 2...2 mod==c0 (modrm)
71 // 1...0 repUsed (0=none, 2=0xF2, 3=0xF3)
75 #define BX_INSTR_METADATA_SEG 0
76 #define BX_INSTR_METADATA_DEST 1
77 #define BX_INSTR_METADATA_NNN 2
78 #define BX_INSTR_METADATA_RM 3
79 #define BX_INSTR_METADATA_BASE 4
80 #define BX_INSTR_METADATA_INDEX 5
81 #define BX_INSTR_METADATA_SCALE 6
82 #define BX_INSTR_METADATA_MODRM 7
84 // using 5-bit field for registers (16 regs in 64-bit, RIP, NIL)
88 // Form (longest case): [opcode+modrm+sib/displacement32/immediate32]
96 Bit16u displ16u
; // for 16-bit modrm forms
97 Bit32u displ32u
; // for 32-bit modrm forms
108 Bit32u Id2
; // Not used (for alignment)
114 #if BX_SUPPORT_X86_64
116 Bit64u Iq
; // for MOV Rx,imm64
121 BX_CPP_INLINE
unsigned modC0() const
123 // This is a cheaper way to test for modRM instructions where
124 // the mod field is 0xc0. FetchDecode flags this condition since
125 // it is quite common to be tested for.
126 return metaInfo
.metaInfo1
& (1<<2);
128 BX_CPP_INLINE
unsigned assertModC0()
130 return metaInfo
.metaInfo1
|= (1<<2);
132 BX_CPP_INLINE
void setOpcodeReg(unsigned opreg
) {
133 // The opcodeReg form (low 3 bits of the opcode byte (extended
134 // by REX.B on x86-64) to be used with IxIxForm or IqForm.
135 metaData
[BX_INSTR_METADATA_RM
] = opreg
;
137 BX_CPP_INLINE
unsigned opcodeReg() const {
138 return metaData
[BX_INSTR_METADATA_RM
];
140 BX_CPP_INLINE
void setModRM(unsigned modrm
) {
141 metaData
[BX_INSTR_METADATA_MODRM
] = modrm
;
143 BX_CPP_INLINE
unsigned modrm() const {
144 return metaData
[BX_INSTR_METADATA_MODRM
];
146 BX_CPP_INLINE
void setNnn(unsigned nnn
) {
147 metaData
[BX_INSTR_METADATA_NNN
] = nnn
;
149 BX_CPP_INLINE
unsigned nnn() const {
150 return metaData
[BX_INSTR_METADATA_NNN
];
152 BX_CPP_INLINE
void setRm(unsigned rm
) {
153 metaData
[BX_INSTR_METADATA_RM
] = rm
;
155 BX_CPP_INLINE
unsigned rm() const {
156 return metaData
[BX_INSTR_METADATA_RM
];
158 BX_CPP_INLINE
void setSibScale(unsigned scale
) {
159 metaData
[BX_INSTR_METADATA_SCALE
] = scale
;
161 BX_CPP_INLINE
unsigned sibScale() const {
162 return metaData
[BX_INSTR_METADATA_SCALE
];
164 BX_CPP_INLINE
void setSibIndex(unsigned index
) {
165 metaData
[BX_INSTR_METADATA_INDEX
] = index
;
167 BX_CPP_INLINE
unsigned sibIndex() const {
168 return metaData
[BX_INSTR_METADATA_INDEX
];
170 BX_CPP_INLINE
void setSibBase(unsigned base
) {
171 metaData
[BX_INSTR_METADATA_BASE
] = base
;
173 BX_CPP_INLINE
unsigned sibBase() const {
174 return metaData
[BX_INSTR_METADATA_BASE
];
176 BX_CPP_INLINE Bit32u
displ32u() const { return modRMForm
.displ32u
; }
177 BX_CPP_INLINE Bit16u
displ16u() const { return modRMForm
.displ16u
; }
178 BX_CPP_INLINE Bit32u
Id() const { return modRMForm
.Id
; }
179 BX_CPP_INLINE Bit16u
Iw() const { return modRMForm
.Iw
; }
180 BX_CPP_INLINE Bit8u
Ib() const { return modRMForm
.Ib
; }
181 BX_CPP_INLINE Bit16u
Iw2() const { return IxIxForm
.Iw2
; } // Legacy
182 BX_CPP_INLINE Bit8u
Ib2() const { return IxIxForm
.Ib2
; } // Legacy
183 #if BX_SUPPORT_X86_64
184 BX_CPP_INLINE Bit64u
Iq() const { return IqForm
.Iq
; }
187 // Info in the metaInfo field.
188 // Note: the 'L' at the end of certain flags, means the value returned
189 // is for Logical comparisons, eg if (i->os32L() && i->as32L()). If you
190 // want a bx_bool value, use os32B() etc. This makes for smaller
191 // code, when a strict 0 or 1 is not necessary.
192 BX_CPP_INLINE
void init(unsigned os32
, unsigned as32
, unsigned os64
, unsigned as64
)
194 metaInfo
.metaInfo1
= (os32
<<3) | (as32
<<4) | (os64
<<5) | (as64
<<6);
195 metaInfo
.metaInfo4
= 0;
197 BX_CPP_INLINE
unsigned seg(void) const {
198 return metaData
[BX_INSTR_METADATA_SEG
];
200 BX_CPP_INLINE
void setSeg(unsigned val
) {
201 metaData
[BX_INSTR_METADATA_SEG
] = val
;
204 BX_CPP_INLINE
unsigned os32L(void) const {
205 return metaInfo
.metaInfo1
& (1<<3);
207 BX_CPP_INLINE
void setOs32B(unsigned bit
) {
208 metaInfo
.metaInfo1
= (metaInfo
.metaInfo1
& ~(1<<3)) | (bit
<<3);
210 BX_CPP_INLINE
void assertOs32(void) {
211 metaInfo
.metaInfo1
|= (1<<3);
214 BX_CPP_INLINE
unsigned as32L(void) const {
215 return metaInfo
.metaInfo1
& (1<<4);
217 BX_CPP_INLINE
void setAs32B(unsigned bit
) {
218 metaInfo
.metaInfo1
= (metaInfo
.metaInfo1
& ~(1<<4)) | (bit
<<4);
221 #if BX_SUPPORT_X86_64
222 BX_CPP_INLINE
unsigned os64L(void) const {
223 return metaInfo
.metaInfo1
& (1<<5);
225 BX_CPP_INLINE
void assertOs64(void) {
226 metaInfo
.metaInfo1
|= (1<<5);
229 BX_CPP_INLINE
unsigned os64L(void) const { return 0; }
232 #if BX_SUPPORT_X86_64
233 BX_CPP_INLINE
unsigned as64L(void) const {
234 return metaInfo
.metaInfo1
& (1<<6);
236 BX_CPP_INLINE
void setAs64B(unsigned bit
) {
237 metaInfo
.metaInfo1
= (metaInfo
.metaInfo1
& ~(1<<6)) | (bit
<<6);
240 BX_CPP_INLINE
unsigned as64L(void) const { return 0; }
243 #if BX_SUPPORT_X86_64
244 BX_CPP_INLINE
unsigned extend8bitL(void) const {
245 return metaInfo
.metaInfo1
& (1<<7);
247 BX_CPP_INLINE
void assertExtend8bit(void) {
248 metaInfo
.metaInfo1
|= (1<<7);
252 BX_CPP_INLINE
unsigned ilen(void) const {
253 return metaInfo
.metaInfo2
;
255 BX_CPP_INLINE
void setILen(unsigned ilen
) {
256 metaInfo
.metaInfo2
= ilen
;
259 BX_CPP_INLINE
unsigned repUsedL(void) const {
260 return metaInfo
.metaInfo1
& 3;
262 BX_CPP_INLINE
unsigned repUsedValue(void) const {
263 return metaInfo
.metaInfo1
& 3;
265 BX_CPP_INLINE
void setRepUsed(unsigned value
) {
266 metaInfo
.metaInfo1
= (metaInfo
.metaInfo1
& ~3) | (value
);
269 BX_CPP_INLINE
unsigned b1(void) const {
270 return metaInfo
.metaInfo3
;
272 BX_CPP_INLINE
void setB1(unsigned b1
) {
273 metaInfo
.metaInfo3
= b1
& 0xff;
276 #if BX_SUPPORT_TRACE_CACHE
277 BX_CPP_INLINE
void setStopTraceAttr(void) {
278 metaInfo
.metaInfo4
|= 1;
280 BX_CPP_INLINE
unsigned getStopTraceAttr(void) const {
281 return metaInfo
.metaInfo4
& 1;
285 // <TAG-CLASS-INSTRUCTION-END>