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