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

« back to all changes in this revision

Viewing changes to cpu/bit64.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: bit64.cc,v 1.12 2008/05/10 18:10:52 sshwarts Exp $
 
2
// $Id: bit64.cc,v 1.20 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_SUPPORT_X86_64
34
34
 
35
 
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSF_GqEq(bxInstruction_c *i)
 
35
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSF_GqEqR(bxInstruction_c *i)
36
36
{
37
 
  /* for 64 bit operand size mode */
38
 
  Bit64u op1_64, op2_64;
39
 
 
40
 
  /* op2_64 is a register or memory reference */
41
 
  if (i->modC0()) {
42
 
    op2_64 = BX_READ_64BIT_REG(i->rm());
43
 
  }
44
 
  else {
45
 
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
46
 
    /* pointer, segment address pair */
47
 
    op2_64 = read_virtual_qword_64(i->seg(), RMAddr(i));
48
 
  }
 
37
  Bit64u op2_64 = BX_READ_64BIT_REG(i->rm());
49
38
 
50
39
  if (op2_64 == 0) {
51
40
    assert_ZF(); /* op1_64 undefined */
52
 
    return;
53
 
  }
54
 
 
55
 
  op1_64 = 0;
56
 
  while ((op2_64 & 0x01) == 0) {
57
 
    op1_64++;
58
 
    op2_64 >>= 1;
59
 
  }
60
 
 
61
 
  SET_FLAGS_OSZAPC_LOGIC_64(op1_64);
62
 
  clear_ZF();
63
 
 
64
 
  /* now write result back to destination */
65
 
  BX_WRITE_64BIT_REG(i->nnn(), op1_64);
 
41
  }
 
42
  else {
 
43
    Bit64u op1_64 = 0;
 
44
    while ((op2_64 & 0x01) == 0) {
 
45
      op1_64++;
 
46
      op2_64 >>= 1;
 
47
    }
 
48
 
 
49
    SET_FLAGS_OSZAPC_LOGIC_64(op1_64);
 
50
    clear_ZF();
 
51
 
 
52
    /* now write result back to destination */
 
53
    BX_WRITE_64BIT_REG(i->nnn(), op1_64);
 
54
  }
66
55
}
67
56
 
68
 
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSR_GqEq(bxInstruction_c *i)
 
57
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BSR_GqEqR(bxInstruction_c *i)
69
58
{
70
 
  /* for 64 bit operand size mode */
71
 
  Bit64u op1_64, op2_64;
72
 
 
73
 
  /* op2_64 is a register or memory reference */
74
 
  if (i->modC0()) {
75
 
    op2_64 = BX_READ_64BIT_REG(i->rm());
76
 
  }
77
 
  else {
78
 
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
79
 
    /* pointer, segment address pair */
80
 
    op2_64 = read_virtual_qword_64(i->seg(), RMAddr(i));
81
 
  }
 
59
  Bit64u op2_64 = BX_READ_64BIT_REG(i->rm());
82
60
 
83
61
  if (op2_64 == 0) {
84
62
    assert_ZF(); /* op1_64 undefined */
85
 
    return;
86
 
  }
87
 
 
88
 
  op1_64 = 63;
89
 
  while ((op2_64 & BX_CONST64(0x8000000000000000)) == 0) {
90
 
    op1_64--;
91
 
    op2_64 <<= 1;
92
 
  }
93
 
 
94
 
  SET_FLAGS_OSZAPC_LOGIC_64(op1_64);
95
 
  clear_ZF();
96
 
 
97
 
  /* now write result back to destination */
98
 
  BX_WRITE_64BIT_REG(i->nnn(), op1_64);
 
63
  }
 
64
  else {
 
65
    Bit64u op1_64 = 63;
 
66
    while ((op2_64 & BX_CONST64(0x8000000000000000)) == 0) {
 
67
      op1_64--;
 
68
      op2_64 <<= 1;
 
69
    }
 
70
 
 
71
    SET_FLAGS_OSZAPC_LOGIC_64(op1_64);
 
72
    clear_ZF();
 
73
 
 
74
    /* now write result back to destination */
 
75
    BX_WRITE_64BIT_REG(i->nnn(), op1_64);
 
76
  }
99
77
}
100
78
 
101
79
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EqGqM(bxInstruction_c *i)
105
83
  Bit64s displacement64;
106
84
  Bit64u index;
107
85
 
108
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
86
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
109
87
 
110
88
  op2_64 = BX_READ_64BIT_REG(i->nnn());
111
89
  index = op2_64 & 0x3f;
112
90
  displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
113
 
  op1_addr = RMAddr(i) + 8 * displacement64;
 
91
  op1_addr = eaddr + 8 * displacement64;
114
92
  if (! i->as64L())
115
93
    op1_addr = (Bit32u) op1_addr;
116
94
 
137
115
  Bit64s displacement64;
138
116
  bx_bool bit_i;
139
117
 
140
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
118
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
141
119
 
142
120
  op2_64 = BX_READ_64BIT_REG(i->nnn());
143
121
  index = op2_64 & 0x3f;
144
122
  displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
145
 
  op1_addr = RMAddr(i) + 8 * displacement64;
 
123
  op1_addr = eaddr + 8 * displacement64;
