1046 |
} |
} |
1047 |
|
|
1048 |
/*** Integer load ***/ |
/*** Integer load ***/ |
1049 |
|
#define op_ldst(name) (*gen_op_##name[ctx->mem_idx])() |
1050 |
#if defined(CONFIG_USER_ONLY) |
#if defined(CONFIG_USER_ONLY) |
1051 |
#define op_ldst(name) gen_op_##name##_raw() |
#define OP_LD_TABLE(width) \ |
1052 |
#define OP_LD_TABLE(width) |
static GenOpFunc *gen_op_l##width[] = { \ |
1053 |
#define OP_ST_TABLE(width) |
&gen_op_l##width##_raw, \ |
1054 |
|
&gen_op_l##width##_le_raw, \ |
1055 |
|
}; |
1056 |
|
#define OP_ST_TABLE(width) \ |
1057 |
|
static GenOpFunc *gen_op_st##width[] = { \ |
1058 |
|
&gen_op_st##width##_raw, \ |
1059 |
|
&gen_op_st##width##_le_raw, \ |
1060 |
|
}; |
1061 |
|
/* Byte access routine are endian safe */ |
1062 |
|
#define gen_op_stb_le_raw gen_op_stb_raw |
1063 |
|
#define gen_op_lbz_le_raw gen_op_lbz_raw |
1064 |
#else |
#else |
|
#define op_ldst(name) (*gen_op_##name[ctx->mem_idx])() |
|
1065 |
#define OP_LD_TABLE(width) \ |
#define OP_LD_TABLE(width) \ |
1066 |
static GenOpFunc *gen_op_l##width[] = { \ |
static GenOpFunc *gen_op_l##width[] = { \ |
1067 |
&gen_op_l##width##_user, \ |
&gen_op_l##width##_user, \ |
1068 |
|
&gen_op_l##width##_le_user, \ |
1069 |
&gen_op_l##width##_kernel, \ |
&gen_op_l##width##_kernel, \ |
1070 |
} |
&gen_op_l##width##_le_kernel, \ |
1071 |
|
}; |
1072 |
#define OP_ST_TABLE(width) \ |
#define OP_ST_TABLE(width) \ |
1073 |
static GenOpFunc *gen_op_st##width[] = { \ |
static GenOpFunc *gen_op_st##width[] = { \ |
1074 |
&gen_op_st##width##_user, \ |
&gen_op_st##width##_user, \ |
1075 |
|
&gen_op_st##width##_le_user, \ |
1076 |
&gen_op_st##width##_kernel, \ |
&gen_op_st##width##_kernel, \ |
1077 |
} |
&gen_op_st##width##_le_kernel, \ |
1078 |
|
}; |
1079 |
|
/* Byte access routine are endian safe */ |
1080 |
|
#define gen_op_stb_le_user gen_op_stb_user |
1081 |
|
#define gen_op_lbz_le_user gen_op_lbz_user |
1082 |
|
#define gen_op_stb_le_kernel gen_op_stb_kernel |
1083 |
|
#define gen_op_lbz_le_kernel gen_op_lbz_kernel |
1084 |
#endif |
#endif |
1085 |
|
|
1086 |
#define GEN_LD(width, opc) \ |
#define GEN_LD(width, opc) \ |
1251 |
GEN_STX(wbr, 0x16, 0x14); |
GEN_STX(wbr, 0x16, 0x14); |
1252 |
|
|
1253 |
/*** Integer load and store multiple ***/ |
/*** Integer load and store multiple ***/ |
1254 |
|
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg) |
1255 |
#if defined(CONFIG_USER_ONLY) |
#if defined(CONFIG_USER_ONLY) |
1256 |
#define op_ldstm(name, reg) gen_op_##name##_raw(reg) |
static GenOpFunc1 *gen_op_lmw[] = { |
1257 |
|
&gen_op_lmw_raw, |
1258 |
|
&gen_op_lmw_le_raw, |
1259 |
|
}; |
1260 |
|
static GenOpFunc1 *gen_op_stmw[] = { |
1261 |
|
&gen_op_stmw_raw, |
1262 |
|
&gen_op_stmw_le_raw, |
1263 |
|
}; |
1264 |
#else |
#else |
|
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg) |
|
1265 |
static GenOpFunc1 *gen_op_lmw[] = { |
static GenOpFunc1 *gen_op_lmw[] = { |
1266 |
&gen_op_lmw_user, |
&gen_op_lmw_user, |
1267 |
|
&gen_op_lmw_le_user, |
1268 |
&gen_op_lmw_kernel, |
&gen_op_lmw_kernel, |
1269 |
|
&gen_op_lmw_le_kernel, |
1270 |
}; |
}; |
1271 |
static GenOpFunc1 *gen_op_stmw[] = { |
static GenOpFunc1 *gen_op_stmw[] = { |
1272 |
&gen_op_stmw_user, |
&gen_op_stmw_user, |
1273 |
|
&gen_op_stmw_le_user, |
1274 |
&gen_op_stmw_kernel, |
&gen_op_stmw_kernel, |
1275 |
|
&gen_op_stmw_le_kernel, |
1276 |
}; |
}; |
1277 |
#endif |
#endif |
1278 |
|
|
1307 |
} |
} |
1308 |
|
|
1309 |
/*** Integer load and store strings ***/ |
/*** Integer load and store strings ***/ |
|
#if defined(CONFIG_USER_ONLY) |
|
|
#define op_ldsts(name, start) gen_op_##name##_raw(start) |
|
|
#define op_ldstsx(name, rd, ra, rb) gen_op_##name##_raw(rd, ra, rb) |
|
|
#else |
|
1310 |
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start) |
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start) |
1311 |
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb) |
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb) |
1312 |
|
#if defined(CONFIG_USER_ONLY) |
1313 |
|
static GenOpFunc1 *gen_op_lswi[] = { |
1314 |
|
&gen_op_lswi_raw, |
1315 |
|
&gen_op_lswi_le_raw, |
1316 |
|
}; |
1317 |
|
static GenOpFunc3 *gen_op_lswx[] = { |
1318 |
|
&gen_op_lswx_raw, |
1319 |
|
&gen_op_lswx_le_raw, |
1320 |
|
}; |
1321 |
|
static GenOpFunc1 *gen_op_stsw[] = { |
1322 |
|
&gen_op_stsw_raw, |
1323 |
|
&gen_op_stsw_le_raw, |
1324 |
|
}; |
1325 |
|
#else |
1326 |
static GenOpFunc1 *gen_op_lswi[] = { |
static GenOpFunc1 *gen_op_lswi[] = { |
1327 |
&gen_op_lswi_user, |
&gen_op_lswi_user, |
1328 |
|
&gen_op_lswi_le_user, |
1329 |
&gen_op_lswi_kernel, |
&gen_op_lswi_kernel, |
1330 |
|
&gen_op_lswi_le_kernel, |
1331 |
}; |
}; |
1332 |
static GenOpFunc3 *gen_op_lswx[] = { |
static GenOpFunc3 *gen_op_lswx[] = { |
1333 |
&gen_op_lswx_user, |
&gen_op_lswx_user, |
1334 |
|
&gen_op_lswx_le_user, |
1335 |
&gen_op_lswx_kernel, |
&gen_op_lswx_kernel, |
1336 |
|
&gen_op_lswx_le_kernel, |
1337 |
}; |
}; |
1338 |
static GenOpFunc1 *gen_op_stsw[] = { |
static GenOpFunc1 *gen_op_stsw[] = { |
1339 |
&gen_op_stsw_user, |
&gen_op_stsw_user, |
1340 |
|
&gen_op_stsw_le_user, |
1341 |
&gen_op_stsw_kernel, |
&gen_op_stsw_kernel, |
1342 |
|
&gen_op_stsw_le_kernel, |
1343 |
}; |
}; |
1344 |
#endif |
#endif |
1345 |
|
|
1435 |
{ |
{ |
1436 |
} |
} |
1437 |
|
|
1438 |
/* lwarx */ |
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])() |
1439 |
|
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])() |
1440 |
#if defined(CONFIG_USER_ONLY) |
#if defined(CONFIG_USER_ONLY) |
1441 |
#define op_lwarx() gen_op_lwarx_raw() |
static GenOpFunc *gen_op_lwarx[] = { |
1442 |
#define op_stwcx() gen_op_stwcx_raw() |
&gen_op_lwarx_raw, |
1443 |
|
&gen_op_lwarx_le_raw, |
1444 |
|
}; |
1445 |
|
static GenOpFunc *gen_op_stwcx[] = { |
1446 |
|
&gen_op_stwcx_raw, |
1447 |
|
&gen_op_stwcx_le_raw, |
1448 |
|
}; |
1449 |
#else |
#else |
|
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])() |
|
1450 |
static GenOpFunc *gen_op_lwarx[] = { |
static GenOpFunc *gen_op_lwarx[] = { |
1451 |
&gen_op_lwarx_user, |
&gen_op_lwarx_user, |
1452 |
|
&gen_op_lwarx_le_user, |
1453 |
&gen_op_lwarx_kernel, |
&gen_op_lwarx_kernel, |
1454 |
|
&gen_op_lwarx_le_kernel, |
1455 |
}; |
}; |
|
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])() |
|
1456 |
static GenOpFunc *gen_op_stwcx[] = { |
static GenOpFunc *gen_op_stwcx[] = { |
1457 |
&gen_op_stwcx_user, |
&gen_op_stwcx_user, |
1458 |
|
&gen_op_stwcx_le_user, |
1459 |
&gen_op_stwcx_kernel, |
&gen_op_stwcx_kernel, |
1460 |
|
&gen_op_stwcx_le_kernel, |
1461 |
}; |
}; |
1462 |
#endif |
#endif |
1463 |
|
|
1464 |
|
/* lwarx */ |
1465 |
GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_RES) |
GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_RES) |
1466 |
{ |
{ |
1467 |
if (rA(ctx->opcode) == 0) { |
if (rA(ctx->opcode) == 0) { |
2554 |
|
|
2555 |
/*** External control ***/ |
/*** External control ***/ |
2556 |
/* Optional: */ |
/* Optional: */ |
|
/* eciwx */ |
|
|
#if defined(CONFIG_USER_ONLY) |
|
|
#define op_eciwx() gen_op_eciwx_raw() |
|
|
#define op_ecowx() gen_op_ecowx_raw() |
|
|
#else |
|
2557 |
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])() |
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])() |
2558 |
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])() |
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])() |
2559 |
|
#if defined(CONFIG_USER_ONLY) |
2560 |
|
static GenOpFunc *gen_op_eciwx[] = { |
2561 |
|
&gen_op_eciwx_raw, |
2562 |
|
&gen_op_eciwx_le_raw, |
2563 |
|
}; |
2564 |
|
static GenOpFunc *gen_op_ecowx[] = { |
2565 |
|
&gen_op_ecowx_raw, |
2566 |
|
&gen_op_ecowx_le_raw, |
2567 |
|
}; |
2568 |
|
#else |
2569 |
static GenOpFunc *gen_op_eciwx[] = { |
static GenOpFunc *gen_op_eciwx[] = { |
2570 |
&gen_op_eciwx_user, |
&gen_op_eciwx_user, |
2571 |
|
&gen_op_eciwx_le_user, |
2572 |
&gen_op_eciwx_kernel, |
&gen_op_eciwx_kernel, |
2573 |
|
&gen_op_eciwx_le_kernel, |
2574 |
}; |
}; |
2575 |
static GenOpFunc *gen_op_ecowx[] = { |
static GenOpFunc *gen_op_ecowx[] = { |
2576 |
&gen_op_ecowx_user, |
&gen_op_ecowx_user, |
2577 |
|
&gen_op_ecowx_le_user, |
2578 |
&gen_op_ecowx_kernel, |
&gen_op_ecowx_kernel, |
2579 |
|
&gen_op_ecowx_le_kernel, |
2580 |
}; |
}; |
2581 |
#endif |
#endif |
2582 |
|
|
2583 |
|
/* eciwx */ |
2584 |
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN) |
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN) |
2585 |
{ |
{ |
2586 |
/* Should check EAR[E] & alignment ! */ |
/* Should check EAR[E] & alignment ! */ |
3209 |
ctx.tb = tb; |
ctx.tb = tb; |
3210 |
ctx.exception = EXCP_NONE; |
ctx.exception = EXCP_NONE; |
3211 |
#if defined(CONFIG_USER_ONLY) |
#if defined(CONFIG_USER_ONLY) |
3212 |
ctx.mem_idx = 0; |
ctx.mem_idx = msr_le; |
3213 |
#else |
#else |
3214 |
ctx.supervisor = 1 - msr_pr; |
ctx.supervisor = 1 - msr_pr; |
3215 |
ctx.mem_idx = 1 - msr_pr; |
ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le; |
3216 |
#endif |
#endif |
3217 |
ctx.fpu_enabled = msr_fp; |
ctx.fpu_enabled = msr_fp; |
3218 |
#if defined (DO_SINGLE_STEP) |
#if defined (DO_SINGLE_STEP) |
3239 |
} |
} |
3240 |
#endif |
#endif |
3241 |
ctx.opcode = ldl_code(ctx.nip); |
ctx.opcode = ldl_code(ctx.nip); |
3242 |
|
if (msr_le) { |
3243 |
|
ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) | |
3244 |
|
((ctx.opcode & 0x00FF0000) >> 8) | |
3245 |
|
((ctx.opcode & 0x0000FF00) << 8) | |
3246 |
|
((ctx.opcode & 0x000000FF) << 24); |
3247 |
|
} |
3248 |
#if defined PPC_DEBUG_DISAS |
#if defined PPC_DEBUG_DISAS |
3249 |
if (loglevel & CPU_LOG_TB_IN_ASM) { |
if (loglevel & CPU_LOG_TB_IN_ASM) { |
3250 |
fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n", |
fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n", |
3251 |
ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode), |
ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode), |
3252 |
opc3(ctx.opcode)); |
opc3(ctx.opcode), msr_le ? "little" : "big"); |
3253 |
} |
} |
3254 |
#endif |
#endif |
3255 |
ctx.nip += 4; |
ctx.nip += 4; |