592 lines
18 KiB
C
592 lines
18 KiB
C
//===-- RISCVInstPrinter.cpp - Convert RISCV MCInst to asm syntax ---------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This class prints an RISCV MCInst to a .s file.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifdef CAPSTONE_HAS_RISCV
|
|
|
|
#include <stdio.h> // DEBUG
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <capstone/platform.h>
|
|
|
|
#include "RISCVInstPrinter.h"
|
|
#include "RISCVBaseInfo.h"
|
|
#include "../../MCInst.h"
|
|
#include "../../SStream.h"
|
|
#include "../../MCRegisterInfo.h"
|
|
#include "../../utils.h"
|
|
#include "../../Mapping.h"
|
|
#include "RISCVMapping.h"
|
|
|
|
//#include "RISCVDisassembler.h"
|
|
|
|
#define GET_REGINFO_ENUM
|
|
#define GET_REGINFO_MC_DESC
|
|
#include "RISCVGenRegisterInfo.inc"
|
|
#define GET_INSTRINFO_ENUM
|
|
#include "RISCVGenInstrInfo.inc"
|
|
|
|
// Autogenerated by tblgen.
|
|
static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
|
|
static bool printAliasInstr(MCInst *MI, SStream *OS, void *info);
|
|
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
|
|
static void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O);
|
|
static void printCSRSystemRegister(MCInst*, unsigned, SStream *);
|
|
static void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O);
|
|
static void printCustomAliasOperand( MCInst *, unsigned, unsigned, SStream *);
|
|
/// getRegisterName - This method is automatically generated by tblgen
|
|
/// from the register set description. This returns the assembler name
|
|
/// for the specified register.
|
|
static const char *getRegisterName(unsigned RegNo, unsigned AltIdx);
|
|
|
|
// Include the auto-generated portion of the assembly writer.
|
|
#define PRINT_ALIAS_INSTR
|
|
#include "RISCVGenAsmWriter.inc"
|
|
|
|
|
|
static void fixDetailOfEffectiveAddr(MCInst *MI)
|
|
{
|
|
// Operands for load and store instructions in RISCV vary widely
|
|
unsigned id = MI->flat_insn->id;
|
|
unsigned reg = 0;
|
|
int64_t imm = 0;
|
|
uint8_t access = 0;
|
|
|
|
switch (id) {
|
|
case RISCV_INS_C_FLD:
|
|
case RISCV_INS_C_LW:
|
|
case RISCV_INS_C_FLW:
|
|
case RISCV_INS_C_LD:
|
|
case RISCV_INS_C_FSD:
|
|
case RISCV_INS_C_SW:
|
|
case RISCV_INS_C_FSW:
|
|
case RISCV_INS_C_SD:
|
|
case RISCV_INS_C_FLDSP:
|
|
case RISCV_INS_C_LWSP:
|
|
case RISCV_INS_C_FLWSP:
|
|
case RISCV_INS_C_LDSP:
|
|
case RISCV_INS_C_FSDSP:
|
|
case RISCV_INS_C_SWSP:
|
|
case RISCV_INS_C_FSWSP:
|
|
case RISCV_INS_C_SDSP:
|
|
case RISCV_INS_FLW:
|
|
case RISCV_INS_FSW:
|
|
case RISCV_INS_FLD:
|
|
case RISCV_INS_FSD:
|
|
case RISCV_INS_LB:
|
|
case RISCV_INS_LBU:
|
|
case RISCV_INS_LD:
|
|
case RISCV_INS_LH:
|
|
case RISCV_INS_LHU:
|
|
case RISCV_INS_LW:
|
|
case RISCV_INS_LWU:
|
|
case RISCV_INS_SB:
|
|
case RISCV_INS_SD:
|
|
case RISCV_INS_SH:
|
|
case RISCV_INS_SW: {
|
|
CS_ASSERT(3 == MI->flat_insn->detail->riscv.op_count);
|
|
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -3)->type);
|
|
CS_ASSERT(RISCV_OP_IMM == RISCV_get_detail_op(MI, -2)->type);
|
|
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);
|
|
|
|
imm = RISCV_get_detail_op(MI, -2)->imm;
|
|
reg = RISCV_get_detail_op(MI, -1)->reg;
|
|
access = RISCV_get_detail_op(MI, -1)->access;
|
|
|
|
RISCV_get_detail_op(MI, -2)->type = RISCV_OP_MEM;
|
|
RISCV_get_detail_op(MI, -2)->mem.base = reg;
|
|
RISCV_get_detail_op(MI, -2)->mem.disp = imm;
|
|
RISCV_get_detail_op(MI, -2)->access = access;
|
|
|
|
RISCV_dec_op_count(MI);
|
|
|
|
break;
|
|
}
|
|
case RISCV_INS_LR_W:
|
|
case RISCV_INS_LR_W_AQ:
|
|
case RISCV_INS_LR_W_AQ_RL:
|
|
case RISCV_INS_LR_W_RL:
|
|
case RISCV_INS_LR_D:
|
|
case RISCV_INS_LR_D_AQ:
|
|
case RISCV_INS_LR_D_AQ_RL:
|
|
case RISCV_INS_LR_D_RL: {
|
|
CS_ASSERT(2 == MI->flat_insn->detail->riscv.op_count);
|
|
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);
|
|
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -2)->type);
|
|
|
|
reg = RISCV_get_detail_op(MI, -1)->reg;
|
|
|
|
RISCV_get_detail_op(MI, -1)->type = RISCV_OP_MEM;
|
|
RISCV_get_detail_op(MI, -1)->mem.base = reg;
|
|
RISCV_get_detail_op(MI, -1)->mem.disp = 0;
|
|
|
|
break;
|
|
}
|
|
case RISCV_INS_SC_W:
|
|
case RISCV_INS_SC_W_AQ:
|
|
case RISCV_INS_SC_W_AQ_RL:
|
|
case RISCV_INS_SC_W_RL:
|
|
case RISCV_INS_SC_D:
|
|
case RISCV_INS_SC_D_AQ:
|
|
case RISCV_INS_SC_D_AQ_RL:
|
|
case RISCV_INS_SC_D_RL:
|
|
case RISCV_INS_AMOADD_D:
|
|
case RISCV_INS_AMOADD_D_AQ:
|
|
case RISCV_INS_AMOADD_D_AQ_RL:
|
|
case RISCV_INS_AMOADD_D_RL:
|
|
case RISCV_INS_AMOADD_W:
|
|
case RISCV_INS_AMOADD_W_AQ:
|
|
case RISCV_INS_AMOADD_W_AQ_RL:
|
|
case RISCV_INS_AMOADD_W_RL:
|
|
case RISCV_INS_AMOAND_D:
|
|
case RISCV_INS_AMOAND_D_AQ:
|
|
case RISCV_INS_AMOAND_D_AQ_RL:
|
|
case RISCV_INS_AMOAND_D_RL:
|
|
case RISCV_INS_AMOAND_W:
|
|
case RISCV_INS_AMOAND_W_AQ:
|
|
case RISCV_INS_AMOAND_W_AQ_RL:
|
|
case RISCV_INS_AMOAND_W_RL:
|
|
case RISCV_INS_AMOMAXU_D:
|
|
case RISCV_INS_AMOMAXU_D_AQ:
|
|
case RISCV_INS_AMOMAXU_D_AQ_RL:
|
|
case RISCV_INS_AMOMAXU_D_RL:
|
|
case RISCV_INS_AMOMAXU_W:
|
|
case RISCV_INS_AMOMAXU_W_AQ:
|
|
case RISCV_INS_AMOMAXU_W_AQ_RL:
|
|
case RISCV_INS_AMOMAXU_W_RL:
|
|
case RISCV_INS_AMOMAX_D:
|
|
case RISCV_INS_AMOMAX_D_AQ:
|
|
case RISCV_INS_AMOMAX_D_AQ_RL:
|
|
case RISCV_INS_AMOMAX_D_RL:
|
|
case RISCV_INS_AMOMAX_W:
|
|
case RISCV_INS_AMOMAX_W_AQ:
|
|
case RISCV_INS_AMOMAX_W_AQ_RL:
|
|
case RISCV_INS_AMOMAX_W_RL:
|
|
case RISCV_INS_AMOMINU_D:
|
|
case RISCV_INS_AMOMINU_D_AQ:
|
|
case RISCV_INS_AMOMINU_D_AQ_RL:
|
|
case RISCV_INS_AMOMINU_D_RL:
|
|
case RISCV_INS_AMOMINU_W:
|
|
case RISCV_INS_AMOMINU_W_AQ:
|
|
case RISCV_INS_AMOMINU_W_AQ_RL:
|
|
case RISCV_INS_AMOMINU_W_RL:
|
|
case RISCV_INS_AMOMIN_D:
|
|
case RISCV_INS_AMOMIN_D_AQ:
|
|
case RISCV_INS_AMOMIN_D_AQ_RL:
|
|
case RISCV_INS_AMOMIN_D_RL:
|
|
case RISCV_INS_AMOMIN_W:
|
|
case RISCV_INS_AMOMIN_W_AQ:
|
|
case RISCV_INS_AMOMIN_W_AQ_RL:
|
|
case RISCV_INS_AMOMIN_W_RL:
|
|
case RISCV_INS_AMOOR_D:
|
|
case RISCV_INS_AMOOR_D_AQ:
|
|
case RISCV_INS_AMOOR_D_AQ_RL:
|
|
case RISCV_INS_AMOOR_D_RL:
|
|
case RISCV_INS_AMOOR_W:
|
|
case RISCV_INS_AMOOR_W_AQ:
|
|
case RISCV_INS_AMOOR_W_AQ_RL:
|
|
case RISCV_INS_AMOOR_W_RL:
|
|
case RISCV_INS_AMOSWAP_D:
|
|
case RISCV_INS_AMOSWAP_D_AQ:
|
|
case RISCV_INS_AMOSWAP_D_AQ_RL:
|
|
case RISCV_INS_AMOSWAP_D_RL:
|
|
case RISCV_INS_AMOSWAP_W:
|
|
case RISCV_INS_AMOSWAP_W_AQ:
|
|
case RISCV_INS_AMOSWAP_W_AQ_RL:
|
|
case RISCV_INS_AMOSWAP_W_RL:
|
|
case RISCV_INS_AMOXOR_D:
|
|
case RISCV_INS_AMOXOR_D_AQ:
|
|
case RISCV_INS_AMOXOR_D_AQ_RL:
|
|
case RISCV_INS_AMOXOR_D_RL:
|
|
case RISCV_INS_AMOXOR_W:
|
|
case RISCV_INS_AMOXOR_W_AQ:
|
|
case RISCV_INS_AMOXOR_W_AQ_RL:
|
|
case RISCV_INS_AMOXOR_W_RL: {
|
|
CS_ASSERT(3 == MI->flat_insn->detail->riscv.op_count);
|
|
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -3)->type);
|
|
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -2)->type);
|
|
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);
|
|
|
|
reg = RISCV_get_detail_op(MI, -1)->reg;
|
|
|
|
RISCV_get_detail_op(MI, -1)->type = RISCV_OP_MEM;
|
|
RISCV_get_detail_op(MI, -1)->mem.base = reg;
|
|
RISCV_get_detail_op(MI, -1)->mem.disp = 0;
|
|
|
|
break;
|
|
}
|
|
default: {
|
|
CS_ASSERT(0 && "id is not a RISC-V memory instruction");
|
|
break;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
//void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
|
// StringRef Annot, const MCSubtargetInfo &STI)
|
|
void RISCV_printInst(MCInst *MI, SStream *O, void *info)
|
|
{
|
|
MCRegisterInfo *MRI = (MCRegisterInfo *) info;
|
|
//bool Res = false;
|
|
//MCInst *NewMI = MI;
|
|
// TODO: RISCV compressd instructions.
|
|
//MCInst UncompressedMI;
|
|
//if (!NoAliases)
|
|
//Res = uncompressInst(UncompressedMI, *MI, MRI, STI);
|
|
//if (Res)
|
|
//NewMI = const_cast<MCInst *>(&UncompressedMI);
|
|
if (/*NoAliases ||*/ !printAliasInstr(MI, O, info))
|
|
printInstruction(MI, O, MRI);
|
|
//printAnnotation(O, Annot);
|
|
// fix load/store type insttuction
|
|
if (MI->csh->detail_opt &&
|
|
MI->flat_insn->detail->riscv.need_effective_addr)
|
|
fixDetailOfEffectiveAddr(MI);
|
|
|
|
return;
|
|
}
|
|
|
|
static void printRegName(SStream *OS, unsigned RegNo)
|
|
{
|
|
SStream_concat0(OS, getRegisterName(RegNo, RISCV_ABIRegAltName));
|
|
}
|
|
|
|
/**
|
|
void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O, const char *Modifier)
|
|
*/
|
|
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
|
{
|
|
unsigned reg;
|
|
int64_t Imm = 0;
|
|
|
|
RISCV_add_cs_detail(MI, OpNo);
|
|
|
|
MCOperand *MO = MCInst_getOperand(MI, OpNo);
|
|
|
|
if (MCOperand_isReg(MO)) {
|
|
reg = MCOperand_getReg(MO);
|
|
printRegName(O, reg);
|
|
} else {
|
|
CS_ASSERT(MCOperand_isImm(MO) && "Unknown operand kind in printOperand");
|
|
Imm = MCOperand_getImm(MO);
|
|
if (Imm >= 0) {
|
|
if (Imm > HEX_THRESHOLD)
|
|
SStream_concat(O, "0x%" PRIx64, Imm);
|
|
else
|
|
SStream_concat(O, "%" PRIu64, Imm);
|
|
} else {
|
|
if (Imm < -HEX_THRESHOLD)
|
|
SStream_concat(O, "-0x%" PRIx64, -Imm);
|
|
else
|
|
SStream_concat(O, "-%" PRIu64, -Imm);
|
|
}
|
|
}
|
|
|
|
//CS_ASSERT(MO.isExpr() && "Unknown operand kind in printOperand");
|
|
|
|
return;
|
|
}
|
|
|
|
static const char *getCSRSystemRegisterName(unsigned CsrNo)
|
|
{
|
|
switch (CsrNo) {
|
|
/*
|
|
* From RISC-V Privileged Architecture Version 1.10.
|
|
* In the same order as Table 2.5.
|
|
*/
|
|
case 0x0000: return "ustatus";
|
|
case 0x0004: return "uie";
|
|
case 0x0005: return "utvec";
|
|
|
|
case 0x0040: return "uscratch";
|
|
case 0x0041: return "uepc";
|
|
case 0x0042: return "ucause";
|
|
case 0x0043: return "utval";
|
|
case 0x0044: return "uip";
|
|
|
|
case 0x0001: return "fflags";
|
|
case 0x0002: return "frm";
|
|
case 0x0003: return "fcsr";
|
|
|
|
case 0x0c00: return "cycle";
|
|
case 0x0c01: return "time";
|
|
case 0x0c02: return "instret";
|
|
case 0x0c03: return "hpmcounter3";
|
|
case 0x0c04: return "hpmcounter4";
|
|
case 0x0c05: return "hpmcounter5";
|
|
case 0x0c06: return "hpmcounter6";
|
|
case 0x0c07: return "hpmcounter7";
|
|
case 0x0c08: return "hpmcounter8";
|
|
case 0x0c09: return "hpmcounter9";
|
|
case 0x0c0a: return "hpmcounter10";
|
|
case 0x0c0b: return "hpmcounter11";
|
|
case 0x0c0c: return "hpmcounter12";
|
|
case 0x0c0d: return "hpmcounter13";
|
|
case 0x0c0e: return "hpmcounter14";
|
|
case 0x0c0f: return "hpmcounter15";
|
|
case 0x0c10: return "hpmcounter16";
|
|
case 0x0c11: return "hpmcounter17";
|
|
case 0x0c12: return "hpmcounter18";
|
|
case 0x0c13: return "hpmcounter19";
|
|
case 0x0c14: return "hpmcounter20";
|
|
case 0x0c15: return "hpmcounter21";
|
|
case 0x0c16: return "hpmcounter22";
|
|
case 0x0c17: return "hpmcounter23";
|
|
case 0x0c18: return "hpmcounter24";
|
|
case 0x0c19: return "hpmcounter25";
|
|
case 0x0c1a: return "hpmcounter26";
|
|
case 0x0c1b: return "hpmcounter27";
|
|
case 0x0c1c: return "hpmcounter28";
|
|
case 0x0c1d: return "hpmcounter29";
|
|
case 0x0c1e: return "hpmcounter30";
|
|
case 0x0c1f: return "hpmcounter31";
|
|
case 0x0c80: return "cycleh";
|
|
case 0x0c81: return "timeh";
|
|
case 0x0c82: return "instreth";
|
|
case 0x0c83: return "hpmcounter3h";
|
|
case 0x0c84: return "hpmcounter4h";
|
|
case 0x0c85: return "hpmcounter5h";
|
|
case 0x0c86: return "hpmcounter6h";
|
|
case 0x0c87: return "hpmcounter7h";
|
|
case 0x0c88: return "hpmcounter8h";
|
|
case 0x0c89: return "hpmcounter9h";
|
|
case 0x0c8a: return "hpmcounter10h";
|
|
case 0x0c8b: return "hpmcounter11h";
|
|
case 0x0c8c: return "hpmcounter12h";
|
|
case 0x0c8d: return "hpmcounter13h";
|
|
case 0x0c8e: return "hpmcounter14h";
|
|
case 0x0c8f: return "hpmcounter15h";
|
|
case 0x0c90: return "hpmcounter16h";
|
|
case 0x0c91: return "hpmcounter17h";
|
|
case 0x0c92: return "hpmcounter18h";
|
|
case 0x0c93: return "hpmcounter19h";
|
|
case 0x0c94: return "hpmcounter20h";
|
|
case 0x0c95: return "hpmcounter21h";
|
|
case 0x0c96: return "hpmcounter22h";
|
|
case 0x0c97: return "hpmcounter23h";
|
|
case 0x0c98: return "hpmcounter24h";
|
|
case 0x0c99: return "hpmcounter25h";
|
|
case 0x0c9a: return "hpmcounter26h";
|
|
case 0x0c9b: return "hpmcounter27h";
|
|
case 0x0c9c: return "hpmcounter28h";
|
|
case 0x0c9d: return "hpmcounter29h";
|
|
case 0x0c9e: return "hpmcounter30h";
|
|
case 0x0c9f: return "hpmcounter31h";
|
|
|
|
case 0x0100: return "sstatus";
|
|
case 0x0102: return "sedeleg";
|
|
case 0x0103: return "sideleg";
|
|
case 0x0104: return "sie";
|
|
case 0x0105: return "stvec";
|
|
case 0x0106: return "scounteren";
|
|
|
|
case 0x0140: return "sscratch";
|
|
case 0x0141: return "sepc";
|
|
case 0x0142: return "scause";
|
|
case 0x0143: return "stval";
|
|
case 0x0144: return "sip";
|
|
|
|
case 0x0180: return "satp";
|
|
|
|
case 0x0f11: return "mvendorid";
|
|
case 0x0f12: return "marchid";
|
|
case 0x0f13: return "mimpid";
|
|
case 0x0f14: return "mhartid";
|
|
|
|
case 0x0300: return "mstatus";
|
|
case 0x0301: return "misa";
|
|
case 0x0302: return "medeleg";
|
|
case 0x0303: return "mideleg";
|
|
case 0x0304: return "mie";
|
|
case 0x0305: return "mtvec";
|
|
case 0x0306: return "mcounteren";
|
|
|
|
case 0x0340: return "mscratch";
|
|
case 0x0341: return "mepc";
|
|
case 0x0342: return "mcause";
|
|
case 0x0343: return "mtval";
|
|
case 0x0344: return "mip";
|
|
|
|
case 0x03a0: return "pmpcfg0";
|
|
case 0x03a1: return "pmpcfg1";
|
|
case 0x03a2: return "pmpcfg2";
|
|
case 0x03a3: return "pmpcfg3";
|
|
case 0x03b0: return "pmpaddr0";
|
|
case 0x03b1: return "pmpaddr1";
|
|
case 0x03b2: return "pmpaddr2";
|
|
case 0x03b3: return "pmpaddr3";
|
|
case 0x03b4: return "pmpaddr4";
|
|
case 0x03b5: return "pmpaddr5";
|
|
case 0x03b6: return "pmpaddr6";
|
|
case 0x03b7: return "pmpaddr7";
|
|
case 0x03b8: return "pmpaddr8";
|
|
case 0x03b9: return "pmpaddr9";
|
|
case 0x03ba: return "pmpaddr10";
|
|
case 0x03bb: return "pmpaddr11";
|
|
case 0x03bc: return "pmpaddr12";
|
|
case 0x03bd: return "pmpaddr13";
|
|
case 0x03be: return "pmpaddr14";
|
|
case 0x03bf: return "pmpaddr15";
|
|
|
|
case 0x0b00: return "mcycle";
|
|
case 0x0b02: return "minstret";
|
|
case 0x0b03: return "mhpmcounter3";
|
|
case 0x0b04: return "mhpmcounter4";
|
|
case 0x0b05: return "mhpmcounter5";
|
|
case 0x0b06: return "mhpmcounter6";
|
|
case 0x0b07: return "mhpmcounter7";
|
|
case 0x0b08: return "mhpmcounter8";
|
|
case 0x0b09: return "mhpmcounter9";
|
|
case 0x0b0a: return "mhpmcounter10";
|
|
case 0x0b0b: return "mhpmcounter11";
|
|
case 0x0b0c: return "mhpmcounter12";
|
|
case 0x0b0d: return "mhpmcounter13";
|
|
case 0x0b0e: return "mhpmcounter14";
|
|
case 0x0b0f: return "mhpmcounter15";
|
|
case 0x0b10: return "mhpmcounter16";
|
|
case 0x0b11: return "mhpmcounter17";
|
|
case 0x0b12: return "mhpmcounter18";
|
|
case 0x0b13: return "mhpmcounter19";
|
|
case 0x0b14: return "mhpmcounter20";
|
|
case 0x0b15: return "mhpmcounter21";
|
|
case 0x0b16: return "mhpmcounter22";
|
|
case 0x0b17: return "mhpmcounter23";
|
|
case 0x0b18: return "mhpmcounter24";
|
|
case 0x0b19: return "mhpmcounter25";
|
|
case 0x0b1a: return "mhpmcounter26";
|
|
case 0x0b1b: return "mhpmcounter27";
|
|
case 0x0b1c: return "mhpmcounter28";
|
|
case 0x0b1d: return "mhpmcounter29";
|
|
case 0x0b1e: return "mhpmcounter30";
|
|
case 0x0b1f: return "mhpmcounter31";
|
|
case 0x0b80: return "mcycleh";
|
|
case 0x0b82: return "minstreth";
|
|
case 0x0b83: return "mhpmcounter3h";
|
|
case 0x0b84: return "mhpmcounter4h";
|
|
case 0x0b85: return "mhpmcounter5h";
|
|
case 0x0b86: return "mhpmcounter6h";
|
|
case 0x0b87: return "mhpmcounter7h";
|
|
case 0x0b88: return "mhpmcounter8h";
|
|
case 0x0b89: return "mhpmcounter9h";
|
|
case 0x0b8a: return "mhpmcounter10h";
|
|
case 0x0b8b: return "mhpmcounter11h";
|
|
case 0x0b8c: return "mhpmcounter12h";
|
|
case 0x0b8d: return "mhpmcounter13h";
|
|
case 0x0b8e: return "mhpmcounter14h";
|
|
case 0x0b8f: return "mhpmcounter15h";
|
|
case 0x0b90: return "mhpmcounter16h";
|
|
case 0x0b91: return "mhpmcounter17h";
|
|
case 0x0b92: return "mhpmcounter18h";
|
|
case 0x0b93: return "mhpmcounter19h";
|
|
case 0x0b94: return "mhpmcounter20h";
|
|
case 0x0b95: return "mhpmcounter21h";
|
|
case 0x0b96: return "mhpmcounter22h";
|
|
case 0x0b97: return "mhpmcounter23h";
|
|
case 0x0b98: return "mhpmcounter24h";
|
|
case 0x0b99: return "mhpmcounter25h";
|
|
case 0x0b9a: return "mhpmcounter26h";
|
|
case 0x0b9b: return "mhpmcounter27h";
|
|
case 0x0b9c: return "mhpmcounter28h";
|
|
case 0x0b9d: return "mhpmcounter29h";
|
|
case 0x0b9e: return "mhpmcounter30h";
|
|
case 0x0b9f: return "mhpmcounter31h";
|
|
|
|
case 0x0323: return "mhpmevent3";
|
|
case 0x0324: return "mhpmevent4";
|
|
case 0x0325: return "mhpmevent5";
|
|
case 0x0326: return "mhpmevent6";
|
|
case 0x0327: return "mhpmevent7";
|
|
case 0x0328: return "mhpmevent8";
|
|
case 0x0329: return "mhpmevent9";
|
|
case 0x032a: return "mhpmevent10";
|
|
case 0x032b: return "mhpmevent11";
|
|
case 0x032c: return "mhpmevent12";
|
|
case 0x032d: return "mhpmevent13";
|
|
case 0x032e: return "mhpmevent14";
|
|
case 0x032f: return "mhpmevent15";
|
|
case 0x0330: return "mhpmevent16";
|
|
case 0x0331: return "mhpmevent17";
|
|
case 0x0332: return "mhpmevent18";
|
|
case 0x0333: return "mhpmevent19";
|
|
case 0x0334: return "mhpmevent20";
|
|
case 0x0335: return "mhpmevent21";
|
|
case 0x0336: return "mhpmevent22";
|
|
case 0x0337: return "mhpmevent23";
|
|
case 0x0338: return "mhpmevent24";
|
|
case 0x0339: return "mhpmevent25";
|
|
case 0x033a: return "mhpmevent26";
|
|
case 0x033b: return "mhpmevent27";
|
|
case 0x033c: return "mhpmevent28";
|
|
case 0x033d: return "mhpmevent29";
|
|
case 0x033e: return "mhpmevent30";
|
|
case 0x033f: return "mhpmevent31";
|
|
|
|
case 0x07a0: return "tselect";
|
|
case 0x07a1: return "tdata1";
|
|
case 0x07a2: return "tdata2";
|
|
case 0x07a3: return "tdata3";
|
|
|
|
case 0x07b0: return "dcsr";
|
|
case 0x07b1: return "dpc";
|
|
case 0x07b2: return "dscratch";
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void printCSRSystemRegister(MCInst *MI, unsigned OpNo,
|
|
//const MCSubtargetInfo &STI,
|
|
SStream *O)
|
|
{
|
|
unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNo));
|
|
const char *Name = getCSRSystemRegisterName(Imm);
|
|
|
|
if (Name) {
|
|
SStream_concat0(O, Name);
|
|
} else {
|
|
SStream_concat(O, "%u", Imm);
|
|
}
|
|
}
|
|
|
|
static void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O)
|
|
{
|
|
unsigned FenceArg = MCOperand_getImm(MCInst_getOperand(MI, OpNo));
|
|
//CS_ASSERT (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg");
|
|
|
|
if ((FenceArg & RISCVFenceField_I) != 0)
|
|
SStream_concat0(O, "i");
|
|
if ((FenceArg & RISCVFenceField_O) != 0)
|
|
SStream_concat0(O, "o");
|
|
if ((FenceArg & RISCVFenceField_R) != 0)
|
|
SStream_concat0(O, "r");
|
|
if ((FenceArg & RISCVFenceField_W) != 0)
|
|
SStream_concat0(O, "w");
|
|
if (FenceArg == 0)
|
|
SStream_concat0(O, "unknown");
|
|
}
|
|
|
|
static void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O)
|
|
{
|
|
enum RoundingMode FRMArg =
|
|
(enum RoundingMode)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
|
|
#if 0
|
|
auto FRMArg =
|
|
static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm());
|
|
O << RISCVFPRndMode::roundingModeToString(FRMArg);
|
|
#endif
|
|
SStream_concat0(O, roundingModeToString(FRMArg));
|
|
}
|
|
|
|
#endif // CAPSTONE_HAS_RISCV
|