diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-09-14 10:46:38 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-09-14 10:46:38 +0100 |
commit | 2b750d9d261bda7f75b39dfc1e1e5f22502929d5 (patch) | |
tree | 694ab983efaf829071c85b1149eec905511b4372 | |
parent | 8f6e82e4ecec9bc2726725275a138bc30f3ffc81 (diff) | |
parent | cdd14a8cf25c34ff8d0777530e8d16565f6bf7a1 (diff) |
Merge remote-tracking branch 'remotes/aurel/tags/pull-sh4-next-20150913' into staging
sh4-next:
- TCG optimizations
- fix initramfs endianness issue
# gpg: Signature made Sun 13 Sep 2015 22:16:12 BST using RSA key ID 1DDD8C9B
# gpg: Good signature from "Aurelien Jarno <aurelien@aurel32.net>"
# gpg: aka "Aurelien Jarno <aurelien@jarno.fr>"
# gpg: aka "Aurelien Jarno <aurel32@debian.org>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 7746 2642 A9EF 94FD 0F77 196D BA9C 7806 1DDD 8C9B
* remotes/aurel/tags/pull-sh4-next-20150913:
sh4: Fix initramfs initialization for endiannes-mismatched targets
target-sh4: improve shad instruction
target-sh4: improve shld instruction
target-sh4: improve cmp/str instruction
target-sh4: use deposit in swap.b instruction
target-sh4: add flags markups for FP helpers
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/sh4/r2d.c | 6 | ||||
-rw-r--r-- | target-sh4/helper.h | 34 | ||||
-rw-r--r-- | target-sh4/translate.c | 126 |
3 files changed, 71 insertions, 95 deletions
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index 5e22ed79b2..3b0b2ecfa4 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -338,9 +338,9 @@ static void r2d_init(MachineState *machine) } /* initialization which should be done by firmware */ - boot_params.loader_type = 1; - boot_params.initrd_start = INITRD_LOAD_OFFSET; - boot_params.initrd_size = initrd_size; + boot_params.loader_type = tswap32(1); + boot_params.initrd_start = tswap32(INITRD_LOAD_OFFSET); + boot_params.initrd_size = tswap32(initrd_size); } if (kernel_cmdline) { diff --git a/target-sh4/helper.h b/target-sh4/helper.h index c9bc407042..dce859caea 100644 --- a/target-sh4/helper.h +++ b/target-sh4/helper.h @@ -18,28 +18,28 @@ DEF_HELPER_2(ld_fpscr, void, env, i32) DEF_HELPER_FLAGS_1(fabs_FT, TCG_CALL_NO_RWG_SE, f32, f32) DEF_HELPER_FLAGS_1(fabs_DT, TCG_CALL_NO_RWG_SE, f64, f64) -DEF_HELPER_3(fadd_FT, f32, env, f32, f32) -DEF_HELPER_3(fadd_DT, f64, env, f64, f64) -DEF_HELPER_2(fcnvsd_FT_DT, f64, env, f32) -DEF_HELPER_2(fcnvds_DT_FT, f32, env, f64) +DEF_HELPER_FLAGS_3(fadd_FT, TCG_CALL_NO_WG, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fadd_DT, TCG_CALL_NO_WG, f64, env, f64, f64) +DEF_HELPER_FLAGS_2(fcnvsd_FT_DT, TCG_CALL_NO_WG, f64, env, f32) +DEF_HELPER_FLAGS_2(fcnvds_DT_FT, TCG_CALL_NO_WG, f32, env, f64) DEF_HELPER_3(fcmp_eq_FT, void, env, f32, f32) DEF_HELPER_3(fcmp_eq_DT, void, env, f64, f64) DEF_HELPER_3(fcmp_gt_FT, void, env, f32, f32) DEF_HELPER_3(fcmp_gt_DT, void, env, f64, f64) -DEF_HELPER_3(fdiv_FT, f32, env, f32, f32) -DEF_HELPER_3(fdiv_DT, f64, env, f64, f64) -DEF_HELPER_2(float_FT, f32, env, i32) -DEF_HELPER_2(float_DT, f64, env, i32) -DEF_HELPER_4(fmac_FT, f32, env, f32, f32, f32) -DEF_HELPER_3(fmul_FT, f32, env, f32, f32) -DEF_HELPER_3(fmul_DT, f64, env, f64, f64) +DEF_HELPER_FLAGS_3(fdiv_FT, TCG_CALL_NO_WG, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fdiv_DT, TCG_CALL_NO_WG, f64, env, f64, f64) +DEF_HELPER_FLAGS_2(float_FT, TCG_CALL_NO_WG, f32, env, i32) +DEF_HELPER_FLAGS_2(float_DT, TCG_CALL_NO_WG, f64, env, i32) +DEF_HELPER_FLAGS_4(fmac_FT, TCG_CALL_NO_WG, f32, env, f32, f32, f32) +DEF_HELPER_FLAGS_3(fmul_FT, TCG_CALL_NO_WG, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fmul_DT, TCG_CALL_NO_WG, f64, env, f64, f64) DEF_HELPER_FLAGS_1(fneg_T, TCG_CALL_NO_RWG_SE, f32, f32) -DEF_HELPER_3(fsub_FT, f32, env, f32, f32) -DEF_HELPER_3(fsub_DT, f64, env, f64, f64) -DEF_HELPER_2(fsqrt_FT, f32, env, f32) -DEF_HELPER_2(fsqrt_DT, f64, env, f64) -DEF_HELPER_2(ftrc_FT, i32, env, f32) -DEF_HELPER_2(ftrc_DT, i32, env, f64) +DEF_HELPER_FLAGS_3(fsub_FT, TCG_CALL_NO_WG, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fsub_DT, TCG_CALL_NO_WG, f64, env, f64, f64) +DEF_HELPER_FLAGS_2(fsqrt_FT, TCG_CALL_NO_WG, f32, env, f32) +DEF_HELPER_FLAGS_2(fsqrt_DT, TCG_CALL_NO_WG, f64, env, f64) +DEF_HELPER_FLAGS_2(ftrc_FT, TCG_CALL_NO_WG, i32, env, f32) +DEF_HELPER_FLAGS_2(ftrc_DT, TCG_CALL_NO_WG, i32, env, f64) DEF_HELPER_3(fipr, void, env, i32, i32) DEF_HELPER_2(ftrv, void, env, i32) diff --git a/target-sh4/translate.c b/target-sh4/translate.c index be0cb321cf..724c0e7106 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -612,15 +612,11 @@ static void _decode_opc(DisasContext * ctx) return; case 0x6008: /* swap.b Rm,Rn */ { - TCGv high, low; - high = tcg_temp_new(); - tcg_gen_andi_i32(high, REG(B7_4), 0xffff0000); - low = tcg_temp_new(); + TCGv low = tcg_temp_new();; tcg_gen_ext16u_i32(low, REG(B7_4)); tcg_gen_bswap16_i32(low, low); - tcg_gen_or_i32(REG(B11_8), high, low); + tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16); tcg_temp_free(low); - tcg_temp_free(high); } return; case 0x6009: /* swap.w Rm,Rn */ @@ -692,18 +688,11 @@ static void _decode_opc(DisasContext * ctx) { TCGv cmp1 = tcg_temp_new(); TCGv cmp2 = tcg_temp_new(); - tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8)); - tcg_gen_andi_i32(cmp2, cmp1, 0xff000000); - tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, cmp2, 0); - tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000); - tcg_gen_setcondi_i32(TCG_COND_EQ, cmp2, cmp2, 0); - tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, cmp2); - tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00); - tcg_gen_setcondi_i32(TCG_COND_EQ, cmp2, cmp2, 0); - tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, cmp2); - tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff); - tcg_gen_setcondi_i32(TCG_COND_EQ, cmp2, cmp2, 0); - tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, cmp2); + tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8)); + tcg_gen_subi_i32(cmp1, cmp2, 0x01010101); + tcg_gen_andc_i32(cmp1, cmp1, cmp2); + tcg_gen_andi_i32(cmp1, cmp1, 0x80808080); + tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0); tcg_temp_free(cmp2); tcg_temp_free(cmp1); } @@ -843,67 +832,54 @@ static void _decode_opc(DisasContext * ctx) return; case 0x400c: /* shad Rm,Rn */ { - TCGLabel *label1 = gen_new_label(); - TCGLabel *label2 = gen_new_label(); - TCGLabel *label3 = gen_new_label(); - TCGLabel *label4 = gen_new_label(); - TCGv shift; - tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1); - /* Rm positive, shift to the left */ - shift = tcg_temp_new(); - tcg_gen_andi_i32(shift, REG(B7_4), 0x1f); - tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift); - tcg_temp_free(shift); - tcg_gen_br(label4); - /* Rm negative, shift to the right */ - gen_set_label(label1); - shift = tcg_temp_new(); - tcg_gen_andi_i32(shift, REG(B7_4), 0x1f); - tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2); - tcg_gen_not_i32(shift, REG(B7_4)); - tcg_gen_andi_i32(shift, shift, 0x1f); - tcg_gen_addi_i32(shift, shift, 1); - tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift); - tcg_temp_free(shift); - tcg_gen_br(label4); - /* Rm = -32 */ - gen_set_label(label2); - tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3); - tcg_gen_movi_i32(REG(B11_8), 0); - tcg_gen_br(label4); - gen_set_label(label3); - tcg_gen_movi_i32(REG(B11_8), 0xffffffff); - gen_set_label(label4); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); + + tcg_gen_andi_i32(t0, REG(B7_4), 0x1f); + + /* positive case: shift to the left */ + tcg_gen_shl_i32(t1, REG(B11_8), t0); + + /* negative case: shift to the right in two steps to + correctly handle the -32 case */ + tcg_gen_xori_i32(t0, t0, 0x1f); + tcg_gen_sar_i32(t2, REG(B11_8), t0); + tcg_gen_sari_i32(t2, t2, 1); + + /* select between the two cases */ + tcg_gen_movi_i32(t0, 0); + tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); } return; case 0x400d: /* shld Rm,Rn */ { - TCGLabel *label1 = gen_new_label(); - TCGLabel *label2 = gen_new_label(); - TCGLabel *label3 = gen_new_label(); - TCGv shift; - tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1); - /* Rm positive, shift to the left */ - shift = tcg_temp_new(); - tcg_gen_andi_i32(shift, REG(B7_4), 0x1f); - tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift); - tcg_temp_free(shift); - tcg_gen_br(label3); - /* Rm negative, shift to the right */ - gen_set_label(label1); - shift = tcg_temp_new(); - tcg_gen_andi_i32(shift, REG(B7_4), 0x1f); - tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2); - tcg_gen_not_i32(shift, REG(B7_4)); - tcg_gen_andi_i32(shift, shift, 0x1f); - tcg_gen_addi_i32(shift, shift, 1); - tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift); - tcg_temp_free(shift); - tcg_gen_br(label3); - /* Rm = -32 */ - gen_set_label(label2); - tcg_gen_movi_i32(REG(B11_8), 0); - gen_set_label(label3); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); + + tcg_gen_andi_i32(t0, REG(B7_4), 0x1f); + + /* positive case: shift to the left */ + tcg_gen_shl_i32(t1, REG(B11_8), t0); + + /* negative case: shift to the right in two steps to + correctly handle the -32 case */ + tcg_gen_xori_i32(t0, t0, 0x1f); + tcg_gen_shr_i32(t2, REG(B11_8), t0); + tcg_gen_shri_i32(t2, t2, 1); + + /* select between the two cases */ + tcg_gen_movi_i32(t0, 0); + tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); } return; case 0x3008: /* sub Rm,Rn */ |