Revision be147d08 target-ppc/translate.c

b/target-ppc/translate.c
480 480
    PPC_FLOAT_EXT     = 0x0000080000000000ULL,
481 481
    /* New wait instruction (PowerPC 2.0x)              */
482 482
    PPC_WAIT          = 0x0000100000000000ULL,
483
    /* New 64 bits extensions (PowerPC 2.0x)            */
484
    PPC_64BX          = 0x0000200000000000ULL,
483 485
};
484 486

  
485 487
/*****************************************************************************/
......
1141 1143
            /* Set process priority to normal */
1142 1144
            gen_op_store_pri(4);
1143 1145
            break;
1146
#if !defined(CONFIG_USER_ONLY)
1147
        case 31:
1148
            if (ctx->supervisor > 0) {
1149
                /* Set process priority to very low */
1150
                gen_op_store_pri(1);
1151
            }
1152
            break;
1153
        case 5:
1154
            if (ctx->supervisor > 0) {
1155
                /* Set process priority to medium-hight */
1156
                gen_op_store_pri(5);
1157
            }
1158
            break;
1159
        case 3:
1160
            if (ctx->supervisor > 0) {
1161
                /* Set process priority to high */
1162
                gen_op_store_pri(6);
1163
            }
1164
            break;
1165
#if defined(TARGET_PPC64H)
1166
        case 7:
1167
            if (ctx->supervisor > 1) {
1168
                /* Set process priority to very high */
1169
                gen_op_store_pri(7);
1170
            }
1171
            break;
1172
#endif
1173
#endif
1144 1174
        default:
1145 1175
            /* nop */
1146 1176
            break;
......
1902 1932

  
1903 1933
/***                           Addressing modes                            ***/
1904 1934
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1905
static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1935
static inline void gen_addr_imm_index (DisasContext *ctx, target_long maskl)
1906 1936
{
1907 1937
    target_long simm = SIMM(ctx->opcode);
1908 1938

  
1909
    if (maskl)
1910
        simm &= ~0x03;
1939
    simm &= ~maskl;
1911 1940
    if (rA(ctx->opcode) == 0) {
1912 1941
        gen_set_T0(simm);
1913 1942
    } else {
......
2051 2080
        return;                                                               \
2052 2081
    }                                                                         \
2053 2082
    if (type == PPC_64B)                                                      \
2054
        gen_addr_imm_index(ctx, 1);                                           \
2083
        gen_addr_imm_index(ctx, 0x03);                                        \
2055 2084
    else                                                                      \
2056 2085
        gen_addr_imm_index(ctx, 0);                                           \
2057 2086
    op_ldst(l##width);                                                        \
......
2116 2145
            return;
2117 2146
        }
2118 2147
    }
2119
    gen_addr_imm_index(ctx, 1);
2148
    gen_addr_imm_index(ctx, 0x03);
2120 2149
    if (ctx->opcode & 0x02) {
2121 2150
        /* lwa (lwau is undefined) */
2122 2151
        op_ldst(lwa);
......
2128 2157
    if (Rc(ctx->opcode))
2129 2158
        gen_op_store_T0_gpr(rA(ctx->opcode));
2130 2159
}
2160
/* lq */
2161
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2162
{
2163
#if defined(CONFIG_USER_ONLY)
2164
    GEN_EXCP_PRIVOPC(ctx);
2165
#else
2166
    int ra, rd;
2167

  
2168
    /* Restore CPU state */
2169
    if (unlikely(ctx->supervisor == 0)) {
2170
        GEN_EXCP_PRIVOPC(ctx);
2171
        return;
2172
    }
2173
    ra = rA(ctx->opcode);
2174
    rd = rD(ctx->opcode);
2175
    if (unlikely((rd & 1) || rd == ra)) {
2176
        GEN_EXCP_INVAL(ctx);
2177
        return;
2178
    }
2179
    if (unlikely(ctx->mem_idx & 1)) {
2180
        /* Little-endian mode is not handled */
2181
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2182
        return;
2183
    }
2184
    gen_addr_imm_index(ctx, 0x0F);
2185
    op_ldst(ld);
2186
    gen_op_store_T1_gpr(rd);
2187
    gen_op_addi(8);
2188
    op_ldst(ld);
2189
    gen_op_store_T1_gpr(rd + 1);
2190
#endif
2191
}
2131 2192
#endif
2132 2193

  
2133 2194
/***                              Integer store                            ***/
......
2147 2208
        return;                                                               \
2148 2209
    }                                                                         \
2149 2210
    if (type == PPC_64B)                                                      \
2150
        gen_addr_imm_index(ctx, 1);                                           \
2211
        gen_addr_imm_index(ctx, 0x03);                                        \
2151 2212
    else                                                                      \
2152 2213
        gen_addr_imm_index(ctx, 0);                                           \
2153 2214
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
......
2193 2254
OP_ST_TABLE(d);
2194 2255
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2195 2256
GEN_STX(d, 0x15, 0x04, PPC_64B);
2196
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2257
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2197 2258
{
2198
    if (Rc(ctx->opcode)) {
2199
        if (unlikely(rA(ctx->opcode) == 0)) {
2259
    int rs;
2260

  
2261
    rs = rS(ctx->opcode);
2262
    if ((ctx->opcode & 0x3) == 0x2) {
2263
#if defined(CONFIG_USER_ONLY)
2264
        GEN_EXCP_PRIVOPC(ctx);
2265
#else
2266
        /* stq */
2267
        if (unlikely(ctx->supervisor == 0)) {
2268
            GEN_EXCP_PRIVOPC(ctx);
2269
            return;
2270
        }
2271
        if (unlikely(rs & 1)) {
2200 2272
            GEN_EXCP_INVAL(ctx);
2201 2273
            return;
2202 2274
        }
2275
        if (unlikely(ctx->mem_idx & 1)) {
2276
            /* Little-endian mode is not handled */
2277
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2278
            return;
2279
        }
2280
        gen_addr_imm_index(ctx, 0x03);
2281
        gen_op_load_gpr_T1(rs);
2282
        op_ldst(std);
2283
        gen_op_addi(8);
2284
        gen_op_load_gpr_T1(rs + 1);
2285
        op_ldst(std);
2286
#endif
2287
    } else {
2288
        /* std / stdu */
2289
        if (Rc(ctx->opcode)) {
2290
            if (unlikely(rA(ctx->opcode) == 0)) {
2291
                GEN_EXCP_INVAL(ctx);
2292
                return;
2293
            }
2294
        }
2295
        gen_addr_imm_index(ctx, 0x03);
2296
        gen_op_load_gpr_T1(rs);
2297
        op_ldst(std);
2298
        if (Rc(ctx->opcode))
2299
            gen_op_store_T0_gpr(rA(ctx->opcode));
2203 2300
    }
2204
    gen_addr_imm_index(ctx, 1);
2205
    gen_op_load_gpr_T1(rS(ctx->opcode));
2206
    op_ldst(std);
2207
    if (Rc(ctx->opcode))
2208
        gen_op_store_T0_gpr(rA(ctx->opcode));
2209 2301
}
2210 2302
#endif
2211 2303
/***                Integer load and store with byte reverse               ***/
......
2620 2712
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2621 2713
{
2622 2714
    /* Stop translation, as the CPU is supposed to sleep from now */
2623
    /* XXX: TODO: handle this idle CPU case */
2624
    GEN_STOP(ctx);
2715
    gen_op_wait();
2716
    GEN_EXCP(ctx, EXCP_HLT, 1);
2625 2717
}
2626 2718

  
2627 2719
/***                         Floating-point load                           ***/
......
3077 3169
}
3078 3170
#endif
3079 3171

  
3172
#if defined(TARGET_PPC64H)
3173
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64B)
3174
{
3175
#if defined(CONFIG_USER_ONLY)
3176
    GEN_EXCP_PRIVOPC(ctx);
3177
#else
3178
    /* Restore CPU state */
3179
    if (unlikely(ctx->supervisor <= 1)) {
3180
        GEN_EXCP_PRIVOPC(ctx);
3181
        return;
3182
    }
3183
    gen_op_hrfid();
3184
    GEN_SYNC(ctx);
3185
#endif
3186
}
3187
#endif
3188

  
3080 3189
/* sc */
3081 3190
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3082 3191
{
......
3193 3302
    uint32_t sprn = SPR(ctx->opcode);
3194 3303

  
3195 3304
#if !defined(CONFIG_USER_ONLY)
3305
#if defined(TARGET_PPC64H)
3306
    if (ctx->supervisor == 2)
3307
        read_cb = ctx->spr_cb[sprn].hea_read;
3308
    else
3309
#endif
3196 3310
    if (ctx->supervisor)
3197 3311
        read_cb = ctx->spr_cb[sprn].oea_read;
3198 3312
    else
......
3253 3367

  
3254 3368
/* mtmsr */
3255 3369
#if defined(TARGET_PPC64)
3256
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3370
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3257 3371
{
3258 3372
#if defined(CONFIG_USER_ONLY)
3259 3373
    GEN_EXCP_PRIVREG(ctx);
......
3262 3376
        GEN_EXCP_PRIVREG(ctx);
3263 3377
        return;
3264 3378
    }
3265
    gen_update_nip(ctx, ctx->nip);
3266 3379
    gen_op_load_gpr_T0(rS(ctx->opcode));
3267
    gen_op_store_msr();
3268
    /* Must stop the translation as machine state (may have) changed */
3269
    /* Note that mtmsr is not always defined as context-synchronizing */
3270
    GEN_STOP(ctx);
3380
    if (ctx->opcode & 0x00010000) {
3381
        /* Special form that does not need any synchronisation */
3382
        gen_op_update_riee();
3383
    } else {
3384
        gen_update_nip(ctx, ctx->nip);
3385
        gen_op_store_msr();
3386
        /* Must stop the translation as machine state (may have) changed */
3387
        /* Note that mtmsr is not always defined as context-synchronizing */
3388
        GEN_STOP(ctx);
3389
    }
3271 3390
#endif
3272 3391
}
3273 3392
#endif
......
3281 3400
        GEN_EXCP_PRIVREG(ctx);
