mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
target/mips: Extract break code into env->error_code
Simplify cpu_loop by doing all of the decode in translate. This fixes a bug in that cpu_loop was not handling the different layout of the R6 version of break16. This fixes a bug in that cpu_loop extracted the wrong bits for the mips16e break16 instruction. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220107213243.212806-17-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
parent
73c0aa6a85
commit
6f3533dd1b
5 changed files with 25 additions and 69 deletions
|
@ -65,6 +65,7 @@ void cpu_loop(CPUMIPSState *env)
|
|||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr, si_code;
|
||||
unsigned int code;
|
||||
abi_long ret;
|
||||
# ifdef TARGET_ABI_MIPSO32
|
||||
unsigned int syscall_num;
|
||||
|
@ -185,71 +186,15 @@ done_syscall:
|
|||
* handling code in arch/mips/kernel/traps.c.
|
||||
*/
|
||||
case EXCP_BREAK:
|
||||
{
|
||||
abi_ulong trap_instr;
|
||||
unsigned int code;
|
||||
|
||||
/*
|
||||
* FIXME: It would be better to decode the trap number
|
||||
* during translate, and store it in error_code while
|
||||
* raising the exception. We should not be re-reading
|
||||
* the opcode here.
|
||||
*/
|
||||
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
if (env->insn_flags & ASE_MICROMIPS) {
|
||||
/* microMIPS mode */
|
||||
ret = get_user_u16(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((trap_instr >> 10) == 0x11) {
|
||||
/* 16-bit instruction */
|
||||
code = trap_instr & 0xf;
|
||||
} else {
|
||||
/* 32-bit instruction */
|
||||
abi_ulong instr_lo;
|
||||
|
||||
ret = get_user_u16(instr_lo,
|
||||
env->active_tc.PC + 2);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
trap_instr = (trap_instr << 16) | instr_lo;
|
||||
code = ((trap_instr >> 6) & ((1 << 20) - 1));
|
||||
/* Unfortunately, microMIPS also suffers from
|
||||
the old assembler bug... */
|
||||
if (code >= (1 << 10)) {
|
||||
code >>= 10;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* MIPS16e mode */
|
||||
ret = get_user_u16(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
code = (trap_instr >> 6) & 0x3f;
|
||||
}
|
||||
} else {
|
||||
ret = get_user_u32(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* As described in the original Linux kernel code, the
|
||||
* below checks on 'code' are to work around an old
|
||||
* assembly bug.
|
||||
*/
|
||||
code = ((trap_instr >> 6) & ((1 << 20) - 1));
|
||||
if (code >= (1 << 10)) {
|
||||
code >>= 10;
|
||||
}
|
||||
}
|
||||
|
||||
do_tr_or_bp(env, code, false);
|
||||
/*
|
||||
* As described in the original Linux kernel code, the below
|
||||
* checks on 'code' are to work around an old assembly bug.
|
||||
*/
|
||||
code = env->error_code;
|
||||
if (code >= (1 << 10)) {
|
||||
code >>= 10;
|
||||
}
|
||||
do_tr_or_bp(env, code, false);
|
||||
break;
|
||||
case EXCP_TRAP:
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue