127 |
127 |
/* internal defines */
|
128 |
128 |
typedef struct DisasContext {
|
129 |
129 |
struct TranslationBlock *tb;
|
130 |
|
uint32_t *nip;
|
|
130 |
uint32_t nip;
|
131 |
131 |
uint32_t opcode;
|
132 |
132 |
uint32_t exception;
|
133 |
133 |
/* Time base offset */
|
... | ... | |
1509 |
1509 |
|
1510 |
1510 |
gen_op_update_tb(ctx->tb_offset);
|
1511 |
1511 |
gen_op_update_decr(ctx->decr_offset);
|
1512 |
|
gen_op_process_exceptions((uint32_t)ctx->nip - 4);
|
|
1512 |
gen_op_process_exceptions(ctx->nip - 4);
|
1513 |
1513 |
if (AA(ctx->opcode) == 0)
|
1514 |
|
target = (uint32_t)ctx->nip + li - 4;
|
|
1514 |
target = ctx->nip + li - 4;
|
1515 |
1515 |
else
|
1516 |
1516 |
target = li;
|
1517 |
1517 |
if (LK(ctx->opcode)) {
|
1518 |
|
gen_op_setlr((uint32_t)ctx->nip);
|
|
1518 |
gen_op_setlr(ctx->nip);
|
1519 |
1519 |
}
|
1520 |
1520 |
gen_op_b((long)ctx->tb, target);
|
1521 |
1521 |
ctx->exception = EXCP_BRANCH;
|
... | ... | |
1535 |
1535 |
|
1536 |
1536 |
gen_op_update_tb(ctx->tb_offset);
|
1537 |
1537 |
gen_op_update_decr(ctx->decr_offset);
|
1538 |
|
gen_op_process_exceptions((uint32_t)ctx->nip - 4);
|
|
1538 |
gen_op_process_exceptions(ctx->nip - 4);
|
1539 |
1539 |
|
1540 |
1540 |
if ((bo & 0x4) == 0)
|
1541 |
1541 |
gen_op_dec_ctr();
|
... | ... | |
1543 |
1543 |
case BCOND_IM:
|
1544 |
1544 |
li = s_ext16(BD(ctx->opcode));
|
1545 |
1545 |
if (AA(ctx->opcode) == 0) {
|
1546 |
|
target = (uint32_t)ctx->nip + li - 4;
|
|
1546 |
target = ctx->nip + li - 4;
|
1547 |
1547 |
} else {
|
1548 |
1548 |
target = li;
|
1549 |
1549 |
}
|
... | ... | |
1557 |
1557 |
break;
|
1558 |
1558 |
}
|
1559 |
1559 |
if (LK(ctx->opcode)) {
|
1560 |
|
gen_op_setlr((uint32_t)ctx->nip);
|
|
1560 |
gen_op_setlr(ctx->nip);
|
1561 |
1561 |
}
|
1562 |
1562 |
if (bo & 0x10) {
|
1563 |
1563 |
/* No CR condition */
|
... | ... | |
1612 |
1612 |
}
|
1613 |
1613 |
}
|
1614 |
1614 |
if (type == BCOND_IM) {
|
1615 |
|
gen_op_btest((long)ctx->tb, target, (uint32_t)ctx->nip);
|
|
1615 |
gen_op_btest((long)ctx->tb, target, ctx->nip);
|
1616 |
1616 |
} else {
|
1617 |
|
gen_op_btest_T1((uint32_t)ctx->nip);
|
|
1617 |
gen_op_btest_T1(ctx->nip);
|
1618 |
1618 |
}
|
1619 |
1619 |
no_test:
|
1620 |
1620 |
ctx->exception = EXCP_BRANCH;
|
... | ... | |
2989 |
2989 |
gen_opc_ptr = gen_opc_buf;
|
2990 |
2990 |
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
|
2991 |
2991 |
gen_opparam_ptr = gen_opparam_buf;
|
2992 |
|
ctx.nip = (uint32_t *)pc_start;
|
|
2992 |
ctx.nip = pc_start;
|
2993 |
2993 |
ctx.tb_offset = 0;
|
2994 |
2994 |
ctx.decr_offset = 0;
|
2995 |
2995 |
ctx.tb = tb;
|
... | ... | |
3015 |
3015 |
lj++;
|
3016 |
3016 |
while (lj < j)
|
3017 |
3017 |
gen_opc_instr_start[lj++] = 0;
|
3018 |
|
gen_opc_pc[lj] = (uint32_t)ctx.nip;
|
|
3018 |
gen_opc_pc[lj] = ctx.nip;
|
3019 |
3019 |
gen_opc_instr_start[lj] = 1;
|
3020 |
3020 |
}
|
3021 |
3021 |
}
|
3022 |
3022 |
#if defined DEBUG_DISAS
|
3023 |
3023 |
if (loglevel > 0) {
|
3024 |
3024 |
fprintf(logfile, "----------------\n");
|
3025 |
|
fprintf(logfile, "nip=%p super=%d ir=%d\n",
|
|
3025 |
fprintf(logfile, "nip=%08x super=%d ir=%d\n",
|
3026 |
3026 |
ctx.nip, 1 - msr_pr, msr_ir);
|
3027 |
3027 |
}
|
3028 |
3028 |
#endif
|
3029 |
|
ctx.opcode = ldl_code(ctx.nip);
|
|
3029 |
ctx.opcode = ldl_code((void *)ctx.nip);
|
3030 |
3030 |
#if defined DEBUG_DISAS
|
3031 |
3031 |
if (loglevel > 0) {
|
3032 |
3032 |
fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n",
|
... | ... | |
3034 |
3034 |
opc3(ctx.opcode));
|
3035 |
3035 |
}
|
3036 |
3036 |
#endif
|
3037 |
|
ctx.nip++;
|
|
3037 |
ctx.nip += 4;
|
3038 |
3038 |
ctx.tb_offset++;
|
3039 |
3039 |
/* Check decrementer exception */
|
3040 |
3040 |
if (++ctx.decr_offset == env->decr + 1)
|
... | ... | |
3054 |
3054 |
if (loglevel > 0) {
|
3055 |
3055 |
if (handler->handler == &gen_invalid) {
|
3056 |
3056 |
fprintf(logfile, "invalid/unsupported opcode: "
|
3057 |
|
"%02x -%02x - %02x (%08x) %p\n",
|
|
3057 |
"%02x -%02x - %02x (%08x) 0x%08x\n",
|
3058 |
3058 |
opc1(ctx.opcode), opc2(ctx.opcode),
|
3059 |
|
opc3(ctx.opcode), ctx.opcode, ctx.nip - 1);
|
|
3059 |
opc3(ctx.opcode), ctx.opcode, ctx.nip - 4);
|
3060 |
3060 |
} else {
|
3061 |
3061 |
fprintf(logfile, "invalid bits: %08x for opcode: "
|
3062 |
|
"%02x -%02x - %02x (0x%08x) (%p)\n",
|
|
3062 |
"%02x -%02x - %02x (0x%08x) (0x%08x)\n",
|
3063 |
3063 |
ctx.opcode & handler->inval, opc1(ctx.opcode),
|
3064 |
3064 |
opc2(ctx.opcode), opc3(ctx.opcode),
|
3065 |
|
ctx.opcode, ctx.nip - 1);
|
|
3065 |
ctx.opcode, ctx.nip - 4);
|
3066 |
3066 |
}
|
3067 |
3067 |
} else {
|
3068 |
3068 |
if (handler->handler == &gen_invalid) {
|
3069 |
3069 |
printf("invalid/unsupported opcode: "
|
3070 |
|
"%02x -%02x - %02x (%08x) %p\n",
|
|
3070 |
"%02x -%02x - %02x (%08x) 0x%08x\n",
|
3071 |
3071 |
opc1(ctx.opcode), opc2(ctx.opcode),
|
3072 |
|
opc3(ctx.opcode), ctx.opcode, ctx.nip - 1);
|
|
3072 |
opc3(ctx.opcode), ctx.opcode, ctx.nip - 4);
|
3073 |
3073 |
} else {
|
3074 |
3074 |
printf("invalid bits: %08x for opcode: "
|
3075 |
|
"%02x -%02x - %02x (0x%08x) (%p)\n",
|
|
3075 |
"%02x -%02x - %02x (0x%08x) (0x%08x)\n",
|
3076 |
3076 |
ctx.opcode & handler->inval, opc1(ctx.opcode),
|
3077 |
3077 |
opc2(ctx.opcode), opc3(ctx.opcode),
|
3078 |
|
ctx.opcode, ctx.nip - 1);
|
|
3078 |
ctx.opcode, ctx.nip - 4);
|
3079 |
3079 |
}
|
3080 |
3080 |
}
|
3081 |
3081 |
(*gen_invalid)(&ctx);
|
... | ... | |
3089 |
3089 |
* - rfi, trap or syscall
|
3090 |
3090 |
* - first instruction of an exception handler
|
3091 |
3091 |
*/
|
3092 |
|
(msr_se && ((uint32_t)ctx.nip < 0x100 ||
|
3093 |
|
(uint32_t)ctx.nip > 0xF00 ||
|
3094 |
|
((uint32_t)ctx.nip & 0xFC) != 0x04) &&
|
|
3092 |
(msr_se && (ctx.nip < 0x100 ||
|
|
3093 |
ctx.nip > 0xF00 ||
|
|
3094 |
(ctx.nip & 0xFC) != 0x04) &&
|
3095 |
3095 |
ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI &&
|
3096 |
3096 |
ctx.exception != EXCP_TRAP)) {
|
3097 |
3097 |
#if !defined(CONFIG_USER_ONLY)
|
... | ... | |
3102 |
3102 |
}
|
3103 |
3103 |
}
|
3104 |
3104 |
/* if we reach a page boundary, stop generation */
|
3105 |
|
if (((uint32_t)ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
|
|
3105 |
if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
|
3106 |
3106 |
if (ctx.exception == EXCP_NONE) {
|
3107 |
|
gen_op_b((long)ctx.tb, (uint32_t)ctx.nip);
|
|
3107 |
gen_op_b((long)ctx.tb, ctx.nip);
|
3108 |
3108 |
ctx.exception = EXCP_BRANCH;
|
3109 |
3109 |
}
|
3110 |
3110 |
}
|
... | ... | |
3113 |
3113 |
if (ctx.exception != EXCP_BRANCH && ctx.exception != EXCP_RFI) {
|
3114 |
3114 |
gen_op_update_tb(ctx.tb_offset);
|
3115 |
3115 |
gen_op_update_decr(ctx.decr_offset);
|
3116 |
|
gen_op_process_exceptions((uint32_t)ctx.nip);
|
|
3116 |
gen_op_process_exceptions(ctx.nip);
|
3117 |
3117 |
}
|
3118 |
3118 |
#if 1
|
3119 |
3119 |
/* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
|
... | ... | |
3136 |
3136 |
}
|
3137 |
3137 |
#endif
|
3138 |
3138 |
} else {
|
3139 |
|
tb->size = (uint32_t)ctx.nip - pc_start;
|
|
3139 |
tb->size = ctx.nip - pc_start;
|
3140 |
3140 |
}
|
3141 |
3141 |
env->access_type = ACCESS_INT;
|
3142 |
3142 |
#ifdef DEBUG_DISAS
|
... | ... | |
3144 |
3144 |
fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
|
3145 |
3145 |
cpu_ppc_dump_state(env, logfile, 0);
|
3146 |
3146 |
fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
|
3147 |
|
disas(logfile, (void *)pc_start, (uint32_t)ctx.nip - pc_start, 0, 0);
|
|
3147 |
disas(logfile, (void *)pc_start, ctx.nip - pc_start, 0, 0);
|
3148 |
3148 |
fprintf(logfile, "\n");
|
3149 |
3149 |
|
3150 |
3150 |
fprintf(logfile, "OP:\n");
|