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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochs486/] [cpu/] [shift8.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: shift8.cc 11313 2012-08-05 13:52:40Z 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
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EbR(bxInstruction_c *i)
28
{
29
  unsigned count;
30
  unsigned bit0, bit7;
31
 
32
  if (i->getIaOpcode() == BX_IA_ROL_Eb)
33
    count = CL;
34
  else
35
    count = i->Ib();
36
 
37
  Bit8u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
38
 
39
  if ((count & 0x07) == 0) {
40
    if (count & 0x18) {
41
      bit0 = (op1_8 &  1);
42
      bit7 = (op1_8 >> 7);
43
      SET_FLAGS_OxxxxC(bit0 ^ bit7, bit0);
44
    }
45
  }
46
  else {
47
    count &= 0x7; // use only lowest 3 bits
48
 
49
    Bit8u result_8 = (op1_8 << count) | (op1_8 >> (8 - count));
50
 
51
    BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), result_8);
52
 
53
    /* set eflags:
54
     * ROL count affects the following flags: C, O
55
     */
56
    bit0 = (result_8 &  1);
57
    bit7 = (result_8 >> 7);
58
 
59
    SET_FLAGS_OxxxxC(bit0 ^ bit7, bit0);
60
  }
61
 
62
  BX_NEXT_INSTR(i);
63
}
64
 
65
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EbM(bxInstruction_c *i)
66
{
67
  unsigned count;
68
  unsigned bit0, bit7;
69
 
70
  if (i->getIaOpcode() == BX_IA_ROL_Eb)
71
    count = CL;
72
  else
73
    count = i->Ib();
74
 
75
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
76
  /* pointer, segment address pair */
77
  Bit8u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
78
 
79
  if ((count & 0x07) == 0) {
80
    if (count & 0x18) {
81
      bit0 = (op1_8 &  1);
82
      bit7 = (op1_8 >> 7);
83
      SET_FLAGS_OxxxxC(bit0 ^ bit7, bit0);
84
    }
85
  }
86
  else {
87
    count &= 0x7; // use only lowest 3 bits
88
 
89
    Bit8u result_8 = (op1_8 << count) | (op1_8 >> (8 - count));
90
 
91
    write_RMW_virtual_byte(result_8);
92
 
93
    /* set eflags:
94
     * ROL count affects the following flags: C, O
95
     */
96
    bit0 = (result_8 &  1);
97
    bit7 = (result_8 >> 7);
98
 
99
    SET_FLAGS_OxxxxC(bit0 ^ bit7, bit0);
100
  }
101
 
102
  BX_NEXT_INSTR(i);
103
}
104
 
105
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EbR(bxInstruction_c *i)
106
{
107
  unsigned count;
108
  unsigned bit6, bit7;
109
 
110
  if (i->getIaOpcode() == BX_IA_ROR_Eb)
111
    count = CL;
112
  else
113
    count = i->Ib();
114
 
115
  Bit8u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
116
 
117
  if ((count & 0x07) == 0) {
118
    if (count & 0x18) {
119
      bit6 = (op1_8 >> 6) & 1;
120
      bit7 = (op1_8 >> 7) & 1;
121
 
122
      SET_FLAGS_OxxxxC(bit6 ^ bit7, bit7);
123
    }
124
  }
125
  else {
126
    count &= 0x7; /* use only bottom 3 bits */
127
 
128
    Bit8u result_8 = (op1_8 >> count) | (op1_8 << (8 - count));
129
 
130
    BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), result_8);
131
 
132
    /* set eflags:
133
     * ROR count affects the following flags: C, O
134
     */
135
    bit6 = (result_8 >> 6) & 1;
136
    bit7 = (result_8 >> 7) & 1;
137
 
138
    SET_FLAGS_OxxxxC(bit6 ^ bit7, bit7);
139
  }
140
 
141
  BX_NEXT_INSTR(i);
142
}
143
 
144
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EbM(bxInstruction_c *i)
145
{
146
  unsigned count;
147
  unsigned bit6, bit7;
148
 
149
  if (i->getIaOpcode() == BX_IA_ROR_Eb)
150
    count = CL;
151
  else
152
    count = i->Ib();
153
 
154
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
155
  /* pointer, segment address pair */
156
  Bit8u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
157
 
158
  if ((count & 0x07) == 0) {
159
    if (count & 0x18) {
160
      bit6 = (op1_8 >> 6) & 1;
161
      bit7 = (op1_8 >> 7) & 1;
162
 
163
      SET_FLAGS_OxxxxC(bit6 ^ bit7, bit7);
164
    }
165
  }
166
  else {
167
    count &= 0x7; /* use only bottom 3 bits */
168
 
169
    Bit8u result_8 = (op1_8 >> count) | (op1_8 << (8 - count));
170
 
171
    write_RMW_virtual_byte(result_8);
172
 
173
    /* set eflags:
174
     * ROR count affects the following flags: C, O
175
     */
176
    bit6 = (result_8 >> 6) & 1;
177
    bit7 = (result_8 >> 7) & 1;
178
 
179
    SET_FLAGS_OxxxxC(bit6 ^ bit7, bit7);
180
  }
181
 
182
  BX_NEXT_INSTR(i);
183
}
184
 