3282 3401
        return;
3283 3402
    }
3284
    gen_update_nip(ctx, ctx->nip);
3285 3403
    gen_op_load_gpr_T0(rS(ctx->opcode));
3404
    if (ctx->opcode & 0x00010000) {
3405
        /* Special form that does not need any synchronisation */
3406
        gen_op_update_riee();
3407
    } else {
3408
        gen_update_nip(ctx, ctx->nip);
3286 3409
#if defined(TARGET_PPC64)
3287
    if (!ctx->sf_mode)
3288
        gen_op_store_msr_32();
3289
    else
3410
        if (!ctx->sf_mode)
3411
            gen_op_store_msr_32();
3412
        else
3290 3413
#endif
3291
        gen_op_store_msr();
3292
    /* Must stop the translation as machine state (may have) changed */
3293
    /* Note that mtmsrd is not always defined as context-synchronizing */
3294
    GEN_STOP(ctx);
3414
            gen_op_store_msr();
3415
        /* Must stop the translation as machine state (may have) changed */
3416
        /* Note that mtmsrd is not always defined as context-synchronizing */
3417
        GEN_STOP(ctx);
3418
    }
3295 3419
#endif
3296 3420
}
3297 3421

  
......
3302 3426
    uint32_t sprn = SPR(ctx->opcode);
3303 3427

  
3304 3428
#if !defined(CONFIG_USER_ONLY)
3429
#if defined(TARGET_PPC64H)
3430
    if (ctx->supervisor == 2)
3431
        write_cb = ctx->spr_cb[sprn].hea_write;
3432
    else
3433
#endif
3305 3434
    if (ctx->supervisor)
3306 3435
        write_cb = ctx->spr_cb[sprn].oea_write;
3307 3436
    else
......
6011 6140
    ctx.mem_idx |= msr_sf << 1;
6012 6141
#endif
6013 6142
#else
6014
    ctx.supervisor = 1 - msr_pr;
6143
#if defined(TARGET_PPC64H)
6144
    if (msr_pr == 0 && msr_hv == 1)
6145
        ctx.supervisor = 2;
6146
    else
6147
#endif
6148
        ctx.supervisor = 1 - msr_pr;
6015 6149
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
6016 6150
#if defined(TARGET_PPC64)
6017 6151
    ctx.mem_idx |= msr_sf << 2;

Also available in: Unified diff