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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochs486/] [cpu/] [shift32.cc] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/////////////////////////////////////////////////////////////////////////
2
// $Id: shift32.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::SHLD_EdGdM(bxInstruction_c *i)
28
{
29
  unsigned count;
30
  unsigned of, cf;
31
 
32
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
33
 
34
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
35
 
36
  if (i->getIaOpcode() == BX_IA_SHLD_EdGd)
37
    count = CL;
38
  else // BX_IA_SHLD_EdGdIb
39
    count = i->Ib();
40
 
41
  count &= 0x1f; // use only 5 LSB's
42
 
43
  if (count) {
44
    Bit32u op2_32 = BX_READ_32BIT_REG(i->src());
45
 
46
    Bit32u result_32 = (op1_32 << count) | (op2_32 >> (32 - count));
47
 
48
    write_RMW_virtual_dword(result_32);
49
 
50
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
51
 
52
    cf = (op1_32 >> (32 - count)) & 0x1;
53
    of = cf ^ (result_32 >> 31); // of = cf ^ result31
54
    SET_FLAGS_OxxxxC(of, cf);
55
  }
56
 
57
  BX_NEXT_INSTR(i);
58
}
59
 
60
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHLD_EdGdR(bxInstruction_c *i)
61
{
62
  Bit32u op1_32, op2_32, result_32;
63
  unsigned count;
64
  unsigned of, cf;
65
 
66
  if (i->getIaOpcode() == BX_IA_SHLD_EdGd)
67
    count = CL;
68
  else // BX_IA_SHLD_EdGdIb
69
    count = i->Ib();
70
 
71
  count &= 0x1f; // use only 5 LSB's
72
 
73
  if (!count) {
74
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
75
  }
76
  else {
77
    op1_32 = BX_READ_32BIT_REG(i->dst());
78
    op2_32 = BX_READ_32BIT_REG(i->src());
79
 
80
    result_32 = (op1_32 << count) | (op2_32 >> (32 - count));
81
 
82
    BX_WRITE_32BIT_REGZ(i->dst(), result_32);
83
 
84
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
85
 
86
    cf = (op1_32 >> (32 - count)) & 0x1;
87
    of = cf ^ (result_32 >> 31); // of = cf ^ result31
88
    SET_FLAGS_OxxxxC(of, cf);
89
  }
90
 
91
  BX_NEXT_INSTR(i);
92
}
93
 
94
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EdGdM(bxInstruction_c *i)
95
{
96
  unsigned count;
97
  unsigned cf, of;
98
 
99
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
100
 
101
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
102
 
103
  if (i->getIaOpcode() == BX_IA_SHRD_EdGd)
104
    count = CL;
105
  else // BX_IA_SHRD_EdGdIb
106
    count = i->Ib();
107
 
108
  count &= 0x1f; // use only 5 LSB's
109
 
110
  if (count) {
111
    Bit32u op2_32 = BX_READ_32BIT_REG(i->src());
112
 
113
    Bit32u result_32 = (op2_32 << (32 - count)) | (op1_32 >> count);
114
 
115
    write_RMW_virtual_dword(result_32);
116
 
117
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
118
 
119
    cf = (op1_32 >> (count - 1)) & 0x1;
120
    of = ((result_32 << 1) ^ result_32) >> 31; // of = result30 ^ result31
121
    SET_FLAGS_OxxxxC(of, cf);
122
  }
123
 
124
  BX_NEXT_INSTR(i);
125
}
126
 
127
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EdGdR(bxInstruction_c *i)
128
{
129
  Bit32u op1_32, op2_32, result_32;
130
  unsigned count;
131
  unsigned cf, of;
132
 
133
  if (i->getIaOpcode() == BX_IA_SHRD_EdGd)
134
    count = CL;
135
  else // BX_IA_SHRD_EdGdIb
136
    count = i->Ib();
137
 
138
  count &= 0x1f; // use only 5 LSB's
139
 
140
  if (!count) {
141
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
142
  }
143
  else {
144
    op1_32 = BX_READ_32BIT_REG(i->dst());
145
    op2_32 = BX_READ_32BIT_REG(i->src());
146
 
147
    result_32 = (op2_32 << (32 - count)) | (op1_32 >> count);
148
 
149
    BX_WRITE_32BIT_REGZ(i->dst(), result_32);
150
 
151
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
152
 
153
    cf = (op1_32 >> (count - 1)) & 0x1;
154
    of = ((result_32 << 1) ^ result_32) >> 31; // of = result30 ^ result31
155
    SET_FLAGS_OxxxxC(of, cf);
156
  }
157
 
158
  BX_NEXT_INSTR(i);
159
}
160
 
