aboutsummaryrefslogtreecommitdiff
path: root/target/loongarch/disas.c
diff options
context:
space:
mode:
authorXiaojuan Yang <yangxiaojuan@loongson.cn>2022-06-06 20:43:15 +0800
committerRichard Henderson <richard.henderson@linaro.org>2022-06-06 18:09:03 +0000
commit5b1dedfe848b61521aa5b46b81a4cc676e9e7c1b (patch)
tree5e119c1e5637aa79bb852e765ccd4e93271bfdb3 /target/loongarch/disas.c
parentdd615fa48da89b2308a907cc4e4956771c75d68f (diff)
target/loongarch: Add LoongArch CSR instruction
This includes: - CSRRD - CSRWR - CSRXCHG Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220606124333.2060567-26-yangxiaojuan@loongson.cn> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/loongarch/disas.c')
-rw-r--r--target/loongarch/disas.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 9454ebb8e9..11a704ff7c 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -8,6 +8,7 @@
#include "qemu/osdep.h"
#include "disas/dis-asm.h"
#include "qemu/bitops.h"
+#include "cpu-csr.h"
typedef struct {
disassemble_info *info;
@@ -25,6 +26,90 @@ static inline int shl_2(DisasContext *ctx, int x)
return x << 2;
}
+#define CSR_NAME(REG) \
+ [LOONGARCH_CSR_##REG] = (#REG)
+
+static const char * const csr_names[] = {
+ CSR_NAME(CRMD),
+ CSR_NAME(PRMD),
+ CSR_NAME(EUEN),
+ CSR_NAME(MISC),
+ CSR_NAME(ECFG),
+ CSR_NAME(ESTAT),
+ CSR_NAME(ERA),
+ CSR_NAME(BADV),
+ CSR_NAME(BADI),
+ CSR_NAME(EENTRY),
+ CSR_NAME(TLBIDX),
+ CSR_NAME(TLBEHI),
+ CSR_NAME(TLBELO0),
+ CSR_NAME(TLBELO1),
+ CSR_NAME(ASID),
+ CSR_NAME(PGDL),
+ CSR_NAME(PGDH),
+ CSR_NAME(PGD),
+ CSR_NAME(PWCL),
+ CSR_NAME(PWCH),
+ CSR_NAME(STLBPS),
+ CSR_NAME(RVACFG),
+ CSR_NAME(CPUID),
+ CSR_NAME(PRCFG1),
+ CSR_NAME(PRCFG2),
+ CSR_NAME(PRCFG3),
+ CSR_NAME(SAVE(0)),
+ CSR_NAME(SAVE(1)),
+ CSR_NAME(SAVE(2)),
+ CSR_NAME(SAVE(3)),
+ CSR_NAME(SAVE(4)),
+ CSR_NAME(SAVE(5)),
+ CSR_NAME(SAVE(6)),
+ CSR_NAME(SAVE(7)),
+ CSR_NAME(SAVE(8)),
+ CSR_NAME(SAVE(9)),
+ CSR_NAME(SAVE(10)),
+ CSR_NAME(SAVE(11)),
+ CSR_NAME(SAVE(12)),
+ CSR_NAME(SAVE(13)),
+ CSR_NAME(SAVE(14)),
+ CSR_NAME(SAVE(15)),
+ CSR_NAME(TID),
+ CSR_NAME(TCFG),
+ CSR_NAME(TVAL),
+ CSR_NAME(CNTC),
+ CSR_NAME(TICLR),
+ CSR_NAME(LLBCTL),
+ CSR_NAME(IMPCTL1),
+ CSR_NAME(IMPCTL2),
+ CSR_NAME(TLBRENTRY),
+ CSR_NAME(TLBRBADV),
+ CSR_NAME(TLBRERA),
+ CSR_NAME(TLBRSAVE),
+ CSR_NAME(TLBRELO0),
+ CSR_NAME(TLBRELO1),
+ CSR_NAME(TLBREHI),
+ CSR_NAME(TLBRPRMD),
+ CSR_NAME(MERRCTL),
+ CSR_NAME(MERRINFO1),
+ CSR_NAME(MERRINFO2),
+ CSR_NAME(MERRENTRY),
+ CSR_NAME(MERRERA),
+ CSR_NAME(MERRSAVE),
+ CSR_NAME(CTAG),
+ CSR_NAME(DMW(0)),
+ CSR_NAME(DMW(1)),
+ CSR_NAME(DMW(2)),
+ CSR_NAME(DMW(3)),
+ CSR_NAME(DBG),
+ CSR_NAME(DERA),
+ CSR_NAME(DSAVE),
+};
+
+static const char *get_csr_name(unsigned num)
+{
+ return ((num < ARRAY_SIZE(csr_names)) && (csr_names[num] != NULL)) ?
+ csr_names[num] : "Undefined CSR";
+}
+
#define output(C, INSN, FMT, ...) \
{ \
(C)->info->fprintf_func((C)->info->stream, "%08x %-9s\t" FMT, \
@@ -205,6 +290,19 @@ static void output_rr_offs(DisasContext *ctx, arg_rr_offs *a,
a->rd, a->offs, ctx->pc + a->offs);
}
+static void output_r_csr(DisasContext *ctx, arg_r_csr *a,
+ const char *mnemonic)
+{
+ output(ctx, mnemonic, "r%d, %d # %s", a->rd, a->csr, get_csr_name(a->csr));
+}
+
+static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a,
+ const char *mnemonic)
+{
+ output(ctx, mnemonic, "r%d, r%d, %d # %s",
+ a->rd, a->rj, a->csr, get_csr_name(a->csr));
+}
+
#define INSN(insn, type) \
static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
{ \
@@ -514,6 +612,9 @@ INSN(blt, rr_offs)
INSN(bge, rr_offs)
INSN(bltu, rr_offs)
INSN(bgeu, rr_offs)
+INSN(csrrd, r_csr)
+INSN(csrwr, r_csr)
+INSN(csrxchg, rr_csr)
#define output_fcmp(C, PREFIX, SUFFIX) \
{ \