Revision 0411a972 target-ppc/op_helper.c

b/target-ppc/op_helper.c
19 19
 */
20 20
#include "exec.h"
21 21

  
22
#include "helper_regs.h"
22 23
#include "op_helper.h"
23 24

  
24 25
#define MEMSUFFIX _raw
......
98 99
    }
99 100
}
100 101

  
101
void do_load_xer (void)
102
{
103
    T0 = (xer_so << XER_SO) |
104
        (xer_ov << XER_OV) |
105
        (xer_ca << XER_CA) |
106
        (xer_bc << XER_BC) |
107
        (xer_cmp << XER_CMP);
108
}
109

  
110
void do_store_xer (void)
111
{
112
    xer_so = (T0 >> XER_SO) & 0x01;
113
    xer_ov = (T0 >> XER_OV) & 0x01;
114
    xer_ca = (T0 >> XER_CA) & 0x01;
115
    xer_cmp = (T0 >> XER_CMP) & 0xFF;
116
    xer_bc = (T0 >> XER_BC) & 0x7F;
117
}
118

  
119 102
#if defined(TARGET_PPC64)
120 103
void do_store_pri (int prio)
121 104
{
......
970 953

  
971 954
#if !defined (CONFIG_USER_ONLY)
972 955
void cpu_dump_rfi (target_ulong RA, target_ulong msr);
973
void do_rfi (void)
956

  
957
void do_store_msr (void)
958
{
959
    T0 = hreg_store_msr(env, T0);
960
    if (T0 != 0) {
961
        env->interrupt_request |= CPU_INTERRUPT_EXITTB;
962
        do_raise_exception(T0);
963
    }
964
}
965

  
966
static always_inline void __do_rfi (target_ulong nip, target_ulong msr,
967
                                    target_ulong msrm, int keep_msrh)
974 968
{
975 969
#if defined(TARGET_PPC64)
976
    if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) {
977
        env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003);
978
        do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
970
    if (msr & (1ULL << MSR_SF)) {
971
        nip = (uint64_t)nip;
972
        msr &= (uint64_t)msrm;
979 973
    } else {
980
        env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
981
        ppc_store_msr_32(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
974
        nip = (uint32_t)nip;
975
        msr = (uint32_t)(msr & msrm);
976
        if (keep_msrh)
977
            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
982 978
    }
983 979
#else
984
    env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
985
    do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
980
    nip = (uint32_t)nip;
981
    msr &= (uint32_t)msrm;
986 982
#endif
983
    /* XXX: beware: this is false if VLE is supported */
984
    env->nip = nip & ~((target_ulong)0x00000003);
985
    hreg_store_msr(env, msr);
987 986
#if defined (DEBUG_OP)
988
    cpu_dump_rfi(env->nip, do_load_msr(env));
987
    cpu_dump_rfi(env->nip, env->msr);
989 988
#endif
989
    /* No need to raise an exception here,
990
     * as rfi is always the last insn of a TB
991
     */
990 992
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
991 993
}
992 994

  
995
void do_rfi (void)
996
{
997
    __do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1],
998
             ~((target_ulong)0xFFFF0000), 1);
999
}
1000

  
993 1001
#if defined(TARGET_PPC64)
994 1002
void do_rfid (void)
995 1003
{
996
    if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) {
997
        env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003);
998
        do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
999
    } else {
1000
        env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
1001
        do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
1002
    }
1003
#if defined (DEBUG_OP)
1004
    cpu_dump_rfi(env->nip, do_load_msr(env));
1005
#endif
1006
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1004
    __do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1],
1005
             ~((target_ulong)0xFFFF0000), 0);
