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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochs486/] [cpu/] [shift16.cc] - Blame information for rev 3

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

Line No. Rev Author Line
1 2 alfik
/////////////////////////////////////////////////////////////////////////
2
// $Id: shift16.cc 11408 2012-09-09 17:44:42Z 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_EwGwM(bxInstruction_c *i)
28
{
29
  Bit32u temp_32, result_32;
30
  unsigned count;
31
  unsigned of, cf;
32
 
33
  /* op1:op2 << count.  result stored in op1 */
34
  if (i->getIaOpcode() == BX_IA_SHLD_EwGw)
35
    count = CL;
36
  else // BX_IA_SHLD_EwGwIb
37
    count = i->Ib();
38
 
39
  count &= 0x1f; // use only 5 LSB's
40
 
41
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
42
 
43
  Bit32u op1_16 = (Bit32u) read_RMW_virtual_word(i->seg(), eaddr);
44
 
45
  if (count) {
46
    Bit32u op2_16 = (Bit32u) BX_READ_16BIT_REG(i->src());
47
 
48
    /* count < 32, since only lower 5 bits used */
49
    temp_32 = (op1_16 << 16) | (op2_16); // double formed by op1:op2
50
    result_32 = temp_32 << count;
51
 
52
    // hack to act like x86 SHLD when count > 16
53
    if (count > 16) {
54
      // for Pentium processor, when count > 16, actually shifting op1:op2:op2 << count,
55
      // it is the same as shifting op2:op2 by count-16
56
      // For P6 and later (CPU_LEVEL >= 6), when count > 16, actually shifting op1:op2:op1 << count,
57
      // which is the same as shifting op2:op1 by count-16
58
      // The behavior is undefined so both ways are correct, we prefer P6 way of implementation
59
      result_32 |= (op1_16 << (count - 16));
60
    }
61
 
62
    Bit16u result_16 = (Bit16u)(result_32 >> 16);
63
 
64
    write_RMW_virtual_word(result_16);
65
 
66
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
67
 
68
    cf = (temp_32 >> (32 - count)) & 0x1;
69
    of = cf ^ (result_16 >> 15); // of = cf ^ result15
70
    SET_FLAGS_OxxxxC(of, cf);
71
  }
72
 
73
  BX_NEXT_INSTR(i);
74
}
75
 
76
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHLD_EwGwR(bxInstruction_c *i)
77
{
78
  Bit32u temp_32, result_32;
79
  unsigned count;
80
  unsigned of, cf;
81
 
82
  /* op1:op2 << count.  result stored in op1 */
83
  if (i->getIaOpcode() == BX_IA_SHLD_EwGw)
84
    count = CL;
85
  else // BX_IA_SHLD_EwGwIb
86
    count = i->Ib();
87
 
88
  count &= 0x1f; // use only 5 LSB's
89
 
90
  if (count) {
91
    Bit32u op1_16 = (Bit32u) BX_READ_16BIT_REG(i->dst());
92
    Bit32u op2_16 = (Bit32u) BX_READ_16BIT_REG(i->src());
93
 
94
    /* count < 32, since only lower 5 bits used */
95
    temp_32 = (op1_16 << 16) | (op2_16); // double formed by op1:op2
96
    result_32 = temp_32 << count;
97
 
98
    // hack to act like x86 SHLD when count > 16
99
    if (count > 16) {
100
      // for Pentium processor, when count > 16, actually shifting op1:op2:op2 << count,
101
      // it is the same as shifting op2:op2 by count-16
102
      // For P6 and later (CPU_LEVEL >= 6), when count > 16, actually shifting op1:op2:op1 << count,
103
      // which is the same as shifting op2:op1 by count-16
104
      // The behavior is undefined so both ways are correct, we prefer P6 way of implementation
105
      result_32 |= (op1_16 << (count - 16));
106
    }
107
 
108
    Bit16u result_16 = (Bit16u)(result_32 >> 16);
109
 
110
    BX_WRITE_16BIT_REG(i->dst(), result_16);
111
 
112
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
113
 
114
    cf = (temp_32 >> (32 - count)) & 0x1;
115
    of = cf ^ (result_16 >> 15); // of = cf ^ result15
116
    SET_FLAGS_OxxxxC(of, cf);
117
  }
118
 
119
  BX_NEXT_INSTR(i);
120
}
121
 
