[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 56/68] target/nios2: Implement Misaligned destination exception
From: |
Richard Henderson |
Subject: |
[PULL 56/68] target/nios2: Implement Misaligned destination exception |
Date: |
Tue, 26 Apr 2022 11:18:55 -0700 |
Indirect branches, plus eret and bret optionally raise
an exception when branching to a misaligned address.
The exception is required when an mmu is enabled, but
enable it always because the fallback behaviour is not
documented (though presumably it discards low bits).
For the purposes of the linux-user cpu loop, if EXCP_UNALIGN
(misaligned data) were to arrive, it would be treated the
same as EXCP_UNALIGND (misaligned destination). See the
!defined(CONFIG_NIOS2_ALIGNMENT_TRAP) block in kernel/traps.c.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220421151735.31996-53-richard.henderson@linaro.org>
---
linux-user/nios2/cpu_loop.c | 6 ++++++
target/nios2/op_helper.c | 9 ++++++++-
target/nios2/translate.c | 15 ++++++++++++++-
3 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/linux-user/nios2/cpu_loop.c b/linux-user/nios2/cpu_loop.c
index 11ecb71843..30a27f252b 100644
--- a/linux-user/nios2/cpu_loop.c
+++ b/linux-user/nios2/cpu_loop.c
@@ -42,6 +42,12 @@ void cpu_loop(CPUNios2State *env)
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->pc);
break;
+ case EXCP_UNALIGN:
+ case EXCP_UNALIGND:
+ force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN,
+ env->ctrl[CR_BADADDR]);
+ break;
+
case EXCP_TRAP:
/*
* TODO: This advance should be done in the translator, as
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c
index a19b504b0e..38a71a1f2d 100644
--- a/target/nios2/op_helper.c
+++ b/target/nios2/op_helper.c
@@ -64,6 +64,13 @@ uint32_t helper_divu(CPUNios2State *env, uint32_t num,
uint32_t den)
void helper_eret(CPUNios2State *env, uint32_t new_status, uint32_t new_pc)
{
Nios2CPU *cpu = env_archcpu(env);
+ CPUState *cs = env_cpu(env);
+
+ if (unlikely(new_pc & 3)) {
+ env->ctrl[CR_BADADDR] = new_pc;
+ cs->exception_index = EXCP_UNALIGND;
+ cpu_loop_exit_restore(cs, GETPC());
+ }
/*
* Both estatus and bstatus have no constraints on write;
@@ -74,6 +81,6 @@ void helper_eret(CPUNios2State *env, uint32_t new_status,
uint32_t new_pc)
env->ctrl[CR_STATUS] = new_status;
env->pc = new_pc;
- cpu_loop_exit(env_cpu(env));
+ cpu_loop_exit(cs);
}
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index a3e87beba4..794b763d8a 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -197,11 +197,24 @@ static void gen_goto_tb(DisasContext *dc, int n, uint32_t
dest)
static void gen_jumpr(DisasContext *dc, int regno, bool is_call)
{
- tcg_gen_mov_tl(cpu_pc, load_gpr(dc, regno));
+ TCGLabel *l = gen_new_label();
+ TCGv test = tcg_temp_new();
+ TCGv dest = load_gpr(dc, regno);
+
+ tcg_gen_andi_tl(test, dest, 3);
+ tcg_gen_brcondi_tl(TCG_COND_NE, test, 0, l);
+ tcg_temp_free(test);
+
+ tcg_gen_mov_tl(cpu_pc, dest);
if (is_call) {
tcg_gen_movi_tl(dest_gpr(dc, R_RA), dc->base.pc_next);
}
tcg_gen_lookup_and_goto_ptr();
+
+ gen_set_label(l);
+ tcg_gen_st_tl(dest, cpu_env, offsetof(CPUNios2State, ctrl[CR_BADADDR]));
+ t_gen_helper_raise_exception(dc, EXCP_UNALIGND);
+
dc->base.is_jmp = DISAS_NORETURN;
}
--
2.34.1
- [PULL 34/68] target/nios2: Handle EXCP_UNALIGN and EXCP_UNALIGND, (continued)
- [PULL 34/68] target/nios2: Handle EXCP_UNALIGN and EXCP_UNALIGND, Richard Henderson, 2022/04/26
- [PULL 35/68] target/nios2: Cleanup set of CR_EXCEPTION for do_interrupt, Richard Henderson, 2022/04/26
- [PULL 31/68] target/nios2: Create EXCP_SEMIHOST for semi-hosting, Richard Henderson, 2022/04/26
- [PULL 36/68] target/nios2: Clean up handling of tlbmisc in do_exception, Richard Henderson, 2022/04/26
- [PULL 40/68] target/nios2: Remove CPU_INTERRUPT_NMI, Richard Henderson, 2022/04/26
- [PULL 43/68] target/nios2: Split out named structs for [IRJ]_TYPE, Richard Henderson, 2022/04/26
- [PULL 46/68] target/nios2: Split out helpers for gen_r_math_logic, Richard Henderson, 2022/04/26
- [PULL 44/68] target/nios2: Split out helpers for gen_i_cmpxx, Richard Henderson, 2022/04/26
- [PULL 49/68] target/nios2: Introduce dest_gpr, Richard Henderson, 2022/04/26
- [PULL 51/68] target/nios2: Enable unaligned traps for system mode, Richard Henderson, 2022/04/26
- [PULL 56/68] target/nios2: Implement Misaligned destination exception,
Richard Henderson <=
- [PULL 53/68] target/nios2: Hoist set of is_jmp into gen_goto_tb, Richard Henderson, 2022/04/26
- [PULL 41/68] target/nios2: Support division error exception, Richard Henderson, 2022/04/26
- [PULL 42/68] target/nios2: Use tcg_constant_tl, Richard Henderson, 2022/04/26
- [PULL 54/68] target/nios2: Use gen_goto_tb for DISAS_TOO_MANY, Richard Henderson, 2022/04/26
- [PULL 64/68] hw/nios2: Introduce Nios2MachineState, Richard Henderson, 2022/04/26
- [PULL 45/68] target/nios2: Split out helpers for gen_i_math_logic, Richard Henderson, 2022/04/26
- [PULL 50/68] target/nios2: Drop CR_STATUS_EH from tb->flags, Richard Henderson, 2022/04/26
- [PULL 52/68] target/nios2: Create gen_jumpr, Richard Henderson, 2022/04/26
- [PULL 57/68] target/nios2: Introduce shadow register sets, Richard Henderson, 2022/04/26
- [PULL 55/68] target/nios2: Use tcg_gen_lookup_and_goto_ptr, Richard Henderson, 2022/04/26