185
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EbR(bxInstruction_c *i)
186
{
187
  Bit8u result_8;
188
  unsigned count;
189
  unsigned of, cf;
190
 
191
  if (i->getIaOpcode() == BX_IA_RCL_Eb)
192
    count = CL;
193
  else
194
    count = i->Ib();
195
 
196
  count = (count & 0x1f) % 9;
197
 
198
  if (! count) {
199
    BX_NEXT_INSTR(i);
200
  }
201
 
202
  Bit8u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
203
 
204
  if (count==1) {
205
    result_8 = (op1_8 << 1) | getB_CF();
206
  }
207
  else {
208
    result_8 = (op1_8 << count) | (getB_CF() << (count - 1)) |
209
               (op1_8 >> (9 - count));
210
  }
211
 
212
  BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), result_8);
213
 
214
  cf = (op1_8 >> (8 - count)) & 0x01;
215
  of = cf ^ (result_8 >> 7);  // of = cf ^ result7
216
  SET_FLAGS_OxxxxC(of, cf);
217
 
218
  BX_NEXT_INSTR(i);
219
}
220
 
221
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EbM(bxInstruction_c *i)
222
{
223
  Bit8u result_8;
224
  unsigned count;
225
  unsigned of, cf;
226
 
227
  if (i->getIaOpcode() == BX_IA_RCL_Eb)
228
    count = CL;
229
  else
230
    count = i->Ib();
231
 
232
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
233
  /* pointer, segment address pair */
234
  Bit8u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
235
 
236
  count = (count & 0x1f) % 9;
237
 
238
  if (! count) {
239
    BX_NEXT_INSTR(i);
240
  }
241
 
242
  if (count==1) {
243
    result_8 = (op1_8 << 1) | getB_CF();
244
  }
245
  else {
246
    result_8 = (op1_8 << count) | (getB_CF() << (count - 1)) |
247
               (op1_8 >> (9 - count));
248
  }
249
 
250
  write_RMW_virtual_byte(result_8);
251
 
252
  cf = (op1_8 >> (8 - count)) & 0x01;
253
  of = cf ^ (result_8 >> 7);  // of = cf ^ result7
254
  SET_FLAGS_OxxxxC(of, cf);
255
 
256
  BX_NEXT_INSTR(i);
257
}
258
 
259
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EbR(bxInstruction_c *i)
260
{
261
  unsigned count;
262
  unsigned cf, of;
263
 
264
  if (i->getIaOpcode() == BX_IA_RCR_Eb)
265
    count = CL;
266
  else
267
    count = i->Ib();
268
 
269
  count = (count & 0x1f) % 9;
270
 
271
  if (count) {
272
    Bit8u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
273
 
274
    Bit8u result_8 = (op1_8 >> count) | (getB_CF() << (8 - count)) |
275
                     (op1_8 << (9 - count));
276
 
277
    BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), result_8);
278
 
279
    cf = (op1_8 >> (count - 1)) & 0x1;
280
    of = (((result_8 << 1) ^ result_8) >> 7) & 0x1; // of = result6 ^ result7
281
    SET_FLAGS_OxxxxC(of, cf);
282
  }
283
 
284
  BX_NEXT_INSTR(i);
285
}
286
 
287
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EbM(bxInstruction_c *i)
288
{
289
  unsigned count;
290
  unsigned cf, of;
291
 
292
  if (i->getIaOpcode() == BX_IA_RCR_Eb)
293
    count = CL;
294
  else
295
    count = i->Ib();
296
 
297
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
298
  /* pointer, segment address pair */
299
  Bit8u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
300
 
301
  count = (count & 0x1f) % 9;
302
 
303
  if (count) {
304
    Bit8u result_8 = (op1_8 >> count) | (getB_CF() << (8 - count)) |
305
                     (op1_8 << (9 - count));
306
 
307
    write_RMW_virtual_byte(result_8);
308
 
309
    cf = (op1_8 >> (count - 1)) & 0x1;
310
    of = (((result_8 << 1) ^ result_8) >> 7) & 0x1; // of = result6 ^ result7
311
    SET_FLAGS_OxxxxC(of, cf);
312
  }
313
 
314
  BX_NEXT_INSTR(i);
315
}
316
 
317
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EbR(bxInstruction_c *i)
318
{
319
  Bit8u result_8;
320
  unsigned count;
321
  unsigned of = 0, cf = 0;
322
 
323
  if (i->getIaOpcode() == BX_IA_SHL_Eb)
324
    count = CL;
325
  else
326
    count = i->Ib();
327
 
328
  count &= 0x1f;
329
 
330
  if (!count) {
331
    BX_NEXT_INSTR(i);
332
  }
333
 
334
  Bit8u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
335
 
336
  if (count <= 8) {
337
    result_8 = (op1_8 << count);
338
    cf = (op1_8 >> (8 - count)) & 0x1;
339
    of = cf ^ (result_8 >> 7);
340
  }
341
  else {
342
    result_8 = 0;
343
  }
344
 
345
  BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), result_8);
346
 