122
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EwGwM(bxInstruction_c *i)
123
{
124
  Bit32u temp_32, result_32;
125
  unsigned count;
126
  unsigned cf, of;
127
 
128
  if (i->getIaOpcode() == BX_IA_SHRD_EwGw)
129
    count = CL;
130
  else // BX_IA_SHRD_EwGwIb
131
    count = i->Ib();
132
 
133
  count &= 0x1f; /* use only 5 LSB's */
134
 
135
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
136
 
137
  Bit32u op1_16 = (Bit32u) read_RMW_virtual_word(i->seg(), eaddr);
138
 
139
  if (count) {
140
    Bit32u op2_16 = (Bit32u) BX_READ_16BIT_REG(i->src());
141
 
142
    /* count < 32, since only lower 5 bits used */
143
    temp_32 = (op2_16 << 16) | op1_16; // double formed by op2:op1
144
    result_32 = temp_32 >> count;
145
 
146
    // hack to act like x86 SHRD when count > 16
147
    if (count > 16) {
148
      // for Pentium processor, when count > 16, actually shifting op2:op2:op1 >> count,
149
      // it is the same as shifting op2:op2 by count-16
150
      // For P6 and later (CPU_LEVEL >= 6), when count > 16, actually shifting op1:op2:op1 >> count,
151
      // which is the same as shifting op1:op2 by count-16
152
      // The behavior is undefined so both ways are correct, we prefer P6 way of implementation
153
      result_32 |= (op1_16 << (32 - count));
154
    }
155
 
156
    Bit16u result_16 = (Bit16u) result_32;
157
 
158
    write_RMW_virtual_word(result_16);
159
 
160
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
161
 
162
    cf = (op1_16 >> (count - 1)) & 0x1;
163
    of = ((Bit16u)((result_16 << 1) ^ result_16) >> 15) & 0x1; // of = result14 ^ result15
164
    SET_FLAGS_OxxxxC(of, cf);
165
  }
166
 
167
  BX_NEXT_INSTR(i);
168
}
169
 
170
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EwGwR(bxInstruction_c *i)
171
{
172
  Bit32u temp_32, result_32;
173
  unsigned count;
174
  unsigned cf, of;
175
 
176
  if (i->getIaOpcode() == BX_IA_SHRD_EwGw)
177
    count = CL;
178
  else // BX_IA_SHRD_EwGwIb
179
    count = i->Ib();
180
 
181
  count &= 0x1f; /* use only 5 LSB's */
182
 
183
  if (count) {
184
    Bit32u op1_16 = (Bit32u) BX_READ_16BIT_REG(i->dst());
185
    Bit32u op2_16 = (Bit32u) BX_READ_16BIT_REG(i->src());
186
 
187
    /* count < 32, since only lower 5 bits used */
188
    temp_32 = (op2_16 << 16) | op1_16; // double formed by op2:op1
189
    result_32 = temp_32 >> count;
190
 
191
    // hack to act like x86 SHRD when count > 16
192
    if (count > 16) {
193
      // for Pentium processor, when count > 16, actually shifting op2:op2:op1 >> count,
194
      // it is the same as shifting op2:op2 by count-16
195
      // For P6 and later (CPU_LEVEL >= 6), when count > 16, actually shifting op1:op2:op1 >> count,
196
      // which is the same as shifting op1:op2 by count-16
197
      // The behavior is undefined so both ways are correct, we prefer P6 way of implementation
198
      result_32 |= (op1_16 << (32 - count));
199
    }
200
 
201
    Bit16u result_16 = (Bit16u) result_32;
202
 
203
    BX_WRITE_16BIT_REG(i->dst(), result_16);
204
 
205
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
206
 
207
    cf = (op1_16 >> (count - 1)) & 0x1;
208
    of = ((Bit16u)((result_16 << 1) ^ result_16) >> 15) & 0x1; // of = result14 ^ result15
209
    SET_FLAGS_OxxxxC(of, cf);
210
  }
211
 
212
  BX_NEXT_INSTR(i);
213
}
214
 
