OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochs486/] [cpu/] [bit32.cc] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/////////////////////////////////////////////////////////////////////////
2
// $Id: bit32.cc 11437 2012-09-21 14:56:56Z sshwarts $
3
/////////////////////////////////////////////////////////////////////////
4
//
5
//  Copyright (C) 2001-2012  The Bochs Project
6
//
7
//  This library is free software; you can redistribute it and/or
8
//  modify it under the terms of the GNU Lesser General Public
9
//  License as published by the Free Software Foundation; either
10
//  version 2 of the License, or (at your option) any later version.
11
//
12
//  This library is distributed in the hope that it will be useful,
13
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
//  Lesser General Public License for more details.
16
//
17
//  You should have received a copy of the GNU Lesser General Public
18
//  License along with this library; if not, write to the Free Software
19
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
20
/////////////////////////////////////////////////////////////////////////
21
 
22
#define NEED_CPU_REG_SHORTCUTS 1
23
#include "bochs.h"
24
#include "cpu.h"
25
#define LOG_THIS BX_CPU_THIS_PTR
26
 
27
#if BX_CPU_LEVEL >= 3
28
 
29
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BSF_GdEdR(bxInstruction_c *i)
30
{
31
  Bit32u op2_32 = BX_READ_32BIT_REG(i->src());
32
 
33
  if (op2_32 == 0) {
34
    assert_ZF(); /* op1_32 undefined */
35
  }
36
  else {
37
    Bit32u op1_32 = 0;
38
    while ((op2_32 & 0x01) == 0) {
39
      op1_32++;
40
      op2_32 >>= 1;
41
    }
42
 
43
    SET_FLAGS_OSZAPC_LOGIC_32(op1_32);
44
    clear_ZF();
45
 
46
    BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
47
  }
48
 
49
  BX_NEXT_INSTR(i);
50
}
51
 
52
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BSR_GdEdR(bxInstruction_c *i)
53
{
54
  Bit32u op2_32 = BX_READ_32BIT_REG(i->src());
55
 
56
  if (op2_32 == 0) {
57
    assert_ZF(); /* op1_32 undefined */
58
  }
59
  else {
60
    Bit32u op1_32 = 31;
61
    while ((op2_32 & 0x80000000) == 0) {
62
      op1_32--;
63
      op2_32 <<= 1;
64
    }
65
 
66
    SET_FLAGS_OSZAPC_LOGIC_32(op1_32);
67
    clear_ZF();
68
 
69
    BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
70
  }
71
 
72
  BX_NEXT_INSTR(i);
73
}
74
 
75
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EdGdM(bxInstruction_c *i)
76
{
77
  bx_address op1_addr;
78
  Bit32u op1_32, op2_32, index;
79
  Bit32s displacement32;
80
 
81
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
82
 
83
  op2_32 = BX_READ_32BIT_REG(i->src());
84
  index = op2_32 & 0x1f;
85
  displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
86
  op1_addr = eaddr + 4 * displacement32;
87
 
88
  /* pointer, segment address pair */
89
  op1_32 = read_virtual_dword(i->seg(), op1_addr & i->asize_mask());
90
 
91
  set_CF((op1_32 >> index) & 0x01);
92
 
93
  BX_NEXT_INSTR(i);
94
}
95
 
96
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EdGdR(bxInstruction_c *i)
97
{
98
  Bit32u op1_32, op2_32;
99
 
100
  op1_32 = BX_READ_32BIT_REG(i->dst());
101
  op2_32 = BX_READ_32BIT_REG(i->src());
102
  op2_32 &= 0x1f;
103
 
104
  set_CF((op1_32 >> op2_32) & 0x01);
105
 
106
  BX_NEXT_INSTR(i);
107
}
108
 
109
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTS_EdGdM(bxInstruction_c *i)
110
{
111
  bx_address op1_addr;
112
  Bit32u op1_32, op2_32, index;
113
  Bit32s displacement32;
114
  bx_bool bit_i;
115
 
116
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
117
 
118
  op2_32 = BX_READ_32BIT_REG(i->src());
119
  index = op2_32 & 0x1f;
120
  displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
121
  op1_addr = eaddr + 4 * displacement32;
122
 
123
  /* pointer, segment address pair */
124
  op1_32 = read_RMW_virtual_dword(i->seg(), op1_addr & i->asize_mask());
125
 
126
  bit_i = (op1_32 >> index) & 0x01;
127
  op1_32 |= (1 << index);
128
 
129
  write_RMW_virtual_dword(op1_32);
130
 
131
  set_CF(bit_i);
132
 
133
  BX_NEXT_INSTR(i);
134
}
135
 
