197
220
BX_CPU_THIS_PTR show_flag |= Flag_call;
223
Bit16u disp16 = i->Iw();
224
Bit16u cs_raw = i->Iw2();
203
BX_CPU_THIS_PTR speculative_rsp = 1;
204
BX_CPU_THIS_PTR prev_rsp = RSP;
206
228
if (protected_mode()) {
207
BX_CPU_THIS_PTR call_protected(i, cs_raw, disp16);
229
call_protected(i, cs_raw, disp16);
211
233
push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
212
push_16((Bit16u) EIP);
236
// CS.LIMIT can't change when in real/v8086 mode
237
if (disp16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
238
BX_ERROR(("CALL16_Ap: instruction pointer not within code segment limits"));
239
exception(BX_GP_EXCEPTION, 0, 0);
214
242
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
215
243
EIP = (Bit32u) disp16;
219
BX_CPU_THIS_PTR speculative_rsp = 0;
221
248
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
222
249
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
225
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EwM(bxInstruction_c *i)
227
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
230
BX_CPU_THIS_PTR show_flag |= Flag_call;
233
Bit16u op1_16 = read_virtual_word(i->seg(), RMAddr(i));
235
if (op1_16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
237
BX_ERROR(("CALL_Ew: IP out of CS limits!"));
238
exception(BX_GP_EXCEPTION, 0, 0);
244
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
247
252
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EwR(bxInstruction_c *i)
249
Bit16u op1_16 = BX_READ_16BIT_REG(i->rm());
254
Bit16u new_IP = BX_READ_16BIT_REG(i->rm());
252
257
BX_CPU_THIS_PTR show_flag |= Flag_call;
255
if (op1_16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
257
BX_ERROR(("CALL_Ew: IP out of CS limits!"));
258
exception(BX_GP_EXCEPTION, 0, 0);
262
/* push 16 bit EA of next instruction */
265
branch_near16(new_IP);
264
269
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
305
314
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_Jw(bxInstruction_c *i)
307
Bit32u new_EIP = EIP + (Bit32s) i->Id();
308
new_EIP &= 0x0000ffff;
310
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
312
BX_ERROR(("JMP_Jw: offset outside of CS limits"));
313
exception(BX_GP_EXCEPTION, 0, 0);
318
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_EIP);
316
Bit16u new_IP = IP + i->Iw();
317
branch_near16(new_IP);
318
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_IP);
321
321
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JO_Jw(bxInstruction_c *i)
324
Bit32u new_EIP = EIP + (Bit32s) i->Id();
325
new_EIP &= 0x0000ffff;
326
branch_near32(new_EIP);
327
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
331
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
324
Bit16u new_IP = IP + i->Iw();
325
branch_near16(new_IP);
326
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
328
#if BX_INSTRUMENTATION
330
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
334
335
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNO_Jw(bxInstruction_c *i)
336
337
if (! get_OF()) {
337
Bit32u new_EIP = EIP + (Bit32s) i->Id();
338
new_EIP &= 0x0000ffff;
339
branch_near32(new_EIP);
340
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
344
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
338
Bit16u new_IP = IP + i->Iw();
339
branch_near16(new_IP);
340
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
342
#if BX_INSTRUMENTATION
344
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
347
349
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JB_Jw(bxInstruction_c *i)
350
Bit32u new_EIP = EIP + (Bit32s) i->Id();
351
new_EIP &= 0x0000ffff;
352
branch_near32(new_EIP);
353
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
357
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
352
Bit16u new_IP = IP + i->Iw();
353
branch_near16(new_IP);
354
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
356
#if BX_INSTRUMENTATION
358
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
360
363
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNB_Jw(bxInstruction_c *i)
362
365
if (! get_CF()) {
363
Bit32u new_EIP = EIP + (Bit32s) i->Id();
364
new_EIP &= 0x0000ffff;
365
branch_near32(new_EIP);
366
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
370
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
366
Bit16u new_IP = IP + i->Iw();
367
branch_near16(new_IP);
368
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
370
#if BX_INSTRUMENTATION
372
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
373
377
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JZ_Jw(bxInstruction_c *i)
376
Bit32u new_EIP = EIP + (Bit32s) i->Id();
377
new_EIP &= 0x0000ffff;
378
branch_near32(new_EIP);
379
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
383
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
380
Bit16u new_IP = IP + i->Iw();
381
branch_near16(new_IP);
382
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
384
#if BX_INSTRUMENTATION
386
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
386
391
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNZ_Jw(bxInstruction_c *i)
388
393
if (! get_ZF()) {
389
Bit32u new_EIP = EIP + (Bit32s) i->Id();
390
new_EIP &= 0x0000ffff;
391
branch_near32(new_EIP);
392
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
396
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
394
Bit16u new_IP = IP + i->Iw();
395
branch_near16(new_IP);
396
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
398
#if BX_INSTRUMENTATION
400
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
399
405
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JBE_Jw(bxInstruction_c *i)
401
407
if (get_CF() || get_ZF()) {
402
Bit32u new_EIP = EIP + (Bit32s) i->Id();
403
new_EIP &= 0x0000ffff;
404
branch_near32(new_EIP);
405
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
409
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
408
Bit16u new_IP = IP + i->Iw();
409
branch_near16(new_IP);
410
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
412
#if BX_INSTRUMENTATION
414
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
412
419
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNBE_Jw(bxInstruction_c *i)
414
421
if (! (get_CF() || get_ZF())) {
415
Bit32u new_EIP = EIP + (Bit32s) i->Id();
416
new_EIP &= 0x0000ffff;
417
branch_near32(new_EIP);
418
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
422
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
422
Bit16u new_IP = IP + i->Iw();
423
branch_near16(new_IP);
424
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
426
#if BX_INSTRUMENTATION
428
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
425
433
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JS_Jw(bxInstruction_c *i)
428
Bit32u new_EIP = EIP + (Bit32s) i->Id();
429
new_EIP &= 0x0000ffff;
430
branch_near32(new_EIP);
431
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
435
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
436
Bit16u new_IP = IP + i->Iw();
437
branch_near16(new_IP);
438
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
440
#if BX_INSTRUMENTATION
442
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
438
447
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNS_Jw(bxInstruction_c *i)
440
449
if (! get_SF()) {
441
Bit32u new_EIP = EIP + (Bit32s) i->Id();
442
new_EIP &= 0x0000ffff;
443
branch_near32(new_EIP);
444
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
448
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
450
Bit16u new_IP = IP + i->Iw();
451
branch_near16(new_IP);
452
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
454
#if BX_INSTRUMENTATION
456
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
451
461
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JP_Jw(bxInstruction_c *i)
454
Bit32u new_EIP = EIP + (Bit32s) i->Id();
455
new_EIP &= 0x0000ffff;
456
branch_near32(new_EIP);
457
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
461
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
464
Bit16u new_IP = IP + i->Iw();
465
branch_near16(new_IP);
466
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
468
#if BX_INSTRUMENTATION
470
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
464
475
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNP_Jw(bxInstruction_c *i)
466
477
if (! get_PF()) {
467
Bit32u new_EIP = EIP + (Bit32s) i->Id();
468
new_EIP &= 0x0000ffff;
469
branch_near32(new_EIP);
470
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
474
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
478
Bit16u new_IP = IP + i->Iw();
479
branch_near16(new_IP);
480
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
482
#if BX_INSTRUMENTATION
484
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
477
489
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JL_Jw(bxInstruction_c *i)
479
491
if (getB_SF() != getB_OF()) {
480
Bit32u new_EIP = EIP + (Bit32s) i->Id();
481
new_EIP &= 0x0000ffff;
482
branch_near32(new_EIP);
483
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
487
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
492
Bit16u new_IP = IP + i->Iw();
493
branch_near16(new_IP);
494
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
496
#if BX_INSTRUMENTATION
498
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
490
503
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNL_Jw(bxInstruction_c *i)
492
505
if (getB_SF() == getB_OF()) {
493
Bit32u new_EIP = EIP + (Bit32s) i->Id();
494
new_EIP &= 0x0000ffff;
495
branch_near32(new_EIP);
496
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
500
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
506
Bit16u new_IP = IP + i->Iw();
507
branch_near16(new_IP);
508
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
510
#if BX_INSTRUMENTATION
512
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
503
517
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JLE_Jw(bxInstruction_c *i)
505
519
if (get_ZF() || (getB_SF() != getB_OF())) {
506
Bit32u new_EIP = EIP + (Bit32s) i->Id();
507
new_EIP &= 0x0000ffff;
508
branch_near32(new_EIP);
509
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
513
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
520
Bit16u new_IP = IP + i->Iw();
521
branch_near16(new_IP);
522
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
524
#if BX_INSTRUMENTATION
526
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
516
531
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNLE_Jw(bxInstruction_c *i)
518
533
if (! get_ZF() && (getB_SF() == getB_OF())) {
519
Bit32u new_EIP = EIP + (Bit32s) i->Id();
520
new_EIP &= 0x0000ffff;
521
branch_near32(new_EIP);
522
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
526
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
529
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EwM(bxInstruction_c *i)
531
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
533
Bit16u new_IP = read_virtual_word(i->seg(), RMAddr(i));
535
if (new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
537
BX_ERROR(("JMP_Ew: offset outside of CS limits"));
538
exception(BX_GP_EXCEPTION, 0, 0);
543
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_IP);
534
Bit16u new_IP = IP + i->Iw();
535
branch_near16(new_IP);
536
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
538
#if BX_INSTRUMENTATION
540
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
546
545
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EwR(bxInstruction_c *i)
548
547
Bit16u new_IP = BX_READ_16BIT_REG(i->rm());
550
if (new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
552
BX_ERROR(("JMP_Ew: offset outside of CS limits"));
553
exception(BX_GP_EXCEPTION, 0, 0);
548
branch_near16(new_IP);
558
549
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_IP);
615
cs_raw = pop_16(); // #SS has higher priority
616
616
flags = pop_16();
618
// CS.LIMIT can't change when in real/v8086 mode
619
if(ip > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
620
BX_ERROR(("IRET16: instruction pointer not within code segment limits"));
621
exception(BX_GP_EXCEPTION, 0, 0);
618
624
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
620
626
write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1);
623
BX_CPU_THIS_PTR speculative_rsp = 0;
625
631
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
626
632
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
635
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JCXZ_Jb(bxInstruction_c *i)
637
// it is impossible to get this instruction in long mode
638
BX_ASSERT(i->as64L() == 0);
648
Bit16u new_IP = IP + i->Iw();
649
branch_near16(new_IP);
650
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
652
#if BX_INSTRUMENTATION
654
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
660
// There is some weirdness in LOOP instructions definition. If an exception
661
// was generated during the instruction execution (for example #GP fault
662
// because EIP was beyond CS segment limits) CPU state should restore the
663
// state prior to instruction execution.
665
// The final point that we are not allowed to decrement ECX register before
666
// it is known that no exceptions can happen.
669
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPNE16_Jb(bxInstruction_c *i)
671
// it is impossible to get this instruction in long mode
672
BX_ASSERT(i->as64L() == 0);
678
if (count != 0 && (get_ZF()==0)) {
679
Bit16u new_IP = IP + i->Iw();
680
branch_near16(new_IP);
681
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
683
#if BX_INSTRUMENTATION
685
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
695
if (count != 0 && (get_ZF()==0)) {
696
Bit16u new_IP = IP + i->Iw();
697
branch_near16(new_IP);
698
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
700
#if BX_INSTRUMENTATION
702
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
710
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPE16_Jb(bxInstruction_c *i)
712
// it is impossible to get this instruction in long mode
713
BX_ASSERT(i->as64L() == 0);
719
if (count != 0 && get_ZF()) {
720
Bit16u new_IP = IP + i->Iw();
721
branch_near16(new_IP);
722
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
724
#if BX_INSTRUMENTATION
726
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
736
if (count != 0 && get_ZF()) {
737
Bit16u new_IP = IP + i->Iw();
738
branch_near16(new_IP);
739
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
741
#if BX_INSTRUMENTATION
743
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
751
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOP16_Jb(bxInstruction_c *i)
753
// it is impossible to get this instruction in long mode
754
BX_ASSERT(i->as64L() == 0);
761
Bit16u new_IP = IP + i->Iw();
762
branch_near16(new_IP);
763
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
765
#if BX_INSTRUMENTATION
767
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
778
Bit16u new_IP = IP + i->Iw();
779
branch_near16(new_IP);
780
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
782
#if BX_INSTRUMENTATION
784
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);