215
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EwM(bxInstruction_c *i)
216
{
217
  unsigned count;
218
  unsigned bit0, bit15;
219
 
220
  if (i->getIaOpcode() == BX_IA_ROL_Ew)
221
    count = CL;
222
  else
223
    count = i->Ib();
224
 
225
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
226
  /* pointer, segment address pair */
227
  Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
228
 
229
  if ((count & 0x0f) == 0) {
230
    if (count & 0x10) {
231
      bit0  = (op1_16 & 0x1);
232
      bit15 = (op1_16 >> 15);
233
      // of = cf ^ result15
234
      SET_FLAGS_OxxxxC(bit0 ^ bit15, bit0);
235
    }
236
  }
237
  else {
238
    count &= 0x0f; // only use bottom 4 bits
239
 
240
    Bit16u result_16 = (op1_16 << count) | (op1_16 >> (16 - count));
241
 
242
    write_RMW_virtual_word(result_16);
243
 
244
    bit0  = (result_16 & 0x1);
245
    bit15 = (result_16 >> 15);
246
    // of = cf ^ result15
247
    SET_FLAGS_OxxxxC(bit0 ^ bit15, bit0);
248
  }
249
 
250
  BX_NEXT_INSTR(i);
251
}
252
 
253
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EwR(bxInstruction_c *i)
254
{
255
  unsigned count;
256
  unsigned bit0, bit15;
257
 
258
  if (i->getIaOpcode() == BX_IA_ROL_Ew)
259
    count = CL;
260
  else
261
    count = i->Ib();
262
 
263
  Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
264
 
265
  if ((count & 0x0f) == 0) {
266
    if (count & 0x10) {
267
      bit0  = (op1_16 & 0x1);
268
      bit15 = (op1_16 >> 15);
269
      // of = cf ^ result15
270
      SET_FLAGS_OxxxxC(bit0 ^ bit15, bit0);
271
    }
272
  }
273
  else {
274
    count &= 0x0f; // only use bottom 4 bits
275
 
276
    Bit16u result_16 = (op1_16 << count) | (op1_16 >> (16 - count));
277
 
278
    BX_WRITE_16BIT_REG(i->dst(), result_16);
279
 
280
    bit0  = (result_16 & 0x1);
281
    bit15 = (result_16 >> 15);
282
    // of = cf ^ result15
283
    SET_FLAGS_OxxxxC(bit0 ^ bit15, bit0);
284
  }
285
 
286
  BX_NEXT_INSTR(i);
287
}
288
 
289
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EwM(bxInstruction_c *i)
290
{
291
  unsigned count;
292
  unsigned bit14, bit15;
293
 
294
  if (i->getIaOpcode() == BX_IA_ROR_Ew)
295
    count = CL;
296
  else
297
    count = i->Ib();
298
 
299
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
300
  /* pointer, segment address pair */
301
  Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
302
 
303
  if ((count & 0x0f) == 0) {
304
    if (count & 0x10) {
305
      bit14 = (op1_16 >> 14) & 1;
306
      bit15 = (op1_16 >> 15) & 1;
307
      // of = result14 ^ result15
308
      SET_FLAGS_OxxxxC(bit14 ^ bit15, bit15);
309
    }
310
  }
311
  else {
312
    count &= 0x0f;  // use only 4 LSB's
313
 
314
    Bit16u result_16 = (op1_16 >> count) | (op1_16 << (16 - count));
315
 
316
    write_RMW_virtual_word(result_16);
317
 
318
    bit14 = (result_16 >> 14) & 1;
319
    bit15 = (result_16 >> 15) & 1;
320
    // of = result14 ^ result15
321
    SET_FLAGS_OxxxxC(bit14 ^ bit15, bit15);
322
  }
323
 
324
  BX_NEXT_INSTR(i);
325
}
326
 