136
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTS_EdGdR(bxInstruction_c *i)
137
{
138
  Bit32u op1_32, op2_32;
139
 
140
  op1_32 = BX_READ_32BIT_REG(i->dst());
141
  op2_32 = BX_READ_32BIT_REG(i->src());
142
  op2_32 &= 0x1f;
143
  set_CF((op1_32 >> op2_32) & 0x01);
144
  op1_32 |= (1 << op2_32);
145
 
146
  /* now write result back to the destination */
147
  BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
148
 
149
  BX_NEXT_INSTR(i);
150
}
151
 
152
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTR_EdGdM(bxInstruction_c *i)
153
{
154
  bx_address op1_addr;
155
  Bit32u op1_32, op2_32, index;
156
  Bit32s displacement32;
157
 
158
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
159
 
160
  op2_32 = BX_READ_32BIT_REG(i->src());
161
  index = op2_32 & 0x1f;
162
  displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
163
  op1_addr = eaddr + 4 * displacement32;
164
 
165
  /* pointer, segment address pair */
166
  op1_32 = read_RMW_virtual_dword(i->seg(), op1_addr & i->asize_mask());
167
 
168
  bx_bool temp_cf = (op1_32 >> index) & 0x01;
169
  op1_32 &= ~(1 << index);
170
 
171
  /* now write back to destination */
172
  write_RMW_virtual_dword(op1_32);
173
 
174
  set_CF(temp_cf);
175
 
176
  BX_NEXT_INSTR(i);
177
}
178
 
179
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTR_EdGdR(bxInstruction_c *i)
180
{
181
  Bit32u op1_32, op2_32;
182
 
183
  op1_32 = BX_READ_32BIT_REG(i->dst());
184
  op2_32 = BX_READ_32BIT_REG(i->src());
185
  op2_32 &= 0x1f;
186
  set_CF((op1_32 >> op2_32) & 0x01);
187
  op1_32 &= ~(1 << op2_32);
188
 
189
  /* now write result back to the destination */
190
  BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
191
 
192
  BX_NEXT_INSTR(i);
193
}
194
 
195
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTC_EdGdM(bxInstruction_c *i)
196
{
197
  bx_address op1_addr;
198
  Bit32u op1_32, op2_32, index_32;
199
  Bit32s displacement32;
200
 
201
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
202
 
203
  op2_32 = BX_READ_32BIT_REG(i->src());
204
  index_32 = op2_32 & 0x1f;
205
 
206
  displacement32 = ((Bit32s) (op2_32 & 0xffffffe0)) / 32;
207
  op1_addr = eaddr + 4 * displacement32;
208
 
209
  op1_32 = read_RMW_virtual_dword(i->seg(), op1_addr & i->asize_mask());
210
  bx_bool temp_CF = (op1_32 >> index_32) & 0x01;
211
  op1_32 ^= (1 << index_32);  /* toggle bit */
212
  set_CF(temp_CF);
213
 
214
  write_RMW_virtual_dword(op1_32);
215
 
216
  BX_NEXT_INSTR(i);
217
}
218
 
219
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTC_EdGdR(bxInstruction_c *i)
220
{
221
  Bit32u op1_32, op2_32;
222
 
223
  op1_32 = BX_READ_32BIT_REG(i->dst());
224
  op2_32 = BX_READ_32BIT_REG(i->src());
225
  op2_32 &= 0x1f;
226
 
227
  bx_bool temp_CF = (op1_32 >> op2_32) & 0x01;
228
  op1_32 ^= (1 << op2_32);  /* toggle bit */
229
  set_CF(temp_CF);
230
 
231
  BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
232
 
233
  BX_NEXT_INSTR(i);
234
}
235
 
236
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EdIbM(bxInstruction_c *i)
237
{
238
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
239
 
240
  Bit32u op1_32 = read_virtual_dword(i->seg(), eaddr);
241
  Bit8u  op2_8  = i->Ib() & 0x1f;
242
 
243
  set_CF((op1_32 >> op2_8) & 0x01);
244
 
245
  BX_NEXT_INSTR(i);
246
}
247
 
248
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BT_EdIbR(bxInstruction_c *i)
249
{
250
  Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
251
  Bit8u  op2_8  = i->Ib() & 0x1f;
252
 
253
  set_CF((op1_32 >> op2_8) & 0x01);
254
 
255
  BX_NEXT_INSTR(i);
256
}
257
 
258
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTS_EdIbM(bxInstruction_c *i)
259
{
260
  Bit8u op2_8 = i->Ib() & 0x1f;
261
 
262
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
263
 
264
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
265
  bx_bool temp_CF = (op1_32 >> op2_8) & 0x01;
266
  op1_32 |= (1 << op2_8);
267
  write_RMW_virtual_dword(op1_32);
268
 
269
  set_CF(temp_CF);
270
 
271
  BX_NEXT_INSTR(i);
272
}
273
 