146
124
  if (! i->as64L())
147
125
    op1_addr = (Bit32u) op1_addr;
148
126
 
175
153
  Bit64u op1_64, op2_64, index;
176
154
  Bit64s displacement64;
177
155
 
178
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
156
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
179
157
 
180
158
  op2_64 = BX_READ_64BIT_REG(i->nnn());
181
159
  index = op2_64 & 0x3f;
182
160
  displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
183
 
  op1_addr = RMAddr(i) + 8 * displacement64;
 
161
  op1_addr = eaddr + 8 * displacement64;
184
162
  if (! i->as64L())
185
163
    op1_addr = (Bit32u) op1_addr;
186
164
 
215
193
  Bit64s displacement64;
216
194
  Bit64u index;
217
195
 
218
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
196
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
219
197
 
220
198
  op2_64 = BX_READ_64BIT_REG(i->nnn());
221
199
  index = op2_64 & 0x3f;
222
200
  displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
223
 
  op1_addr = RMAddr(i) + 8 * displacement64;
 
201
  op1_addr = eaddr + 8 * displacement64;
224
202
  if (! i->as64L())
225
203
    op1_addr = (Bit32u) op1_addr;
226
204
 
249
227
 
250
228
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EqIbM(bxInstruction_c *i)
251
229
{
252
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
230
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
253
231
 
254
 
  Bit64u op1_64 = read_virtual_qword_64(i->seg(), RMAddr(i));
 
232
  Bit64u op1_64 = read_virtual_qword_64(i->seg(), eaddr);
255
233
  Bit8u  op2_8  = i->Ib() & 0x3f;
256
234
 
257
235
  set_CF((op1_64 >> op2_8) & 0x01);
269
247
{
270
248
  Bit8u op2_8 = i->Ib() & 0x3f;
271
249
 
272
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
250
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
273
251
 
274
 
  Bit64u op1_64 = read_RMW_virtual_qword_64(i->seg(), RMAddr(i));
 
252
  Bit64u op1_64 = read_RMW_virtual_qword_64(i->seg(), eaddr);
275
253
  bx_bool temp_CF = (op1_64 >> op2_8) & 0x01;
276
254
  op1_64 |= (((Bit64u) 1) << op2_8);
277
255
  write_RMW_virtual_qword(op1_64);
295
273
{
296
274
  Bit8u op2_8 = i->Ib() & 0x3f;
297
275
 
298
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
276
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
299
277
 
300
 
  Bit64u op1_64 = read_RMW_virtual_qword_64(i->seg(), RMAddr(i));
 
278
  Bit64u op1_64 = read_RMW_virtual_qword_64(i->seg(), eaddr);
301
279
  bx_bool temp_CF = (op1_64 >> op2_8) & 0x01;
302
280
  op1_64 ^= (((Bit64u) 1) << op2_8);  /* toggle bit */
303
281
  write_RMW_virtual_qword(op1_64);
321
299
{
322
300
  Bit8u op2_8 = i->Ib() & 0x3f;
323
301
 
324
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
302
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
325
303
 
326
 
  Bit64u op1_64 = read_RMW_virtual_qword_64(i->seg(), RMAddr(i));
 
304
  Bit64u op1_64 = read_RMW_virtual_qword_64(i->seg(), eaddr);
327
305
  bx_bool temp_CF = (op1_64 >> op2_8) & 0x01;
328
306
  op1_64 &= ~(((Bit64u) 1) << op2_8);
329
307
  write_RMW_virtual_qword(op1_64);
344
322
}
345
323
 
346
324
/* 0F B8 */
347
 
void BX_CPP_AttrRegparmN(1) BX_CPU_C::POPCNT_GqEq(bxInstruction_c *i)
 
325
void BX_CPP_AttrRegparmN(1) BX_CPU_C::POPCNT_GqEqR(bxInstruction_c *i)
348
326
{
349
 
#if BX_SUPPORT_POPCNT || (BX_SUPPORT_SSE >= 5) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0)
350
 
  Bit64u op1_64, op2_64;
351
 
 
352
 
  /* op2_16 is a register or memory reference */
353
 
  if (i->modC0()) {
354
 
    op2_64 = BX_READ_64BIT_REG(i->rm());
355
 
  }
356
 
  else {
357
 
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
358
 
    /* pointer, segment address pair */
359
 
    op2_64 = read_virtual_qword_64(i->seg(), RMAddr(i));
360
 
  }
361
 
 
362
 
  op1_64 = 0;
 
327
#if BX_SUPPORT_POPCNT || (BX_SUPPORT_SSE > 4) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0)
 
328
  Bit64u op2_64 = BX_READ_64BIT_REG(i->rm());
 
329
 
 
330
  Bit64u op1_64 = 0;
363
331
  while (op2_64 != 0) {
364
332
    if (op2_64 & 1) op1_64++;
365
333
    op2_64 >>= 1;
372
340
  BX_WRITE_64BIT_REG(i->nnn(), op1_64);
373
341
#else
374
342
  BX_INFO(("POPCNT_GqEq: required POPCNT support, use --enable-popcnt option"));
375
 
  UndefinedOpcode(i);
 
343
  exception(BX_UD_EXCEPTION, 0, 0);
376
344
#endif
377
345
}
378
346