327
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EwR(bxInstruction_c *i)
328
{
329
  unsigned count;
330
  unsigned bit14, bit15;
331
 
332
  if (i->getIaOpcode() == BX_IA_ROR_Ew)
333
    count = CL;
334
  else
335
    count = i->Ib();
336
 
337
  Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
338
 
339
  if ((count & 0x0f) == 0) {
340
    if (count & 0x10) {
341
      bit14 = (op1_16 >> 14) & 1;
342
      bit15 = (op1_16 >> 15) & 1;
343
      // of = result14 ^ result15
344
      SET_FLAGS_OxxxxC(bit14 ^ bit15, bit15);
345
    }
346
  }
347
  else {
348
    count &= 0x0f;  // use only 4 LSB's
349
 
350
    Bit16u result_16 = (op1_16 >> count) | (op1_16 << (16 - count));
351
 
352
    BX_WRITE_16BIT_REG(i->dst(), result_16);
353
 
354
    bit14 = (result_16 >> 14) & 1;
355
    bit15 = (result_16 >> 15) & 1;
356
    // of = result14 ^ result15
357
    SET_FLAGS_OxxxxC(bit14 ^ bit15, bit15);
358
  }
359
 
360
  BX_NEXT_INSTR(i);
361
}
362
 
363
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EwM(bxInstruction_c *i)
364
{
365
  Bit16u result_16;
366
  unsigned count;
367
  unsigned of, cf;
368
 
369
  if (i->getIaOpcode() == BX_IA_RCL_Ew)
370
    count = CL;
371
  else
372
    count = i->Ib();
373
 
374
  count = (count & 0x1f) % 17;
375
 
376
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
377
  /* pointer, segment address pair */
378
  Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
379
 
380
  if (count) {
381
    if (count==1) {
382
      result_16 = (op1_16 << 1) | getB_CF();
383
    }
384
    else if (count==16) {
385
      result_16 = (getB_CF() << 15) | (op1_16 >> 1);
386
    }
387
    else { // 2..15
388
      result_16 = (op1_16 << count) | (getB_CF() << (count - 1)) |
389
                  (op1_16 >> (17 - count));
390
    }
391
 
392
    write_RMW_virtual_word(result_16);
393
 
394
    cf = (op1_16 >> (16 - count)) & 0x1;
395
    of = cf ^ (result_16 >> 15); // of = cf ^ result15
396
    SET_FLAGS_OxxxxC(of, cf);
397
  }
398
 
399
  BX_NEXT_INSTR(i);
400
}
401
 
402
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EwR(bxInstruction_c *i)
403
{
404
  Bit16u result_16;
405
  unsigned count;
406
  unsigned of, cf;
407
 
408
  if (i->getIaOpcode() == BX_IA_RCL_Ew)
409
    count = CL;
410
  else
411
    count = i->Ib();
412
 
413
  count = (count & 0x1f) % 17;
414
 
415
  if (count) {
416
    Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
417
 
418
    if (count==1) {
419
      result_16 = (op1_16 << 1) | getB_CF();
420
    }
421
    else if (count==16) {
422
      result_16 = (getB_CF() << 15) | (op1_16 >> 1);
423
    }
424
    else { // 2..15
425
      result_16 = (op1_16 << count) | (getB_CF() << (count - 1)) |
426
                  (op1_16 >> (17 - count));
427
    }
428
 
429
    BX_WRITE_16BIT_REG(i->dst(), result_16);
430
 
431
    cf = (op1_16 >> (16 - count)) & 0x1;
432
    of = cf ^ (result_16 >> 15); // of = cf ^ result15
433
    SET_FLAGS_OxxxxC(of, cf);
434
  }
435
 
436
  BX_NEXT_INSTR(i);
437
}
438
 
