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>
This commit is contained in:
parent
1852ce5a70
commit
990c162e67
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue