Revision b5b38f61 target-i386/op.c

b/target-i386/op.c
290 290
}
291 291
#endif
292 292

  
293
/* division, flags are undefined */
294

  
295
void OPPROTO op_divb_AL_T0(void)
296
{
297
    unsigned int num, den, q, r;
298

  
299
    num = (EAX & 0xffff);
300
    den = (T0 & 0xff);
301
    if (den == 0) {
302
        raise_exception(EXCP00_DIVZ);
303
    }
304
    q = (num / den);
305
    if (q > 0xff)
306
        raise_exception(EXCP00_DIVZ);
307
    q &= 0xff;
308
    r = (num % den) & 0xff;
309
    EAX = (EAX & ~0xffff) | (r << 8) | q;
310
}
311

  
312
void OPPROTO op_idivb_AL_T0(void)
313
{
314
    int num, den, q, r;
315

  
316
    num = (int16_t)EAX;
317
    den = (int8_t)T0;
318
    if (den == 0) {
319
        raise_exception(EXCP00_DIVZ);
320
    }
321
    q = (num / den);
322
    if (q != (int8_t)q)
323
        raise_exception(EXCP00_DIVZ);
324
    q &= 0xff;
325
    r = (num % den) & 0xff;
326
    EAX = (EAX & ~0xffff) | (r << 8) | q;
327
}
328

  
329
void OPPROTO op_divw_AX_T0(void)
330
{
331
    unsigned int num, den, q, r;
332

  
333
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
334
    den = (T0 & 0xffff);
335
    if (den == 0) {
336
        raise_exception(EXCP00_DIVZ);
337
    }
338
    q = (num / den);
339
    if (q > 0xffff)
340
        raise_exception(EXCP00_DIVZ);
341
    q &= 0xffff;
342
    r = (num % den) & 0xffff;
343
    EAX = (EAX & ~0xffff) | q;
344
    EDX = (EDX & ~0xffff) | r;
345
}
346

  
347
void OPPROTO op_idivw_AX_T0(void)
348
{
349
    int num, den, q, r;
350

  
351
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
352
    den = (int16_t)T0;
353
    if (den == 0) {
354
        raise_exception(EXCP00_DIVZ);
355
    }
356
    q = (num / den);
357
    if (q != (int16_t)q)
358
        raise_exception(EXCP00_DIVZ);
359
    q &= 0xffff;
360
    r = (num % den) & 0xffff;
361
    EAX = (EAX & ~0xffff) | q;
362
    EDX = (EDX & ~0xffff) | r;
363
}
364

  
365
#ifdef TARGET_X86_64
366
void OPPROTO op_divq_EAX_T0(void)
367
{
368
    helper_divq_EAX_T0();
369
}
370

  
371
void OPPROTO op_idivq_EAX_T0(void)
372
{
373
    helper_idivq_EAX_T0();
374
}
375
#endif
376

  
377 293
/* constant load & misc op */
378 294

  
379 295
/* XXX: consistent names */
......
423 339

  
424 340
#endif
425 341

  
426
void OPPROTO op_hlt(void)
427
{
428
    helper_hlt();
429
}
430

  
431
void OPPROTO op_monitor(void)
432
{
433
    helper_monitor();
434
}
435

  
436
void OPPROTO op_mwait(void)
437
{
438
    helper_mwait();
439
}
440

  
441
void OPPROTO op_debug(void)
442
{
443
    env->exception_index = EXCP_DEBUG;
444
    cpu_loop_exit();
445
}
446

  
447
void OPPROTO op_raise_interrupt(void)
448
{
449
    int intno, next_eip_addend;
450
    intno = PARAM1;
451
    next_eip_addend = PARAM2;
452
    raise_interrupt(intno, 1, 0, next_eip_addend);
453
}
454

  
455
void OPPROTO op_raise_exception(void)
456
{
457
    int exception_index;
458
    exception_index = PARAM1;
459
    raise_exception(exception_index);
460
}
461

  
462 342
void OPPROTO op_into(void)
463 343
{
464 344
    int eflags;
......
469 349
    FORCE_RET();
470 350
}
471 351

  
472
void OPPROTO op_cli(void)
473
{
474
    env->eflags &= ~IF_MASK;
475
}
476

  
477
void OPPROTO op_sti(void)
478
{
479
    env->eflags |= IF_MASK;
480
}
481

  
482
void OPPROTO op_set_inhibit_irq(void)
483
{
484
    env->hflags |= HF_INHIBIT_IRQ_MASK;
485
}
486

  
487
void OPPROTO op_reset_inhibit_irq(void)
488
{
489
    env->hflags &= ~HF_INHIBIT_IRQ_MASK;
490
}
491

  
492
void OPPROTO op_rsm(void)
493
{
494
    helper_rsm();
495
}
496

  
497
#if 0
498
/* vm86plus instructions */
499
void OPPROTO op_cli_vm(void)
500
{
501
    env->eflags &= ~VIF_MASK;
502
}
503

  
504
void OPPROTO op_sti_vm(void)
505
{
506
    env->eflags |= VIF_MASK;
507
    if (env->eflags & VIP_MASK) {
508
        EIP = PARAM1;
509
        raise_exception(EXCP0D_GPF);
510
    }
511
    FORCE_RET();
512
}
513
#endif
514

  
515
void OPPROTO op_boundw(void)
516
{
517
    int low, high, v;
518
    low = ldsw(A0);
519
    high = ldsw(A0 + 2);
520
    v = (int16_t)T0;
521
    if (v < low || v > high) {
522
        raise_exception(EXCP05_BOUND);
523
    }
524
    FORCE_RET();
525
}
526

  
527
void OPPROTO op_boundl(void)
528
{
529
    int low, high, v;
530
    low = ldl(A0);
531
    high = ldl(A0 + 4);
532
    v = T0;
533
    if (v < low || v > high) {
534
        raise_exception(EXCP05_BOUND);
535
    }
536
    FORCE_RET();
537
}
538

  
539 352
void OPPROTO op_cmpxchg8b(void)
540 353
{
541 354
    helper_cmpxchg8b();
542 355
}
543 356

  
544
void OPPROTO op_single_step(void)
545
{
546
    helper_single_step();
547
}
548

  
549 357
/* multiple size ops */
550 358

  
551 359
#define ldul ldl
......
680 488
}
681 489
#endif
682 490

  
683
void OPPROTO op_rdtsc(void)
684
{
685
    helper_rdtsc();
686
}
687

  
688
void OPPROTO op_rdpmc(void)
689
{
690
    helper_rdpmc();
691
}
692

  
693
void OPPROTO op_cpuid(void)
694
{
695
    helper_cpuid();
696
}
697

  
698
void OPPROTO op_enter_level(void)
699
{
700
    helper_enter_level(PARAM1, PARAM2);
701
}
702

  
703
#ifdef TARGET_X86_64
704
void OPPROTO op_enter64_level(void)
705
{
706
    helper_enter64_level(PARAM1, PARAM2);
707
}
708
#endif
709

  
710
void OPPROTO op_sysenter(void)
711
{
712
    helper_sysenter();
713
}
714

  
715
void OPPROTO op_sysexit(void)
716
{
717
    helper_sysexit();
718
}
719

  
720
#ifdef TARGET_X86_64
721
void OPPROTO op_syscall(void)
722
{
723
    helper_syscall(PARAM1);
724
}
725

  
726
void OPPROTO op_sysret(void)
727
{
728
    helper_sysret(PARAM1);
729
}
730
#endif
731

  
732
void OPPROTO op_rdmsr(void)
733
{
734
    helper_rdmsr();
735
}
736

  
737
void OPPROTO op_wrmsr(void)
738
{
739
    helper_wrmsr();
740
}
741

  
742 491
/* bcd */
743 492

  
744
/* XXX: exception */
745 493
void OPPROTO op_aam(void)
746 494
{
747
    int base = PARAM1;
748
    int al, ah;
749
    al = EAX & 0xff;
750
    ah = al / base;
751
    al = al % base;
752
    EAX = (EAX & ~0xffff) | al | (ah << 8);
753
    CC_DST = al;
495
    helper_aam(PARAM1);
754 496
}
755 497

  
756 498
void OPPROTO op_aad(void)
757 499
{
758
    int base = PARAM1;
759
    int al, ah;
760
    al = EAX & 0xff;
761
    ah = (EAX >> 8) & 0xff;
762
    al = ((ah * base) + al) & 0xff;
763
    EAX = (EAX & ~0xffff) | al;
764
    CC_DST = al;
500
    helper_aad(PARAM1);
765 501
}
766 502

  
767 503
void OPPROTO op_aaa(void)
768 504
{
769
    int icarry;
770
    int al, ah, af;
771
    int eflags;
772

  
773
    eflags = cc_table[CC_OP].compute_all();
774
    af = eflags & CC_A;
775
    al = EAX & 0xff;
776
    ah = (EAX >> 8) & 0xff;
777

  
778
    icarry = (al > 0xf9);
779
    if (((al & 0x0f) > 9 ) || af) {
780
        al = (al + 6) & 0x0f;
781
        ah = (ah + 1 + icarry) & 0xff;
782
        eflags |= CC_C | CC_A;
783
    } else {
784
        eflags &= ~(CC_C | CC_A);
785
        al &= 0x0f;
786
    }
787
    EAX = (EAX & ~0xffff) | al | (ah << 8);
788
    CC_SRC = eflags;
789
    FORCE_RET();
505
    helper_aaa();
790 506
}
791 507

  
792 508
void OPPROTO op_aas(void)
793 509
{
794
    int icarry;
795
    int al, ah, af;
796
    int eflags;
797

  
798
    eflags = cc_table[CC_OP].compute_all();
799
    af = eflags & CC_A;
800
    al = EAX & 0xff;
801
    ah = (EAX >> 8) & 0xff;
802

  
803
    icarry = (al < 6);
804
    if (((al & 0x0f) > 9 ) || af) {
805
        al = (al - 6) & 0x0f;
806
        ah = (ah - 1 - icarry) & 0xff;
807
        eflags |= CC_C | CC_A;
808
    } else {
809
        eflags &= ~(CC_C | CC_A);
810
        al &= 0x0f;
811
    }
812
    EAX = (EAX & ~0xffff) | al | (ah << 8);
813
    CC_SRC = eflags;
814
    FORCE_RET();
510
    helper_aas();
815 511
}
816 512

  
817 513
void OPPROTO op_daa(void)
818 514
{
819
    int al, af, cf;
820
    int eflags;
821

  
822
    eflags = cc_table[CC_OP].compute_all();
823
    cf = eflags & CC_C;
824
    af = eflags & CC_A;
825
    al = EAX & 0xff;
826

  
827
    eflags = 0;
828
    if (((al & 0x0f) > 9 ) || af) {
829
        al = (al + 6) & 0xff;
830
        eflags |= CC_A;
831
    }
832
    if ((al > 0x9f) || cf) {
833
        al = (al + 0x60) & 0xff;
834
        eflags |= CC_C;
835
    }
836
    EAX = (EAX & ~0xff) | al;
837
    /* well, speed is not an issue here, so we compute the flags by hand */
838
    eflags |= (al == 0) << 6; /* zf */
839
    eflags |= parity_table[al]; /* pf */
840
    eflags |= (al & 0x80); /* sf */
841
    CC_SRC = eflags;
842
    FORCE_RET();
515
    helper_daa();
843 516
}
844 517

  
845 518
void OPPROTO op_das(void)
846 519
{
847
    int al, al1, af, cf;
848
    int eflags;
849

  
850
    eflags = cc_table[CC_OP].compute_all();
851
    cf = eflags & CC_C;
852
    af = eflags & CC_A;
853
    al = EAX & 0xff;
854

  
855
    eflags = 0;
856
    al1 = al;
857
    if (((al & 0x0f) > 9 ) || af) {
858
        eflags |= CC_A;
859
        if (al < 6 || cf)
860
            eflags |= CC_C;
861
        al = (al - 6) & 0xff;
862
    }
863
    if ((al1 > 0x99) || cf) {
864
        al = (al - 0x60) & 0xff;
865
        eflags |= CC_C;
866
    }
867
    EAX = (EAX & ~0xff) | al;
868
    /* well, speed is not an issue here, so we compute the flags by hand */
869
    eflags |= (al == 0) << 6; /* zf */
870
    eflags |= parity_table[al]; /* pf */
871
    eflags |= (al & 0x80); /* sf */
872
    CC_SRC = eflags;
873
    FORCE_RET();
520
    helper_das();
874 521
}
875 522

  
876 523
/* segment handling */
......
878 525
/* never use it with R_CS */
879 526
void OPPROTO op_movl_seg_T0(void)
880 527
{
881
    load_seg(PARAM1, T0);
528
    helper_load_seg(PARAM1, T0);
882 529
}
883 530

  
884 531
/* faster VM86 version */
......
901 548

  
902 549
void OPPROTO op_lsl(void)
903 550
{
904
    helper_lsl();
551
    helper_lsl(T0);
905 552
}
906 553

  
907 554
void OPPROTO op_lar(void)
908 555
{
909
    helper_lar();
556
    helper_lar(T0);
910 557
}
911 558

  
912 559
void OPPROTO op_verr(void)
913 560
{
914
    helper_verr();
561
    helper_verr(T0);
915 562
}
916 563

  
917 564
void OPPROTO op_verw(void)
918 565
{
919
    helper_verw();
566
    helper_verw(T0);
920 567
}
921 568

  
922 569
void OPPROTO op_arpl(void)
......
969 616
    helper_lret_protected(PARAM1, PARAM2);