439
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EwM(bxInstruction_c *i)
440
{
441
  unsigned count;
442
  unsigned of, cf;
443
 
444
  if (i->getIaOpcode() == BX_IA_RCR_Ew)
445
    count = CL;
446
  else
447
    count = i->Ib();
448
 
449
  count = (count & 0x1f) % 17;
450
 
451
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
452
  /* pointer, segment address pair */
453
  Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
454
 
455
  if (count) {
456
    Bit16u result_16 = (op1_16 >> count) | (getB_CF() << (16 - count)) |
457
                       (op1_16 << (17 - count));
458
 
459
    write_RMW_virtual_word(result_16);
460
 
461
    cf = (op1_16 >> (count - 1)) & 0x1;
462
    of = ((Bit16u)((result_16 << 1) ^ result_16) >> 15) & 0x1; // of = result15 ^ result14
463
    SET_FLAGS_OxxxxC(of, cf);
464
  }
465
 
466
  BX_NEXT_INSTR(i);
467
}
468
 
469
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EwR(bxInstruction_c *i)
470
{
471
  unsigned count;
472
  unsigned of, cf;
473
 
474
  if (i->getIaOpcode() == BX_IA_RCR_Ew)
475
    count = CL;
476
  else
477
    count = i->Ib();
478
 
479
  count = (count & 0x1f) % 17;
480
 
481
  if (count) {
482
    Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
483
 
484
    Bit16u result_16 = (op1_16 >> count) | (getB_CF() << (16 - count)) |
485
                       (op1_16 << (17 - count));
486
 
487
    BX_WRITE_16BIT_REG(i->dst(), result_16);
488
 
489
    cf = (op1_16 >> (count - 1)) & 0x1;
490
    of = ((Bit16u)((result_16 << 1) ^ result_16) >> 15) & 0x1; // of = result15 ^ result14
491
    SET_FLAGS_OxxxxC(of, cf);
492
  }
493
 
494
  BX_NEXT_INSTR(i);
495
}
496
 
497
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EwM(bxInstruction_c *i)
498
{
499
  Bit16u result_16;
500
  unsigned count;
501
  unsigned of = 0, cf = 0;
502
 
503
  if (i->getIaOpcode() == BX_IA_SHL_Ew)
504
    count = CL;
505
  else
506
    count = i->Ib();
507
 
508
  count &= 0x1f; /* use only 5 LSB's */
509
 
510
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
511
  /* pointer, segment address pair */
512
  Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
513
 
514
  if (count) {
515
    if (count <= 16) {
516
      result_16 = (op1_16 << count);
517
      cf = (op1_16 >> (16 - count)) & 0x1;
518
      of = cf ^ (result_16 >> 15); // of = cf ^ result15
519
    }
520
    else {
521
      result_16 = 0;
522
    }
523
 
524
    write_RMW_virtual_word(result_16);
525
 
526
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
527
    SET_FLAGS_OxxxxC(of, cf);
528
  }
529
 
530
  BX_NEXT_INSTR(i);
531
}
532
 
533
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EwR(bxInstruction_c *i)
534
{
535
  Bit16u result_16;
536
  unsigned count;
537
  unsigned of = 0, cf = 0;
538
 
539
  if (i->getIaOpcode() == BX_IA_SHL_Ew)
540
    count = CL;
541
  else
542
    count = i->Ib();
543
 
544
  count &= 0x1f; /* use only 5 LSB's */
545
 
546
  if (count) {
547
    Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
548
 
549
    if (count <= 16) {
550
      result_16 = (op1_16 << count);
551
      cf = (op1_16 >> (16 - count)) & 0x1;
552
      of = cf ^ (result_16 >> 15); // of = cf ^ result15
553
    }
554
    else {
555
      result_16 = 0;
556
    }
557
 
558
    BX_WRITE_16BIT_REG(i->dst(), result_16);
559
 
560
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
561
    SET_FLAGS_OxxxxC(of, cf);
562
  }
563
 
564
  BX_NEXT_INSTR(i);
565
}
566
 
