~ubuntu-branches/ubuntu/saucy/bochs/saucy-proposed

« back to all changes in this revision

Viewing changes to cpu/bit16.cc

  • Committer: Bazaar Package Importer
  • Author(s): David Futcher
  • Date: 2009-04-30 07:46:11 UTC
  • mfrom: (1.1.11 upstream) (4.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090430074611-6dih80a5mk2uvxhk
Tags: 2.3.7+20090416-1ubuntu1
* Merge from debian unstable (LP: #370427), remaining changes:
  - debian/patches/12_no-ssp.patch: Build bios with -fno-stack-protector
  - Add Replaces/Conflicts for bochsbios-qemu (<< 2.3.6-2)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
/////////////////////////////////////////////////////////////////////////
4
4
//
5
5
//  Copyright (C) 2001  MandrakeSoft S.A.
22
22
//
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
/////////////////////////////////////////////////////////////////////////
27
27
 
28
28
#define NEED_CPU_REG_SHORTCUTS 1
32
32
 
33
33
#if BX_CPU_LEVEL >= 3
34
34
 
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)
36
36
{
37
 
  Bit16u op1_16, op2_16;
38
 
 
39
 
  /* op2_16 is a register or memory reference */
40
 
  if (i->modC0()) {
41
 
    op2_16 = BX_READ_16BIT_REG(i->rm());
42
 
  }
43
 
  else {
44
 
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
45
 
 
46
 
    /* pointer, segment address pair */
47
 
    op2_16 = read_virtual_word(i->seg(), RMAddr(i));
48
 
  }
 
37
  Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
49
38
 
50
39
  if (op2_16 == 0) {
51
40
    assert_ZF(); /* op1_16 undefined */
52
 
    return;
53
 
  }
54
 
 
55
 
  op1_16 = 0;
56
 
  while ((op2_16 & 0x01) == 0) {
57
 
    op1_16++;
58
 
    op2_16 >>= 1;
59
 
  }
60
 
 
61
 
  SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
62
 
  clear_ZF();
63
 
 
64
 
  /* now write result back to destination */
65
 
  BX_WRITE_16BIT_REG(i->nnn(), op1_16);
 
41
  }
 
42
  else {
 
43
    Bit16u op1_16 = 0;
 
44
    while ((op2_16 & 0x01) == 0) {
 
45
      op1_16++;
 
46
      op2_16 >>= 1;
 
47
    }
 
48
 
 
49
    SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
 
50
    clear_ZF();
 
51
 
 
52
    /* now write result back to destination */
 
53
    BX_WRITE_16BIT_REG(i->nnn(), op1_16);
 
54
  }
66
55
}
67
56
 
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)
69
58
{
70
 
  Bit16u op1_16, op2_16;
71
 
 
72
 
  /* op2_16 is a register or memory reference */
73
 
  if (i->modC0()) {
74
 
    op2_16 = BX_READ_16BIT_REG(i->rm());
75
 
  }
76
 
  else {
77
 
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
78
 
 
79
 
    /* pointer, segment address pair */
80
 
    op2_16 = read_virtual_word(i->seg(), RMAddr(i));
81
 
  }
 
59
  Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
82
60
 
83
61
  if (op2_16 == 0) {
84
62
    assert_ZF(); /* op1_16 undefined */
85
 
    return;
86
 
  }
87
 
 
88
 
  op1_16 = 15;
89
 
  while ((op2_16 & 0x8000) == 0) {
90
 
    op1_16--;
91
 
    op2_16 <<= 1;
92
 
  }
93
 
 
94
 
  SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
95
 
  clear_ZF();
96
 
 
97
 
  /* now write result back to destination */
98
 
  BX_WRITE_16BIT_REG(i->nnn(), op1_16);
 
63
  }
 
64
  else {
 
65
    Bit16u op1_16 = 15;
 
66
    while ((op2_16 & 0x8000) == 0) {
 
67
      op1_16--;
 
68
      op2_16 <<= 1;
 
69
    }
 
70
 
 
71
    SET_FLAGS_OSZAPC_LOGIC_16(op1_16);
 
72
    clear_ZF();
 
73
 
 
74
    /* now write result back to destination */
 
75
    BX_WRITE_16BIT_REG(i->nnn(), op1_16);
 
76
  }
99
77
}
100
78
 
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;
106
84
 
107
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
85
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
108
86
 
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;
113
91
  if (! i->as32L())
114
92
    op1_addr = (Bit16u) op1_addr;
115
93
#if BX_SUPPORT_X86_64
140
118
  Bit32s displacement32;
141
119
  bx_bool bit_i;
142
120
 
143
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
121
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
144
122
 
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;
184
162
 
185
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
163
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
186
164
 
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;
228
206
 
229
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
207
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
230
208
 
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
264
242
 
265
243
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EwIbM(bxInstruction_c *i)
266
244
{
267
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
245
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
268
246
 
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;
271
249
 
272
250
  set_CF((op1_16 >> op2_8) & 0x01);
284
262
{
285
263
  Bit8u op2_8 = i->Ib() & 0xf;
286
264
 
287
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
265
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
288
266
 
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);
310
288
{
311
289
  Bit8u op2_8 = i->Ib() & 0xf;
312
290
 
313
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
291
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
314
292
 
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);
336
314
{
337
315
  Bit8u op2_8 = i->Ib() & 0xf;
338
316
 
339
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
317
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
340
318
 
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);
359
337
}
360
338
 
361
339
/* 0F B8 */
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)
363
341
{
364
 
#if BX_SUPPORT_POPCNT || (BX_SUPPORT_SSE >= 5) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0)
365
 
  Bit16u op1_16, op2_16;
366
 
 
367
 
  /* op2_16 is a register or memory reference */
368
 
  if (i->modC0()) {
369
 
    op2_16 = BX_READ_16BIT_REG(i->rm());
370
 
  }
371
 
  else {
372
 
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
373
 
    /* pointer, segment address pair */
374
 
    op2_16 = read_virtual_word(i->seg(), RMAddr(i));
375
 
  }
376
 
 
377
 
  op1_16 = 0;
 
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());
 
344
 
 
345
  Bit16u op1_16 = 0;
378
346
  while (op2_16 != 0) {
379
347
    if (op2_16 & 1) op1_16++;
380
348
    op2_16 >>= 1;
387
355
  BX_WRITE_16BIT_REG(i->nnn(), op1_16);
388
356
#else
389
357
  BX_INFO(("POPCNT_GwEw: required POPCNT support, use --enable-popcnt option"));
390
 
  UndefinedOpcode(i);
 
358
  exception(BX_UD_EXCEPTION, 0, 0);
391
359
#endif
392
360
}
393
361