347
  SET_FLAGS_OSZAPC_LOGIC_8(result_8);
348
  SET_FLAGS_OxxxxC(of, cf);
349
 
350
  BX_NEXT_INSTR(i);
351
}
352
 
353
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EbM(bxInstruction_c *i)
354
{
355
  Bit8u result_8;
356
  unsigned count;
357
  unsigned of = 0, cf = 0;
358
 
359
  if (i->getIaOpcode() == BX_IA_SHL_Eb)
360
    count = CL;
361
  else
362
    count = i->Ib();
363
 
364
  count &= 0x1f;
365
 
366
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
367
  /* pointer, segment address pair */
368
  Bit8u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
369
 
370
  if (!count) {
371
    BX_NEXT_INSTR(i);
372
  }
373
 
374
  if (count <= 8) {
375
    result_8 = (op1_8 << count);
376
    cf = (op1_8 >> (8 - count)) & 0x1;
377
    of = cf ^ (result_8 >> 7);
378
  }
379
  else {
380
    result_8 = 0;
381
  }
382
 
383
  write_RMW_virtual_byte(result_8);
384
 
385
  SET_FLAGS_OSZAPC_LOGIC_8(result_8);
386
  SET_FLAGS_OxxxxC(of, cf);
387
 
388
  BX_NEXT_INSTR(i);
389
}
390
 
391
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EbR(bxInstruction_c *i)
392
{
393
  unsigned count;
394
 
395
  if (i->getIaOpcode() == BX_IA_SHR_Eb)
396
    count = CL;
397
  else
398
    count = i->Ib();
399
 
400
  count &= 0x1f;
401
 
402
  if (count) {
403
    Bit8u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
404
    Bit8u result_8 = (op1_8 >> count);
405
    BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), result_8);
406
 
407
    unsigned cf = (op1_8 >> (count - 1)) & 0x1;
408
    // note, that of == result7 if count == 1 and
409
    //            of == 0       if count >= 2
410
    unsigned of = (((result_8 << 1) ^ result_8) >> 7) & 0x1;
411
 
412
    SET_FLAGS_OSZAPC_LOGIC_8(result_8);
413
    SET_FLAGS_OxxxxC(of, cf);
414
  }
415
 
416
  BX_NEXT_INSTR(i);
417
}
418
 
419
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EbM(bxInstruction_c *i)
420
{
421
  unsigned count;
422
 
423
  if (i->getIaOpcode() == BX_IA_SHR_Eb)
424
    count = CL;
425
  else
426
    count = i->Ib();
427
 
428
  count &= 0x1f;
429
 
430
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
431
  /* pointer, segment address pair */
432
  Bit8u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
433
 
434
  if (count) {
435
    Bit8u result_8 = (op1_8 >> count);
436
 
437
    write_RMW_virtual_byte(result_8);
438
 
439
    unsigned cf = (op1_8 >> (count - 1)) & 0x1;
440
    // note, that of == result7 if count == 1 and
441
    //            of == 0       if count >= 2
442
    unsigned of = (((result_8 << 1) ^ result_8) >> 7) & 0x1;
443
 
444
    SET_FLAGS_OSZAPC_LOGIC_8(result_8);
445
    SET_FLAGS_OxxxxC(of, cf);
446
  }
447
 
448
  BX_NEXT_INSTR(i);
449
}
450
 
451
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EbR(bxInstruction_c *i)
452
{
453
  unsigned count;
454
 
455
  if (i->getIaOpcode() == BX_IA_SAR_Eb)
456
    count = CL;
457
  else
458
    count = i->Ib();
459
 
460
  count &= 0x1f;
461
 
462
  if (count) {
463
    Bit8u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
464
    Bit8u result_8 = ((Bit8s) op1_8) >> count;
465
    BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), result_8);
466
 
467
    unsigned cf = (((Bit8s) op1_8) >> (count - 1)) & 0x1;
468
 
469
    SET_FLAGS_OSZAPC_LOGIC_8(result_8);
470
    /* signed overflow cannot happen in SAR instruction */
471
    SET_FLAGS_OxxxxC(0, cf);
472
  }
473
 
474
  BX_NEXT_INSTR(i);
475
}
476
 
477
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EbM(bxInstruction_c *i)
478
{
479
  unsigned count;
480
 
481
  if (i->getIaOpcode() == BX_IA_SAR_Eb)
482
    count = CL;
483
  else
484
    count = i->Ib();
485
 
486
  count &= 0x1f;
487
 
488
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
489
  /* pointer, segment address pair */
490
  Bit8u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
491
 
492
  if (count) {
493
    Bit8u result_8 = ((Bit8s) op1_8) >> count;
494
 
495
    write_RMW_virtual_byte(result_8);
496
 
497
    unsigned cf = (((Bit8s) op1_8) >> (count - 1)) & 0x1;
498
 
499
    SET_FLAGS_OSZAPC_LOGIC_8(result_8);
500
    /* signed overflow cannot happen in SAR instruction */
501
    SET_FLAGS_OxxxxC(0, cf);
502
  }
503
 
504
  BX_NEXT_INSTR(i);
505
}

powered by: WebSVN 2.1.0

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