@@ -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)