Message ID | 20211130103752.72099-3-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | target/m68k: Implement conditional traps | expand |
Le 30/11/2021 à 11:37, Richard Henderson a écrit : > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/754 > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/m68k/cpu.h | 2 ++ > target/m68k/cpu.c | 1 + > target/m68k/translate.c | 21 +++++++++++++++++++++ > 3 files changed, 24 insertions(+) > > diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h > index a3423729ef..03f600f7e7 100644 > --- a/target/m68k/cpu.h > +++ b/target/m68k/cpu.h > @@ -527,6 +527,8 @@ enum m68k_features { > M68K_FEATURE_MOVEC, > /* Unaligned data accesses (680[2346]0) */ > M68K_FEATURE_UNALIGNED_DATA, > + /* TRAPCC insn. (680[2346]0, and CPU32) */ > + M68K_FEATURE_TRAPCC, > }; > > static inline int m68k_feature(CPUM68KState *env, int feature) > diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c > index c7aeb7da9c..5f778773d1 100644 > --- a/target/m68k/cpu.c > +++ b/target/m68k/cpu.c > @@ -162,6 +162,7 @@ static void m68020_cpu_initfn(Object *obj) > m68k_set_feature(env, M68K_FEATURE_CHK2); > m68k_set_feature(env, M68K_FEATURE_MSP); > m68k_set_feature(env, M68K_FEATURE_UNALIGNED_DATA); > + m68k_set_feature(env, M68K_FEATURE_TRAPCC); > } > > /* > diff --git a/target/m68k/translate.c b/target/m68k/translate.c > index 858ba761fc..cf29f35d91 100644 > --- a/target/m68k/translate.c > +++ b/target/m68k/translate.c > @@ -4879,6 +4879,26 @@ DISAS_INSN(trapv) > do_trapcc(s, 9); /* VS */ > } > > +DISAS_INSN(trapcc) > +{ > + /* Consume and discard the immediate operand. */ > + switch (extract32(insn, 0, 3)) { > + case 2: /* trapcc.w */ > + (void)read_im16(env, s); > + break; > + case 3: /* trapcc.l */ > + (void)read_im32(env, s); > + break; Do we need to actually read the memory to trigger a fault if needed or can we only increase the PC? Normally these values are for the trap handler. > + case 4: /* trapcc (no operand) */ > + break; > + default: > + /* Illegal insn */ > + disas_undef(env, s, insn); > + return; > + } > + do_trapcc(s, extract32(insn, 8, 4)); > +} Do we need to change something in m68k_interrupt_all()? if (!is_hw) { switch (cs->exception_index) { case EXCP_RTE: /* Return from an exception. */ m68k_rte(env); return; case EXCP_TRAP0 ... EXCP_TRAP15: /* Move the PC after the trap instruction. */ retaddr += 2; break; } } Thanks, Laurent > + > static void gen_load_fcr(DisasContext *s, TCGv res, int reg) > { > switch (reg) { > @@ -6051,6 +6071,7 @@ void register_m68k_insns (CPUM68KState *env) > INSN(scc, 50c0, f0f8, CF_ISA_A); /* Scc.B Dx */ > INSN(scc, 50c0, f0c0, M68000); /* Scc.B <EA> */ > INSN(dbcc, 50c8, f0f8, M68000); > + INSN(trapcc, 50f8, f0f8, TRAPCC); > INSN(tpf, 51f8, fff8, CF_ISA_A); > > /* Branch instructions. */ >
On 11/30/21 12:57 PM, Laurent Vivier wrote: >> +DISAS_INSN(trapcc) >> +{ >> + /* Consume and discard the immediate operand. */ >> + switch (extract32(insn, 0, 3)) { >> + case 2: /* trapcc.w */ >> + (void)read_im16(env, s); >> + break; >> + case 3: /* trapcc.l */ >> + (void)read_im32(env, s); >> + break; > > Do we need to actually read the memory to trigger a fault if needed or can we only > increase the PC? Yes, and to pass the entire instruction to plugins. >> + case 4: /* trapcc (no operand) */ >> + break; >> + default: >> + /* Illegal insn */ >> + disas_undef(env, s, insn); >> + return; >> + } >> + do_trapcc(s, extract32(insn, 8, 4)); >> +} > > Do we need to change something in m68k_interrupt_all()? Yes, and cpu_loop. Thanks, r~
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index a3423729ef..03f600f7e7 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -527,6 +527,8 @@ enum m68k_features { M68K_FEATURE_MOVEC, /* Unaligned data accesses (680[2346]0) */ M68K_FEATURE_UNALIGNED_DATA, + /* TRAPCC insn. (680[2346]0, and CPU32) */ + M68K_FEATURE_TRAPCC, }; static inline int m68k_feature(CPUM68KState *env, int feature) diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index c7aeb7da9c..5f778773d1 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -162,6 +162,7 @@ static void m68020_cpu_initfn(Object *obj) m68k_set_feature(env, M68K_FEATURE_CHK2); m68k_set_feature(env, M68K_FEATURE_MSP); m68k_set_feature(env, M68K_FEATURE_UNALIGNED_DATA); + m68k_set_feature(env, M68K_FEATURE_TRAPCC); } /* diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 858ba761fc..cf29f35d91 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4879,6 +4879,26 @@ DISAS_INSN(trapv) do_trapcc(s, 9); /* VS */ } +DISAS_INSN(trapcc) +{ + /* Consume and discard the immediate operand. */ + switch (extract32(insn, 0, 3)) { + case 2: /* trapcc.w */ + (void)read_im16(env, s); + break; + case 3: /* trapcc.l */ + (void)read_im32(env, s); + break; + case 4: /* trapcc (no operand) */ + break; + default: + /* Illegal insn */ + disas_undef(env, s, insn); + return; + } + do_trapcc(s, extract32(insn, 8, 4)); +} + static void gen_load_fcr(DisasContext *s, TCGv res, int reg) { switch (reg) { @@ -6051,6 +6071,7 @@ void register_m68k_insns (CPUM68KState *env) INSN(scc, 50c0, f0f8, CF_ISA_A); /* Scc.B Dx */ INSN(scc, 50c0, f0c0, M68000); /* Scc.B <EA> */ INSN(dbcc, 50c8, f0f8, M68000); + INSN(trapcc, 50f8, f0f8, TRAPCC); INSN(tpf, 51f8, fff8, CF_ISA_A); /* Branch instructions. */
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/754 Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/m68k/cpu.h | 2 ++ target/m68k/cpu.c | 1 + target/m68k/translate.c | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+)