Revision 81ad8ba2 target-sparc/translate.c

b/target-sparc/translate.c
353 353
#endif
354 354
#endif
355 355

  
356
#ifdef TARGET_SPARC64
357
// 'a' versions allowed to user depending on asi
358
#if defined(CONFIG_USER_ONLY)
356
/* moves */
357
#ifdef CONFIG_USER_ONLY
359 358
#define supervisor(dc) 0
359
#ifdef TARGET_SPARC64
360 360
#define hypervisor(dc) 0
361
#endif
361 362
#define gen_op_ldst(name)        gen_op_##name##_raw()
362
#define OP_LD_TABLE(width)                                              \
363
    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
364
    {                                                                   \
365
        int asi, offset;                                                \
366
                                                                        \
367
        if (IS_IMM) {                                                   \
368
            offset = GET_FIELD(insn, 25, 31);                           \
369
            if (is_ld)                                                  \
370
                gen_op_ld_asi_reg(offset, size, sign);                  \
371
            else                                                        \
372
                gen_op_st_asi_reg(offset, size, sign);                  \
373
            return;                                                     \
374
        }                                                               \
375
        asi = GET_FIELD(insn, 19, 26);                                  \
376
        switch (asi) {                                                  \
377
        case 0x80: /* Primary address space */                          \
378
            gen_op_##width##_raw();                                     \
379
            break;                                                      \
380
        case 0x82: /* Primary address space, non-faulting load */       \
381
            gen_op_##width##_raw();                                     \
382
            break;                                                      \
383
        default:                                                        \
384
            break;                                                      \
385
        }                                                               \
386
    }
387

  
388 363
#else
364
#define supervisor(dc) (dc->mem_idx == 1)
365
#ifdef TARGET_SPARC64
366
#define hypervisor(dc) (dc->mem_idx == 2)
367
#endif
389 368
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
390 369
#define OP_LD_TABLE(width)                                              \
391 370
    static GenOpFunc * const gen_op_##width[] = {                       \
392 371
        &gen_op_##width##_user,                                         \
393 372
        &gen_op_##width##_kernel,                                       \
394
    };                                                                  \
395
                                                                        \
396
    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
397
    {                                                                   \
398
        int asi, offset;                                                \
399
                                                                        \
400
        if (IS_IMM) {                                                   \
401
            offset = GET_FIELD(insn, 25, 31);                           \
402
            if (is_ld)                                                  \
403
                gen_op_ld_asi_reg(offset, size, sign);                  \
404
            else                                                        \
405
                gen_op_st_asi_reg(offset, size, sign);                  \
406
            return;                                                     \
407
        }                                                               \
408
        asi = GET_FIELD(insn, 19, 26);                                  \
409
        if (is_ld)                                                      \
410
            gen_op_ld_asi(asi, size, sign);                             \
411
        else                                                            \
412
            gen_op_st_asi(asi, size, sign);                             \
413
    }
414

  
415
#define supervisor(dc) (dc->mem_idx == 1)
416
#define hypervisor(dc) (dc->mem_idx == 2)
417
#endif
418
#else
419
#if defined(CONFIG_USER_ONLY)
420
#define gen_op_ldst(name)        gen_op_##name##_raw()
421
#define OP_LD_TABLE(width)
422
#define supervisor(dc) 0
423
#else
424
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
425
#define OP_LD_TABLE(width)                                                    \
426
static GenOpFunc * const gen_op_##width[] = {                                 \
427
    &gen_op_##width##_user,                                                   \
428
    &gen_op_##width##_kernel,                                                 \
429
};                                                                            \
430
                                                                              \
431
static void gen_op_##width##a(int insn, int is_ld, int size, int sign)        \
432
{                                                                             \
433
    int asi;                                                                  \
434
                                                                              \
435
    asi = GET_FIELD(insn, 19, 26);                                            \
436
    switch (asi) {                                                            \
437
        case 10: /* User data access */                                       \
438
            gen_op_##width##_user();                                          \
439
            break;                                                            \
440
        case 11: /* Supervisor data access */                                 \
441
            gen_op_##width##_kernel();                                        \
442
            break;                                                            \
443
        case 0x20 ... 0x2f: /* MMU passthrough */                             \
444
            if (is_ld)                                                        \
445
                gen_op_ld_asi(asi, size, sign);                               \
446
            else                                                              \
447
                gen_op_st_asi(asi, size, sign);                               \
448
            break;                                                            \
449
        default:                                                              \
450
            if (is_ld)                                                        \
451
                gen_op_ld_asi(asi, size, sign);                               \
452
            else                                                              \
453
                gen_op_st_asi(asi, size, sign);                               \
454
            break;                                                            \
455
    }                                                                         \
456
}
457

  
458
#define supervisor(dc) (dc->mem_idx == 1)
459
#endif
373
    };
460 374
#endif
461 375

  
376
#ifndef CONFIG_USER_ONLY
462 377
OP_LD_TABLE(ld);
463 378
OP_LD_TABLE(st);
464 379
OP_LD_TABLE(ldub);
......
481 396
OP_LD_TABLE(ldsw);
482 397
OP_LD_TABLE(ldx);
483 398
OP_LD_TABLE(stx);
484
OP_LD_TABLE(cas);
485
OP_LD_TABLE(casx);
399
#endif
400
#endif
401

  
402
/* asi moves */
403
#ifdef TARGET_SPARC64
404
static inline void gen_ld_asi(int insn, int size, int sign)
405
{
406
    int asi, offset;
407

  
408
    if (IS_IMM) {
409
        offset = GET_FIELD(insn, 25, 31);
410
        gen_op_ld_asi_reg(offset, size, sign);
411
    } else {
412
        asi = GET_FIELD(insn, 19, 26);
413
        gen_op_ld_asi(asi, size, sign);
414
    }
415
}
416

  
417
static inline void gen_st_asi(int insn, int size)
418
{
419
    int asi, offset;
420

  
421
    if (IS_IMM) {
422
        offset = GET_FIELD(insn, 25, 31);
423
        gen_op_st_asi_reg(offset, size);
424
    } else {
425
        asi = GET_FIELD(insn, 19, 26);
426
        gen_op_st_asi(asi, size);
427
    }
428
}
429

  
430
static inline void gen_swap_asi(int insn)
431
{
432
    int asi, offset;
433

  
434
    if (IS_IMM) {
435
        offset = GET_FIELD(insn, 25, 31);
436
        gen_op_swap_asi_reg(offset);
437
    } else {
438
        asi = GET_FIELD(insn, 19, 26);
439
        gen_op_swap_asi(asi);
440
    }
441
}
442

  
443
static inline void gen_ldstub_asi(int insn)
444
{
445
    int asi, offset;
446

  
447
    if (IS_IMM) {
448
        offset = GET_FIELD(insn, 25, 31);
449
        gen_op_ldstub_asi_reg(offset);
450
    } else {
451
        asi = GET_FIELD(insn, 19, 26);
452
        gen_op_ldstub_asi(asi);
453
    }
454
}
455

  
456
static inline void gen_ldda_asi(int insn)
457
{
458
    int asi, offset;
459

  
460
    if (IS_IMM) {
461
        offset = GET_FIELD(insn, 25, 31);
462
        gen_op_ldda_asi_reg(offset);
463
    } else {
464
        asi = GET_FIELD(insn, 19, 26);
465
        gen_op_ldda_asi(asi);
466
    }
467
}
468

  
469
static inline void gen_stda_asi(int insn)
470
{
471
    int asi, offset;
472

  
473
    if (IS_IMM) {
474
        offset = GET_FIELD(insn, 25, 31);
475
        gen_op_stda_asi_reg(offset);
476
    } else {
477
        asi = GET_FIELD(insn, 19, 26);
478
        gen_op_stda_asi(asi);
479
    }
480
}
481

  
482
static inline void gen_cas_asi(int insn)
483
{
484
    int asi, offset;
485

  
486
    if (IS_IMM) {
487
        offset = GET_FIELD(insn, 25, 31);
488
        gen_op_cas_asi_reg(offset);
489
    } else {
490
        asi = GET_FIELD(insn, 19, 26);
491
        gen_op_cas_asi(asi);
492
    }
493
}
494

  
495
static inline void gen_casx_asi(int insn)
496
{
497
    int asi, offset;
498

  
499
    if (IS_IMM) {
500
        offset = GET_FIELD(insn, 25, 31);
501
        gen_op_casx_asi_reg(offset);
502
    } else {
503
        asi = GET_FIELD(insn, 19, 26);
504
        gen_op_casx_asi(asi);
505
    }
506
}
507

  
508
#elif !defined(CONFIG_USER_ONLY)
509

  
510
static inline void gen_ld_asi(int insn, int size, int sign)
511
{
512
    int asi;
513

  
514
    asi = GET_FIELD(insn, 19, 26);
515
    gen_op_ld_asi(asi, size, sign);
516
}
517

  
518
static inline void gen_st_asi(int insn, int size)
519
{
520
    int asi;
521

  
522
    asi = GET_FIELD(insn, 19, 26);
523
    gen_op_st_asi(asi, size);
524
}
525

  
526
static inline void gen_ldstub_asi(int insn)
527
{
528
    int asi;
529

  
530
    asi = GET_FIELD(insn, 19, 26);
531
    gen_op_ldstub_asi(asi);
532
}
533

  
534
static inline void gen_swap_asi(int insn)
535
{
536
    int asi;
537

  
538
    asi = GET_FIELD(insn, 19, 26);
539
    gen_op_swap_asi(asi);
540
}
541

  
542
static inline void gen_ldda_asi(int insn)
543
{
544
    int asi;
545

  
546
    asi = GET_FIELD(insn, 19, 26);
547
    gen_op_ld_asi(asi, 8, 0);
548
}
549

  
550
static inline void gen_stda_asi(int insn)
551
{
552
    int asi;
553

  
554
    asi = GET_FIELD(insn, 19, 26);
555
    gen_op_st_asi(asi, 8);
556
}
486 557
#endif
487 558

  
488 559
static inline void gen_movl_imm_TN(int reg, uint32_t imm)
......
2796 2867
            rs1 = GET_FIELD(insn, 13, 17);