274
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTS_EdIbR(bxInstruction_c *i)
275
{
276
  Bit8u op2_8 = i->Ib() & 0x1f;
277
 
278
  Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
279
  bx_bool temp_CF = (op1_32 >> op2_8) & 0x01;
280
  op1_32 |= (1 << op2_8);
281
  BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
282
 
283
  set_CF(temp_CF);
284
 
285
  BX_NEXT_INSTR(i);
286
}
287
 
288
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTC_EdIbM(bxInstruction_c *i)
289
{
290
  Bit8u op2_8 = i->Ib() & 0x1f;
291
 
292
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
293
 
294
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
295
  bx_bool temp_CF = (op1_32 >> op2_8) & 0x01;
296
  op1_32 ^= (1 << op2_8);  /* toggle bit */
297
  write_RMW_virtual_dword(op1_32);
298
 
299
  set_CF(temp_CF);
300
 
301
  BX_NEXT_INSTR(i);
302
}
303
 
304
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTC_EdIbR(bxInstruction_c *i)
305
{
306
  Bit8u op2_8 = i->Ib() & 0x1f;
307
 
308
  Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
309
  bx_bool temp_CF = (op1_32 >> op2_8) & 0x01;
310
  op1_32 ^= (1 << op2_8);  /* toggle bit */
311
  BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
312
 
313
  set_CF(temp_CF);
314
 
315
  BX_NEXT_INSTR(i);
316
}
317
 
318
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTR_EdIbM(bxInstruction_c *i)
319
{
320
  Bit8u op2_8 = i->Ib() & 0x1f;
321
 
322
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
323
 
324
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
325
  bx_bool temp_CF = (op1_32 >> op2_8) & 0x01;
326
  op1_32 &= ~(1 << op2_8);
327
  write_RMW_virtual_dword(op1_32);
328
 
329
  set_CF(temp_CF);
330
 
331
  BX_NEXT_INSTR(i);
332
}
333
 
334
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BTR_EdIbR(bxInstruction_c *i)
335
{
336
  Bit8u op2_8 = i->Ib() & 0x1f;
337
 
338
  Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
339
  bx_bool temp_CF = (op1_32 >> op2_8) & 0x01;
340
  op1_32 &= ~(1 << op2_8);
341
  BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
342
 
343
  set_CF(temp_CF);
344
 
345
  BX_NEXT_INSTR(i);
346
}
347
 
348
/* F3 0F B8 */
349
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPCNT_GdEdR(bxInstruction_c *i)
350
{
351
  Bit32u op2_32 = BX_READ_32BIT_REG(i->src());
352
 
353
  Bit32u op1_32 = 0;
354
  while (op2_32 != 0) {
355
    op2_32 &= (op2_32-1);
356
    op1_32++;
357
  }
358
 
359
  Bit32u flags = op1_32 ? 0 : EFlagsZFMask;
360
  setEFlagsOSZAPC(flags);
361
 
362
  BX_WRITE_32BIT_REGZ(i->dst(), op1_32);
363
 
364
  BX_NEXT_INSTR(i);
365
}
366
 
367
/* F3 0F BC */
368
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::TZCNT_GdEdR(bxInstruction_c *i)
369
{
370
  Bit32u op1_32 = BX_READ_32BIT_REG(i->src());
371
  Bit32u mask = 0x1, result_32 = 0;
372
 
373
  while ((op1_32 & mask) == 0 && mask) {
374
    mask <<= 1;
375
    result_32++;
376
  }
377
 
378
  set_CF(! op1_32);
379
  set_ZF(! result_32);
380
 
381
  BX_WRITE_32BIT_REGZ(i->dst(), result_32);
382
 
383
  BX_NEXT_INSTR(i);
384
}
385
 
386
/* F3 0F BD */
387
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LZCNT_GdEdR(bxInstruction_c *i)
388
{
389
  Bit32u op1_32 = BX_READ_32BIT_REG(i->src());
390
  Bit32u mask = 0x80000000, result_32 = 0;
391
 
392
  while ((op1_32 & mask) == 0 && mask) {
393
    mask >>= 1;
394
    result_32++;
395
  }
396
 
397
  set_CF(! op1_32);
398
  set_ZF(! result_32);
399
 
400
  BX_WRITE_32BIT_REGZ(i->dst(), result_32);
401
 
402
  BX_NEXT_INSTR(i);
403
}
404
 
405
#endif // (BX_CPU_LEVEL >= 3)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.