From: Yongbok Kim <yongbok.kim@imgtec.com>
To: Leon Alrae <leon.alrae@imgtec.com>, qemu-devel@nongnu.org
Cc: aurelien@aurel32.net
Subject: Re: [Qemu-devel] [PATCH 2/6] target-mips: implement forbidden slot
Date: Mon, 20 Oct 2014 12:10:41 +0100 [thread overview]
Message-ID: <5444EDB1.5090607@imgtec.com> (raw)
In-Reply-To: <1405354795-25884-3-git-send-email-leon.alrae@imgtec.com>
On 14/07/2014 17:19, Leon Alrae wrote:
> When conditional compact branch is encountered decode one more instruction in
> current translation block - that will be forbidden slot. Instruction in
> forbidden slot will be executed only if conditional compact branch is not taken.
>
> Any control transfer instruction (CTI) which are branches, jumps, ERET,
> DERET, WAIT and PAUSE will generate RI exception if executed in forbidden or
> delay slot.
>
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
> target-mips/cpu.h | 5 ++-
> target-mips/translate.c | 89 +++++++++++++++++++++++++++++++---------------
> 2 files changed, 63 insertions(+), 31 deletions(-)
>
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index 2a762d2..a35ab9d 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -462,7 +462,7 @@ struct CPUMIPSState {
> #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
> uint32_t hflags; /* CPU State */
> /* TMASK defines different execution modes */
> -#define MIPS_HFLAG_TMASK 0x2C07FF
> +#define MIPS_HFLAG_TMASK 0x6C07FF
> #define MIPS_HFLAG_MODE 0x00007 /* execution modes */
> /* The KSU flags must be the lowest bits in hflags. The flag order
> must be the same as defined for CP0 Status. This allows to use
> @@ -488,7 +488,7 @@ struct CPUMIPSState {
> * the delay slot, record what type of branch it is so that we can
> * resume translation properly. It might be possible to reduce
> * this from three bits to two. */
> -#define MIPS_HFLAG_BMASK_BASE 0x03800
> +#define MIPS_HFLAG_BMASK_BASE 0x403800
> #define MIPS_HFLAG_B 0x00800 /* Unconditional branch */
> #define MIPS_HFLAG_BC 0x01000 /* Conditional branch */
> #define MIPS_HFLAG_BL 0x01800 /* Likely branch */
> @@ -506,6 +506,7 @@ struct CPUMIPSState {
> /* Extra flag about HWREna register. */
> #define MIPS_HFLAG_HWRENA_ULR 0x100000 /* ULR bit from HWREna is set. */
> #define MIPS_HFLAG_SBRI 0x200000 /* R6 SDBBP causes RI excpt. in user mode */
> +#define MIPS_HFLAG_FBNSLOT 0x400000 /* Forbidden slot */
> target_ulong btarget; /* Jump / branch target */
> target_ulong bcond; /* Branch condition (if needed) */
>
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index d0f695a..4ed81fe 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -7686,12 +7686,20 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
> case OPC_ERET:
> opn = "eret";
> check_insn(ctx, ISA_MIPS2);
> + if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
> + MIPS_DEBUG("CTI in delay / forbidden slot");
> + goto die;
> + }
> gen_helper_eret(cpu_env);
> ctx->bstate = BS_EXCP;
> break;
> case OPC_DERET:
> opn = "deret";
> check_insn(ctx, ISA_MIPS32);
> + if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
> + MIPS_DEBUG("CTI in delay / forbidden slot");
> + goto die;
> + }
> if (!(ctx->hflags & MIPS_HFLAG_DM)) {
> MIPS_INVAL(opn);
> generate_exception(ctx, EXCP_RI);
> @@ -7703,6 +7711,10 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
> case OPC_WAIT:
> opn = "wait";
> check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
> + if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
> + MIPS_DEBUG("CTI in delay / forbidden slot");
> + goto die;
> + }
> /* If we get an exception, we want to restart at next instruction */
> ctx->pc += 4;
> save_cpu_state(ctx, 1);
> @@ -7729,6 +7741,12 @@ static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
> const char *opn = "cp1 cond branch";
> TCGv_i32 t0 = tcg_temp_new_i32();
>
> + if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
> + MIPS_DEBUG("CTI in delay / forbidden slot");
> + generate_exception(ctx, EXCP_RI);
> + goto out;
> + }
> +
> if (cc != 0)
> check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
>
> @@ -10299,6 +10317,10 @@ static void gen_branch(DisasContext *ctx, int insn_bytes)
> save_cpu_state(ctx, 0);
> /* FIXME: Need to clear can_do_io. */
> switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
> + case MIPS_HFLAG_FBNSLOT:
> + MIPS_DEBUG("forbidden slot");
> + gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
> + break;
> case MIPS_HFLAG_B:
> /* unconditional branch */
> MIPS_DEBUG("unconditional branch");
> @@ -15711,56 +15733,56 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
> gen_branch(ctx, 4);
> } else {
> /* Conditional compact branch */
> - int l1 = gen_new_label();
> + int fs = gen_new_label();
> save_cpu_state(ctx, 0);
>
> switch (opc) {
> case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
> if (rs == 0 && rt != 0) {
> /* OPC_BLEZALC */
> - tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
> } else if (rs != 0 && rt != 0 && rs == rt) {
> /* OPC_BGEZALC */
> - tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
> } else {
> /* OPC_BGEUC */
> - tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
> + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
> }
> break;
> case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
> if (rs == 0 && rt != 0) {
> /* OPC_BGTZALC */
> - tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
> } else if (rs != 0 && rt != 0 && rs == rt) {
> /* OPC_BLTZALC */
> - tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
> } else {
> /* OPC_BLTUC */
> - tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
> + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
> }
> break;
> case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
> if (rs == 0 && rt != 0) {
> /* OPC_BLEZC */
> - tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
> } else if (rs != 0 && rt != 0 && rs == rt) {
> /* OPC_BGEZC */
> - tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
> } else {
> /* OPC_BGEC */
> - tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
> + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
> }
> break;
> case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
> if (rs == 0 && rt != 0) {
> /* OPC_BGTZC */
> - tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
> } else if (rs != 0 && rt != 0 && rs == rt) {
> /* OPC_BLTZC */
> - tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
> } else {
> /* OPC_BLTC */
> - tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
> + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
> }
> break;
> case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
> @@ -15789,10 +15811,10 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
> tcg_gen_or_tl(t4, t4, input_overflow);
> if (opc == OPC_BOVC) {
> /* OPC_BOVC */
> - tcg_gen_brcondi_tl(TCG_COND_NE, t4, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
> } else {
> /* OPC_BNVC */
> - tcg_gen_brcondi_tl(TCG_COND_EQ, t4, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
> }
> tcg_temp_free(input_overflow);
> tcg_temp_free(t4);
> @@ -15802,27 +15824,27 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
> /* OPC_BEQZALC, OPC_BNEZALC */
> if (opc == OPC_BEQZALC) {
> /* OPC_BEQZALC */
> - tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
> } else {
> /* OPC_BNEZALC */
> - tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
> }
> } else {
> /* OPC_BEQC, OPC_BNEC */
> if (opc == OPC_BEQC) {
> /* OPC_BEQC */
> - tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
> + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
> } else {
> /* OPC_BNEC */
> - tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
> + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
> }
> }
> break;
> case OPC_BEQZC:
> - tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
> break;
> case OPC_BNEZC:
> - tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
> + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
> break;
> default:
> MIPS_INVAL("Compact conditional branch/jump");
> @@ -15831,12 +15853,11 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
> }
>
> /* Generating branch here as compact branches don't have delay slot */
> - /* TODO: implement forbidden slot */
> - gen_goto_tb(ctx, 1, ctx->pc + 4);
> - gen_set_label(l1);
> - gen_goto_tb(ctx, 0, ctx->btarget);
> + gen_goto_tb(ctx, 1, ctx->btarget);
> + gen_set_label(fs);
> +
> + ctx->hflags |= MIPS_HFLAG_FBNSLOT;
> MIPS_DEBUG("Compact conditional branch");
> - ctx->bstate = BS_BRANCH;
> }
>
> out:
> @@ -16054,6 +16075,16 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
> op1 = MASK_SPECIAL(ctx->opcode);
> switch (op1) {
> case OPC_SLL: /* Shift with immediate */
> + if (sa == 5 && rd == 0 &&
> + rs == 0 && rt == 0) { /* PAUSE */
> + if (ctx->insn_flags & ISA_MIPS32R6 &&
> + ctx->hflags & MIPS_HFLAG_BMASK) {
> + MIPS_DEBUG("CTI in delay / forbidden slot");
> + generate_exception(ctx, EXCP_RI);
> + break;
> + }
> + }
> + /* Fallthrough */
> case OPC_SRA:
> gen_shift_imm(ctx, op1, rd, rt, sa);
> break;
> @@ -17647,7 +17678,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
> int num_insns;
> int max_insns;
> int insn_bytes;
> - int is_delay;
> + int is_slot;
>
> if (search_pc)
> qemu_log("search pc %d\n", search_pc);
> @@ -17712,7 +17743,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
> if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
> gen_io_start();
>
> - is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
> + is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
> if (!(ctx.hflags & MIPS_HFLAG_M16)) {
> ctx.opcode = cpu_ldl_code(env, ctx.pc);
> insn_bytes = 4;
> @@ -17729,7 +17760,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
> break;
> }
>
> - if (is_delay) {
> + if (is_slot) {
> gen_branch(&ctx, insn_bytes);
> }
> ctx.pc += insn_bytes;
Comments on 4155 , 7839 and 15616 are also required changes to indicate
it might be delay or forbidden slot.
Otherwise,
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Regards,
Yongbok
next prev parent reply other threads:[~2014-10-20 11:10 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-14 16:19 [Qemu-devel] [PATCH 0/6] target-mips: implement new MIPS64 Release 6 features Leon Alrae
2014-07-14 16:19 ` [Qemu-devel] [PATCH 1/6] target-mips: add Config5.SBRI Leon Alrae
2014-10-16 14:32 ` Yongbok Kim
2014-07-14 16:19 ` [Qemu-devel] [PATCH 2/6] target-mips: implement forbidden slot Leon Alrae
2014-10-20 11:10 ` Yongbok Kim [this message]
2014-07-14 16:19 ` [Qemu-devel] [PATCH 3/6] target-mips: CP0_Status.CU0 no longer allows the user to access CP0 Leon Alrae
2014-10-17 9:58 ` Yongbok Kim
2014-07-14 16:19 ` [Qemu-devel] [PATCH 4/6] target-mips: add restrictions for possible values in registers Leon Alrae
2014-10-20 10:19 ` Yongbok Kim
2014-10-21 13:54 ` Leon Alrae
2014-07-14 16:19 ` [Qemu-devel] [PATCH 5/6] target-mips: correctly handle access to unimplemented CP0 register Leon Alrae
2014-10-20 10:49 ` Yongbok Kim
2014-07-14 16:19 ` [Qemu-devel] [PATCH 6/6] target-mips: enable features in MIPS64R6-generic CPU Leon Alrae
2014-10-20 14:23 ` Yongbok Kim
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=5444EDB1.5090607@imgtec.com \
--to=yongbok.kim@imgtec.com \
--cc=aurelien@aurel32.net \
--cc=leon.alrae@imgtec.com \
--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.