diff mbox series

[RFC,v2,14/30] target/loongarch: Implement privilege instructions disassembly

Message ID 1636594528-8175-15-git-send-email-yangxiaojuan@loongson.cn (mailing list archive)
State New, archived
Headers show
Series Add Loongarch softmmu support. | expand

Commit Message

Xiaojuan Yang Nov. 11, 2021, 1:35 a.m. UTC
Signed-off-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
---
 target/loongarch/disas.c | 86 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
diff mbox series

Patch

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 1501462991..65aa0443bd 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -28,18 +28,28 @@  typedef enum {
     la_codec_2r_im16,
     la_codec_2r_im14,
     la_codec_2r_im12,
+    la_codec_2r_im8,
+    la_codec_r_im14,
     la_codec_r_cd,
     la_codec_r_cj,
     la_codec_code,
     la_codec_whint,
+    la_codec_invtlb,
     la_codec_r_ofs21,
     la_codec_cj_ofs21,
     la_codec_ofs26,
     la_codec_cond,
     la_codec_sel,
+    la_codec_empty,
+    la_codec_r_seq,
 
 } la_codec;
 
+#define la_fmt_empty           "nt"
+#define la_fmt_rd_csr          "nt0,x"
+#define la_fmt_rj_seq          "nt1,x"
+#define la_fmt_invtlb          "ntx,1,2"
+#define la_fmt_rd_rj_csr       "nt0,1,x"
 #define la_fmt_rd_rj           "nt0,1"
 #define la_fmt_rj_rk           "nt1,2"
 #define la_fmt_rd_si20         "nt0,i(x)"
