qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2] MIPS: Translate breaks and traps into the ap


From: Meador Inge
Subject: Re: [Qemu-devel] [PATCH v2] MIPS: Translate breaks and traps into the appropriate signal
Date: Mon, 4 Feb 2013 13:46:17 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2

Ping: http://patchwork.ozlabs.org/patch/211162/.

On 01/10/2013 04:50 PM, Meador Inge wrote:
> GCC and GAS are capable of generating traps or breaks to check for
> division by zero.  Additionally, GAS is capable of generating traps
> or breaks to check for overflow on certain division and multiplication
> operations.  The Linux kernel translates these traps and breaks into
> signals.  This patch implements the corresponding feature in QEMU.
> 
> Signed-off-by: Meador Inge <address@hidden>
> ---
> Changes since v1:
> 
>   * Moved the BRK_* enumerations from target-mips/cpu.h to
>     linux-user/main.c since they are only used in main.c
> 
>   * Fixed some style violations found by checkpatch.pl.
> 
>   * Removed a superfluous break.
> 
>  linux-user/main.c |   76 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 75 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 9ade1bf..583940c 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -2182,6 +2182,33 @@ static int do_store_exclusive(CPUMIPSState *env)
>      return segv;
>  }
>  
> +/* Break codes */
> +enum {
> +    BRK_OVERFLOW = 6,
> +    BRK_DIVZERO = 7
> +};
> +
> +static int do_break(CPUMIPSState *env, target_siginfo_t *info,
> +                    unsigned int code)
> +{
> +    int ret = -1;
> +
> +    switch (code) {
> +    case BRK_OVERFLOW:
> +    case BRK_DIVZERO:
> +        info->si_signo = TARGET_SIGFPE;
> +        info->si_errno = 0;
> +        info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
> +        queue_signal(env, info->si_signo, &*info);
> +        ret = 0;
> +        break;
> +    default:
> +        break;
> +    }
> +
> +    return ret;
> +}
> +
>  void cpu_loop(CPUMIPSState *env)
>  {
>      target_siginfo_t info;
> @@ -2297,8 +2324,55 @@ done_syscall:
>              info.si_code = TARGET_ILL_ILLOPC;
>              queue_signal(env, info.si_signo, &info);
>              break;
> +        /* The code below was inspired by the MIPS Linux kernel trap
> +         * handling code in arch/mips/kernel/traps.c.
> +         */
> +        case EXCP_BREAK:
> +            {
> +                abi_ulong trap_instr;
> +                unsigned int code;
> +
> +                ret = get_user_ual(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;
> +                }
> +
> +                if (do_break(env, &info, code) != 0) {
> +                    goto error;
> +                }
> +            }
> +            break;
> +        case EXCP_TRAP:
> +            {
> +                abi_ulong trap_instr;
> +                unsigned int code = 0;
> +
> +                ret = get_user_ual(trap_instr, env->active_tc.PC);
> +                if (ret != 0) {
> +                    goto error;
> +                }
> +
> +                /* The immediate versions don't provide a code.  */
> +                if (!(trap_instr & 0xFC000000)) {
> +                    code = ((trap_instr >> 6) & ((1 << 10) - 1));
> +                }
> +
> +                if (do_break(env, &info, code) != 0) {
> +                    goto error;
> +                }
> +            }
> +            break;
>          default:
> -            //        error:
> +error:
>              fprintf(stderr, "qemu: unhandled CPU exception 0x%x - 
> aborting\n",
>                      trapnr);
>              cpu_dump_state(env, stderr, fprintf, 0);
> 


-- 
Meador Inge
CodeSourcery / Mentor Embedded



reply via email to

[Prev in Thread] Current Thread [Next in Thread]