diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-02-25 17:28:36 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-03-13 06:44:37 -0700 |
commit | 990c162e672dfadac7b4b3420c8fe08d88d13a3f (patch) | |
tree | 39895b34ffee6c3fdb6c4b81326802f2f2756de0 /target/mips/tcg/translate.c | |
parent | 1852ce5a701f0c781ba2b861ee75fd2dd68d6797 (diff) | |
download | qemu-990c162e672dfadac7b4b3420c8fe08d88d13a3f.zip qemu-990c162e672dfadac7b4b3420c8fe08d88d13a3f.tar.gz qemu-990c162e672dfadac7b4b3420c8fe08d88d13a3f.tar.bz2 |
target/mips: Split out gen_lxl
Common subroutine for LDL and LWL.
Use tcg_constant_tl instead of tcg_const_tl and t2.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/mips/tcg/translate.c')
-rw-r--r-- | target/mips/tcg/translate.c | 106 |
1 files changed, 36 insertions, 70 deletions
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 0fa9634..05c8d4c 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -1995,6 +1995,32 @@ static target_ulong pc_relative_pc(DisasContext *ctx) return pc; } +/* LWL or LDL, depending on MemOp. */ +static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, + int mem_idx, MemOp mop) +{ + int sizem1 = memop_size(mop) - 1; + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + + /* + * Do a byte access to possibly trigger a page + * fault with the unaligned address. + */ + tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); + tcg_gen_andi_tl(t1, addr, sizem1); + if (!cpu_is_bigendian(ctx)) { + tcg_gen_xori_tl(t1, t1, sizem1); + } + tcg_gen_shli_tl(t1, t1, 3); + tcg_gen_andi_tl(t0, addr, ~sizem1); + tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); + tcg_gen_shl_tl(t0, t0, t1); + tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); + tcg_gen_andc_tl(t1, reg, t1); + tcg_gen_or_tl(reg, t0, t1); +} + /* Load */ static void gen_ld(DisasContext *ctx, uint32_t opc, int rt, int base, int offset) @@ -2034,25 +2060,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LDL: t1 = tcg_temp_new(); - /* - * Do a byte access to possibly trigger a page - * fault with the unaligned address. - */ - tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 7); - if (!cpu_is_bigendian(ctx)) { - tcg_gen_xori_tl(t1, t1, 7); - } - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~7); - tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); - tcg_gen_shl_tl(t0, t0, t1); - t2 = tcg_const_tl(-1); - tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); - tcg_gen_andc_tl(t1, t1, t2); - tcg_gen_or_tl(t0, t0, t1); - gen_store_gpr(t0, rt); + gen_lxl(ctx, t1, t0, mem_idx, MO_TEUQ); + gen_store_gpr(t1, rt); break; case OPC_LDR: t1 = tcg_temp_new(); @@ -2133,26 +2143,10 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, /* fall through */ case OPC_LWL: t1 = tcg_temp_new(); - /* - * Do a byte access to possibly trigger a page - * fault with the unaligned address. - */ - tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 3); - if (!cpu_is_bigendian(ctx)) { - tcg_gen_xori_tl(t1, t1, 3); - } - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~3); - tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); - tcg_gen_shl_tl(t0, t0, t1); - t2 = tcg_const_tl(-1); - tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); - tcg_gen_andc_tl(t1, t1, t2); - tcg_gen_or_tl(t0, t0, t1); - tcg_gen_ext32s_tl(t0, t0); - gen_store_gpr(t0, rt); + gen_lxl(ctx, t1, t0, mem_idx, MO_TEUL); + tcg_gen_ext32s_tl(t1, t1); + gen_store_gpr(t1, rt); break; case OPC_LWRE: mem_idx = MIPS_HFLAG_UM; @@ -4220,28 +4214,12 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, case OPC_GSLWLC1: check_cp1_enabled(ctx); gen_base_offset_addr(ctx, t0, rs, shf_offset); - t1 = tcg_temp_new(); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 3); - if (!cpu_is_bigendian(ctx)) { - tcg_gen_xori_tl(t1, t1, 3); - } - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~3); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); - tcg_gen_shl_tl(t0, t0, t1); - t2 = tcg_const_tl(-1); - tcg_gen_shl_tl(t2, t2, t1); fp0 = tcg_temp_new_i32(); gen_load_fpr32(ctx, fp0, rt); + t1 = tcg_temp_new(); tcg_gen_ext_i32_tl(t1, fp0); - tcg_gen_andc_tl(t1, t1, t2); - tcg_gen_or_tl(t0, t0, t1); -#if defined(TARGET_MIPS64) - tcg_gen_extrl_i64_i32(fp0, t0); -#else - tcg_gen_ext32s_tl(fp0, t0); -#endif + gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUL); + tcg_gen_trunc_tl_i32(fp0, t1); gen_store_fpr32(ctx, fp0, rt); break; case OPC_GSLWRC1: @@ -4277,21 +4255,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, check_cp1_enabled(ctx); gen_base_offset_addr(ctx, t0, rs, shf_offset); t1 = tcg_temp_new(); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 7); - if (!cpu_is_bigendian(ctx)) { - tcg_gen_xori_tl(t1, t1, 7); - } - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~7); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); - tcg_gen_shl_tl(t0, t0, t1); - t2 = tcg_const_tl(-1); - tcg_gen_shl_tl(t2, t2, t1); gen_load_fpr64(ctx, t1, rt); - tcg_gen_andc_tl(t1, t1, t2); - tcg_gen_or_tl(t0, t0, t1); - gen_store_fpr64(ctx, t0, rt); + gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUQ); + gen_store_fpr64(ctx, t1, rt); break; case OPC_GSLDRC1: check_cp1_enabled(ctx); |