@@ -68,6 +78,7 @@  typedef enum {
 #define la_fmt_d_cd_fj_fk      "K.dtH,4,5"
 #define la_fmt_fd_fj_fk_fa     "nt3,4,5,6"
 #define la_fmt_fd_fj_fk_ca     "nt3,4,5,L"
+#define la_fmt_cop_rj_si12     "ntM,1,i(x)"
 
 typedef struct {
     uint32_t pc;
@@ -88,6 +99,8 @@  const char * const fccregnames[8] = {
 };
 
 /* operand extractors */
+#define IM_5 5
+#define IM_8 8
 #define IM_12 12
 #define IM_14 14
 #define IM_15 15
@@ -170,6 +183,12 @@  static int32_t operand_im12(uint32_t insn)
     return imm > (1 << 11) ? imm - (1 << 12) : imm;
 }
 
+static int32_t operand_im8(uint32_t insn)
+{
+    int32_t imm = (int32_t)((insn >> 10) & 0xff);
+    return imm > (1 << 7) ? imm - (1 << 8) : imm;
+}
+
 static uint32_t operand_cd(uint32_t insn)
 {
     return insn & 0x7;
@@ -191,6 +210,12 @@  static int32_t operand_whint(uint32_t insn)
     return imm > (1 << 14) ? imm - (1 << 15) : imm;
 }
 
+static int32_t operand_invop(uint32_t insn)
+{
+    int32_t imm = (int32_t)(insn & 0x1f);
+    return imm > (1 << 4) ? imm - (1 << 5) : imm;
+}
+
 static int32_t operand_ofs21(uint32_t insn)
 {
     int32_t imm = (((int32_t)insn & 0x1f) << 16) |
@@ -220,6 +245,8 @@  static void decode_insn_operands(la_decode *dec)
 {
     uint32_t insn = dec->insn;
     switch (dec->codec) {
+    case la_codec_empty:
+        break;
     case la_codec_2r:
         dec->r1 = operand_r1(insn);
         dec->r2 = operand_r2(insn);
@@ -291,6 +318,17 @@  static void decode_insn_operands(la_decode *dec)
         dec->imm = operand_im12(insn);
         dec->bit = IM_12;
         break;
+    case la_codec_2r_im8:
+        dec->r1 = operand_r1(insn);
+        dec->r2 = operand_r2(insn);
+        dec->imm = operand_im8(insn);
+        dec->bit = IM_8;
+        break;
+    case la_codec_r_im14:
+        dec->r1 = operand_r1(insn);
+        dec->imm = operand_im14(insn);
+        dec->bit = IM_14;
+        break;
     case la_codec_r_cd:
         dec->r1 = operand_cd(insn);
         dec->r2 = operand_r2(insn);
@@ -299,6 +337,12 @@  static void decode_insn_operands(la_decode *dec)
         dec->r1 = operand_r1(insn);
         dec->r2 = operand_cj(insn);
         break;
+    case la_codec_r_seq:
+        dec->r1 = 0;
+        dec->r2 = operand_r1(insn);
+        dec->imm = operand_im8(insn);
+        dec->bit = IM_8;
+        break;
     case la_codec_code:
         dec->code = operand_code(insn);
         break;
@@ -306,6 +350,12 @@  static void decode_insn_operands(la_decode *dec)
         dec->imm = operand_whint(insn);
         dec->bit = IM_15;
         break;
+    case la_codec_invtlb:
+        dec->imm = operand_invop(insn);
+        dec->bit = IM_5;
+        dec->r2 = operand_r2(insn);
+        dec->r3 = operand_r3(insn);
+        break;
     case la_codec_r_ofs21:
         dec->imm = operand_ofs21(insn);
         dec->bit = IM_21;
@@ -499,6 +549,10 @@  static void format_insn(char *buf, size_t buflen,  const char* name,
         case 'L': /* ca */
             append(buf, fccregnames[dec->r4], buflen);
             break;
+        case 'M': /* cop */
+            snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm2) & 0x1f);
+            append(buf, tmp, buflen);
+            break;
         case 'i': /* sixx d */
             snprintf(tmp, sizeof(tmp), "%d", dec->imm);
             append(buf, tmp, buflen);
@@ -509,6 +563,14 @@  static void format_insn(char *buf, size_t buflen,  const char* name,
             break;
         case 'x': /* sixx x */
             switch (dec->bit) {
+            case IM_5:
+                snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x1f);
+                append(buf, tmp, buflen);
+                break;
+            case IM_8:
+                snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xff);
+                append(buf, tmp, buflen);
+                break;
             case IM_12:
                 snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfff);
                 append(buf, tmp, buflen);
@@ -916,3 +978,27 @@  INSN(blt,          la_fmt_rj_rd_offs16, la_codec_2r_im16)
 INSN(bge,          la_fmt_rj_rd_offs16, la_codec_2r_im16)
 INSN(bltu,         la_fmt_rj_rd_offs16, la_codec_2r_im16)
 INSN(bgeu,         la_fmt_rj_rd_offs16, la_codec_2r_im16)
+INSN(csrrd,        la_fmt_rd_csr,       la_codec_r_im14)
+INSN(csrwr,        la_fmt_rd_csr,       la_codec_r_im14)
+INSN(csrxchg,      la_fmt_rd_rj_csr,    la_codec_2r_im14)
+INSN(iocsrrd_b,    la_fmt_rd_rj,        la_codec_2r)
+INSN(iocsrrd_h,    la_fmt_rd_rj,        la_codec_2r)
+INSN(iocsrrd_w,    la_fmt_rd_rj,        la_codec_2r)
+INSN(iocsrrd_d,    la_fmt_rd_rj,        la_codec_2r)
+INSN(iocsrwr_b,    la_fmt_rd_rj,        la_codec_2r)
+INSN(iocsrwr_h,    la_fmt_rd_rj,        la_codec_2r)
+INSN(iocsrwr_w,    la_fmt_rd_rj,        la_codec_2r)
+INSN(iocsrwr_d,    la_fmt_rd_rj,        la_codec_2r)
+INSN(cacop,        la_fmt_rd_rj_si,     la_codec_2r_im12)
+INSN(tlbsrch,      la_fmt_empty,        la_codec_empty)
+INSN(tlbrd,        la_fmt_empty,        la_codec_empty)
+INSN(tlbwr,        la_fmt_empty,        la_codec_empty)
+INSN(tlbfill,      la_fmt_empty,        la_codec_empty)
+INSN(tlbclr,       la_fmt_empty,        la_codec_empty)
+INSN(tlbflush,     la_fmt_empty,        la_codec_empty)
+INSN(invtlb,       la_fmt_invtlb,       la_codec_invtlb)
+INSN(lddir,        la_fmt_rd_rj_si,     la_codec_2r_im8)
+INSN(ldpte,        la_fmt_rj_seq,       la_codec_r_seq)
+INSN(ertn,         la_fmt_empty,        la_codec_empty)
+INSN(idle,         la_fmt_whint,        la_codec_whint)
+INSN(dbcl,         la_fmt_code,         la_codec_code)