Signed-off-by: Song Gao <gaos...@loongson.cn> Signed-off-by: Xiaojuan Yang <yangxiaoj...@loongson.cn> --- target/loongarch/disas.c | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+)
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) -- 2.27.0