From 88f7e01d44717785fed3828ba64af132667e1c5d Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Wed, 14 Feb 2018 21:05:43 -0500 Subject: [PATCH] target-mips: simplify LWL/LDL mask generation The LWL/LDL instructions mask the GPR with a mask depending on the address alignement. It is currently computed by doing: mask = 0x7fffffffffffffffull >> (t1 ^ 63) It's simpler to generate it by doing: mask = ~(-1 << t1) It uses one TCG instruction less, and it avoids a 32/64-bit constant loading which can take a few instructions on RISC hosts. Backports commit eb02cc3f89013612cb05df23b5441741e902bbd2 from qemu --- qemu/target-mips/translate.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 51830b6a..e285c26e 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -2160,11 +2160,10 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_andi_tl(tcg_ctx, t0, t0, ~7); tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEQ); tcg_gen_shl_tl(tcg_ctx, t0, t0, t1); - tcg_gen_xori_tl(tcg_ctx, t1, t1, 63); - t2 = tcg_const_tl(tcg_ctx, 0x7fffffffffffffffull); - tcg_gen_shr_tl(tcg_ctx, t2, t2, t1); + t2 = tcg_const_tl(tcg_ctx, -1); + tcg_gen_shl_tl(tcg_ctx, t2, t2, t1); gen_load_gpr(ctx, t1, rt); - tcg_gen_and_tl(tcg_ctx, t1, t1, t2); + tcg_gen_andc_tl(tcg_ctx, t1, t1, t2); tcg_temp_free(tcg_ctx, t2); tcg_gen_or_tl(tcg_ctx, t0, t0, t1); tcg_temp_free(tcg_ctx, t1); @@ -2253,11 +2252,10 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_andi_tl(tcg_ctx, t0, t0, ~3); tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEUL); tcg_gen_shl_tl(tcg_ctx, t0, t0, t1); - tcg_gen_xori_tl(tcg_ctx, t1, t1, 31); - t2 = tcg_const_tl(tcg_ctx, 0x7fffffffull); - tcg_gen_shr_tl(tcg_ctx, t2, t2, t1); + t2 = tcg_const_tl(tcg_ctx, -1); + tcg_gen_shl_tl(tcg_ctx, t2, t2, t1); gen_load_gpr(ctx, t1, rt); - tcg_gen_and_tl(tcg_ctx, t1, t1, t2); + tcg_gen_andc_tl(tcg_ctx, t1, t1, t2); tcg_temp_free(tcg_ctx, t2); tcg_gen_or_tl(tcg_ctx, t0, t0, t1); tcg_temp_free(tcg_ctx, t1);