[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 39/48] target/nios2: Implement Misaligned destination exceptio
|
From: |
Richard Henderson |
|
Subject: |
[PATCH v5 39/48] target/nios2: Implement Misaligned destination exception |
|
Date: |
Thu, 10 Mar 2022 03:27:16 -0800 |
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.
Signed-off-by: Richard Henderson <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 ea364b7d1f..67220128aa 100644
--- a/linux-user/nios2/cpu_loop.c
+++ b/linux-user/nios2/cpu_loop.c
@@ -43,6 +43,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:
switch (env->error_code) {
case 0:
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c
index c93b66c9aa..849867becd 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 f7bab0908b..1e784c8a37 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -170,11 +170,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.25.1
- [PATCH v5 30/48] target/nios2: Support division error exception, (continued)
- [PATCH v5 30/48] target/nios2: Support division error exception, Richard Henderson, 2022/03/10
- [PATCH v5 28/48] target/nios2: Implement CR_STATUS.RSIE, Richard Henderson, 2022/03/10
- [PATCH v5 33/48] target/nios2: Drop CR_STATUS_EH from tb->flags, Richard Henderson, 2022/03/10
- [PATCH v5 32/48] target/nios2: Introduce dest_gpr, Richard Henderson, 2022/03/10
- [PATCH v5 34/48] target/nios2: Enable unaligned traps for system mode, Richard Henderson, 2022/03/10
- [PATCH v5 38/48] target/nios2: Use tcg_gen_lookup_and_goto_ptr, Richard Henderson, 2022/03/10
- [PATCH v5 31/48] target/nios2: Use tcg_constant_tl, Richard Henderson, 2022/03/10
- [PATCH v5 35/48] target/nios2: Create gen_jumpr, Richard Henderson, 2022/03/10
- [PATCH v5 37/48] target/nios2: Use gen_goto_tb for DISAS_TOO_MANY, Richard Henderson, 2022/03/10
- [PATCH v5 36/48] target/nios2: Hoist set of is_jmp into gen_goto_tb, Richard Henderson, 2022/03/10
- [PATCH v5 39/48] target/nios2: Implement Misaligned destination exception,
Richard Henderson <=
- [PATCH v5 41/48] target/nios2: Introduce shadow register sets, Richard Henderson, 2022/03/10
- [PATCH v5 46/48] hw/nios2: Introduce Nios2MachineState, Richard Henderson, 2022/03/10
- [PATCH v5 40/48] linux-user/nios2: Handle various SIGILL exceptions, Richard Henderson, 2022/03/10
- [PATCH v5 42/48] target/nios2: Implement rdprs, wrprs, Richard Henderson, 2022/03/10
- [PATCH v5 43/48] target/nios2: Update helper_eret for shadow registers, Richard Henderson, 2022/03/10