This patch separates the load and store instruction to a separate function. The repetition of the source code can be reduced and further optimizations can be implemented. In this case it checks for a zero offset and optimizes it.
Signed-off-by: Sebastian Macke <sebast...@macke.de> --- target-openrisc/translate.c | 119 +++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 41 deletions(-) diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index b90181d..543aa67 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -254,6 +254,63 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0) gen_sync_flags(dc); } +static void gen_loadstore(DisasContext *dc, uint32 op0, + uint32_t ra, uint32_t rb, uint32_t rd, + uint32_t offset) +{ + TCGv t0 = cpu_R[ra]; + if (offset != 0) { + t0 = tcg_temp_new(); + tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(offset, 16)); + } + + switch (op0) { + case 0x21: /* l.lwz */ + tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, MO_TEUL); + break; + + case 0x22: /* l.lws */ + tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, MO_TESL); + break; + + case 0x23: /* l.lbz */ + tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, MO_UB); + break; + + case 0x24: /* l.lbs */ + tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, MO_SB); + break; + + case 0x25: /* l.lhz */ + tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, MO_TEUW); + break; + + case 0x26: /* l.lhs */ + tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, MO_TESW); + break; + + case 0x35: /* l.sw */ + tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, MO_TEUL); + break; + + case 0x36: /* l.sb */ + tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, MO_UB); + break; + + case 0x37: /* l.sh */ + tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, MO_TEUW); + break; + + default: + break; + } + + if (offset != 0) { + tcg_temp_free(t0); + } + +} + static void dec_calc(DisasContext *dc, uint32_t insn) { @@ -702,6 +759,9 @@ static void dec_calc(DisasContext *dc, uint32_t insn) } } + + + static void dec_misc(DisasContext *dc, uint32_t insn) { uint32_t op0, op1; @@ -710,7 +770,6 @@ static void dec_misc(DisasContext *dc, uint32_t insn) uint32_t L6, K5; #endif uint32_t I16, I5, I11, N26, tmp; - TCGMemOp mop; op0 = extract32(insn, 26, 6); op1 = extract32(insn, 24, 2); @@ -843,48 +902,37 @@ static void dec_misc(DisasContext *dc, uint32_t insn) /*#ifdef TARGET_OPENRISC64 case 0x20: l.ld LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16); - check_ob64s(dc); - mop = MO_TEQ; - goto do_load; + gen_loadstore(dc, op0, ra, rb, rd, I16); #endif*/ case 0x21: /* l.lwz */ LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16); - mop = MO_TEUL; - goto do_load; + gen_loadstore(dc, op0, ra, rb, rd, I16); + break; case 0x22: /* l.lws */ LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16); - mop = MO_TESL; - goto do_load; + gen_loadstore(dc, op0, ra, rb, rd, I16); + break; case 0x23: /* l.lbz */ LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16); - mop = MO_UB; - goto do_load; + gen_loadstore(dc, op0, ra, rb, rd, I16); + break; case 0x24: /* l.lbs */ LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16); - mop = MO_SB; - goto do_load; + gen_loadstore(dc, op0, ra, rb, rd, I16); + break; case 0x25: /* l.lhz */ LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16); - mop = MO_TEUW; - goto do_load; + gen_loadstore(dc, op0, ra, rb, rd, I16); + break; case 0x26: /* l.lhs */ LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16); - mop = MO_TESW; - goto do_load; - - do_load: - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop); - tcg_temp_free(t0); - } + gen_loadstore(dc, op0, ra, rb, rd, I16); break; case 0x27: /* l.addi */ @@ -1021,33 +1069,22 @@ static void dec_misc(DisasContext *dc, uint32_t insn) /*#ifdef TARGET_OPENRISC64 case 0x34: l.sd LOG_DIS("l.sd %d, r%d, r%d, %d\n", I5, ra, rb, I11); - check_ob64s(dc); - mop = MO_TEQ; - goto do_store; + gen_loadstore(dc, op0, ra, rb, rd, tmp); #endif*/ case 0x35: /* l.sw */ LOG_DIS("l.sw %d, r%d, r%d, %d\n", I5, ra, rb, I11); - mop = MO_TEUL; - goto do_store; + gen_loadstore(dc, op0, ra, rb, rd, tmp); + break; case 0x36: /* l.sb */ LOG_DIS("l.sb %d, r%d, r%d, %d\n", I5, ra, rb, I11); - mop = MO_UB; - goto do_store; + gen_loadstore(dc, op0, ra, rb, rd, tmp); + break; case 0x37: /* l.sh */ LOG_DIS("l.sh %d, r%d, r%d, %d\n", I5, ra, rb, I11); - mop = MO_TEUW; - goto do_store; - - do_store: - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16)); - tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop); - tcg_temp_free(t0); - } + gen_loadstore(dc, op0, ra, rb, rd, tmp); break; default: -- 2.2.2