1
1
/////////////////////////////////////////////////////////////////////////
2
// $Id: bit16.cc,v 1.9 2008/04/25 07:40:50 sshwarts Exp $
2
// $Id: bit16.cc,v 1.16 2009/01/16 18:18:58 sshwarts Exp $
3
3
/////////////////////////////////////////////////////////////////////////
5
5
// Copyright (C) 2001 MandrakeSoft S.A.
23
23
// You should have received a copy of the GNU Lesser General Public
24
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
25
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
26
26
/////////////////////////////////////////////////////////////////////////
28
28
#define NEED_CPU_REG_SHORTCUTS 1
33
33
#if BX_CPU_LEVEL >= 3
35
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSF_GwEw(bxInstruction_c *i)
35
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSF_GwEwR(bxInstruction_c *i)
37
Bit16u op1_16, op2_16;
39
/* op2_16 is a register or memory reference */
41
op2_16 = BX_READ_16BIT_REG(i->rm());
44
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
46
/* pointer, segment address pair */
47
op2_16 = read_virtual_word(i->seg(), RMAddr(i));
37
Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
51
40
assert_ZF(); /* op1_16 undefined */
56
while ((op2_16 & 0x01) == 0) {
61
SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
64
/* now write result back to destination */
65
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
44
while ((op2_16 & 0x01) == 0) {
49
SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
52
/* now write result back to destination */
53
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
68
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSR_GwEw(bxInstruction_c *i)
57
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSR_GwEwR(bxInstruction_c *i)
70
Bit16u op1_16, op2_16;
72
/* op2_16 is a register or memory reference */
74
op2_16 = BX_READ_16BIT_REG(i->rm());
77
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
79
/* pointer, segment address pair */
80
op2_16 = read_virtual_word(i->seg(), RMAddr(i));
59
Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
84
62
assert_ZF(); /* op1_16 undefined */
89
while ((op2_16 & 0x8000) == 0) {
94
SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
97
/* now write result back to destination */
98
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
66
while ((op2_16 & 0x8000) == 0) {
71
SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
74
/* now write result back to destination */
75
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
101
79
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EwGwM(bxInstruction_c *i)
104
82
Bit16u op1_16, op2_16, index;
105
83
Bit32s displacement32;
107
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
85
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
109
87
op2_16 = BX_READ_16BIT_REG(i->nnn());
110
88
index = op2_16 & 0x0f;
111
89
displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
112
op1_addr = RMAddr(i) + 2 * displacement32;
90
op1_addr = eaddr + 2 * displacement32;
114
92
op1_addr = (Bit16u) op1_addr;
115
93
#if BX_SUPPORT_X86_64
140
118
Bit32s displacement32;
143
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
121
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
145
123
op2_16 = BX_READ_16BIT_REG(i->nnn());
146
124
index = op2_16 & 0x0f;
147
125
displacement32 = ((Bit16s) (op2_16 & 0xfff0)) / 16;
148
op1_addr = RMAddr(i) + 2 * displacement32;
126
op1_addr = eaddr + 2 * displacement32;
149
127
if (! i->as32L())
150
128
op1_addr = (Bit16u) op1_addr;
151
129
#if BX_SUPPORT_X86_64
182
160
Bit16u op1_16, op2_16, index;
183
161
Bit32s displacement32;
185
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
163
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
187
165
op2_16 = BX_READ_16BIT_REG(i->nnn());
188
166
index = op2_16 & 0x0f;
189
167
displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
190
op1_addr = RMAddr(i) + 2 * displacement32;
168
op1_addr = eaddr + 2 * displacement32;
191
169
if (! i->as32L())
192
170
op1_addr = (Bit16u) op1_addr;
193
171
#if BX_SUPPORT_X86_64
226
204
Bit16u op1_16, op2_16, index_16;
227
205
Bit16s displacement16;
229
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
207
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
231
209
op2_16 = BX_READ_16BIT_REG(i->nnn());
232
210
index_16 = op2_16 & 0x0f;
233
211
displacement16 = ((Bit16s) (op2_16 & 0xfff0)) / 16;
234
op1_addr = RMAddr(i) + 2 * displacement16;
212
op1_addr = eaddr + 2 * displacement16;
235
213
if (! i->as32L())
236
214
op1_addr = (Bit16u) op1_addr;
237
215
#if BX_SUPPORT_X86_64
265
243
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EwIbM(bxInstruction_c *i)
267
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
245
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
269
Bit16u op1_16 = read_virtual_word(i->seg(), RMAddr(i));
247
Bit16u op1_16 = read_virtual_word(i->seg(), eaddr);
270
248
Bit8u op2_8 = i->Ib() & 0xf;
272
250
set_CF((op1_16 >> op2_8) & 0x01);
285
263
Bit8u op2_8 = i->Ib() & 0xf;
287
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
265
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
289
Bit16u op1_16 = read_RMW_virtual_word(i->seg(), RMAddr(i));
267
Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
290
268
bx_bool temp_CF = (op1_16 >> op2_8) & 0x01;
291
269
op1_16 |= (((Bit16u) 1) << op2_8);
292
270
write_RMW_virtual_word(op1_16);
311
289
Bit8u op2_8 = i->Ib() & 0xf;
313
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
291
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
315
Bit16u op1_16 = read_RMW_virtual_word(i->seg(), RMAddr(i));
293
Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
316
294
bx_bool temp_CF = (op1_16 >> op2_8) & 0x01;
317
295
op1_16 ^= (((Bit16u) 1) << op2_8); /* toggle bit */
318
296
write_RMW_virtual_word(op1_16);
337
315
Bit8u op2_8 = i->Ib() & 0xf;
339
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
317
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
341
Bit16u op1_16 = read_RMW_virtual_word(i->seg(), RMAddr(i));
319
Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
342
320
bx_bool temp_CF = (op1_16 >> op2_8) & 0x01;
343
321
op1_16 &= ~(((Bit16u) 1) << op2_8);
344
322
write_RMW_virtual_word(op1_16);
362
void BX_CPP_AttrRegparmN(1) BX_CPU_C::POPCNT_GwEw(bxInstruction_c *i)
340
void BX_CPP_AttrRegparmN(1) BX_CPU_C::POPCNT_GwEwR(bxInstruction_c *i)
364
#if BX_SUPPORT_POPCNT || (BX_SUPPORT_SSE >= 5) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0)
365
Bit16u op1_16, op2_16;
367
/* op2_16 is a register or memory reference */
369
op2_16 = BX_READ_16BIT_REG(i->rm());
372
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
373
/* pointer, segment address pair */
374
op2_16 = read_virtual_word(i->seg(), RMAddr(i));
342
#if BX_SUPPORT_POPCNT || (BX_SUPPORT_SSE > 4) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0)
343
Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
378
346
while (op2_16 != 0) {
379
347
if (op2_16 & 1) op1_16++;
387
355
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
389
357
BX_INFO(("POPCNT_GwEw: required POPCNT support, use --enable-popcnt option"));
358
exception(BX_UD_EXCEPTION, 0, 0);