1 /////////////////////////////////////////////////////////////////////////
2 // $Id: bit.cc,v 1.59 2008/08/11 18:53:23 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
31 #define LOG_THIS BX_CPU_THIS_PTR
35 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETO_EbM(bxInstruction_c
*i
)
37 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
39 Bit8u result_8
= getB_OF();
40 write_virtual_byte(i
->seg(), eaddr
, result_8
);
43 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETO_EbR(bxInstruction_c
*i
)
45 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), getB_OF());
48 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNO_EbM(bxInstruction_c
*i
)
50 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
52 Bit8u result_8
= !getB_OF();
53 write_virtual_byte(i
->seg(), eaddr
, result_8
);
56 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNO_EbR(bxInstruction_c
*i
)
58 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), !getB_OF());
61 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETB_EbM(bxInstruction_c
*i
)
63 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
65 Bit8u result_8
= getB_CF();
66 write_virtual_byte(i
->seg(), eaddr
, result_8
);
69 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETB_EbR(bxInstruction_c
*i
)
71 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), getB_CF());
74 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNB_EbM(bxInstruction_c
*i
)
76 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
78 Bit8u result_8
= !getB_CF();
79 write_virtual_byte(i
->seg(), eaddr
, result_8
);
82 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNB_EbR(bxInstruction_c
*i
)
84 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), !getB_CF());
87 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETZ_EbM(bxInstruction_c
*i
)
89 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
91 Bit8u result_8
= getB_ZF();
92 write_virtual_byte(i
->seg(), eaddr
, result_8
);
95 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETZ_EbR(bxInstruction_c
*i
)
97 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), getB_ZF());
100 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNZ_EbM(bxInstruction_c
*i
)
102 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
104 Bit8u result_8
= !getB_ZF();
105 write_virtual_byte(i
->seg(), eaddr
, result_8
);
108 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNZ_EbR(bxInstruction_c
*i
)
110 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), !getB_ZF());
113 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETBE_EbM(bxInstruction_c
*i
)
115 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
117 Bit8u result_8
= (getB_CF() | getB_ZF());
118 write_virtual_byte(i
->seg(), eaddr
, result_8
);
121 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETBE_EbR(bxInstruction_c
*i
)
123 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), (getB_CF() | getB_ZF()));
126 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNBE_EbM(bxInstruction_c
*i
)
128 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
130 Bit8u result_8
= !(getB_CF() | getB_ZF());
131 write_virtual_byte(i
->seg(), eaddr
, result_8
);
134 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNBE_EbR(bxInstruction_c
*i
)
136 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), !(getB_CF() | getB_ZF()));
139 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETS_EbM(bxInstruction_c
*i
)
141 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
143 Bit8u result_8
= getB_SF();
144 write_virtual_byte(i
->seg(), eaddr
, result_8
);
147 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETS_EbR(bxInstruction_c
*i
)
149 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), getB_SF());
152 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNS_EbM(bxInstruction_c
*i
)
154 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
156 Bit8u result_8
= !getB_SF();
157 write_virtual_byte(i
->seg(), eaddr
, result_8
);
160 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNS_EbR(bxInstruction_c
*i
)
162 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), !getB_SF());
165 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETP_EbM(bxInstruction_c
*i
)
167 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
169 Bit8u result_8
= getB_PF();
170 write_virtual_byte(i
->seg(), eaddr
, result_8
);
173 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETP_EbR(bxInstruction_c
*i
)
175 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), getB_PF());
178 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNP_EbM(bxInstruction_c
*i
)
180 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
182 Bit8u result_8
= !getB_PF();
183 write_virtual_byte(i
->seg(), eaddr
, result_8
);
186 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNP_EbR(bxInstruction_c
*i
)
188 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), !getB_PF());
191 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETL_EbM(bxInstruction_c
*i
)
193 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
195 Bit8u result_8
= (getB_SF() ^ getB_OF());
196 write_virtual_byte(i
->seg(), eaddr
, result_8
);
199 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETL_EbR(bxInstruction_c
*i
)
201 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), (getB_SF() ^ getB_OF()));
204 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNL_EbM(bxInstruction_c
*i
)
206 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
208 Bit8u result_8
= !(getB_SF() ^ getB_OF());
209 write_virtual_byte(i
->seg(), eaddr
, result_8
);
212 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNL_EbR(bxInstruction_c
*i
)
214 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), !(getB_SF() ^ getB_OF()));
217 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETLE_EbM(bxInstruction_c
*i
)
219 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
221 Bit8u result_8
= getB_ZF() | (getB_SF() ^ getB_OF());
222 write_virtual_byte(i
->seg(), eaddr
, result_8
);
225 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETLE_EbR(bxInstruction_c
*i
)
227 Bit8u result_8
= getB_ZF() | (getB_SF() ^ getB_OF());
228 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
231 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNLE_EbM(bxInstruction_c
*i
)
233 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
235 Bit8u result_8
= !(getB_ZF() | (getB_SF() ^ getB_OF()));
236 write_virtual_byte(i
->seg(), eaddr
, result_8
);
239 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SETNLE_EbR(bxInstruction_c
*i
)
241 Bit8u result_8
= !(getB_ZF() | (getB_SF() ^ getB_OF()));
242 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
245 void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSWAP_ERX(bxInstruction_c
*i
)
247 #if BX_CPU_LEVEL >= 4
248 Bit32u val32
, b0
, b1
, b2
, b3
;
250 if (i
->os32L() == 0) {
251 BX_ERROR(("BSWAP with 16-bit opsize: undefined behavior !"));
254 val32
= BX_READ_32BIT_REG(i
->opcodeReg());
255 b0
= val32
& 0xff; val32
>>= 8;
256 b1
= val32
& 0xff; val32
>>= 8;
257 b2
= val32
& 0xff; val32
>>= 8;
259 val32
= (b0
<<24) | (b1
<<16) | (b2
<<8) | b3
;
261 BX_WRITE_32BIT_REGZ(i
->opcodeReg(), val32
);
263 BX_INFO(("BSWAP_ERX: required CPU >= 4, use --enable-cpu-level=4 option"));
264 exception(BX_UD_EXCEPTION
, 0, 0);
268 #if BX_SUPPORT_X86_64
269 void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSWAP_RRX(bxInstruction_c
*i
)
271 Bit64u val64
, b0
, b1
, b2
, b3
, b4
, b5
, b6
, b7
;
273 val64
= BX_READ_64BIT_REG(i
->opcodeReg());
274 b0
= val64
& 0xff; val64
>>= 8;
275 b1
= val64
& 0xff; val64
>>= 8;
276 b2
= val64
& 0xff; val64
>>= 8;
277 b3
= val64
& 0xff; val64
>>= 8;
278 b4
= val64
& 0xff; val64
>>= 8;
279 b5
= val64
& 0xff; val64
>>= 8;
280 b6
= val64
& 0xff; val64
>>= 8;
282 val64
= (b0
<<56) | (b1
<<48) | (b2
<<40) | (b3
<<32) | (b4
<<24) | (b4
<<16) | (b4
<<8) | b7
;
284 BX_WRITE_64BIT_REG(i
->opcodeReg(), val64
);
289 #if (BX_SUPPORT_SSE >= 4) || (BX_SUPPORT_SSE >= 3 && BX_SUPPORT_SSE_EXTENSION > 0)
291 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_GwEw(bxInstruction_c
*i
)
294 Bit16u val16
, b0
, b1
;
297 val16
= BX_READ_16BIT_REG(i
->rm());
300 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
301 val16
= read_virtual_word(i
->seg(), eaddr
);
304 b0
= val16
& 0xff; val16
>>= 8;
306 val16
= (b1
<<8) | b0
;
308 BX_WRITE_16BIT_REG(i
->nnn(), val16
);
310 BX_INFO(("MOVBE_GwEw: required MOVBE support, use --enable-movbe option"));
311 exception(BX_UD_EXCEPTION
, 0, 0);
315 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_EwGw(bxInstruction_c
*i
)
318 Bit16u val16
= BX_READ_16BIT_REG(i
->nnn()), b0
, b1
;
320 b0
= val16
& 0xff; val16
>>= 8;
322 val16
= (b1
<<8) | b0
;
325 BX_WRITE_16BIT_REG(i
->rm(), val16
);
328 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
329 write_virtual_word(i
->seg(), eaddr
, val16
);
332 BX_INFO(("MOVBE_EwGw: required MOVBE support, use --enable-movbe option"));
333 exception(BX_UD_EXCEPTION
, 0, 0);
337 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_GdEd(bxInstruction_c
*i
)
340 Bit32u val32
, b0
, b1
, b2
, b3
;
343 val32
= BX_READ_32BIT_REG(i
->rm());
346 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
347 val32
= read_virtual_dword(i
->seg(), eaddr
);
350 b0
= val32
& 0xff; val32
>>= 8;
351 b1
= val32
& 0xff; val32
>>= 8;
352 b2
= val32
& 0xff; val32
>>= 8;
354 val32
= (b0
<<24) | (b1
<<16) | (b2
<<8) | b3
;
356 BX_WRITE_32BIT_REGZ(i
->nnn(), val32
);
358 BX_INFO(("MOVBE_GdEd: required MOVBE support, use --enable-movbe option"));
359 exception(BX_UD_EXCEPTION
, 0, 0);
363 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_EdGd(bxInstruction_c
*i
)
366 Bit32u val32
= BX_READ_32BIT_REG(i
->nnn()), b0
, b1
, b2
, b3
;
368 b0
= val32
& 0xff; val32
>>= 8;
369 b1
= val32
& 0xff; val32
>>= 8;
370 b2
= val32
& 0xff; val32
>>= 8;
372 val32
= (b0
<<24) | (b1
<<16) | (b2
<<8) | b3
;
375 BX_WRITE_32BIT_REGZ(i
->rm(), val32
);
378 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
379 write_virtual_dword(i
->seg(), eaddr
, val32
);
382 BX_INFO(("MOVBE_EdGd: required MOVBE support, use --enable-movbe option"));
383 exception(BX_UD_EXCEPTION
, 0, 0);
387 #if BX_SUPPORT_X86_64
389 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_GqEq(bxInstruction_c
*i
)
392 Bit64u val64
, b0
, b1
, b2
, b3
, b4
, b5
, b6
, b7
;
395 val64
= BX_READ_64BIT_REG(i
->rm());
398 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
399 val64
= read_virtual_qword(i
->seg(), eaddr
);
402 b0
= val64
& 0xff; val64
>>= 8;
403 b1
= val64
& 0xff; val64
>>= 8;
404 b2
= val64
& 0xff; val64
>>= 8;
405 b3
= val64
& 0xff; val64
>>= 8;
406 b4
= val64
& 0xff; val64
>>= 8;
407 b5
= val64
& 0xff; val64
>>= 8;
408 b6
= val64
& 0xff; val64
>>= 8;
410 val64
= (b0
<<56) | (b1
<<48) | (b2
<<40) | (b3
<<32) | (b4
<<24) | (b4
<<16) | (b4
<<8) | b7
;
412 BX_WRITE_64BIT_REG(i
->nnn(), val64
);
414 BX_INFO(("MOVBE_GqEq: required MOVBE support, use --enable-movbe option"));
415 exception(BX_UD_EXCEPTION
, 0, 0);
419 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_EqGq(bxInstruction_c
*i
)
422 Bit64u val64
= BX_READ_64BIT_REG(i
->nnn());
423 Bit64u b0
, b1
, b2
, b3
, b4
, b5
, b6
, b7
;
425 b0
= val64
& 0xff; val64
>>= 8;
426 b1
= val64
& 0xff; val64
>>= 8;
427 b2
= val64
& 0xff; val64
>>= 8;
428 b3
= val64
& 0xff; val64
>>= 8;
429 b4
= val64
& 0xff; val64
>>= 8;
430 b5
= val64
& 0xff; val64
>>= 8;
431 b6
= val64
& 0xff; val64
>>= 8;
433 val64
= (b0
<<56) | (b1
<<48) | (b2
<<40) | (b3
<<32) | (b4
<<24) | (b4
<<16) | (b4
<<8) | b7
;
436 BX_WRITE_64BIT_REG(i
->rm(), val64
);
439 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
440 write_virtual_qword(i
->seg(), eaddr
, val64
);
443 BX_INFO(("MOVBE_EqGq: required MOVBE support, use --enable-movbe option"));
444 exception(BX_UD_EXCEPTION
, 0, 0);
448 #endif // (BX_SUPPORT_X86_64)
450 #endif // (BX_SUPPORT_SSE >= 4) || (BX_SUPPORT_SSE >= 3 && BX_SUPPORT_SSE_EXTENSION > 0)
452 #endif // (BX_CPU_LEVEL >= 3)