Revision 81ad8ba2 target-sparc/op_helper.c

b/target-sparc/op_helper.c
137 137
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
138 138
#endif
139 139

  
140
#if defined(CONFIG_USER_ONLY)
141
void helper_ld_asi(int asi, int size, int sign)
142
{
143
}
144

  
145
void helper_st_asi(int asi, int size, int sign)
146
{
147
}
148
#else
149 140
#ifndef TARGET_SPARC64
141
#ifndef CONFIG_USER_ONLY
150 142
void helper_ld_asi(int asi, int size, int sign)
151 143
{
152 144
    uint32_t ret = 0;
......
200 192
            break;
201 193
        }
202 194
        break;
195
    case 0xa: /* User data access */
196
        switch(size) {
197
        case 1:
198
            ret = ldub_user(T0);
199
            break;
200
        case 2:
201
            ret = lduw_user(T0 & ~1);
202
            break;
203
        default:
204
        case 4:
205
            ret = ldl_user(T0 & ~3);
206
            break;
207
        case 8:
208
            ret = ldl_user(T0 & ~3);
209
            T0 = ldl_user((T0 + 4) & ~3);
210
            break;
211
        }
212
        break;
213
    case 0xb: /* Supervisor data access */
214
        switch(size) {
215
        case 1:
216
            ret = ldub_kernel(T0);
217
            break;
218
        case 2:
219
            ret = lduw_kernel(T0 & ~1);
220
            break;
221
        default:
222
        case 4:
223
            ret = ldl_kernel(T0 & ~3);
224
            break;
225
        case 8:
226
            ret = ldl_kernel(T0 & ~3);
227
            T0 = ldl_kernel((T0 + 4) & ~3);
228
            break;
229
        }
230
        break;
203 231
    case 0xc: /* I-cache tag */
204 232
    case 0xd: /* I-cache data */
205 233
    case 0xe: /* D-cache tag */
......
253 281
        ret = 0;
254 282
        break;
255 283
    }
256
    T1 = ret;
284
    if (sign) {
285
        switch(size) {
286
        case 1:
287
            T1 = (int8_t) ret;
288
        case 2:
289
            T1 = (int16_t) ret;
290
        default:
291
            T1 = ret;
292
            break;
293
        }
294
    }
295
    else
296
        T1 = ret;
257 297
}
258 298

  
259
void helper_st_asi(int asi, int size, int sign)
299
void helper_st_asi(int asi, int size)
260 300
{
261 301
    switch(asi) {
262 302
    case 2: /* SuperSparc MXCC registers */
......
325 365
#endif
326 366
            return;
327 367
        }
368
    case 0xa: /* User data access */
369
        switch(size) {
370
        case 1:
371
            stb_user(T0, T1);
372
            break;
373
        case 2:
374
            stw_user(T0 & ~1, T1);
375
            break;
376
        default:
377
        case 4:
378
            stl_user(T0 & ~3, T1);
379
            break;
380
        case 8:
381
            stl_user(T0 & ~3, T1);
382
            stl_user((T0 + 4) & ~3, T2);
383
            break;
384
        }
385
        break;
386
    case 0xb: /* Supervisor data access */
387
        switch(size) {
388
        case 1:
389
            stb_kernel(T0, T1);
390
            break;
391
        case 2:
392
            stw_kernel(T0 & ~1, T1);
393
            break;
394
        default:
395
        case 4:
396
            stl_kernel(T0 & ~3, T1);
397
            break;
398
        case 8:
399
            stl_kernel(T0 & ~3, T1);
400
            stl_kernel((T0 + 4) & ~3, T2);
401
            break;
402
        }
403
        break;
328 404
    case 0xc: /* I-cache tag */
329 405
    case 0xd: /* I-cache data */
330 406
    case 0xe: /* D-cache tag */
......
422 498
    }
423 499
}
424 500

  
425
#else
501
#endif /* CONFIG_USER_ONLY */
502
#else /* TARGET_SPARC64 */
503

  
504
#ifdef CONFIG_USER_ONLY
505
void helper_ld_asi(int asi, int size, int sign)
506
{
507
    uint64_t ret = 0;
508

  
509
    if (asi < 0x80)
510
        raise_exception(TT_PRIV_ACT);
511

  
512
    switch (asi) {
513
    case 0x80: // Primary
514
    case 0x82: // Primary no-fault
515
    case 0x88: // Primary LE
516
    case 0x8a: // Primary no-fault LE
517
        {
518
            switch(size) {
519
            case 1:
520
                ret = ldub_raw(T0);
521
                break;
522
            case 2:
523
                ret = lduw_raw(T0 & ~1);
524
                break;
525
            case 4:
526
                ret = ldl_raw(T0 & ~3);
527
                break;
528
            default:
529
            case 8:
530
                ret = ldq_raw(T0 & ~7);
531
                break;
532
            }
533
        }
534
        break;
535
    case 0x81: // Secondary
536
    case 0x83: // Secondary no-fault
537
    case 0x89: // Secondary LE
538
    case 0x8b: // Secondary no-fault LE
539
        // XXX
540
        break;
541
    default:
542
        break;
543
    }
544

  
545
    /* Convert from little endian */
546
    switch (asi) {
547
    case 0x88: // Primary LE
548
    case 0x89: // Secondary LE
549
    case 0x8a: // Primary no-fault LE
550
    case 0x8b: // Secondary no-fault LE
551
        switch(size) {
552
        case 2:
553
            ret = bswap16(ret);
554
        case 4:
555
            ret = bswap32(ret);
556
        case 8:
557
            ret = bswap64(ret);
558
        default:
559
            break;
560
        }
561
    default:
562
        break;
563
    }
564

  
565
    /* Convert to signed number */
566
    if (sign) {
567
        switch(size) {
568
        case 1:
569
            ret = (int8_t) ret;
570
        case 2:
571
            ret = (int16_t) ret;
572
        case 4:
573
            ret = (int32_t) ret;
574
        default:
575
            break;
576
        }
577
    }
578
    T1 = ret;
579
}
580

  
581
void helper_st_asi(int asi, int size)
582
{
583
    if (asi < 0x80)
584
        raise_exception(TT_PRIV_ACT);
585

  
586
    /* Convert to little endian */
587
    switch (asi) {
588
    case 0x88: // Primary LE
589
    case 0x89: // Secondary LE
590
        switch(size) {
591
        case 2:
592
            T0 = bswap16(T0);
593
        case 4:
594
            T0 = bswap32(T0);
595
        case 8:
596
            T0 = bswap64(T0);
597
        default:
598
            break;
599
        }
600
    default:
601
        break;
602
    }
603

  
604
    switch(asi) {
605
    case 0x80: // Primary
606
    case 0x88: // Primary LE
607
        {
608
            switch(size) {
609
            case 1:
610
                stb_raw(T0, T1);
611
                break;
612
            case 2:
613
                stw_raw(T0 & ~1, T1);
614
                break;
615
            case 4:
616
                stl_raw(T0 & ~3, T1);
617
                break;
618
            case 8:
619
            default:
620
                stq_raw(T0 & ~7, T1);
621
                break;
622
            }
623
        }
624
        break;
625
    case 0x81: // Secondary
626
    case 0x89: // Secondary LE
627
        // XXX
628
        return;
629

  
630
    case 0x82: // Primary no-fault, RO
631
    case 0x83: // Secondary no-fault, RO
632
    case 0x8a: // Primary no-fault LE, RO
633
    case 0x8b: // Secondary no-fault LE, RO
634
    default:
635
        do_unassigned_access(T0, 1, 0, 1);
636
        return;
637
    }
638
}
639

  
640
#else /* CONFIG_USER_ONLY */
426 641

  
427 642
void helper_ld_asi(int asi, int size, int sign)
428 643
{
......
432 647
        raise_exception(TT_PRIV_ACT);
433 648

  
434 649
    switch (asi) {
650
    case 0x10: // As if user primary
651
    case 0x18: // As if user primary LE
652
    case 0x80: // Primary
653
    case 0x82: // Primary no-fault
654
    case 0x88: // Primary LE
655
    case 0x8a: // Primary no-fault LE
656
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
657
            switch(size) {
658
            case 1:
659
                ret = ldub_kernel(T0);
660
                break;
661
            case 2:
662
                ret = lduw_kernel(T0 & ~1);
663
                break;
664
            case 4:
665
                ret = ldl_kernel(T0 & ~3);
666
                break;
667
            default:
668
            case 8:
669
                ret = ldq_kernel(T0 & ~7);
670
                break;
671
            }
672
        } else {
673
            switch(size) {
674
            case 1:
675
                ret = ldub_user(T0);
676
                break;
677
            case 2:
678
                ret = lduw_user(T0 & ~1);
679
                break;
680
            case 4:
681
                ret = ldl_user(T0 & ~3);
682
                break;
683
            default:
684
            case 8:
685
                ret = ldq_user(T0 & ~7);
686
                break;
687
            }
688
        }
689
        break;
435 690
    case 0x14: // Bypass
436 691
    case 0x15: // Bypass, non-cacheable
692
    case 0x1c: // Bypass LE
693
    case 0x1d: // Bypass, non-cacheable LE
437 694
        {
438 695
            switch(size) {
439 696
            case 1:
......
454 711
        }
455 712
    case 0x04: // Nucleus
456 713
    case 0x0c: // Nucleus Little Endian (LE)
457
    case 0x10: // As if user primary
458 714
    case 0x11: // As if user secondary
459
    case 0x18: // As if user primary LE
460 715
    case 0x19: // As if user secondary LE
461
    case 0x1c: // Bypass LE
462
    case 0x1d: // Bypass, non-cacheable LE
463 716
    case 0x24: // Nucleus quad LDD 128 bit atomic
464 717
    case 0x2c: // Nucleus quad LDD 128 bit atomic
465 718
    case 0x4a: // UPA config
466
    case 0x82: // Primary no-fault
719
    case 0x81: // Secondary
467 720
    case 0x83: // Secondary no-fault
468
    case 0x88: // Primary LE
469 721
    case 0x89: // Secondary LE
470
    case 0x8a: // Primary no-fault LE
471 722
    case 0x8b: // Secondary no-fault LE
472 723
        // XXX
473 724
        break;
......
540 791
        ret = 0;
541 792
        break;
542 793
    }
794

  
795
    /* Convert from little endian */
796
    switch (asi) {
797
    case 0x0c: // Nucleus Little Endian (LE)
798
    case 0x18: // As if user primary LE
799
    case 0x19: // As if user secondary LE
800
    case 0x1c: // Bypass LE
801
    case 0x1d: // Bypass, non-cacheable LE
802
    case 0x88: // Primary LE
803
    case 0x89: // Secondary LE
804
    case 0x8a: // Primary no-fault LE
805
    case 0x8b: // Secondary no-fault LE
806
        switch(size) {
807
        case 2:
808
            ret = bswap16(ret);
809
        case 4:
810
            ret = bswap32(ret);
811
        case 8:
812
            ret = bswap64(ret);
813
        default:
814
            break;
815
        }
816
    default:
817
        break;
818
    }
819

  
820
    /* Convert to signed number */
821
    if (sign) {
822
        switch(size) {
823
        case 1:
824
            ret = (int8_t) ret;
825
        case 2:
826
            ret = (int16_t) ret;
827
        case 4:
828
            ret = (int32_t) ret;
829
        default:
830
            break;
831
        }
832
    }
543 833
    T1 = ret;
544 834
}
545 835

  
546
void helper_st_asi(int asi, int size, int sign)
836
void helper_st_asi(int asi, int size)
547 837
{
548 838
    if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
549 839
        raise_exception(TT_PRIV_ACT);
550 840

  
841
    /* Convert to little endian */
842
    switch (asi) {
843
    case 0x0c: // Nucleus Little Endian (LE)
844
    case 0x18: // As if user primary LE
845
    case 0x19: // As if user secondary LE
846
    case 0x1c: // Bypass LE
847
    case 0x1d: // Bypass, non-cacheable LE
848
    case 0x81: // Secondary
849
    case 0x88: // Primary LE
850
    case 0x89: // Secondary LE
851
        switch(size) {
852
        case 2:
853
            T0 = bswap16(T0);
854
        case 4:
855
            T0 = bswap32(T0);
856
        case 8:
857
            T0 = bswap64(T0);
858
        default:
859
            break;
860
        }
861
    default:
862
        break;
863
    }
864

  
551 865
    switch(asi) {
866
    case 0x10: // As if user primary
867
    case 0x18: // As if user primary LE
868
    case 0x80: // Primary
869
    case 0x88: // Primary LE
870
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
871
            switch(size) {
872
            case 1:
873
                stb_kernel(T0, T1);
874
                break;
875
            case 2:
876
                stw_kernel(T0 & ~1, T1);
877
                break;
878
            case 4:
879
                stl_kernel(T0 & ~3, T1);
880
                break;
881
            case 8:
882
            default:
883
                stq_kernel(T0 & ~7, T1);
884
                break;
885
            }
886
        } else {
887
            switch(size) {
888
            case 1:
889
                stb_user(T0, T1);
890
                break;
891
            case 2:
892
                stw_user(T0 & ~1, T1);
893
                break;
894
            case 4:
895
                stl_user(T0 & ~3, T1);
896
                break;
897
            case 8:
898
            default:
899
                stq_user(T0 & ~7, T1);
900
                break;
901
            }
902
        }
903
        break;
552 904
    case 0x14: // Bypass
553 905
    case 0x15: // Bypass, non-cacheable
906
    case 0x1c: // Bypass LE
907
    case 0x1d: // Bypass, non-cacheable LE
554 908
        {
555 909
            switch(size) {
556 910
            case 1:
......
571 925
        return;
572 926
    case 0x04: // Nucleus
573 927
    case 0x0c: // Nucleus Little Endian (LE)
574
    case 0x10: // As if user primary
575 928
    case 0x11: // As if user secondary
576
    case 0x18: // As if user primary LE
577 929
    case 0x19: // As if user secondary LE
578
    case 0x1c: // Bypass LE
579
    case 0x1d: // Bypass, non-cacheable LE
580 930
    case 0x24: // Nucleus quad LDD 128 bit atomic
581 931
    case 0x2c: // Nucleus quad LDD 128 bit atomic
582 932
    case 0x4a: // UPA config
583
    case 0x88: // Primary LE
584 933
    case 0x89: // Secondary LE
585 934
        // XXX
586 935
        return;
......
756 1105
        return;
757 1106
    }
758 1107
}
759
#endif
760
#endif /* !CONFIG_USER_ONLY */
1108
#endif /* CONFIG_USER_ONLY */
1109
#endif /* TARGET_SPARC64 */
761 1110

  
762 1111
#ifndef TARGET_SPARC64
763 1112
void helper_rett()

Also available in: Unified diff