diff mbox series

[v11,18/20] disas/riscv: enable disassembly for zicfiss instructions

Message ID 20240828174739.714313-19-debug@rivosinc.com (mailing list archive)
State New, archived
Headers show
Series riscv support for control flow integrity extensions | expand

Commit Message

Deepak Gupta Aug. 28, 2024, 5:47 p.m. UTC
Enable disassembly for sspush, sspopchk, ssrdp & ssamoswap.
Disasembly is only enabled if zimop and zicfiss ext is set to true.

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
 disas/riscv.c | 40 +++++++++++++++++++++++++++++++++++++++-
 disas/riscv.h |  1 +
 2 files changed, 40 insertions(+), 1 deletion(-)

Comments

Alistair Francis Aug. 29, 2024, 12:04 a.m. UTC | #1
On Thu, Aug 29, 2024 at 3:52 AM Deepak Gupta <debug@rivosinc.com> wrote:
>
> Enable disassembly for sspush, sspopchk, ssrdp & ssamoswap.
> Disasembly is only enabled if zimop and zicfiss ext is set to true.
>
> Signed-off-by: Deepak Gupta <debug@rivosinc.com>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  disas/riscv.c | 40 +++++++++++++++++++++++++++++++++++++++-
>  disas/riscv.h |  1 +
>  2 files changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index c7c92acef7..5eafb7f7f3 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -975,6 +975,11 @@ typedef enum {
>      rv_op_amocas_b  = 944,
>      rv_op_amocas_h  = 945,
>      rv_op_lpad = 946,
> +    rv_op_sspush = 947,
> +    rv_op_sspopchk = 948,
> +    rv_op_ssrdp = 949,
> +    rv_op_ssamoswap_w = 950,
> +    rv_op_ssamoswap_d = 951,
>  } rv_op;
>
>  /* register names */
> @@ -2234,6 +2239,11 @@ const rv_opcode_data rvi_opcode_data[] = {
>      { "amocas.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
>      { "amocas.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
>      { "lpad", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
> +    { "sspush", rv_codec_r, rv_fmt_rs2, NULL, 0, 0, 0 },
> +    { "sspopchk", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "ssrdp", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
> +    { "ssamoswap.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
> +    { "ssamoswap.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
>  };
>
>  /* CSR names */
> @@ -2251,6 +2261,7 @@ static const char *csr_name(int csrno)
>      case 0x0009: return "vxsat";
>      case 0x000a: return "vxrm";
>      case 0x000f: return "vcsr";
> +    case 0x0011: return "ssp";
>      case 0x0015: return "seed";
>      case 0x0017: return "jvt";
>      case 0x0040: return "uscratch";
> @@ -3077,6 +3088,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
>              case 66: op = rv_op_amoor_w; break;
>              case 67: op = rv_op_amoor_d; break;
>              case 68: op = rv_op_amoor_q; break;
> +            case 74: op = rv_op_ssamoswap_w; break;
> +            case 75: op = rv_op_ssamoswap_d; break;
>              case 96: op = rv_op_amoand_b; break;
>              case 97: op = rv_op_amoand_h; break;
>              case 98: op = rv_op_amoand_w; break;
> @@ -4028,7 +4041,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
>              case 3: op = rv_op_csrrc; break;
>              case 4:
>                  if (dec->cfg->ext_zimop) {
> -                    int imm_mop5, imm_mop3;
> +                    int imm_mop5, imm_mop3, reg_num;
>                      if ((extract32(inst, 22, 10) & 0b1011001111)
>                          == 0b1000000111) {
>                          imm_mop5 = deposit32(deposit32(extract32(inst, 20, 2),
> @@ -4036,11 +4049,36 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
>                                                         extract32(inst, 26, 2)),
>                                               4, 1, extract32(inst, 30, 1));
>                          op = rv_mop_r_0 + imm_mop5;
> +                        /* if zicfiss enabled and mop5 is shadow stack */
> +                        if (dec->cfg->ext_zicfiss &&
> +                            ((imm_mop5 & 0b11100) == 0b11100)) {
> +                                /* rs1=0 means ssrdp */
> +                                if ((inst & (0b011111 << 15)) == 0) {
> +                                    op = rv_op_ssrdp;
> +                                }
> +                                /* rd=0 means sspopchk */
> +                                reg_num = (inst >> 15) & 0b011111;
> +                                if (((inst & (0b011111 << 7)) == 0) &&
> +                                    ((reg_num == 1) || (reg_num == 5))) {
> +                                    op = rv_op_sspopchk;
> +                                }
> +                        }
>                      } else if ((extract32(inst, 25, 7) & 0b1011001)
>                                 == 0b1000001) {
>                          imm_mop3 = deposit32(extract32(inst, 26, 2),
>                                               2, 1, extract32(inst, 30, 1));
>                          op = rv_mop_rr_0 + imm_mop3;
> +                        /* if zicfiss enabled and mop3 is shadow stack */
> +                        if (dec->cfg->ext_zicfiss &&
> +                            ((imm_mop3 & 0b111) == 0b111)) {
> +                                /* rs1=0 and rd=0 means sspush */
> +                                reg_num = (inst >> 20) & 0b011111;
> +                                if (((inst & (0b011111 << 15)) == 0) &&
> +                                    ((inst & (0b011111 << 7)) == 0) &&
> +                                    ((reg_num == 1) || (reg_num == 5))) {
> +                                    op = rv_op_sspush;
> +                                }
> +                        }
>                      }
>                  }
>                  break;
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 1182457aff..4895c5a301 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -224,6 +224,7 @@ enum {
>
>  #define rv_fmt_none                   "O\t"
>  #define rv_fmt_rs1                    "O\t1"
> +#define rv_fmt_rs2                    "O\t2"
>  #define rv_fmt_offset                 "O\to"
>  #define rv_fmt_pred_succ              "O\tp,s"
>  #define rv_fmt_rs1_rs2                "O\t1,2"
> --
> 2.44.0
>
>
diff mbox series

Patch

diff --git a/disas/riscv.c b/disas/riscv.c
index c7c92acef7..5eafb7f7f3 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -975,6 +975,11 @@  typedef enum {
     rv_op_amocas_b  = 944,
     rv_op_amocas_h  = 945,
     rv_op_lpad = 946,
+    rv_op_sspush = 947,
+    rv_op_sspopchk = 948,
+    rv_op_ssrdp = 949,
+    rv_op_ssamoswap_w = 950,
+    rv_op_ssamoswap_d = 951,
 } rv_op;
 
 /* register names */
@@ -2234,6 +2239,11 @@  const rv_opcode_data rvi_opcode_data[] = {
     { "amocas.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
     { "amocas.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
     { "lpad", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+    { "sspush", rv_codec_r, rv_fmt_rs2, NULL, 0, 0, 0 },
+    { "sspopchk", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "ssrdp", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
+    { "ssamoswap.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+    { "ssamoswap.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 };
 
 /* CSR names */
@@ -2251,6 +2261,7 @@  static const char *csr_name(int csrno)
     case 0x0009: return "vxsat";
     case 0x000a: return "vxrm";
     case 0x000f: return "vcsr";
+    case 0x0011: return "ssp";
     case 0x0015: return "seed";
     case 0x0017: return "jvt";
     case 0x0040: return "uscratch";
@@ -3077,6 +3088,8 @@  static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
             case 66: op = rv_op_amoor_w; break;
             case 67: op = rv_op_amoor_d; break;
             case 68: op = rv_op_amoor_q; break;
+            case 74: op = rv_op_ssamoswap_w; break;
+            case 75: op = rv_op_ssamoswap_d; break;
             case 96: op = rv_op_amoand_b; break;
             case 97: op = rv_op_amoand_h; break;
             case 98: op = rv_op_amoand_w; break;
@@ -4028,7 +4041,7 @@  static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
             case 3: op = rv_op_csrrc; break;
             case 4:
                 if (dec->cfg->ext_zimop) {
-                    int imm_mop5, imm_mop3;
+                    int imm_mop5, imm_mop3, reg_num;
                     if ((extract32(inst, 22, 10) & 0b1011001111)
                         == 0b1000000111) {
                         imm_mop5 = deposit32(deposit32(extract32(inst, 20, 2),
@@ -4036,11 +4049,36 @@  static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
                                                        extract32(inst, 26, 2)),
                                              4, 1, extract32(inst, 30, 1));
                         op = rv_mop_r_0 + imm_mop5;
+                        /* if zicfiss enabled and mop5 is shadow stack */
+                        if (dec->cfg->ext_zicfiss &&
+                            ((imm_mop5 & 0b11100) == 0b11100)) {
+                                /* rs1=0 means ssrdp */
+                                if ((inst & (0b011111 << 15)) == 0) {
+                                    op = rv_op_ssrdp;
+                                }
+                                /* rd=0 means sspopchk */
+                                reg_num = (inst >> 15) & 0b011111;
+                                if (((inst & (0b011111 << 7)) == 0) &&
+                                    ((reg_num == 1) || (reg_num == 5))) {
+                                    op = rv_op_sspopchk;
+                                }
+                        }
                     } else if ((extract32(inst, 25, 7) & 0b1011001)
                                == 0b1000001) {
                         imm_mop3 = deposit32(extract32(inst, 26, 2),
                                              2, 1, extract32(inst, 30, 1));
                         op = rv_mop_rr_0 + imm_mop3;
+                        /* if zicfiss enabled and mop3 is shadow stack */
+                        if (dec->cfg->ext_zicfiss &&
+                            ((imm_mop3 & 0b111) == 0b111)) {
+                                /* rs1=0 and rd=0 means sspush */
+                                reg_num = (inst >> 20) & 0b011111;
+                                if (((inst & (0b011111 << 15)) == 0) &&
+                                    ((inst & (0b011111 << 7)) == 0) &&
+                                    ((reg_num == 1) || (reg_num == 5))) {
+                                    op = rv_op_sspush;
+                                }
+                        }
                     }
                 }
                 break;
diff --git a/disas/riscv.h b/disas/riscv.h
index 1182457aff..4895c5a301 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -224,6 +224,7 @@  enum {
 
 #define rv_fmt_none                   "O\t"
 #define rv_fmt_rs1                    "O\t1"
+#define rv_fmt_rs2                    "O\t2"
 #define rv_fmt_offset                 "O\to"
 #define rv_fmt_pred_succ              "O\tp,s"
 #define rv_fmt_rs1_rs2                "O\t1,2"