From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] SH4: Implement FD bit
Date: Sun, 7 Dec 2008 23:47:34 +0100 [thread overview]
Message-ID: <20081207224734.GD3591@volta.aurel32.net> (raw)
In-Reply-To: <200812012022.02276.vladimir@codesourcery.com>
On Mon, Dec 01, 2008 at 08:22:02PM +0300, Vladimir Prus wrote:
>
> SH4 manual say that if a floating point instruction is executed while
> FD bit in the status register is 1, an exception should be raised. QEMU
> presently does not do that, so the kernel does not initialize FP state
> for any thread, nor does it save/restore FP state. The most apparent
> consequence is that while recent gcc/libc expect double-precision mode
> to be set by kernel, they run in single-precision mode, and all FP code
> produces wrong values.
>
> This patch fixes this. It also fixes a couple of places where PC was
> not updated before handling an exception, although both those places
> deal with invalid instruction and don't lead to any user-visible bugs.
>
> - Volodya
Thanks, applied.
> commit 0cbaa15c2db2168937fa154d5f1f625497392552
> Author: Vladimir Prus <vladimir@codesourcery.com>
> Date: Mon Dec 1 19:28:32 2008 +0300
>
> SH: Implement FD bit
>
> * target-sh4/cpu.h (cpu_get_tb_cpu_state): Include SR's FD bit in
> the flags.
> * target-sh4/helper.h (raise_fpu_disable, raise_slot_fpu_disable):
> New helpers.
> * targets-sh4/op_helper.c (helper_raise_fpu_disable)
> (helper_raise_slot_fpu_disable): New.
> * target-sh4/translate.c (CHECK_NOT_DELAY_SLOT, CHECK_PRIVILEGED):
> Set PC to the right value.
> (CHECK_FPU_ENABLED): New.
> (_decode_opc): Use CHECK_FPU_ENABLED for FP instructions.
>
> diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
> index aae9b42..e6c658e 100644
> --- a/target-sh4/cpu.h
> +++ b/target-sh4/cpu.h
> @@ -294,6 +294,7 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
> | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */
> | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */
> | (env->sr & (SR_MD | SR_RB)) /* Bits 29-30 */
> + | (env->sr & SR_FD) /* Bit 15 */
> | (env->store_requests ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
> }
>
> diff --git a/target-sh4/helper.h b/target-sh4/helper.h
> index c3f6393..d995688 100644
> --- a/target-sh4/helper.h
> +++ b/target-sh4/helper.h
> @@ -3,6 +3,8 @@
> DEF_HELPER_0(ldtlb, void)
> DEF_HELPER_0(raise_illegal_instruction, void)
> DEF_HELPER_0(raise_slot_illegal_instruction, void)
> +DEF_HELPER_0(raise_fpu_disable, void)
> +DEF_HELPER_0(raise_slot_fpu_disable, void)
> DEF_HELPER_0(debug, void)
> DEF_HELPER_1(sleep, void, i32)
> DEF_HELPER_1(trapa, void, i32)
> diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
> index c18d67c..b4982b0 100644
> --- a/target-sh4/op_helper.c
> +++ b/target-sh4/op_helper.c
> @@ -89,6 +89,18 @@ void helper_raise_slot_illegal_instruction(void)
> cpu_loop_exit();
> }
>
> +void helper_raise_fpu_disable(void)
> +{
> + env->exception_index = 0x800;
> + cpu_loop_exit();
> +}
> +
> +void helper_raise_slot_fpu_disable(void)
> +{
> + env->exception_index = 0x820;
> + cpu_loop_exit();
> +}
> +
> void helper_debug(void)
> {
> env->exception_index = EXCP_DEBUG;
> diff --git a/target-sh4/translate.c b/target-sh4/translate.c
> index 80c0f30..d11a738 100644
> --- a/target-sh4/translate.c
> +++ b/target-sh4/translate.c
> @@ -457,17 +457,36 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
> #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
>
> #define CHECK_NOT_DELAY_SLOT \
> - if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
> - {gen_helper_raise_slot_illegal_instruction(); ctx->bstate = BS_EXCP; \
> - return;}
> + if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
> + { \
> + tcg_gen_movi_i32(cpu_pc, ctx->pc-2); \
> + gen_helper_raise_slot_illegal_instruction(); \
> + ctx->bstate = BS_EXCP; \
> + return; \
> + }
>
> #define CHECK_PRIVILEGED \
> if (IS_USER(ctx)) { \
> + tcg_gen_movi_i32(cpu_pc, ctx->pc); \
> gen_helper_raise_illegal_instruction(); \
> ctx->bstate = BS_EXCP; \
> return; \
> }
>
> +#define CHECK_FPU_ENABLED \
> + if (ctx->flags & SR_FD) \
> + { \
> + if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
> + tcg_gen_movi_i32(cpu_pc, ctx->pc-2); \
> + gen_helper_raise_slot_fpu_disable(); \
> + } else { \
> + tcg_gen_movi_i32(cpu_pc, ctx->pc); \
> + gen_helper_raise_fpu_disable(); \
> + } \
> + ctx->bstate = BS_EXCP; \
> + return; \
> + }
> +
> static void _decode_opc(DisasContext * ctx)
> {
> /* This code tries to make movcal emulation sufficiently
> @@ -504,6 +523,13 @@ static void _decode_opc(DisasContext * ctx)
> }
> }
>
> + /* The 0xfffd instruction is underfined, so we don't want to
> + raise fpu disable exception on it. */
> + if (((ctx->opcode & 0xf000) == 0xf000)
> + && (ctx->opcode != 0xfffd))
> + {
> + CHECK_FPU_ENABLED
> + }
> #if 0
> fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
> #endif
> @@ -1498,12 +1524,14 @@ static void _decode_opc(DisasContext * ctx)
> LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
> LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
> LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022, {})
> - LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {})
> + LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
> case 0x406a: /* lds Rm,FPSCR */
> + CHECK_FPU_ENABLED
> gen_helper_ld_fpscr(REG(B11_8));
> ctx->bstate = BS_STOP;
> return;
> case 0x4066: /* lds.l @Rm+,FPSCR */
> + CHECK_FPU_ENABLED
> {
> TCGv addr = tcg_temp_new();
> tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
> @@ -1514,9 +1542,11 @@ static void _decode_opc(DisasContext * ctx)
> }
> return;
> case 0x006a: /* sts FPSCR,Rn */
> + CHECK_FPU_ENABLED
> tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
> return;
> case 0x4062: /* sts FPSCR,@-Rn */
> + CHECK_FPU_ENABLED
> {
> TCGv addr, val;
> val = tcg_temp_new();
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' aurel32@debian.org | aurelien@aurel32.net
`- people.debian.org/~aurel32 | www.aurel32.net
next prev parent reply other threads:[~2008-12-07 22:47 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-01 17:22 [Qemu-devel] SH4: Implement FD bit Vladimir Prus
2008-12-07 22:47 ` Aurelien Jarno [this message]
2008-12-09 16:36 ` [Qemu-devel] " Vladimir Prus
2008-12-10 9:15 ` Aurelien Jarno
2008-12-10 11:04 ` [Qemu-devel] " Vladimir Prus
2008-12-10 17:31 ` Aurelien Jarno
2008-12-11 20:12 ` [Qemu-devel] " Lionel Landwerlin
2008-12-11 20:57 ` Laurent Desnogues
2008-12-11 22:02 ` Lionel Landwerlin
2008-12-11 22:21 ` Laurent Desnogues
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081207224734.GD3591@volta.aurel32.net \
--to=aurelien@aurel32.net \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.