161
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EdM(bxInstruction_c *i)
162
{
163
  unsigned count;
164
 
165
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
166
 
167
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
168
 
169
  if (i->getIaOpcode() == BX_IA_ROL_Ed)
170
    count = CL;
171
  else
172
    count = i->Ib();
173
 
174
  count &= 0x1f;
175
 
176
  if (count) {
177
    Bit32u result_32 = (op1_32 << count) | (op1_32 >> (32 - count));
178
 
179
    write_RMW_virtual_dword(result_32);
180
 
181
    unsigned bit0  = (result_32 & 0x1);
182
    unsigned bit31 = (result_32 >> 31);
183
    // of = cf ^ result31
184
    SET_FLAGS_OxxxxC(bit0 ^ bit31, bit0);
185
  }
186
 
187
  BX_NEXT_INSTR(i);
188
}
189
 
190
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EdR(bxInstruction_c *i)
191
{
192
  Bit32u op1_32, result_32;
193
  unsigned count;
194
  unsigned bit0, bit31;
195
 
196
  if (i->getIaOpcode() == BX_IA_ROL_Ed)
197
    count = CL;
198
  else
199
    count = i->Ib();
200
 
201
  count &= 0x1f;
202
 
203
  if (!count) {
204
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
205
  }
206
  else {
207
    op1_32 = BX_READ_32BIT_REG(i->dst());
208
    result_32 = (op1_32 << count) | (op1_32 >> (32 - count));
209
    BX_WRITE_32BIT_REGZ(i->dst(), result_32);
210
 
211
    bit0  = (result_32 & 0x1);
212
    bit31 = (result_32 >> 31);
213
    // of = cf ^ result31
214
    SET_FLAGS_OxxxxC(bit0 ^ bit31, bit0);
215
  }
216
 
217
  BX_NEXT_INSTR(i);
218
}
219
 
220
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EdM(bxInstruction_c *i)
221
{
222
  unsigned count;
223
  unsigned bit31, bit30;
224
 
225
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
226
 
227
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
228
 
229
  if (i->getIaOpcode() == BX_IA_ROR_Ed)
230
    count = CL;
231
  else
232
    count = i->Ib();
233
 
234
  count &= 0x1f;
235
 
236
  if (count) {
237
    Bit32u result_32 = (op1_32 >> count) | (op1_32 << (32 - count));
238
 
239
    write_RMW_virtual_dword(result_32);
240
 
241
    bit31 = (result_32 >> 31) & 1;
242
    bit30 = (result_32 >> 30) & 1;
243
    // of = result30 ^ result31
244
    SET_FLAGS_OxxxxC(bit30 ^ bit31, bit31);
245
  }
246
 
247
  BX_NEXT_INSTR(i);
248
}
249
 
250
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EdR(bxInstruction_c *i)
251
{
252
  Bit32u op1_32, result_32;
253
  unsigned count;
254
  unsigned bit31, bit30;
255
 
256
  if (i->getIaOpcode() == BX_IA_ROR_Ed)
257
    count = CL;
258
  else
259
    count = i->Ib();
260
 
261
  count &= 0x1f;
262
 
263
  if (!count) {
264
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
265
  }
266
  else {
267
    op1_32 = BX_READ_32BIT_REG(i->dst());
268
    result_32 = (op1_32 >> count) | (op1_32 << (32 - count));
269
    BX_WRITE_32BIT_REGZ(i->dst(), result_32);
270
 
271
    bit31 = (result_32 >> 31) & 1;
272
    bit30 = (result_32 >> 30) & 1;
273
    // of = result30 ^ result31
274
    SET_FLAGS_OxxxxC(bit30 ^ bit31, bit31);
275
  }
276
 
277
  BX_NEXT_INSTR(i);
278
}
279
 
280
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EdM(bxInstruction_c *i)
281
{
282
  Bit32u result_32;
283
  unsigned count;
284
  unsigned cf, of;
285
 
286
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
287
 
288
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
289
 
290
  if (i->getIaOpcode() == BX_IA_RCL_Ed)
291
    count = CL;
292
  else
293
    count = i->Ib();
294
 
295
  count &= 0x1f;
296
  if (!count) {
297
    BX_NEXT_INSTR(i);
298
  }
299
 
300
  if (count==1) {
301
    result_32 = (op1_32 << 1) | getB_CF();
302
  }
303
  else {
304
    result_32 = (op1_32 << count) | (getB_CF() << (count - 1)) |
305
                (op1_32 >> (33 - count));
306
  }
307
 
308
  write_RMW_virtual_dword(result_32);
309
 
310
  cf = (op1_32 >> (32 - count)) & 0x1;
311
  of = cf ^ (result_32 >> 31); // of = cf ^ result31
312
  SET_FLAGS_OxxxxC(of, cf);
313
 
314
  BX_NEXT_INSTR(i);
315
}
316
 
317
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EdR(bxInstruction_c *i)
318
{
319
  Bit32u result_32;
320
  unsigned count;
321
  unsigned cf, of;
322
 
323
  if (i->getIaOpcode() == BX_IA_RCL_Ed)
324
    count = CL;
325
  else
326
    count = i->Ib();
327
 
328
  count &= 0x1f;
329
  if (!count) {
330
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
331
    BX_NEXT_INSTR(i);
332
  }
333
 
334
  Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
335
 
336
  if (count==1) {
337
    result_32 = (op1_32 << 1) | getB_CF();
338
  }
339
  else {
340
    result_32 = (op1_32 << count) | (getB_CF() << (count - 1)) |
341
                (op1_32 >> (33 - count));
342
  }
343
 
344
  BX_WRITE_32BIT_REGZ(i->dst(), result_32);
345
 
346
  cf = (op1_32 >> (32 - count)) & 0x1;
347
  of = cf ^ (result_32 >> 31); // of = cf ^ result31
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::RCR_EdM(bxInstruction_c *i)
354
{
355
  Bit32u result_32;
356
  unsigned count;
357
  unsigned cf, of;
358
 
359
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
360
 
361
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
362
 
363
  if (i->getIaOpcode() == BX_IA_RCR_Ed)
364
    count = CL;
365
  else
366
    count = i->Ib();
367
 
368
  count &= 0x1f;
369
 
370
  if (!count) {
371
    BX_NEXT_INSTR(i);
372
  }
373
 
374
  if (count==1) {
375
    result_32 = (op1_32 >> 1) | (getB_CF() << 31);
376
  }
377
  else {
378
    result_32 = (op1_32 >> count) | (getB_CF() << (32 - count)) |
379
                (op1_32 << (33 - count));
380
  }
381
 
382
  write_RMW_virtual_dword(result_32);
383
 
384
  cf = (op1_32 >> (count - 1)) & 0x1;
385
  of = ((result_32 << 1) ^ result_32) >> 31; // of = result30 ^ result31
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::RCR_EdR(bxInstruction_c *i)
392
{
393
  Bit32u result_32;
394
  unsigned count;
395
  unsigned cf, of;
396
 
397
  if (i->getIaOpcode() == BX_IA_RCR_Ed)
398
    count = CL;
399
  else
400
    count = i->Ib();
401
 
402
  count &= 0x1f;
403
 
404
  if (!count) {
405
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
406
    BX_NEXT_INSTR(i);
407
  }
408
 
409
  Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
410
 
411
  if (count==1) {
412
    result_32 = (op1_32 >> 1) | (getB_CF() << 31);
413
  }
414
  else {
415
    result_32 = (op1_32 >> count) | (getB_CF() << (32 - count)) |
416
                (op1_32 << (33 - count));
417
  }
418
 
419
  BX_WRITE_32BIT_REGZ(i->dst(), result_32);
420
 
421
  cf = (op1_32 >> (count - 1)) & 0x1;
422
  of = ((result_32 << 1) ^ result_32) >> 31; // of = result30 ^ result31
423
  SET_FLAGS_OxxxxC(of, cf);
424
 
425
  BX_NEXT_INSTR(i);
426
}
427
 
428
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EdM(bxInstruction_c *i)
429
{
430
  unsigned count;
431
  unsigned cf, of;
432
 
433
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
434
 
435
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
436
 
437
  if (i->getIaOpcode() == BX_IA_SHL_Ed)
438
    count = CL;
439
  else
440
    count = i->Ib();
441
 
442
  count &= 0x1f;
443
 
444
  if (count) {
445
    /* count < 32, since only lower 5 bits used */
446
    Bit32u result_32 = (op1_32 << count);
447
 
448
    write_RMW_virtual_dword(result_32);
449
 
450
    cf = (op1_32 >> (32 - count)) & 0x1;
451
    of = cf ^ (result_32 >> 31);
452
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
453
    SET_FLAGS_OxxxxC(of, cf);
454
  }
455
 
456
  BX_NEXT_INSTR(i);
457
}
458
 
459
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EdR(bxInstruction_c *i)
460
{
461
  unsigned count;
462
 
463
  if (i->getIaOpcode() == BX_IA_SHL_Ed)
464
    count = CL;
465
  else
466
    count = i->Ib();
467
 
468
  count &= 0x1f;
469
 
470
  if (!count) {
471
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
472
  }
473
  else {
474
    Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
475
 
476
    /* count < 32, since only lower 5 bits used */
477
    Bit32u result_32 = (op1_32 << count);
478
 
479
    BX_WRITE_32BIT_REGZ(i->dst(), result_32);
480
 
481
    unsigned cf = (op1_32 >> (32 - count)) & 0x1;
482
    unsigned of = cf ^ (result_32 >> 31);
483
 
484
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
485
    SET_FLAGS_OxxxxC(of, cf);
486
  }
487
 
488
  BX_NEXT_INSTR(i);
489
}
490
 
491
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EdM(bxInstruction_c *i)
492
{
493
  unsigned count;
494
 
495
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
496
 
497
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
498
 
499
  if (i->getIaOpcode() == BX_IA_SHR_Ed)
500
    count = CL;
501
  else
502
    count = i->Ib();
503
 
504
  count &= 0x1f;
505
 
506
  if (count) {
507
    Bit32u result_32 = (op1_32 >> count);
508
 
509
    write_RMW_virtual_dword(result_32);
510
 
511
    unsigned cf = (op1_32 >> (count - 1)) & 0x1;
512
    // note, that of == result31 if count == 1 and
513
    //            of == 0        if count >= 2
514
    unsigned of = ((result_32 << 1) ^ result_32) >> 31;
515
 
516
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
517
    SET_FLAGS_OxxxxC(of, cf);
518
  }
519
 
520
  BX_NEXT_INSTR(i);
521
}
522
 
523
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EdR(bxInstruction_c *i)
524
{
525
  unsigned count;
526
 
527
  if (i->getIaOpcode() == BX_IA_SHR_Ed)
528
    count = CL;
529
  else
530
    count = i->Ib();
531
 
532
  count &= 0x1f;
533
 
534
  if (!count) {
535
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
536
  }
537
  else {
538
    Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
539
    Bit32u result_32 = (op1_32 >> count);
540
    BX_WRITE_32BIT_REGZ(i->dst(), result_32);
541
 
542
    unsigned cf = (op1_32 >> (count - 1)) & 0x1;
543
    // note, that of == result31 if count == 1 and
544
    //            of == 0        if count >= 2
545
    unsigned of = ((result_32 << 1) ^ result_32) >> 31;
546
 
547
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
548
    SET_FLAGS_OxxxxC(of, cf);
549
  }
550
 
551
  BX_NEXT_INSTR(i);
552
}
553
 
554
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EdM(bxInstruction_c *i)
555
{
556
  unsigned count;
557
 
558
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
559
 
560
  Bit32u op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
561
 
562
  if (i->getIaOpcode() == BX_IA_SAR_Ed)
563
    count = CL;
564
  else
565
    count = i->Ib();
566
 
567
  count &= 0x1f;
568
 
569
  if (count) {
570
    /* count < 32, since only lower 5 bits used */
571
    Bit32u result_32 = ((Bit32s) op1_32) >> count;
572
 
573
    write_RMW_virtual_dword(result_32);
574
 
575
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
576
    unsigned cf = (op1_32 >> (count - 1)) & 1;
577
    SET_FLAGS_OxxxxC(0, cf); /* signed overflow cannot happen in SAR instruction */
578
  }
579
 
580
  BX_NEXT_INSTR(i);
581
}
582
 
583
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EdR(bxInstruction_c *i)
584
{
585
  unsigned count;
586
 
587
  if (i->getIaOpcode() == BX_IA_SAR_Ed)
588
    count = CL;
589
  else
590
    count = i->Ib();
591
 
592
  count &= 0x1f;
593
 
594
  if (!count) {
595
    BX_CLEAR_64BIT_HIGH(i->dst()); // always clear upper part of the register
596
  }
597
  else {
598
    Bit32u op1_32 = BX_READ_32BIT_REG(i->dst());
599
 
600
    /* count < 32, since only lower 5 bits used */
601
    Bit32u result_32 = ((Bit32s) op1_32) >> count;
602
 
603
    BX_WRITE_32BIT_REGZ(i->dst(), result_32);
604
 
605
    SET_FLAGS_OSZAPC_LOGIC_32(result_32);
606
    unsigned cf = (op1_32 >> (count - 1)) & 1;
607
    SET_FLAGS_OxxxxC(0, cf); /* signed overflow cannot happen in SAR instruction */
608
  }
609
 
610
  BX_NEXT_INSTR(i);
611
}

powered by: WebSVN 2.1.0

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