Revision e1f3808e target-m68k/helper.c

b/target-m68k/helper.c
27 27
#include "exec-all.h"
28 28
#include "qemu-common.h"
29 29

  
30
#include "helpers.h"
31

  
32
#define SIGNBIT (1u << 31)
33

  
30 34
enum m68k_cpuid {
31 35
    M68K_CPUID_M5206,
32 36
    M68K_CPUID_M5208,
......
121 125
CPUM68KState *cpu_m68k_init(const char *cpu_model)
122 126
{
123 127
    CPUM68KState *env;
128
    static int inited;
124 129

  
125 130
    env = malloc(sizeof(CPUM68KState));
126 131
    if (!env)
127 132
        return NULL;
128 133
    cpu_exec_init(env);
134
    if (!inited) {
135
        inited = 1;
136
        m68k_tcg_init();
137
    }
129 138

  
130 139
    env->cpu_model_str = cpu_model;
131 140

  
......
211 220
        if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
212 221
            flags |= CCF_V;
213 222
        break;
214
    case CC_OP_SHL:
215
        if (src >= 32) {
216
            SET_NZ(0);
217
        } else {
218
            tmp = dest << src;
219
            SET_NZ(tmp);
220
        }
221
        if (src && src <= 32 && (dest & (1 << (32 - src))))
222
            flags |= CCF_C;
223
        break;
224
    case CC_OP_SHR:
225
        if (src >= 32) {
226
            SET_NZ(0);
227
        } else {
228
            tmp = dest >> src;
229
            SET_NZ(tmp);
230
        }
231
        if (src && src <= 32 && ((dest >> (src - 1)) & 1))
232
            flags |= CCF_C;
233
        break;
234
    case CC_OP_SAR:
235
        if (src >= 32) {
236
            SET_NZ(-1);
237
        } else {
238
            tmp = (int32_t)dest >> src;
239
            SET_NZ(tmp);
240
        }
241
        if (src && src <= 32 && (((int32_t)dest >> (src - 1)) & 1))
223
    case CC_OP_SHIFT:
224
        SET_NZ(dest);
225
        if (src)
242 226
            flags |= CCF_C;
243 227
        break;
244 228
    default:
......
248 232
    env->cc_dest = flags;
249 233
}
250 234

  
251
float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1)
252
{
253
    /* ??? This may incorrectly raise exceptions.  */
254
    /* ??? Should flush denormals to zero.  */
255
    float64 res;
256
    res = float64_sub(src0, src1, &env->fp_status);
257
    if (float64_is_nan(res)) {
258
        /* +/-inf compares equal against itself, but sub returns nan.  */
259
        if (!float64_is_nan(src0)
260
            && !float64_is_nan(src1)) {
261
            res = float64_zero;
262
            if (float64_lt_quiet(src0, res, &env->fp_status))
263
                res = float64_chs(res);
264
        }
265
    }
266
    return res;
267
}
268

  
269
void helper_movec(CPUM68KState *env, int reg, uint32_t val)
235
void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
270 236
{
271 237
    switch (reg) {
272 238
    case 0x02: /* CACR */
......
286 252
    }
287 253
}
288 254

  
289
void m68k_set_macsr(CPUM68KState *env, uint32_t val)
255
void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
290 256
{
291 257
    uint32_t acc;
292 258
    int8_t exthigh;
......
376 342
}
377 343

  
378 344
#endif
345

  
346
uint32_t HELPER(bitrev)(uint32_t x)
347
{
348
    x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
349
    x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
350
    x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
351
    return bswap32(x);
352
}
353

  
354
uint32_t HELPER(ff1)(uint32_t x)
355
{
356
    int n;
357
    for (n = 32; x; n--)
358
        x >>= 1;
359
    return n;
360
}
361

  
362
uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
363
{
364
    /* The result has the opposite sign to the original value.  */
365
    if (ccr & CCF_V)
366
        val = (((int32_t)val) >> 31) ^ SIGNBIT;
367
    return val;
368
}
369

  
370
uint32_t HELPER(subx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
371
{
372
    uint32_t res;
373
    uint32_t old_flags;
374

  
375
    old_flags = env->cc_dest;
376
    if (env->cc_x) {
377
        env->cc_x = (op1 <= op2);
378
        env->cc_op = CC_OP_SUBX;
379
        res = op1 - (op2 + 1);
380
    } else {
381
        env->cc_x = (op1 < op2);
382
        env->cc_op = CC_OP_SUB;
383
        res = op1 - op2;
384
    }
385
    env->cc_dest = res;
386
    env->cc_src = op2;
387
    cpu_m68k_flush_flags(env, env->cc_op);
388
    /* !Z is sticky.  */
389
    env->cc_dest &= (old_flags | ~CCF_Z);
390
    return res;
391
}
392

  
393
uint32_t HELPER(addx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
394
{
395
    uint32_t res;
396
    uint32_t old_flags;
397

  
398
    old_flags = env->cc_dest;
399
    if (env->cc_x) {
400
        res = op1 + op2 + 1;
401
        env->cc_x = (res <= op2);
402
        env->cc_op = CC_OP_ADDX;
403
    } else {
404
        res = op1 + op2;
405
        env->cc_x = (res < op2);
406
        env->cc_op = CC_OP_ADD;
407
    }
408
    env->cc_dest = res;
409
    env->cc_src = op2;
410
    cpu_m68k_flush_flags(env, env->cc_op);
411
    /* !Z is sticky.  */
412
    env->cc_dest &= (old_flags | ~CCF_Z);
413
    return res;
414
}
415

  
416
uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
417
{
418
    return a < b;
419
}
420

  
421
uint32_t HELPER(btest)(uint32_t x)
422
{
423
    return x != 0;
424
}
425

  
426
void HELPER(set_sr)(CPUState *env, uint32_t val)
427
{
428
    env->sr = val & 0xffff;
429
    m68k_switch_sp(env);
430
}
431

  
432
uint32_t HELPER(shl_cc)(CPUState *env, uint32_t val, uint32_t shift)
433
{
434
    uint32_t result;
435
    uint32_t cf;
436

  
437
    shift &= 63;
438
    if (shift == 0) {
439
        result = val;
440
        cf = env->cc_src & CCF_C;
441
    } else if (shift < 32) {
442
        result = val << shift;
443
        cf = (val >> (32 - shift)) & 1;
444
    } else if (shift == 32) {
445
        result = 0;
446
        cf = val & 1;
447
    } else /* shift > 32 */ {
448
        result = 0;
449
        cf = 0;
450
    }
451
    env->cc_src = cf;
452
    env->cc_x = (cf != 0);
453
    env->cc_dest = result;
454
    return result;
455
}
456

  
457
uint32_t HELPER(shr_cc)(CPUState *env, uint32_t val, uint32_t shift)
458
{
459
    uint32_t result;
460
    uint32_t cf;
461

  
462
    shift &= 63;
463
    if (shift == 0) {
464
        result = val;
465
        cf = env->cc_src & CCF_C;
466
    } else if (shift < 32) {
467
        result = val >> shift;
468
        cf = (val >> (shift - 1)) & 1;
469
    } else if (shift == 32) {
470
        result = 0;
471
        cf = val >> 31;
472
    } else /* shift > 32 */ {
473
        result = 0;
474
        cf = 0;
475
    }
476
    env->cc_src = cf;
477
    env->cc_x = (cf != 0);
478
    env->cc_dest = result;
479
    return result;
480
}
481

  
482
uint32_t HELPER(sar_cc)(CPUState *env, uint32_t val, uint32_t shift)
483
{
484
    uint32_t result;
485
    uint32_t cf;
486

  
487
    shift &= 63;
488
    if (shift == 0) {
489
        result = val;
490
        cf = (env->cc_src & CCF_C) != 0;
491
    } else if (shift < 32) {
492
        result = (int32_t)val >> shift;
493
        cf = (val >> (shift - 1)) & 1;
494
    } else /* shift >= 32 */ {
495
        result = (int32_t)val >> 31;
496
        cf = val >> 31;
497
    }
498
    env->cc_src = cf;
499
    env->cc_x = cf;
500
    env->cc_dest = result;
501
    return result;
502
}
503

  
504
/* FPU helpers.  */
505
uint32_t HELPER(f64_to_i32)(CPUState *env, float64 val)
506
{
507
    return float64_to_int32(val, &env->fp_status);
508
}
509

  
510
float32 HELPER(f64_to_f32)(CPUState *env, float64 val)
511
{
512
    return float64_to_float32(val, &env->fp_status);
513
}
514

  
515
float64 HELPER(i32_to_f64)(CPUState *env, uint32_t val)
516
{
517
    return int32_to_float64(val, &env->fp_status);
518
}
519

  
520
float64 HELPER(f32_to_f64)(CPUState *env, float32 val)
521
{
522
    return float32_to_float64(val, &env->fp_status);
523
}
524

  
525
float64 HELPER(iround_f64)(CPUState *env, float64 val)
526
{
527
    return float64_round_to_int(val, &env->fp_status);
528
}
529

  
530
float64 HELPER(itrunc_f64)(CPUState *env, float64 val)
531
{
532
    return float64_trunc_to_int(val, &env->fp_status);
533
}
534

  
535
float64 HELPER(sqrt_f64)(CPUState *env, float64 val)
536
{
537
    return float64_sqrt(val, &env->fp_status);
538
}
539

  
540
float64 HELPER(abs_f64)(float64 val)
541
{
542
    return float64_abs(val);
543
}
544

  
545
float64 HELPER(chs_f64)(float64 val)
546
{
547
    return float64_chs(val);
548
}
549

  
550
float64 HELPER(add_f64)(CPUState *env, float64 a, float64 b)
551
{
552
    return float64_add(a, b, &env->fp_status);
553
}
554

  
555
float64 HELPER(sub_f64)(CPUState *env, float64 a, float64 b)
556
{
557
    return float64_sub(a, b, &env->fp_status);
558
}
559

  
560
float64 HELPER(mul_f64)(CPUState *env, float64 a, float64 b)
561
{
562
    return float64_mul(a, b, &env->fp_status);
563
}
564

  
565
float64 HELPER(div_f64)(CPUState *env, float64 a, float64 b)
566
{
567
    return float64_div(a, b, &env->fp_status);
568
}
569

  
570
float64 HELPER(sub_cmp_f64)(CPUState *env, float64 a, float64 b)
571
{
572
    /* ??? This may incorrectly raise exceptions.  */
573
    /* ??? Should flush denormals to zero.  */
574
    float64 res;
575
    res = float64_sub(a, b, &env->fp_status);
576
    if (float64_is_nan(res)) {
577
        /* +/-inf compares equal against itself, but sub returns nan.  */
578
        if (!float64_is_nan(a)
579
            && !float64_is_nan(b)) {
580
            res = float64_zero;
581
            if (float64_lt_quiet(a, res, &env->fp_status))
582
                res = float64_chs(res);
583
        }
584
    }
585
    return res;
586
}
587

  
588
uint32_t HELPER(compare_f64)(CPUState *env, float64 val)
589
{
590
    return float64_compare_quiet(val, float64_zero, &env->fp_status);
591
}
592

  
593
/* MAC unit.  */
594
/* FIXME: The MAC unit implementation is a bit of a mess.  Some helpers
595
   take values,  others take register numbers and manipulate the contents
596
   in-place.  */
597
void HELPER(mac_move)(CPUState *env, uint32_t dest, uint32_t src)
598
{
599
    uint32_t mask;
600
    env->macc[dest] = env->macc[src];
601
    mask = MACSR_PAV0 << dest;
602
    if (env->macsr & (MACSR_PAV0 << src))
603
        env->macsr |= mask;
604
    else
605
        env->macsr &= ~mask;
606
}
607

  
608
uint64_t HELPER(macmuls)(CPUState *env, uint32_t op1, uint32_t op2)
609
{
610
    int64_t product;
611
    int64_t res;
612

  
613
    product = (uint64_t)op1 * op2;
614
    res = (product << 24) >> 24;
615
    if (res != product) {
616
        env->macsr |= MACSR_V;
617
        if (env->macsr & MACSR_OMC) {
618
            /* Make sure the accumulate operation overflows.  */
619
            if (product < 0)
620
                res = ~(1ll << 50);
621
            else
622
                res = 1ll << 50;
623
        }
624
    }
625
    return res;
626
}
627

  
628
uint64_t HELPER(macmulu)(CPUState *env, uint32_t op1, uint32_t op2)
629
{
630
    uint64_t product;
631

  
632
    product = (uint64_t)op1 * op2;
633
    if (product & (0xffffffull << 40)) {
634
        env->macsr |= MACSR_V;
635
        if (env->macsr & MACSR_OMC) {
636
            /* Make sure the accumulate operation overflows.  */
637
            product = 1ll << 50;
638
        } else {
639
            product &= ((1ull << 40) - 1);
640
        }
641
    }
642
    return product;
643
}
644

  
645
uint64_t HELPER(macmulf)(CPUState *env, uint32_t op1, uint32_t op2)
646
{
647
    uint64_t product;
648
    uint32_t remainder;
649

  
650
    product = (uint64_t)op1 * op2;
651
    if (env->macsr & MACSR_RT) {
652
        remainder = product & 0xffffff;
653
        product >>= 24;
654
        if (remainder > 0x800000)
655
            product++;
656
        else if (remainder == 0x800000)
657
            product += (product & 1);
658
    } else {
659
        product >>= 24;
660
    }
661
    return product;
662
}
663

  
664
void HELPER(macsats)(CPUState *env, uint32_t acc)
665
{
666
    int64_t tmp;
667
    int64_t result;
668
    tmp = env->macc[acc];
669
    result = ((tmp << 16) >> 16);
670
    if (result != tmp) {
671
        env->macsr |= MACSR_V;
672
    }
673
    if (env->macsr & MACSR_V) {
674
        env->macsr |= MACSR_PAV0 << acc;
675
        if (env->macsr & MACSR_OMC) {
676
            /* The result is saturated to 32 bits, despite overflow occuring
677
               at 48 bits.  Seems weird, but that's what the hardware docs
678
               say.  */
679
            result = (result >> 63) ^ 0x7fffffff;
680
        }
681
    }
682
    env->macc[acc] = result;
683
}
684

  
685
void HELPER(macsatu)(CPUState *env, uint32_t acc)
686
{
687
    uint64_t val;
688

  
689
    val = env->macc[acc];
690
    if (val & (0xffffull << 48)) {
691
        env->macsr |= MACSR_V;
692
    }
693
    if (env->macsr & MACSR_V) {
694
        env->macsr |= MACSR_PAV0 << acc;
695
        if (env->macsr & MACSR_OMC) {
696
            if (val > (1ull << 53))
697
                val = 0;
698
            else
699
                val = (1ull << 48) - 1;
700
        } else {
701
            val &= ((1ull << 48) - 1);
702
        }
703
    }
704
    env->macc[acc] = val;
705
}
706

  
707
void HELPER(macsatf)(CPUState *env, uint32_t acc)
708
{
709
    int64_t sum;
710
    int64_t result;
711

  
712
    sum = env->macc[acc];
713
    result = (sum << 16) >> 16;
714
    if (result != sum) {
715
        env->macsr |= MACSR_V;
716
    }
717
    if (env->macsr & MACSR_V) {
718
        env->macsr |= MACSR_PAV0 << acc;
719
        if (env->macsr & MACSR_OMC) {
720
            result = (result >> 63) ^ 0x7fffffffffffll;
721
        }
722
    }
723
    env->macc[acc] = result;
724
}
725

  
726
void HELPER(mac_set_flags)(CPUState *env, uint32_t acc)
727
{
728
    uint64_t val;
729
    val = env->macc[acc];
730
    if (val == 0)
731
        env->macsr |= MACSR_Z;
732
    else if (val & (1ull << 47));
733
        env->macsr |= MACSR_N;
734
    if (env->macsr & (MACSR_PAV0 << acc)) {
735
        env->macsr |= MACSR_V;
736
    }
737
    if (env->macsr & MACSR_FI) {
738
        val = ((int64_t)val) >> 40;
739
        if (val != 0 && val != -1)
740
            env->macsr |= MACSR_EV;
741
    } else if (env->macsr & MACSR_SU) {
742
        val = ((int64_t)val) >> 32;
743
        if (val != 0 && val != -1)
744
            env->macsr |= MACSR_EV;
745
    } else {
746
        if ((val >> 32) != 0)
747
            env->macsr |= MACSR_EV;
748
    }
749
}
750

  
751
void HELPER(flush_flags)(CPUState *env, uint32_t cc_op)
752
{
753
    cpu_m68k_flush_flags(env, cc_op);
754
}
755

  
756
uint32_t HELPER(get_macf)(CPUState *env, uint64_t val)
757
{
758
    int rem;
759
    uint32_t result;
760

  
761
    if (env->macsr & MACSR_SU) {
762
        /* 16-bit rounding.  */
763
        rem = val & 0xffffff;
764
        val = (val >> 24) & 0xffffu;
765
        if (rem > 0x800000)
766
            val++;
767
        else if (rem == 0x800000)
768
            val += (val & 1);
769
    } else if (env->macsr & MACSR_RT) {
770
        /* 32-bit rounding.  */
771
        rem = val & 0xff;
772
        val >>= 8;
773
        if (rem > 0x80)
774
            val++;
775
        else if (rem == 0x80)
776
            val += (val & 1);
777
    } else {
778
        /* No rounding.  */
779
        val >>= 8;
780
    }
781
    if (env->macsr & MACSR_OMC) {
782
        /* Saturate.  */
783
        if (env->macsr & MACSR_SU) {
784
            if (val != (uint16_t) val) {
785
                result = ((val >> 63) ^ 0x7fff) & 0xffff;
786
            } else {
787
                result = val & 0xffff;
788
            }
789
        } else {
790
            if (val != (uint32_t)val) {
791
                result = ((uint32_t)(val >> 63) & 0x7fffffff);
792
            } else {
793
                result = (uint32_t)val;
794
            }
795
        }
796
    } else {
797
        /* No saturation.  */
798
        if (env->macsr & MACSR_SU) {
799
            result = val & 0xffff;
800
        } else {
801
            result = (uint32_t)val;
802
        }
803
    }
804
    return result;
805
}
806

  
807
uint32_t HELPER(get_macs)(uint64_t val)
808
{
809
    if (val == (int32_t)val) {
810
        return (int32_t)val;
811
    } else {
812
        return (val >> 61) ^ ~SIGNBIT;
813
    }
814
}
815

  
816
uint32_t HELPER(get_macu)(uint64_t val)
817
{
818
    if ((val >> 32) == 0) {
819
        return (uint32_t)val;
820
    } else {
821
        return 0xffffffffu;
822
    }
823
}
824

  
825
uint32_t HELPER(get_mac_extf)(CPUState *env, uint32_t acc)
826
{
827
    uint32_t val;
828
    val = env->macc[acc] & 0x00ff;
829
    val = (env->macc[acc] >> 32) & 0xff00;
830
    val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
831
    val |= (env->macc[acc + 1] >> 16) & 0xff000000;
832
    return val;
833
}
834

  
835
uint32_t HELPER(get_mac_exti)(CPUState *env, uint32_t acc)
836
{
837
    uint32_t val;
838
    val = (env->macc[acc] >> 32) & 0xffff;
839
    val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
840
    return val;
841
}
842

  
843
void HELPER(set_mac_extf)(CPUState *env, uint32_t val, uint32_t acc)
844
{
845
    int64_t res;
846
    int32_t tmp;
847
    res = env->macc[acc] & 0xffffffff00ull;
848
    tmp = (int16_t)(val & 0xff00);
849
    res |= ((int64_t)tmp) << 32;
850
    res |= val & 0xff;
851
    env->macc[acc] = res;
852
    res = env->macc[acc + 1] & 0xffffffff00ull;
853
    tmp = (val & 0xff000000);
854
    res |= ((int64_t)tmp) << 16;
855
    res |= (val >> 16) & 0xff;
856
    env->macc[acc + 1] = res;
857
}
858

  
859
void HELPER(set_mac_exts)(CPUState *env, uint32_t val, uint32_t acc)
860
{
861
    int64_t res;
862
    int32_t tmp;
863
    res = (uint32_t)env->macc[acc];
864
    tmp = (int16_t)val;
865
    res |= ((int64_t)tmp) << 32;
866
    env->macc[acc] = res;
867
    res = (uint32_t)env->macc[acc + 1];
868
    tmp = val & 0xffff0000;
869
    res |= (int64_t)tmp << 16;
870
    env->macc[acc + 1] = res;
871
}
872

  
873
void HELPER(set_mac_extu)(CPUState *env, uint32_t val, uint32_t acc)
874
{
875
    uint64_t res;
876
    res = (uint32_t)env->macc[acc];
877
    res |= ((uint64_t)(val & 0xffff)) << 32;
878
    env->macc[acc] = res;
879
    res = (uint32_t)env->macc[acc + 1];
880
    res |= (uint64_t)(val & 0xffff0000) << 16;
881
    env->macc[acc + 1] = res;
882
}

Also available in: Unified diff