* [PATCH v3 1/9] target/nios2: Replace DISAS_TB_JUMP with DISAS_NORETURN
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-28 22:08 ` [PATCH v3 2/9] target/nios2: Use global cpu_env Richard Henderson
` (8 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, Peter Maydell, crwulff
The only semantic of DISAS_TB_JUMP is that we've done goto_tb,
which is the same as DISAS_NORETURN -- we've exited the tb.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 399f22d938..388fae93a2 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -37,7 +37,6 @@
/* is_jmp field values */
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
#define INSTRUCTION_FLG(func, flags) { (func), (flags) }
#define INSTRUCTION(func) \
@@ -209,7 +208,7 @@ static void jmpi(DisasContext *dc, uint32_t code, uint32_t flags)
{
J_TYPE(instr, code);
gen_goto_tb(dc, 0, (dc->pc & 0xF0000000) | (instr.imm26 << 2));
- dc->is_jmp = DISAS_TB_JUMP;
+ dc->is_jmp = DISAS_NORETURN;
}
static void call(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -269,7 +268,7 @@ static void br(DisasContext *dc, uint32_t code, uint32_t flags)
I_TYPE(instr, code);
gen_goto_tb(dc, 0, dc->pc + 4 + (instr.imm16.s & -4));
- dc->is_jmp = DISAS_TB_JUMP;
+ dc->is_jmp = DISAS_NORETURN;
}
static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -281,7 +280,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
gen_goto_tb(dc, 0, dc->pc + 4);
gen_set_label(l1);
gen_goto_tb(dc, 1, dc->pc + 4 + (instr.imm16.s & -4));
- dc->is_jmp = DISAS_TB_JUMP;
+ dc->is_jmp = DISAS_NORETURN;
}
/* Comparison instructions */
@@ -883,7 +882,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
break;
case DISAS_NORETURN:
- case DISAS_TB_JUMP:
/* nothing more to generate */
break;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 2/9] target/nios2: Use global cpu_env
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
2021-06-28 22:08 ` [PATCH v3 1/9] target/nios2: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-28 22:08 ` [PATCH v3 3/9] target/nios2: Use global cpu_R Richard Henderson
` (7 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, Peter Maydell, crwulff
We do not need to copy this into DisasContext.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 388fae93a2..39538e1870 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -97,7 +97,6 @@
}
typedef struct DisasContext {
- TCGv_ptr cpu_env;
TCGv *cpu_R;
TCGv_i32 zero;
int is_jmp;
@@ -147,7 +146,7 @@ static void t_gen_helper_raise_exception(DisasContext *dc,
TCGv_i32 tmp = tcg_const_i32(index);
tcg_gen_movi_tl(dc->cpu_R[R_PC], dc->pc);
- gen_helper_raise_exception(dc->cpu_env, tmp);
+ gen_helper_raise_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
dc->is_jmp = DISAS_NORETURN;
}
@@ -474,7 +473,7 @@ static void rdctl(DisasContext *dc, uint32_t code, uint32_t flags)
tcg_gen_mov_tl(dc->cpu_R[instr.c], dc->cpu_R[instr.imm5 + CR_BASE]);
#ifdef DEBUG_MMU
TCGv_i32 tmp = tcg_const_i32(instr.imm5 + CR_BASE);
- gen_helper_mmu_read_debug(dc->cpu_R[instr.c], dc->cpu_env, tmp);
+ gen_helper_mmu_read_debug(dc->cpu_R[instr.c], cpu_env, tmp);
tcg_temp_free_i32(tmp);
#endif
}
@@ -504,7 +503,7 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t flags)
{
#if !defined(CONFIG_USER_ONLY)
TCGv_i32 tmp = tcg_const_i32(instr.imm5 + CR_BASE);
- gen_helper_mmu_write(dc->cpu_env, tmp, load_gpr(dc, instr.a));
+ gen_helper_mmu_write(cpu_env, tmp, load_gpr(dc, instr.a));
tcg_temp_free_i32(tmp);
#endif
break;
@@ -521,7 +520,7 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t flags)
if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
gen_io_start();
}
- gen_helper_check_interrupts(dc->cpu_env);
+ gen_helper_check_interrupts(cpu_env);
dc->is_jmp = DISAS_UPDATE;
}
#endif
@@ -817,7 +816,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
int num_insns;
/* Initialize DC */
- dc->cpu_env = cpu_env;
dc->cpu_R = cpu_R;
dc->is_jmp = DISAS_NEXT;
dc->pc = tb->pc;
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 3/9] target/nios2: Use global cpu_R
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
2021-06-28 22:08 ` [PATCH v3 1/9] target/nios2: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
2021-06-28 22:08 ` [PATCH v3 2/9] target/nios2: Use global cpu_env Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-28 22:08 ` [PATCH v3 4/9] target/nios2: Add DisasContextBase to DisasContext Richard Henderson
` (6 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, Peter Maydell, crwulff
We do not need to copy this into DisasContext.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 73 +++++++++++++++++++---------------------
1 file changed, 34 insertions(+), 39 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 39538e1870..6bdd388bd8 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -97,7 +97,6 @@
}
typedef struct DisasContext {
- TCGv *cpu_R;
TCGv_i32 zero;
int is_jmp;
target_ulong pc;
@@ -106,6 +105,8 @@ typedef struct DisasContext {
bool singlestep_enabled;
} DisasContext;
+static TCGv cpu_R[NUM_CORE_REGS];
+
typedef struct Nios2Instruction {
void (*handler)(DisasContext *dc, uint32_t code, uint32_t flags);
uint32_t flags;
@@ -134,7 +135,7 @@ static TCGv load_zero(DisasContext *dc)
static TCGv load_gpr(DisasContext *dc, uint8_t reg)
{
if (likely(reg != R_ZERO)) {
- return dc->cpu_R[reg];
+ return cpu_R[reg];
} else {
return load_zero(dc);
}
@@ -145,7 +146,7 @@ static void t_gen_helper_raise_exception(DisasContext *dc,
{
TCGv_i32 tmp = tcg_const_i32(index);
- tcg_gen_movi_tl(dc->cpu_R[R_PC], dc->pc);
+ tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
gen_helper_raise_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
dc->is_jmp = DISAS_NORETURN;
@@ -170,10 +171,10 @@ static void gen_goto_tb(DisasContext *dc, int n, uint32_t dest)
if (use_goto_tb(dc, dest)) {
tcg_gen_goto_tb(n);
- tcg_gen_movi_tl(dc->cpu_R[R_PC], dest);
+ tcg_gen_movi_tl(cpu_R[R_PC], dest);
tcg_gen_exit_tb(tb, n);
} else {
- tcg_gen_movi_tl(dc->cpu_R[R_PC], dest);
+ tcg_gen_movi_tl(cpu_R[R_PC], dest);
tcg_gen_exit_tb(NULL, 0);
}
}
@@ -212,7 +213,7 @@ static void jmpi(DisasContext *dc, uint32_t code, uint32_t flags)
static void call(DisasContext *dc, uint32_t code, uint32_t flags)
{
- tcg_gen_movi_tl(dc->cpu_R[R_RA], dc->pc + 4);
+ tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
jmpi(dc, code, flags);
}
@@ -234,7 +235,7 @@ static void gen_ldx(DisasContext *dc, uint32_t code, uint32_t flags)
* the Nios2 CPU.
*/
if (likely(instr.b != R_ZERO)) {
- data = dc->cpu_R[instr.b];
+ data = cpu_R[instr.b];
} else {
data = tcg_temp_new();
}
@@ -275,7 +276,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
I_TYPE(instr, code);
TCGLabel *l1 = gen_new_label();
- tcg_gen_brcond_tl(flags, dc->cpu_R[instr.a], dc->cpu_R[instr.b], l1);
+ tcg_gen_brcond_tl(flags, cpu_R[instr.a], cpu_R[instr.b], l1);
gen_goto_tb(dc, 0, dc->pc + 4);
gen_set_label(l1);
gen_goto_tb(dc, 1, dc->pc + 4 + (instr.imm16.s & -4));
@@ -287,8 +288,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
static void (fname)(DisasContext *dc, uint32_t code, uint32_t flags) \
{ \
I_TYPE(instr, (code)); \
- tcg_gen_setcondi_tl(flags, (dc)->cpu_R[instr.b], (dc)->cpu_R[instr.a], \
- (op3)); \
+ tcg_gen_setcondi_tl(flags, cpu_R[instr.b], cpu_R[instr.a], (op3)); \
}
gen_i_cmpxx(gen_cmpxxsi, instr.imm16.s)
@@ -302,10 +302,9 @@ static void (fname)(DisasContext *dc, uint32_t code, uint32_t flags) \
if (unlikely(instr.b == R_ZERO)) { /* Store to R_ZERO is ignored */ \
return; \
} else if (instr.a == R_ZERO) { /* MOVxI optimizations */ \
- tcg_gen_movi_tl(dc->cpu_R[instr.b], (resimm) ? (op3) : 0); \
+ tcg_gen_movi_tl(cpu_R[instr.b], (resimm) ? (op3) : 0); \
} else { \
- tcg_gen_##insn##_tl((dc)->cpu_R[instr.b], (dc)->cpu_R[instr.a], \
- (op3)); \
+ tcg_gen_##insn##_tl(cpu_R[instr.b], cpu_R[instr.a], (op3)); \
} \
}
@@ -400,8 +399,8 @@ static const Nios2Instruction i_type_instructions[] = {
*/
static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
{
- tcg_gen_mov_tl(dc->cpu_R[CR_STATUS], dc->cpu_R[CR_ESTATUS]);
- tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_EA]);
+ tcg_gen_mov_tl(cpu_R[CR_STATUS], cpu_R[CR_ESTATUS]);
+ tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_EA]);
dc->is_jmp = DISAS_JUMP;
}
@@ -409,7 +408,7 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
/* PC <- ra */
static void ret(DisasContext *dc, uint32_t code, uint32_t flags)
{
- tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_RA]);
+ tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_RA]);
dc->is_jmp = DISAS_JUMP;
}
@@ -417,7 +416,7 @@ static void ret(DisasContext *dc, uint32_t code, uint32_t flags)
/* PC <- ba */
static void bret(DisasContext *dc, uint32_t code, uint32_t flags)
{
- tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_BA]);
+ tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_BA]);
dc->is_jmp = DISAS_JUMP;
}
@@ -427,7 +426,7 @@ static void jmp(DisasContext *dc, uint32_t code, uint32_t flags)
{
R_TYPE(instr, code);
- tcg_gen_mov_tl(dc->cpu_R[R_PC], load_gpr(dc, instr.a));
+ tcg_gen_mov_tl(cpu_R[R_PC], load_gpr(dc, instr.a));
dc->is_jmp = DISAS_JUMP;
}
@@ -438,7 +437,7 @@ static void nextpc(DisasContext *dc, uint32_t code, uint32_t flags)
R_TYPE(instr, code);
if (likely(instr.c != R_ZERO)) {
- tcg_gen_movi_tl(dc->cpu_R[instr.c], dc->pc + 4);
+ tcg_gen_movi_tl(cpu_R[instr.c], dc->pc + 4);
}
}
@@ -450,8 +449,8 @@ static void callr(DisasContext *dc, uint32_t code, uint32_t flags)
{
R_TYPE(instr, code);
- tcg_gen_mov_tl(dc->cpu_R[R_PC], load_gpr(dc, instr.a));
- tcg_gen_movi_tl(dc->cpu_R[R_RA], dc->pc + 4);
+ tcg_gen_mov_tl(cpu_R[R_PC], load_gpr(dc, instr.a));
+ tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
dc->is_jmp = DISAS_JUMP;
}
@@ -470,10 +469,10 @@ static void rdctl(DisasContext *dc, uint32_t code, uint32_t flags)
{
#if !defined(CONFIG_USER_ONLY)
if (likely(instr.c != R_ZERO)) {
- tcg_gen_mov_tl(dc->cpu_R[instr.c], dc->cpu_R[instr.imm5 + CR_BASE]);
+ tcg_gen_mov_tl(cpu_R[instr.c], cpu_R[instr.imm5 + CR_BASE]);
#ifdef DEBUG_MMU
TCGv_i32 tmp = tcg_const_i32(instr.imm5 + CR_BASE);
- gen_helper_mmu_read_debug(dc->cpu_R[instr.c], cpu_env, tmp);
+ gen_helper_mmu_read_debug(cpu_R[instr.c], cpu_env, tmp);
tcg_temp_free_i32(tmp);
#endif
}
@@ -483,7 +482,7 @@ static void rdctl(DisasContext *dc, uint32_t code, uint32_t flags)
default:
if (likely(instr.c != R_ZERO)) {
- tcg_gen_mov_tl(dc->cpu_R[instr.c], dc->cpu_R[instr.imm5 + CR_BASE]);
+ tcg_gen_mov_tl(cpu_R[instr.c], cpu_R[instr.imm5 + CR_BASE]);
}
break;
}
@@ -510,7 +509,7 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t flags)
}
default:
- tcg_gen_mov_tl(dc->cpu_R[instr.imm5 + CR_BASE], load_gpr(dc, instr.a));
+ tcg_gen_mov_tl(cpu_R[instr.imm5 + CR_BASE], load_gpr(dc, instr.a));
break;
}
@@ -531,8 +530,8 @@ static void gen_cmpxx(DisasContext *dc, uint32_t code, uint32_t flags)
{
R_TYPE(instr, code);
if (likely(instr.c != R_ZERO)) {
- tcg_gen_setcond_tl(flags, dc->cpu_R[instr.c], dc->cpu_R[instr.a],
- dc->cpu_R[instr.b]);
+ tcg_gen_setcond_tl(flags, cpu_R[instr.c], cpu_R[instr.a],
+ cpu_R[instr.b]);
}
}
@@ -542,8 +541,7 @@ static void (fname)(DisasContext *dc, uint32_t code, uint32_t flags) \
{ \
R_TYPE(instr, (code)); \
if (likely(instr.c != R_ZERO)) { \
- tcg_gen_##insn((dc)->cpu_R[instr.c], load_gpr((dc), instr.a), \
- (op3)); \
+ tcg_gen_##insn(cpu_R[instr.c], load_gpr((dc), instr.a), (op3)); \
} \
}
@@ -567,8 +565,8 @@ static void (fname)(DisasContext *dc, uint32_t code, uint32_t flags) \
R_TYPE(instr, (code)); \
if (likely(instr.c != R_ZERO)) { \
TCGv t0 = tcg_temp_new(); \
- tcg_gen_##insn(t0, dc->cpu_R[instr.c], \
- load_gpr(dc, instr.a), load_gpr(dc, instr.b)); \
+ tcg_gen_##insn(t0, cpu_R[instr.c], \
+ load_gpr(dc, instr.a), load_gpr(dc, instr.b)); \
tcg_temp_free(t0); \
} \
}
@@ -584,7 +582,7 @@ static void (fname)(DisasContext *dc, uint32_t code, uint32_t flags) \
if (likely(instr.c != R_ZERO)) { \
TCGv t0 = tcg_temp_new(); \
tcg_gen_andi_tl(t0, load_gpr((dc), instr.b), 31); \
- tcg_gen_##insn((dc)->cpu_R[instr.c], load_gpr((dc), instr.a), t0); \
+ tcg_gen_##insn(cpu_R[instr.c], load_gpr((dc), instr.a), t0); \
tcg_temp_free(t0); \
} \
}
@@ -618,8 +616,8 @@ static void divs(DisasContext *dc, uint32_t code, uint32_t flags)
tcg_gen_or_tl(t2, t2, t3);
tcg_gen_movi_tl(t3, 0);
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_div_tl(dc->cpu_R[instr.c], t0, t1);
- tcg_gen_ext32s_tl(dc->cpu_R[instr.c], dc->cpu_R[instr.c]);
+ tcg_gen_div_tl(cpu_R[instr.c], t0, t1);
+ tcg_gen_ext32s_tl(cpu_R[instr.c], cpu_R[instr.c]);
tcg_temp_free(t3);
tcg_temp_free(t2);
@@ -644,8 +642,8 @@ static void divu(DisasContext *dc, uint32_t code, uint32_t flags)
tcg_gen_ext32u_tl(t0, load_gpr(dc, instr.a));
tcg_gen_ext32u_tl(t1, load_gpr(dc, instr.b));
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
- tcg_gen_divu_tl(dc->cpu_R[instr.c], t0, t1);
- tcg_gen_ext32s_tl(dc->cpu_R[instr.c], dc->cpu_R[instr.c]);
+ tcg_gen_divu_tl(cpu_R[instr.c], t0, t1);
+ tcg_gen_ext32s_tl(cpu_R[instr.c], cpu_R[instr.c]);
tcg_temp_free(t3);
tcg_temp_free(t2);
@@ -794,8 +792,6 @@ static const char * const regnames[] = {
"rpc"
};
-static TCGv cpu_R[NUM_CORE_REGS];
-
#include "exec/gen-icount.h"
static void gen_exception(DisasContext *dc, uint32_t excp)
@@ -816,7 +812,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
int num_insns;
/* Initialize DC */
- dc->cpu_R = cpu_R;
dc->is_jmp = DISAS_NEXT;
dc->pc = tb->pc;
dc->tb = tb;
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 4/9] target/nios2: Add DisasContextBase to DisasContext
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (2 preceding siblings ...)
2021-06-28 22:08 ` [PATCH v3 3/9] target/nios2: Use global cpu_R Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-29 9:18 ` Peter Maydell
2021-06-28 22:08 ` [PATCH v3 5/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (5 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, crwulff
Migrate the is_jmp, tb and singlestep_enabled fields from
DisasContext into the base. Use pc_first instead of tb->pc.
Increment pc_next prior to decode, leaving the address of
the current insn in dc->pc.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 70 +++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 34 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 6bdd388bd8..12f987651a 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -97,12 +97,10 @@
}
typedef struct DisasContext {
+ DisasContextBase base;
TCGv_i32 zero;
- int is_jmp;
target_ulong pc;
- TranslationBlock *tb;
int mem_idx;
- bool singlestep_enabled;
} DisasContext;
static TCGv cpu_R[NUM_CORE_REGS];
@@ -149,17 +147,17 @@ static void t_gen_helper_raise_exception(DisasContext *dc,
tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
gen_helper_raise_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
- dc->is_jmp = DISAS_NORETURN;
+ dc->base.is_jmp = DISAS_NORETURN;
}
static bool use_goto_tb(DisasContext *dc, uint32_t dest)
{
- if (unlikely(dc->singlestep_enabled)) {
+ if (unlikely(dc->base.singlestep_enabled)) {
return false;
}
#ifndef CONFIG_USER_ONLY
- return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
+ return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
#else
return true;
#endif
@@ -167,7 +165,7 @@ static bool use_goto_tb(DisasContext *dc, uint32_t dest)
static void gen_goto_tb(DisasContext *dc, int n, uint32_t dest)
{
- TranslationBlock *tb = dc->tb;
+ const TranslationBlock *tb = dc->base.tb;
if (use_goto_tb(dc, dest)) {
tcg_gen_goto_tb(n);
@@ -186,7 +184,7 @@ static void gen_excp(DisasContext *dc, uint32_t code, uint32_t flags)
static void gen_check_supervisor(DisasContext *dc)
{
- if (dc->tb->flags & CR_STATUS_U) {
+ if (dc->base.tb->flags & CR_STATUS_U) {
/* CPU in user mode, privileged instruction called, stop. */
t_gen_helper_raise_exception(dc, EXCP_SUPERI);
}
@@ -208,7 +206,7 @@ static void jmpi(DisasContext *dc, uint32_t code, uint32_t flags)
{
J_TYPE(instr, code);
gen_goto_tb(dc, 0, (dc->pc & 0xF0000000) | (instr.imm26 << 2));
- dc->is_jmp = DISAS_NORETURN;
+ dc->base.is_jmp = DISAS_NORETURN;
}
static void call(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -268,7 +266,7 @@ static void br(DisasContext *dc, uint32_t code, uint32_t flags)
I_TYPE(instr, code);
gen_goto_tb(dc, 0, dc->pc + 4 + (instr.imm16.s & -4));
- dc->is_jmp = DISAS_NORETURN;
+ dc->base.is_jmp = DISAS_NORETURN;
}
static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -280,7 +278,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
gen_goto_tb(dc, 0, dc->pc + 4);
gen_set_label(l1);
gen_goto_tb(dc, 1, dc->pc + 4 + (instr.imm16.s & -4));
- dc->is_jmp = DISAS_NORETURN;
+ dc->base.is_jmp = DISAS_NORETURN;
}
/* Comparison instructions */
@@ -402,7 +400,7 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
tcg_gen_mov_tl(cpu_R[CR_STATUS], cpu_R[CR_ESTATUS]);
tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_EA]);
- dc->is_jmp = DISAS_JUMP;
+ dc->base.is_jmp = DISAS_JUMP;
}
/* PC <- ra */
@@ -410,7 +408,7 @@ static void ret(DisasContext *dc, uint32_t code, uint32_t flags)
{
tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_RA]);
- dc->is_jmp = DISAS_JUMP;
+ dc->base.is_jmp = DISAS_JUMP;
}
/* PC <- ba */
@@ -418,7 +416,7 @@ static void bret(DisasContext *dc, uint32_t code, uint32_t flags)
{
tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_BA]);
- dc->is_jmp = DISAS_JUMP;
+ dc->base.is_jmp = DISAS_JUMP;
}
/* PC <- rA */
@@ -428,7 +426,7 @@ static void jmp(DisasContext *dc, uint32_t code, uint32_t flags)
tcg_gen_mov_tl(cpu_R[R_PC], load_gpr(dc, instr.a));
- dc->is_jmp = DISAS_JUMP;
+ dc->base.is_jmp = DISAS_JUMP;
}
/* rC <- PC + 4 */
@@ -452,7 +450,7 @@ static void callr(DisasContext *dc, uint32_t code, uint32_t flags)
tcg_gen_mov_tl(cpu_R[R_PC], load_gpr(dc, instr.a));
tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
- dc->is_jmp = DISAS_JUMP;
+ dc->base.is_jmp = DISAS_JUMP;
}
/* rC <- ctlN */
@@ -516,11 +514,11 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t flags)
/* If interrupts were enabled using WRCTL, trigger them. */
#if !defined(CONFIG_USER_ONLY)
if ((instr.imm5 + CR_BASE) == CR_STATUS) {
- if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
+ if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
gen_helper_check_interrupts(cpu_env);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
}
#endif
}
@@ -801,7 +799,7 @@ static void gen_exception(DisasContext *dc, uint32_t excp)
tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
gen_helper_raise_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
- dc->is_jmp = DISAS_NORETURN;
+ dc->base.is_jmp = DISAS_NORETURN;
}
/* generate intermediate code for basic block 'tb'. */
@@ -812,11 +810,14 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
int num_insns;
/* Initialize DC */
- dc->is_jmp = DISAS_NEXT;
- dc->pc = tb->pc;
- dc->tb = tb;
+
+ dc->base.tb = tb;
+ dc->base.singlestep_enabled = cs->singlestep_enabled;
+ dc->base.is_jmp = DISAS_NEXT;
+ dc->base.pc_first = tb->pc;
+ dc->base.pc_next = tb->pc;
+
dc->mem_idx = cpu_mmu_index(env, false);
- dc->singlestep_enabled = cs->singlestep_enabled;
/* Set up instruction counts */
num_insns = 0;
@@ -829,10 +830,10 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
gen_tb_start(tb);
do {
- tcg_gen_insn_start(dc->pc);
+ tcg_gen_insn_start(dc->base.pc_next);
num_insns++;
- if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+ if (unlikely(cpu_breakpoint_test(cs, dc->base.pc_next, BP_ANY))) {
gen_exception(dc, EXCP_DEBUG);
/* The address covered by the breakpoint must be included in
[tb->pc, tb->pc + tb->size) in order to for it to be
@@ -846,25 +847,26 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
gen_io_start();
}
+ dc->pc = dc->base.pc_next;
+ dc->base.pc_next += 4;
+
/* Decode an instruction */
handle_instruction(dc, env);
- dc->pc += 4;
-
/* Translation stops when a conditional branch is encountered.
* Otherwise the subsequent code could get translated several times.
* Also stop translation when a page boundary is reached. This
* ensures prefetch aborts occur at the right place. */
- } while (!dc->is_jmp &&
+ } while (!dc->base.is_jmp &&
!tcg_op_buf_full() &&
num_insns < max_insns);
/* Indicate where the next block should start */
- switch (dc->is_jmp) {
+ switch (dc->base.is_jmp) {
case DISAS_NEXT:
case DISAS_UPDATE:
/* Save the current PC back into the CPU register */
- tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
+ tcg_gen_movi_tl(cpu_R[R_PC], dc->base.pc_next);
tcg_gen_exit_tb(NULL, 0);
break;
@@ -883,15 +885,15 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
gen_tb_end(tb, num_insns);
/* Mark instruction starts for the final generated instruction */
- tb->size = dc->pc - tb->pc;
+ tb->size = dc->pc - dc->base.pc_first;
tb->icount = num_insns;
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(tb->pc)) {
+ && qemu_log_in_addr_range(dc->base.pc_first)) {
FILE *logfile = qemu_log_lock();
- qemu_log("IN: %s\n", lookup_symbol(tb->pc));
- log_target_disas(cs, tb->pc, dc->pc - tb->pc);
+ qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
+ log_target_disas(cs, tb->pc, dc->base.pc_next - dc->base.pc_first);
qemu_log("\n");
qemu_log_unlock(logfile);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v3 4/9] target/nios2: Add DisasContextBase to DisasContext
2021-06-28 22:08 ` [PATCH v3 4/9] target/nios2: Add DisasContextBase to DisasContext Richard Henderson
@ 2021-06-29 9:18 ` Peter Maydell
0 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2021-06-29 9:18 UTC (permalink / raw)
To: Richard Henderson; +Cc: Marek Vasut, Chris Wulff, QEMU Developers
On Mon, 28 Jun 2021 at 23:14, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Migrate the is_jmp, tb and singlestep_enabled fields from
> DisasContext into the base. Use pc_first instead of tb->pc.
> Increment pc_next prior to decode, leaving the address of
> the current insn in dc->pc.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/nios2/translate.c | 70 +++++++++++++++++++++-------------------
> 1 file changed, 36 insertions(+), 34 deletions(-)
>
>
> /* Indicate where the next block should start */
> - switch (dc->is_jmp) {
> + switch (dc->base.is_jmp) {
> case DISAS_NEXT:
> case DISAS_UPDATE:
> /* Save the current PC back into the CPU register */
> - tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
> + tcg_gen_movi_tl(cpu_R[R_PC], dc->base.pc_next);
> tcg_gen_exit_tb(NULL, 0);
> break;
>
> @@ -883,15 +885,15 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
> gen_tb_end(tb, num_insns);
>
> /* Mark instruction starts for the final generated instruction */
> - tb->size = dc->pc - tb->pc;
> + tb->size = dc->pc - dc->base.pc_first;
Shouldn't this one be "dc->base.pc_next - dc->base.pc_first" ?
> tb->icount = num_insns;
>
> #ifdef DEBUG_DISAS
> if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
> - && qemu_log_in_addr_range(tb->pc)) {
> + && qemu_log_in_addr_range(dc->base.pc_first)) {
> FILE *logfile = qemu_log_lock();
> - qemu_log("IN: %s\n", lookup_symbol(tb->pc));
> - log_target_disas(cs, tb->pc, dc->pc - tb->pc);
> + qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
> + log_target_disas(cs, tb->pc, dc->base.pc_next - dc->base.pc_first);
Here you could use tb->size for the 3rd argument (which
makes it clearer that the arguments are right -- we disassemble
the whole size of the TB starting at its first PC value).
> qemu_log("\n");
> qemu_log_unlock(logfile);
> }
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 5/9] target/nios2: Convert to TranslatorOps
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (3 preceding siblings ...)
2021-06-28 22:08 ` [PATCH v3 4/9] target/nios2: Add DisasContextBase to DisasContext Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-29 9:21 ` Peter Maydell
2021-06-28 22:08 ` [PATCH v3 6/9] target/nios2: Remove assignment to env in handle_instruction Richard Henderson
` (4 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, crwulff
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 128 ++++++++++++++++++++-------------------
1 file changed, 65 insertions(+), 63 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 12f987651a..66f4c25b06 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -803,74 +803,69 @@ static void gen_exception(DisasContext *dc, uint32_t excp)
}
/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+static void nios2_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
CPUNios2State *env = cs->env_ptr;
- DisasContext dc1, *dc = &dc1;
- int num_insns;
-
- /* Initialize DC */
-
- dc->base.tb = tb;
- dc->base.singlestep_enabled = cs->singlestep_enabled;
- dc->base.is_jmp = DISAS_NEXT;
- dc->base.pc_first = tb->pc;
- dc->base.pc_next = tb->pc;
+ int page_insns;
dc->mem_idx = cpu_mmu_index(env, false);
- /* Set up instruction counts */
- num_insns = 0;
- if (max_insns > 1) {
- int page_insns = (TARGET_PAGE_SIZE - (tb->pc & ~TARGET_PAGE_MASK)) / 4;
- if (max_insns > page_insns) {
- max_insns = page_insns;
- }
- }
+ /* Bound the number of insns to execute to those left on the page. */
+ page_insns = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
+ dc->base.max_insns = MIN(page_insns, dc->base.max_insns);
+}
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(dc->base.pc_next);
- num_insns++;
+static void nios2_tr_tb_start(DisasContextBase *db, CPUState *cs)
+{
+}
- if (unlikely(cpu_breakpoint_test(cs, dc->base.pc_next, BP_ANY))) {
- gen_exception(dc, EXCP_DEBUG);
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- dc->pc += 4;
- break;
- }
+static void nios2_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
+{
+ tcg_gen_insn_start(dcbase->pc_next);
+}
- if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
- gen_io_start();
- }
+static bool nios2_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
+ const CPUBreakpoint *bp)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
- dc->pc = dc->base.pc_next;
- dc->base.pc_next += 4;
+ gen_exception(dc, EXCP_DEBUG);
+ /*
+ * The address covered by the breakpoint must be included in
+ * [tb->pc, tb->pc + tb->size) in order to for it to be
+ * properly cleared -- thus we increment the PC here so that
+ * the logic setting tb->size below does the right thing.
+ */
+ dc->base.pc_next += 4;
+ return true;
+}
- /* Decode an instruction */
- handle_instruction(dc, env);
+static void nios2_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
+ CPUNios2State *env = cs->env_ptr;
- /* Translation stops when a conditional branch is encountered.
- * Otherwise the subsequent code could get translated several times.
- * Also stop translation when a page boundary is reached. This
- * ensures prefetch aborts occur at the right place. */
- } while (!dc->base.is_jmp &&
- !tcg_op_buf_full() &&
- num_insns < max_insns);
+ dc->pc = dc->base.pc_next;
+ dc->base.pc_next += 4;
+
+ /* Decode an instruction */
+ handle_instruction(dc, env);
+}
+
+static void nios2_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
/* Indicate where the next block should start */
switch (dc->base.is_jmp) {
- case DISAS_NEXT:
+ case DISAS_TOO_MANY:
case DISAS_UPDATE:
/* Save the current PC back into the CPU register */
tcg_gen_movi_tl(cpu_R[R_PC], dc->base.pc_next);
tcg_gen_exit_tb(NULL, 0);
break;
- default:
case DISAS_JUMP:
/* The jump will already have updated the PC register */
tcg_gen_exit_tb(NULL, 0);
@@ -879,25 +874,32 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
case DISAS_NORETURN:
/* nothing more to generate */
break;
+
+ default:
+ g_assert_not_reached();
}
+}
- /* End off the block */
- gen_tb_end(tb, num_insns);
+static void nios2_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
+{
+ qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
+ log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
+}
- /* Mark instruction starts for the final generated instruction */
- tb->size = dc->pc - dc->base.pc_first;
- tb->icount = num_insns;
+static const TranslatorOps nios2_tr_ops = {
+ .init_disas_context = nios2_tr_init_disas_context,
+ .tb_start = nios2_tr_tb_start,
+ .insn_start = nios2_tr_insn_start,
+ .breakpoint_check = nios2_tr_breakpoint_check,
+ .translate_insn = nios2_tr_translate_insn,
+ .tb_stop = nios2_tr_tb_stop,
+ .disas_log = nios2_tr_disas_log,
+};
-#ifdef DEBUG_DISAS
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(dc->base.pc_first)) {
- FILE *logfile = qemu_log_lock();
- qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
- log_target_disas(cs, tb->pc, dc->base.pc_next - dc->base.pc_first);
- qemu_log("\n");
- qemu_log_unlock(logfile);
- }
-#endif
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+{
+ DisasContext dc;
+ translator_loop(&nios2_tr_ops, &dc.base, cs, tb, max_insns);
}
void nios2_cpu_dump_state(CPUState *cs, FILE *f, int flags)
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 6/9] target/nios2: Remove assignment to env in handle_instruction
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (4 preceding siblings ...)
2021-06-28 22:08 ` [PATCH v3 5/9] target/nios2: Convert to TranslatorOps Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-29 9:22 ` Peter Maydell
2021-06-28 22:08 ` [PATCH v3 7/9] target/nios2: Clean up goto " Richard Henderson
` (3 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, crwulff
Direct assignments to env during translation do not work.
As it happens, the only way we can get here is if env->pc
is already set to dc->pc. We will trap on the first insn
we execute anywhere on the page.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 66f4c25b06..6fd4330b31 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -740,14 +740,15 @@ static void handle_instruction(DisasContext *dc, CPUNios2State *env)
uint32_t code;
uint8_t op;
const Nios2Instruction *instr;
+
#if defined(CONFIG_USER_ONLY)
/* FIXME: Is this needed ? */
if (dc->pc >= 0x1000 && dc->pc < 0x2000) {
- env->regs[R_PC] = dc->pc;
t_gen_helper_raise_exception(dc, 0xaa);
return;
}
#endif
+
code = cpu_ldl_code(env, dc->pc);
op = get_opcode(code);
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v3 6/9] target/nios2: Remove assignment to env in handle_instruction
2021-06-28 22:08 ` [PATCH v3 6/9] target/nios2: Remove assignment to env in handle_instruction Richard Henderson
@ 2021-06-29 9:22 ` Peter Maydell
0 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2021-06-29 9:22 UTC (permalink / raw)
To: Richard Henderson; +Cc: Marek Vasut, Chris Wulff, QEMU Developers
On Mon, 28 Jun 2021 at 23:12, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Direct assignments to env during translation do not work.
>
> As it happens, the only way we can get here is if env->pc
> is already set to dc->pc. We will trap on the first insn
> we execute anywhere on the page.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/nios2/translate.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/target/nios2/translate.c b/target/nios2/translate.c
> index 66f4c25b06..6fd4330b31 100644
> --- a/target/nios2/translate.c
> +++ b/target/nios2/translate.c
> @@ -740,14 +740,15 @@ static void handle_instruction(DisasContext *dc, CPUNios2State *env)
> uint32_t code;
> uint8_t op;
> const Nios2Instruction *instr;
> +
> #if defined(CONFIG_USER_ONLY)
> /* FIXME: Is this needed ? */
> if (dc->pc >= 0x1000 && dc->pc < 0x2000) {
> - env->regs[R_PC] = dc->pc;
> t_gen_helper_raise_exception(dc, 0xaa);
> return;
> }
> #endif
> +
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 7/9] target/nios2: Clean up goto in handle_instruction
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (5 preceding siblings ...)
2021-06-28 22:08 ` [PATCH v3 6/9] target/nios2: Remove assignment to env in handle_instruction Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-29 9:22 ` Peter Maydell
2021-06-28 22:08 ` [PATCH v3 8/9] target/nios2: Inline handle_instruction Richard Henderson
` (2 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, crwulff
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 6fd4330b31..9e71267b42 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -753,7 +753,8 @@ static void handle_instruction(DisasContext *dc, CPUNios2State *env)
op = get_opcode(code);
if (unlikely(op >= ARRAY_SIZE(i_type_instructions))) {
- goto illegal_op;
+ t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
+ return;
}
dc->zero = NULL;
@@ -764,11 +765,6 @@ static void handle_instruction(DisasContext *dc, CPUNios2State *env)
if (dc->zero) {
tcg_temp_free(dc->zero);
}
-
- return;
-
-illegal_op:
- t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
}
static const char * const regnames[] = {
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v3 7/9] target/nios2: Clean up goto in handle_instruction
2021-06-28 22:08 ` [PATCH v3 7/9] target/nios2: Clean up goto " Richard Henderson
@ 2021-06-29 9:22 ` Peter Maydell
0 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2021-06-29 9:22 UTC (permalink / raw)
To: Richard Henderson; +Cc: Marek Vasut, Chris Wulff, QEMU Developers
On Mon, 28 Jun 2021 at 23:12, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/nios2/translate.c | 8 ++------
> 1 file changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/target/nios2/translate.c b/target/nios2/translate.c
> index 6fd4330b31..9e71267b42 100644
> --- a/target/nios2/translate.c
> +++ b/target/nios2/translate.c
> @@ -753,7 +753,8 @@ static void handle_instruction(DisasContext *dc, CPUNios2State *env)
> op = get_opcode(code);
>
> if (unlikely(op >= ARRAY_SIZE(i_type_instructions))) {
> - goto illegal_op;
> + t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
> + return;
> }
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 8/9] target/nios2: Inline handle_instruction
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (6 preceding siblings ...)
2021-06-28 22:08 ` [PATCH v3 7/9] target/nios2: Clean up goto " Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-29 9:27 ` Peter Maydell
2021-06-28 22:08 ` [PATCH v3 9/9] target/nios2: Use pc_next for pc + 4 Richard Henderson
2021-06-29 17:12 ` [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
9 siblings, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, crwulff
Move handle_instruction into nios2_tr_translate_insn
as the only caller.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 66 +++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 35 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 9e71267b42..abc7e5f96a 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -735,38 +735,6 @@ illegal_op:
t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
}
-static void handle_instruction(DisasContext *dc, CPUNios2State *env)
-{
- uint32_t code;
- uint8_t op;
- const Nios2Instruction *instr;
-
-#if defined(CONFIG_USER_ONLY)
- /* FIXME: Is this needed ? */
- if (dc->pc >= 0x1000 && dc->pc < 0x2000) {
- t_gen_helper_raise_exception(dc, 0xaa);
- return;
- }
-#endif
-
- code = cpu_ldl_code(env, dc->pc);
- op = get_opcode(code);
-
- if (unlikely(op >= ARRAY_SIZE(i_type_instructions))) {
- t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
- return;
- }
-
- dc->zero = NULL;
-
- instr = &i_type_instructions[op];
- instr->handler(dc, code, instr->flags);
-
- if (dc->zero) {
- tcg_temp_free(dc->zero);
- }
-}
-
static const char * const regnames[] = {
"zero", "at", "r2", "r3",
"r4", "r5", "r6", "r7",
@@ -842,12 +810,40 @@ static void nios2_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
CPUNios2State *env = cs->env_ptr;
+ const Nios2Instruction *instr;
+ uint32_t code, pc;
+ uint8_t op;
- dc->pc = dc->base.pc_next;
- dc->base.pc_next += 4;
+ pc = dc->base.pc_next;
+ dc->pc = pc;
+ dc->base.pc_next = pc + 4;
/* Decode an instruction */
- handle_instruction(dc, env);
+
+#if defined(CONFIG_USER_ONLY)
+ /* FIXME: Is this needed ? */
+ if (pc >= 0x1000 && pc < 0x2000) {
+ t_gen_helper_raise_exception(dc, 0xaa);
+ return;
+ }
+#endif
+
+ code = cpu_ldl_code(env, pc);
+ op = get_opcode(code);
+
+ if (unlikely(op >= ARRAY_SIZE(i_type_instructions))) {
+ t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
+ return;
+ }
+
+ dc->zero = NULL;
+
+ instr = &i_type_instructions[op];
+ instr->handler(dc, code, instr->flags);
+
+ if (dc->zero) {
+ tcg_temp_free(dc->zero);
+ }
}
static void nios2_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v3 8/9] target/nios2: Inline handle_instruction
2021-06-28 22:08 ` [PATCH v3 8/9] target/nios2: Inline handle_instruction Richard Henderson
@ 2021-06-29 9:27 ` Peter Maydell
2021-06-29 13:53 ` Richard Henderson
0 siblings, 1 reply; 19+ messages in thread
From: Peter Maydell @ 2021-06-29 9:27 UTC (permalink / raw)
To: Richard Henderson; +Cc: Marek Vasut, Chris Wulff, QEMU Developers
On Mon, 28 Jun 2021 at 23:13, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Move handle_instruction into nios2_tr_translate_insn
> as the only caller.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/nios2/translate.c | 66 +++++++++++++++++++---------------------
> 1 file changed, 31 insertions(+), 35 deletions(-)
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Side note: I think we could replace all the handling of dc->zero
by having load_gpr() return a tcg_constant_i32(0) for R_ZERO,
which then never needs freeing. (We never try to write back
to what we get from load_gpr().)
thanks
-- PMM
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v3 8/9] target/nios2: Inline handle_instruction
2021-06-29 9:27 ` Peter Maydell
@ 2021-06-29 13:53 ` Richard Henderson
2021-06-29 13:55 ` Peter Maydell
0 siblings, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2021-06-29 13:53 UTC (permalink / raw)
To: Peter Maydell; +Cc: Marek Vasut, Chris Wulff, QEMU Developers
On 6/29/21 2:27 AM, Peter Maydell wrote:
> On Mon, 28 Jun 2021 at 23:13, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Move handle_instruction into nios2_tr_translate_insn
>> as the only caller.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> target/nios2/translate.c | 66 +++++++++++++++++++---------------------
>> 1 file changed, 31 insertions(+), 35 deletions(-)
>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>
> Side note: I think we could replace all the handling of dc->zero
> by having load_gpr() return a tcg_constant_i32(0) for R_ZERO,
> which then never needs freeing. (We never try to write back
> to what we get from load_gpr().)
Quite right. There are several targets that could benefit from that simplification.
r~
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v3 8/9] target/nios2: Inline handle_instruction
2021-06-29 13:53 ` Richard Henderson
@ 2021-06-29 13:55 ` Peter Maydell
0 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2021-06-29 13:55 UTC (permalink / raw)
To: Richard Henderson; +Cc: Marek Vasut, Chris Wulff, QEMU Developers
On Tue, 29 Jun 2021 at 14:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 6/29/21 2:27 AM, Peter Maydell wrote:
> > On Mon, 28 Jun 2021 at 23:13, Richard Henderson
> > <richard.henderson@linaro.org> wrote:
> >>
> >> Move handle_instruction into nios2_tr_translate_insn
> >> as the only caller.
> >>
> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> >> ---
> >> target/nios2/translate.c | 66 +++++++++++++++++++---------------------
> >> 1 file changed, 31 insertions(+), 35 deletions(-)
> >
> > Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> >
> > Side note: I think we could replace all the handling of dc->zero
> > by having load_gpr() return a tcg_constant_i32(0) for R_ZERO,
> > which then never needs freeing. (We never try to write back
> > to what we get from load_gpr().)
>
> Quite right. There are several targets that could benefit from that simplification.
I'm still hoping one day you'll get around to making tcg_temp_free_*()
calls entirely unnecessary :-)
-- PMM
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 9/9] target/nios2: Use pc_next for pc + 4
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (7 preceding siblings ...)
2021-06-28 22:08 ` [PATCH v3 8/9] target/nios2: Inline handle_instruction Richard Henderson
@ 2021-06-28 22:08 ` Richard Henderson
2021-06-29 9:27 ` Peter Maydell
2021-06-29 17:12 ` [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
9 siblings, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2021-06-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, Peter Maydell, crwulff
We have pre-computed the next instruction address into
dc->base.pc_next, so we might as well use it.
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/translate.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index abc7e5f96a..930f3d3395 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -211,7 +211,7 @@ static void jmpi(DisasContext *dc, uint32_t code, uint32_t flags)
static void call(DisasContext *dc, uint32_t code, uint32_t flags)
{
- tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
+ tcg_gen_movi_tl(cpu_R[R_RA], dc->base.pc_next);
jmpi(dc, code, flags);
}
@@ -265,7 +265,7 @@ static void br(DisasContext *dc, uint32_t code, uint32_t flags)
{
I_TYPE(instr, code);
- gen_goto_tb(dc, 0, dc->pc + 4 + (instr.imm16.s & -4));
+ gen_goto_tb(dc, 0, dc->base.pc_next + (instr.imm16.s & -4));
dc->base.is_jmp = DISAS_NORETURN;
}
@@ -275,9 +275,9 @@ static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
TCGLabel *l1 = gen_new_label();
tcg_gen_brcond_tl(flags, cpu_R[instr.a], cpu_R[instr.b], l1);
- gen_goto_tb(dc, 0, dc->pc + 4);
+ gen_goto_tb(dc, 0, dc->base.pc_next);
gen_set_label(l1);
- gen_goto_tb(dc, 1, dc->pc + 4 + (instr.imm16.s & -4));
+ gen_goto_tb(dc, 1, dc->base.pc_next + (instr.imm16.s & -4));
dc->base.is_jmp = DISAS_NORETURN;
}
@@ -435,7 +435,7 @@ static void nextpc(DisasContext *dc, uint32_t code, uint32_t flags)
R_TYPE(instr, code);
if (likely(instr.c != R_ZERO)) {
- tcg_gen_movi_tl(cpu_R[instr.c], dc->pc + 4);
+ tcg_gen_movi_tl(cpu_R[instr.c], dc->base.pc_next);
}
}
@@ -448,7 +448,7 @@ static void callr(DisasContext *dc, uint32_t code, uint32_t flags)
R_TYPE(instr, code);
tcg_gen_mov_tl(cpu_R[R_PC], load_gpr(dc, instr.a));
- tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
+ tcg_gen_movi_tl(cpu_R[R_RA], dc->base.pc_next);
dc->base.is_jmp = DISAS_JUMP;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v3 9/9] target/nios2: Use pc_next for pc + 4
2021-06-28 22:08 ` [PATCH v3 9/9] target/nios2: Use pc_next for pc + 4 Richard Henderson
@ 2021-06-29 9:27 ` Peter Maydell
0 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2021-06-29 9:27 UTC (permalink / raw)
To: Richard Henderson; +Cc: Marek Vasut, Chris Wulff, QEMU Developers
On Mon, 28 Jun 2021 at 23:08, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We have pre-computed the next instruction address into
> dc->base.pc_next, so we might as well use it.
>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v3 0/9] target/nios2: Convert to TranslatorOps
2021-06-28 22:08 [PATCH v3 0/9] target/nios2: Convert to TranslatorOps Richard Henderson
` (8 preceding siblings ...)
2021-06-28 22:08 ` [PATCH v3 9/9] target/nios2: Use pc_next for pc + 4 Richard Henderson
@ 2021-06-29 17:12 ` Richard Henderson
9 siblings, 0 replies; 19+ messages in thread
From: Richard Henderson @ 2021-06-29 17:12 UTC (permalink / raw)
To: qemu-devel; +Cc: marex, crwulff
On 6/28/21 3:08 PM, Richard Henderson wrote:
> I've reached a point where *all* targets must use the translator loop.
> Do that, plus some other obvious cleanups.
>
> Changes for v3:
> * Improve the commentary on patch 4 (pmm).
> * Inline handle_instruction.
> * Use pc_next for pc+4 (pmm).
>
> Changes for v2:
> * Fix (drop) singlestep check for max_insns.
> We already do that generically.
Now fully reviewed. Queuing to tcg-next.
r~
^ permalink raw reply [flat|nested] 19+ messages in thread