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~