567
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EwM(bxInstruction_c *i)
568
{
569
  unsigned count;
570
  unsigned of, cf;
571
 
572
  if (i->getIaOpcode() == BX_IA_SHR_Ew)
573
    count = CL;
574
  else
575
    count = i->Ib();
576
 
577
  count &= 0x1f; /* use only 5 LSB's */
578
 
579
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
580
  /* pointer, segment address pair */
581
  Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
582
 
583
  if (count) {
584
    Bit16u result_16 = (op1_16 >> count);
585
 
586
    write_RMW_virtual_word(result_16);
587
 
588
    cf = (op1_16 >> (count - 1)) & 0x1;
589
    // note, that of == result15 if count == 1 and
590
    //            of == 0        if count >= 2
591
    of = ((Bit16u)((result_16 << 1) ^ result_16) >> 15) & 0x1;
592
 
593
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
594
    SET_FLAGS_OxxxxC(of, cf);
595
  }
596
 
597
  BX_NEXT_INSTR(i);
598
}
599
 
600
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EwR(bxInstruction_c *i)
601
{
602
  unsigned count;
603
  unsigned of, cf;
604
 
605
  if (i->getIaOpcode() == BX_IA_SHR_Ew)
606
    count = CL;
607
  else
608
    count = i->Ib();
609
 
610
  count &= 0x1f; /* use only 5 LSB's */
611
 
612
  if (count) {
613
    Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
614
    Bit16u result_16 = (op1_16 >> count);
615
    BX_WRITE_16BIT_REG(i->dst(), result_16);
616
 
617
    cf = (op1_16 >> (count - 1)) & 0x1;
618
    // note, that of == result15 if count == 1 and
619
    //            of == 0        if count >= 2
620
    of = ((Bit16u)((result_16 << 1) ^ result_16) >> 15) & 0x1;
621
 
622
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
623
    SET_FLAGS_OxxxxC(of, cf);
624
  }
625
 
626
  BX_NEXT_INSTR(i);
627
}
628
 
629
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EwM(bxInstruction_c *i)
630
{
631
  unsigned count, cf;
632
 
633
  if (i->getIaOpcode() == BX_IA_SAR_Ew)
634
    count = CL;
635
  else
636
    count = i->Ib();
637
 
638
  count &= 0x1f;  /* use only 5 LSB's */
639
 
640
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
641
  /* pointer, segment address pair */
642
  Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
643
 
644
  if (count) {
645
    Bit16u result_16 = ((Bit16s) op1_16) >> count;
646
 
647
    cf = (((Bit16s) op1_16) >> (count - 1)) & 0x1;
648
 
649
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
650
    /* signed overflow cannot happen in SAR instruction */
651
    SET_FLAGS_OxxxxC(0, cf);
652
 
653
    write_RMW_virtual_word(result_16);
654
  }
655
 
656
  BX_NEXT_INSTR(i);
657
}
658
 
659
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EwR(bxInstruction_c *i)
660
{
661
  unsigned count, cf;
662
 
663
  if (i->getIaOpcode() == BX_IA_SAR_Ew)
664
    count = CL;
665
  else
666
    count = i->Ib();
667
 
668
  count &= 0x1f;  /* use only 5 LSB's */
669
 
670
  if (count) {
671
    Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
672
    Bit16u result_16 = ((Bit16s) op1_16) >> count;
673
    BX_WRITE_16BIT_REG(i->dst(), result_16);
674
 
675
    cf = (((Bit16s) op1_16) >> (count - 1)) & 0x1;
676
 
677
    SET_FLAGS_OSZAPC_LOGIC_16(result_16);
678
    /* signed overflow cannot happen in SAR instruction */
679
    SET_FLAGS_OxxxxC(0, cf);
680
  }
681
 
682
  BX_NEXT_INSTR(i);
683
}

powered by: WebSVN 2.1.0

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