970 617
}
971 618

  
972
void OPPROTO op_lldt_T0(void)
973
{
974
    helper_lldt_T0();
975
}
976

  
977
void OPPROTO op_ltr_T0(void)
978
{
979
    helper_ltr_T0();
980
}
981

  
982 619
/* CR registers access. */
983 620
void OPPROTO op_movl_crN_T0(void)
984 621
{
......
1046 683
    helper_movl_crN_T0(0);
1047 684
}
1048 685

  
1049
void OPPROTO op_invlpg_A0(void)
1050
{
1051
    helper_invlpg(A0);
1052
}
1053

  
1054 686
void OPPROTO op_movl_T0_env(void)
1055 687
{
1056 688
    T0 = *(uint32_t *)((char *)env + PARAM1);
......
1282 914
}
1283 915
#endif
1284 916

  
1285
void OPPROTO op_cld(void)
1286
{
1287
    DF = 1;
1288
}
1289

  
1290
void OPPROTO op_std(void)
1291
{
1292
    DF = -1;
1293
}
1294

  
1295 917
void OPPROTO op_clc(void)
1296 918
{
1297 919
    int eflags;
......
1422 1044
{
1423 1045
    T0 = 0;
1424 1046
}
1425

  
1426
/* Secure Virtual Machine ops */
1427

  
1428
void OPPROTO op_vmrun(void)
1429
{
1430
    helper_vmrun(EAX);
1431
}
1432

  
1433
void OPPROTO op_vmmcall(void)
1434
{
1435
    helper_vmmcall();
1436
}
1437

  
1438
void OPPROTO op_vmload(void)
1439
{
1440
    helper_vmload(EAX);
1441
}
1442

  
1443
void OPPROTO op_vmsave(void)
1444
{
1445
    helper_vmsave(EAX);
1446
}
1447

  
1448
void OPPROTO op_stgi(void)
1449
{
1450
    helper_stgi();
1451
}
1452

  
1453
void OPPROTO op_clgi(void)
1454
{
1455
    helper_clgi();
1456
}
1457

  
1458
void OPPROTO op_skinit(void)
1459
{
1460
    helper_skinit();
1461
}
1462

  
1463
void OPPROTO op_invlpga(void)
1464
{
1465
    helper_invlpga();
1466
}

Also available in: Unified diff