On 6/9/21 6:43 PM, LIU Zhiwei wrote:
1)First a multiply instruction, if the source value big enough, it will return a result with some bits not zero in MSW 32-bit.

Multiply is fine. Input bits outside the low 32 cannot appear in the low 32 of the output. Multiply-high-part on the other hand will require sign- or zero-extension of inputs.

2)If next instruction is a divide instruction,  the MSW 32-bit will influence the divide instruction result.

Yes, division requires extension too.

So I think use *_tl can't satisfy the need to run 32-bit program on 
qemu-riscv64.

I said some operations will require extra work -- I gave right-shift as an 
example.

You just have to be careful about deciding what extra work to do. I am suggesting that truncation to *_i32 is almost always not the correct answer.

Perhaps make it easier by changing gen_get_gpr and gen_set_gpr:

/* Return sign-extended version of gpr. */
static void get_gpr_s(DisasContext *ctx, TCGv t, int reg_num)
{
    if (reg_num == 0) {
        tcg_gen_movi_tl(t, 0);
    } else if (is_32bit(ctx)) {
        tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
    } else {
        tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
    }
}

/* Return zero-extended version of gpr. */
static void get_gpr_u(DisasContext *ctx, TCGv t, int reg_num);
{
    if (reg_num == 0) {
        tcg_gen_movi_tl(t, 0);
    } else if (is_32bit(ctx)) {
        tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
    } else {
        tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
    }
}

/* Return gpr with undefined high bits (which will be ignored). */
static void get_gpr_x(TCGv t, int reg_num);
{
    if (reg_num == 0) {
        tcg_gen_movi_tl(t, 0);
    } else {
        tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
    }
}

And similarly for set.


r~

Reply via email to