gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,

             uint32_t up_shift, CPUTriCoreState *env)

{

    TCGv temp = tcg_temp_new();

    TCGv temp2 = tcg_temp_new();

    TCGv temp3 = tcg_temp_new();

    TCGv_i64 t1 = tcg_temp_new_i64();

    TCGv_i64 t2 = tcg_temp_new_i64();

    TCGv_i64 t3 = tcg_temp_new_i64();

    TCGv_i64 t4 = tcg_temp_new_i64();



    tcg_gen_ext_i32_i64(t2, arg2);

    tcg_gen_ext_i32_i64(t3, arg3);



    tcg_gen_mul_i64(t2, t2, t3);



    tcg_gen_ext_i32_i64(t1, arg1);

    /* if we shift part of the fraction out, we need to round up */

    tcg_gen_andi_i64(t4, t2, (1ll << (up_shift - n)) - 1);

    tcg_gen_setcondi_i64(TCG_COND_NE, t4, t4, 0);

    tcg_gen_sari_i64(t2, t2, up_shift - n);

    tcg_gen_add_i64(t2, t2, t4);



    tcg_gen_sub_i64(t3, t1, t2);

    tcg_gen_trunc_i64_i32(temp3, t3);

    /* calc v bit */

    tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL);

    tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL);

    tcg_gen_or_i64(t1, t1, t2);

    tcg_gen_trunc_i64_i32(cpu_PSW_V, t1);

    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);

    /* We produce an overflow on the host if the mul before was

       (0x80000000 * 0x80000000) << 1). If this is the

       case, we negate the ovf. */

    if (n == 1) {

        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x80000000);

        tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);

        tcg_gen_and_tl(temp, temp, temp2);

        tcg_gen_shli_tl(temp, temp, 31);

        /* negate v bit, if special condition */

        tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);

    }

    /* Calc SV bit */

    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);

    /* Calc AV/SAV bits */

    tcg_gen_add_tl(cpu_PSW_AV, temp3, temp3);

    tcg_gen_xor_tl(cpu_PSW_AV, temp3, cpu_PSW_AV);

    /* calc SAV */

    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);

    /* write back result */

    tcg_gen_mov_tl(ret, temp3);



    tcg_temp_free(temp);

    tcg_temp_free(temp2);

    tcg_temp_free(temp3);

    tcg_temp_free_i64(t1);

    tcg_temp_free_i64(t2);

    tcg_temp_free_i64(t3);

    tcg_temp_free_i64(t4);

}