2797 2868
            save_state(dc);
2798 2869
            gen_movl_reg_T0(rs1);
2799
            if (IS_IMM) {       /* immediate */
2870
            if (xop == 0x3c || xop == 0x3e)
2871
            {
2872
                rs2 = GET_FIELD(insn, 27, 31);
2873
                gen_movl_reg_T1(rs2);
2874
            }
2875
            else if (IS_IMM) {       /* immediate */
2800 2876
                rs2 = GET_FIELDs(insn, 19, 31);
2801 2877
#if defined(OPTIM)
2802 2878
                if (rs2 != 0) {
......
2873 2949
                        goto illegal_insn;
2874 2950
                    if (!supervisor(dc))
2875 2951
                        goto priv_insn;
2876
#ifdef CONFIG_USER_ONLY
2952
#elif CONFIG_USER_ONLY
2877 2953
                    gen_op_check_align_T0_3();
2878 2954
#endif
2879
                    gen_op_lda(insn, 1, 4, 0);
2880
#else
2881
#ifdef CONFIG_USER_ONLY
2882
                    gen_op_check_align_T0_3();
2883
#endif
2884
                    gen_op_lduwa(insn, 1, 4, 0);
2885
#endif
2955
                    gen_ld_asi(insn, 4, 0);
2886 2956
                    break;
2887 2957
                case 0x11:      /* load unsigned byte alternate */
2888 2958
#ifndef TARGET_SPARC64
......
2891 2961
                    if (!supervisor(dc))
2892 2962
                        goto priv_insn;
2893 2963
#endif
2894
                    gen_op_lduba(insn, 1, 1, 0);
2964
                    gen_ld_asi(insn, 1, 0);
2895 2965
                    break;
2896 2966
                case 0x12:      /* load unsigned halfword alternate */
2897 2967
#ifndef TARGET_SPARC64
......
2899 2969
                        goto illegal_insn;
2900 2970
                    if (!supervisor(dc))
2901 2971
                        goto priv_insn;
2902
#endif
2903
#ifdef CONFIG_USER_ONLY
2972
#elif CONFIG_USER_ONLY
2904 2973
                    gen_op_check_align_T0_1();
2905 2974
#endif
2906
                    gen_op_lduha(insn, 1, 2, 0);
2975
                    gen_ld_asi(insn, 2, 0);
2907 2976
                    break;
2908 2977
                case 0x13:      /* load double word alternate */
2909 2978
#ifndef TARGET_SPARC64
......
2915 2984
                    if (rd & 1)
2916 2985
                        goto illegal_insn;
2917 2986
                    gen_op_check_align_T0_7();
2918
                    gen_op_ldda(insn, 1, 8, 0);
2987
                    gen_ldda_asi(insn);
2919 2988
                    gen_movl_T0_reg(rd + 1);
2920 2989
                    break;
2921 2990
                case 0x19:      /* load signed byte alternate */
......
2925 2994
                    if (!supervisor(dc))
2926 2995
                        goto priv_insn;
2927 2996
#endif
2928
                    gen_op_ldsba(insn, 1, 1, 1);
2997
                    gen_ld_asi(insn, 1, 1);
2929 2998
                    break;
2930 2999
                case 0x1a:      /* load signed halfword alternate */
2931 3000
#ifndef TARGET_SPARC64
......
2933 3002
                        goto illegal_insn;
2934 3003
                    if (!supervisor(dc))
2935 3004
                        goto priv_insn;
2936
#endif
2937
#ifdef CONFIG_USER_ONLY
3005
#elif CONFIG_USER_ONLY
2938 3006
                    gen_op_check_align_T0_1();
2939 3007
#endif
2940
                    gen_op_ldsha(insn, 1, 2 ,1);
3008
                    gen_ld_asi(insn, 2, 1);
2941 3009
                    break;
2942 3010
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
2943 3011
#ifndef TARGET_SPARC64
......
2946 3014
                    if (!supervisor(dc))
2947 3015
                        goto priv_insn;
2948 3016
#endif
2949
                    gen_op_ldstuba(insn, 1, 1, 0);
3017
                    gen_ldstub_asi(insn);
2950 3018
                    break;
2951 3019
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
2952 3020
#ifndef TARGET_SPARC64
......
2954 3022
                        goto illegal_insn;
2955 3023
                    if (!supervisor(dc))
2956 3024
                        goto priv_insn;
2957
#endif
2958
                    gen_movl_reg_T1(rd);
2959
#ifdef CONFIG_USER_ONLY
3025
#elif CONFIG_USER_ONLY
2960 3026
                    gen_op_check_align_T0_3();
2961 3027
#endif
2962
                    gen_op_swapa(insn, 1, 4, 0);
3028
                    gen_movl_reg_T1(rd);
3029
                    gen_swap_asi(insn);
2963 3030
                    break;
2964 3031

  
2965 3032
#ifndef TARGET_SPARC64
......
2967 3034
                case 0x31: /* ldcsr */
2968 3035
                case 0x33: /* lddc */
2969 3036
                    goto ncp_insn;
2970
                    /* avoid warnings */
2971
                    (void) &gen_op_stfa;
2972
                    (void) &gen_op_stdfa;
2973
                    (void) &gen_op_ldfa;
2974
                    (void) &gen_op_lddfa;
2975
#else
2976
                    (void) &gen_op_lda;
2977
#if !defined(CONFIG_USER_ONLY)
2978
                    (void) &gen_op_cas;
2979
                    (void) &gen_op_casx;
2980
#endif
2981 3037
#endif
2982 3038
#endif
2983 3039
#ifdef TARGET_SPARC64
......
2995 3051
#ifdef CONFIG_USER_ONLY
2996 3052
                    gen_op_check_align_T0_3();
2997 3053
#endif
2998
                    gen_op_ldswa(insn, 1, 4, 1);
3054
                    gen_ld_asi(insn, 4, 1);
2999 3055
                    break;
3000 3056
                case 0x1b: /* V9 ldxa */
3001 3057
                    gen_op_check_align_T0_7();
3002
                    gen_op_ldxa(insn, 1, 8, 0);
3058
                    gen_ld_asi(insn, 8, 0);
3003 3059
                    break;
3004 3060
                case 0x2d: /* V9 prefetch, no effect */
3005 3061
                    goto skip_move;
......
3007 3063
#ifdef CONFIG_USER_ONLY
3008 3064
                    gen_op_check_align_T0_3();
3009 3065
#endif
3010
                    gen_op_ldfa(insn, 1, 8, 0); // XXX
3011
                    break;
3066
                    gen_ld_asi(insn, 8, 0); // XXX
3067
                    goto skip_move;
3012 3068
                case 0x33: /* V9 lddfa */
3013 3069
                    gen_op_check_align_T0_7();
3014
                    gen_op_lddfa(insn, 1, 8, 0); // XXX
3015

  
3016
                    break;
3070
                    gen_ld_asi(insn, 8, 0); // XXX
3071
                    goto skip_move;
3017 3072
                case 0x3d: /* V9 prefetcha, no effect */
3018 3073
                    goto skip_move;
3019 3074
                case 0x32: /* V9 ldqfa */
......
3092 3147
#ifdef CONFIG_USER_ONLY
3093 3148
                    gen_op_check_align_T0_3();
3094 3149
#endif
3095
                    gen_op_sta(insn, 0, 4, 0);
3150
                    gen_st_asi(insn, 4);
3096 3151
                    break;
3097 3152
                case 0x15:
3098 3153
#ifndef TARGET_SPARC64
......
3101 3156
                    if (!supervisor(dc))
3102 3157
                        goto priv_insn;
3103 3158
#endif
3104
                    gen_op_stba(insn, 0, 1, 0);
3159
                    gen_st_asi(insn, 1);
3105 3160
                    break;
3106 3161
                case 0x16:
3107 3162
#ifndef TARGET_SPARC64
......
3113 3168
#ifdef CONFIG_USER_ONLY
3114 3169
                    gen_op_check_align_T0_1();
3115 3170
#endif
3116
                    gen_op_stha(insn, 0, 2, 0);
3171
                    gen_st_asi(insn, 2);
3117 3172
                    break;
3118 3173
                case 0x17:
3119 3174
#ifndef TARGET_SPARC64
......
3127 3182
                    gen_op_check_align_T0_7();
3128 3183
                    flush_T2(dc);
3129 3184
                    gen_movl_reg_T2(rd + 1);
3130
                    gen_op_stda(insn, 0, 8, 0);
3185
                    gen_stda_asi(insn);
3131 3186
                    break;
3132 3187
#endif
3133 3188
#ifdef TARGET_SPARC64
......
3137 3192
                    break;
3138 3193
                case 0x1e: /* V9 stxa */
3139 3194
                    gen_op_check_align_T0_7();
3140
                    gen_op_stxa(insn, 0, 8, 0); // XXX
3195
                    gen_st_asi(insn, 8);
3141 3196
                    break;
3142 3197
#endif
3143 3198
                default:
......
3184 3239
#ifdef CONFIG_USER_ONLY
3185 3240
                    gen_op_check_align_T0_3();
3186 3241
#endif
3187
                    gen_op_stfa(insn, 0, 0, 0); // XXX
3242
                    gen_st_asi(insn, 0); // XXX
3188 3243
                    break;
3189 3244
                case 0x37: /* V9 stdfa */
3190 3245
                    gen_op_check_align_T0_7();
3191
                    gen_op_stdfa(insn, 0, 0, 0); // XXX
3246
                    gen_st_asi(insn, 0); // XXX
3192 3247
                    break;
3193 3248
                case 0x3c: /* V9 casa */
3194 3249
#ifdef CONFIG_USER_ONLY
3195 3250
                    gen_op_check_align_T0_3();
3196 3251
#endif
3197
                    gen_op_casa(insn, 0, 4, 0); // XXX
3252
                    flush_T2(dc);
3253
                    gen_movl_reg_T2(rd);
3254
                    gen_cas_asi(insn);
3255
                    gen_movl_T1_reg(rd);
3198 3256
                    break;
3199 3257
                case 0x3e: /* V9 casxa */
3200 3258
                    gen_op_check_align_T0_7();
3201
                    gen_op_casxa(insn, 0, 8, 0); // XXX
3259
                    flush_T2(dc);
3260
                    gen_movl_reg_T2(rd);
3261
                    gen_casx_asi(insn);
3262
                    gen_movl_T1_reg(rd);
3202 3263
                    break;
3203 3264
                case 0x36: /* V9 stqfa */
3204 3265
                    goto nfpu_insn;

Also available in: Unified diff