Re: [PATCH v7 13/18] target/riscv: support for 128-bit arithmetic instructions
On Tue, Dec 14, 2021 at 2:44 AM Frédéric Pétrot wrote: > > Addition of 128-bit adds and subs in their various sizes, > "set if less than"s and branches. > Refactored the code to have a comparison function used for both stls and > branches. > > Signed-off-by: Frédéric Pétrot > Co-authored-by: Fabien Portas Reviewed-by: Alistair Francis Alistair > --- > target/riscv/insn32.decode | 3 + > target/riscv/translate.c| 63 -- > target/riscv/insn_trans/trans_rvb.c.inc | 20 +-- > target/riscv/insn_trans/trans_rvi.c.inc | 159 +--- > target/riscv/insn_trans/trans_rvm.c.inc | 26 ++-- > 5 files changed, 222 insertions(+), 49 deletions(-) > > diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode > index e338a803a0..afaf243b4e 100644 > --- a/target/riscv/insn32.decode > +++ b/target/riscv/insn32.decode > @@ -171,9 +171,12 @@ sraw 010 . . 101 . 0111011 @r > ldu . 111 . 011 @i > lq . 010 . 000 @i > sq . 100 . 0100011 @s > +addid . 000 . 1011011 @i > sllid00 .. . 001 . 1011011 @sh6 > srlid00 .. . 101 . 1011011 @sh6 > sraid01 .. . 101 . 1011011 @sh6 > +addd 000 . . 000 . 011 @r > +subd 010 . . 000 . 011 @r > slld 000 . . 001 . 011 @r > srld 000 . . 101 . 011 @r > srad 010 . . 101 . 011 @r > diff --git a/target/riscv/translate.c b/target/riscv/translate.c > index 15e628308d..02176ec1a9 100644 > --- a/target/riscv/translate.c > +++ b/target/riscv/translate.c > @@ -506,57 +506,96 @@ static bool gen_logic(DisasContext *ctx, arg_r *a, > } > > static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext, > - void (*func)(TCGv, TCGv, target_long)) > + void (*func)(TCGv, TCGv, target_long), > + void (*f128)(TCGv, TCGv, TCGv, TCGv, > target_long)) > { > TCGv dest = dest_gpr(ctx, a->rd); > TCGv src1 = get_gpr(ctx, a->rs1, ext); > > -func(dest, src1, a->imm); > +if (get_ol(ctx) < MXL_RV128) { > +func(dest, src1, a->imm); > +gen_set_gpr(ctx, a->rd, dest); > +} else { > +if (f128 == NULL) { > +return false; > +} > > -gen_set_gpr(ctx, a->rd, dest); > +TCGv src1h = get_gprh(ctx, a->rs1); > +TCGv desth = dest_gprh(ctx, a->rd); > + > +f128(dest, desth, src1, src1h, a->imm); > +gen_set_gpr128(ctx, a->rd, dest, desth); > +} > return true; > } > > static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext, > - void (*func)(TCGv, TCGv, TCGv)) > + void (*func)(TCGv, TCGv, TCGv), > + void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, > TCGv)) > { > TCGv dest = dest_gpr(ctx, a->rd); > TCGv src1 = get_gpr(ctx, a->rs1, ext); > TCGv src2 = tcg_constant_tl(a->imm); > > -func(dest, src1, src2); > +if (get_ol(ctx) < MXL_RV128) { > +func(dest, src1, src2); > +gen_set_gpr(ctx, a->rd, dest); > +} else { > +if (f128 == NULL) { > +return false; > +} > > -gen_set_gpr(ctx, a->rd, dest); > +TCGv src1h = get_gprh(ctx, a->rs1); > +TCGv src2h = tcg_constant_tl(-(a->imm < 0)); > +TCGv desth = dest_gprh(ctx, a->rd); > + > +f128(dest, desth, src1, src1h, src2, src2h); > +gen_set_gpr128(ctx, a->rd, dest, desth); > +} > return true; > } > > static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext, > - void (*func)(TCGv, TCGv, TCGv)) > + void (*func)(TCGv, TCGv, TCGv), > + void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv)) > { > TCGv dest = dest_gpr(ctx, a->rd); > TCGv src1 = get_gpr(ctx, a->rs1, ext); > TCGv src2 = get_gpr(ctx, a->rs2, ext); > > -func(dest, src1, src2); > +if (get_ol(ctx) < MXL_RV128) { > +func(dest, src1, src2); > +gen_set_gpr(ctx, a->rd, dest); > +} else { > +if (f128 == NULL) { > +return false; > +} > > -gen_set_gpr(ctx, a->rd, dest); > +TCGv src1h = get_gprh(ctx, a->rs1); > +TCGv src2h = get_gprh(ctx, a->rs2); > +TCGv desth = dest_gprh(ctx, a->rd); > + > +f128(dest, desth, src1, src1h, src2, src2h); > +gen_set_gpr128(ctx, a->rd, dest, desth); > +} > return true; > } > > static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext, > void (*f_tl)(TCGv, TCGv, TCGv), > - void (*f_32)(TCGv, TCGv, TCGv)) > + void
[PATCH v7 13/18] target/riscv: support for 128-bit arithmetic instructions
Addition of 128-bit adds and subs in their various sizes, "set if less than"s and branches. Refactored the code to have a comparison function used for both stls and branches. Signed-off-by: Frédéric Pétrot Co-authored-by: Fabien Portas --- target/riscv/insn32.decode | 3 + target/riscv/translate.c| 63 -- target/riscv/insn_trans/trans_rvb.c.inc | 20 +-- target/riscv/insn_trans/trans_rvi.c.inc | 159 +--- target/riscv/insn_trans/trans_rvm.c.inc | 26 ++-- 5 files changed, 222 insertions(+), 49 deletions(-) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index e338a803a0..afaf243b4e 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -171,9 +171,12 @@ sraw 010 . . 101 . 0111011 @r ldu . 111 . 011 @i lq . 010 . 000 @i sq . 100 . 0100011 @s +addid . 000 . 1011011 @i sllid00 .. . 001 . 1011011 @sh6 srlid00 .. . 101 . 1011011 @sh6 sraid01 .. . 101 . 1011011 @sh6 +addd 000 . . 000 . 011 @r +subd 010 . . 000 . 011 @r slld 000 . . 001 . 011 @r srld 000 . . 101 . 011 @r srad 010 . . 101 . 011 @r diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 15e628308d..02176ec1a9 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -506,57 +506,96 @@ static bool gen_logic(DisasContext *ctx, arg_r *a, } static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext, - void (*func)(TCGv, TCGv, target_long)) + void (*func)(TCGv, TCGv, target_long), + void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long)) { TCGv dest = dest_gpr(ctx, a->rd); TCGv src1 = get_gpr(ctx, a->rs1, ext); -func(dest, src1, a->imm); +if (get_ol(ctx) < MXL_RV128) { +func(dest, src1, a->imm); +gen_set_gpr(ctx, a->rd, dest); +} else { +if (f128 == NULL) { +return false; +} -gen_set_gpr(ctx, a->rd, dest); +TCGv src1h = get_gprh(ctx, a->rs1); +TCGv desth = dest_gprh(ctx, a->rd); + +f128(dest, desth, src1, src1h, a->imm); +gen_set_gpr128(ctx, a->rd, dest, desth); +} return true; } static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext, - void (*func)(TCGv, TCGv, TCGv)) + void (*func)(TCGv, TCGv, TCGv), + void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv)) { TCGv dest = dest_gpr(ctx, a->rd); TCGv src1 = get_gpr(ctx, a->rs1, ext); TCGv src2 = tcg_constant_tl(a->imm); -func(dest, src1, src2); +if (get_ol(ctx) < MXL_RV128) { +func(dest, src1, src2); +gen_set_gpr(ctx, a->rd, dest); +} else { +if (f128 == NULL) { +return false; +} -gen_set_gpr(ctx, a->rd, dest); +TCGv src1h = get_gprh(ctx, a->rs1); +TCGv src2h = tcg_constant_tl(-(a->imm < 0)); +TCGv desth = dest_gprh(ctx, a->rd); + +f128(dest, desth, src1, src1h, src2, src2h); +gen_set_gpr128(ctx, a->rd, dest, desth); +} return true; } static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext, - void (*func)(TCGv, TCGv, TCGv)) + void (*func)(TCGv, TCGv, TCGv), + void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv)) { TCGv dest = dest_gpr(ctx, a->rd); TCGv src1 = get_gpr(ctx, a->rs1, ext); TCGv src2 = get_gpr(ctx, a->rs2, ext); -func(dest, src1, src2); +if (get_ol(ctx) < MXL_RV128) { +func(dest, src1, src2); +gen_set_gpr(ctx, a->rd, dest); +} else { +if (f128 == NULL) { +return false; +} -gen_set_gpr(ctx, a->rd, dest); +TCGv src1h = get_gprh(ctx, a->rs1); +TCGv src2h = get_gprh(ctx, a->rs2); +TCGv desth = dest_gprh(ctx, a->rd); + +f128(dest, desth, src1, src1h, src2, src2h); +gen_set_gpr128(ctx, a->rd, dest, desth); +} return true; } static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext, void (*f_tl)(TCGv, TCGv, TCGv), - void (*f_32)(TCGv, TCGv, TCGv)) + void (*f_32)(TCGv, TCGv, TCGv), + void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv)) { int olen = get_olen(ctx); if (olen != TARGET_LONG_BITS) { if (olen == 32) { f_tl = f_32; -} else { +} else if (olen != 128) { g_assert_not_reached(); } } -