1007 1006
}
1008 1007
#endif
1009 1008
#if defined(TARGET_PPC64H)
1010 1009
void do_hrfid (void)
1011 1010
{
1012
    if (env->spr[SPR_HSRR1] & (1ULL << MSR_SF)) {
1013
        env->nip = (uint64_t)(env->spr[SPR_HSRR0] & ~0x00000003);
1014
        do_store_msr(env, (uint64_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
1015
    } else {
1016
        env->nip = (uint32_t)(env->spr[SPR_HSRR0] & ~0x00000003);
1017
        do_store_msr(env, (uint32_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
1018
    }
1019
#if defined (DEBUG_OP)
1020
    cpu_dump_rfi(env->nip, do_load_msr(env));
1021
#endif
1022
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1011
    __do_rfi(env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
1012
             ~((target_ulong)0xFFFF0000), 0);
1023 1013
}
1024 1014
#endif
1025 1015
#endif
......
1214 1204

  
1215 1205
void do_POWER_rfsvc (void)
1216 1206
{
1217
    env->nip = env->lr & ~0x00000003UL;
1218
    T0 = env->ctr & 0x0000FFFFUL;
1219
    do_store_msr(env, T0);
1220
#if defined (DEBUG_OP)
1221
    cpu_dump_rfi(env->nip, do_load_msr(env));
1222
#endif
1223
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1207
    __do_rfi(env->lr, env->ctr, 0x0000FFFF, 0);
1224 1208
}
1225 1209

  
1226 1210
/* PowerPC 601 BAT management helper */
......
1332 1316
#if !defined(CONFIG_USER_ONLY)
1333 1317
void do_40x_rfci (void)
1334 1318
{
1335
    env->nip = env->spr[SPR_40x_SRR2];
1336
    do_store_msr(env, env->spr[SPR_40x_SRR3] & ~0xFFFF0000);
1337
#if defined (DEBUG_OP)
1338
    cpu_dump_rfi(env->nip, do_load_msr(env));
1339
#endif
1340
    env->interrupt_request = CPU_INTERRUPT_EXITTB;
1319
    __do_rfi(env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
1320
             ~((target_ulong)0xFFFF0000), 0);
1341 1321
}
1342 1322

  
1343 1323
void do_rfci (void)
1344 1324
{
1345
#if defined(TARGET_PPC64)
1346
    if (env->spr[SPR_BOOKE_CSRR1] & (1 << MSR_CM)) {
1347
        env->nip = (uint64_t)env->spr[SPR_BOOKE_CSRR0];
1348
    } else
1349
#endif
1350
    {
1351
        env->nip = (uint32_t)env->spr[SPR_BOOKE_CSRR0];
1352
    }
1353
    do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_CSRR1] & ~0x3FFF0000);
1354
#if defined (DEBUG_OP)
1355
    cpu_dump_rfi(env->nip, do_load_msr(env));
1356
#endif
1357
    env->interrupt_request = CPU_INTERRUPT_EXITTB;
1325
    __do_rfi(env->spr[SPR_BOOKE_CSRR0], SPR_BOOKE_CSRR1,
1326
             ~((target_ulong)0x3FFF0000), 0);
1358 1327
}
1359 1328

  
1360 1329
void do_rfdi (void)
1361 1330
{
1362
#if defined(TARGET_PPC64)
1363
    if (env->spr[SPR_BOOKE_DSRR1] & (1 << MSR_CM)) {
1364
        env->nip = (uint64_t)env->spr[SPR_BOOKE_DSRR0];
1365
    } else
1366
#endif
1367
    {
1368
        env->nip = (uint32_t)env->spr[SPR_BOOKE_DSRR0];
1369
    }
1370
    do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_DSRR1] & ~0x3FFF0000);
1371
#if defined (DEBUG_OP)
1372
    cpu_dump_rfi(env->nip, do_load_msr(env));
1373
#endif
1374
    env->interrupt_request = CPU_INTERRUPT_EXITTB;
1331
    __do_rfi(env->spr[SPR_BOOKE_DSRR0], SPR_BOOKE_DSRR1,
1332
             ~((target_ulong)0x3FFF0000), 0);
1375 1333
}
1376 1334

  
1377 1335
void do_rfmci (void)
1378 1336
{
1379
#if defined(TARGET_PPC64)
1380
    if (env->spr[SPR_BOOKE_MCSRR1] & (1 << MSR_CM)) {
1381
        env->nip = (uint64_t)env->spr[SPR_BOOKE_MCSRR0];
1382
    } else
1383
#endif
1384
    {
1385
        env->nip = (uint32_t)env->spr[SPR_BOOKE_MCSRR0];
1386
    }
1387
    do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_MCSRR1] & ~0x3FFF0000);
1388
#if defined (DEBUG_OP)
1389
    cpu_dump_rfi(env->nip, do_load_msr(env));
1390
#endif
1391
    env->interrupt_request = CPU_INTERRUPT_EXITTB;
1337
    __do_rfi(env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1,
1338
             ~((target_ulong)0x3FFF0000), 0);
1392 1339
}
1393 1340

  
1394 1341
void do_load_403_pb (int num)

Also available in: Unified diff