Re: [PATCH v7 13/18] target/riscv: support for 128-bit arithmetic instructions

2022-01-05 Thread Alistair Francis
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

2021-12-13 Thread Frédéric Pétrot
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();
 }
 }
-