Commit 2b750d9d authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 8f6e82e4 cdd14a8c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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) {
+17 −17
Original line number Diff line number Diff line
@@ -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)
+51 −75
Original line number Diff line number Diff line
@@ -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 */