Skip to content

Commit

Permalink
xtensa: add add_cs_detail
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow committed Jul 10, 2024
1 parent fcf1632 commit 4120266
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 23 deletions.
6 changes: 6 additions & 0 deletions MCInst.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ void MCOperand_setFPImm(MCOperand *op, double Val)
op->FPImmVal = Val;
}

MCExpr *MCOperand_getExpr(const MCOperand *MC)
{
assert(0 && "unimplemented expr");
return NULL;
}

MCOperand *MCOperand_CreateReg1(MCInst *mcInst, unsigned Reg)
{
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
Expand Down
4 changes: 3 additions & 1 deletion MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
typedef struct MCInst MCInst;
typedef struct cs_struct cs_struct;
typedef struct MCOperand MCOperand;
typedef unsigned MCRegister;
typedef void MCExpr;

/// MCOperand - Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union.
Expand Down Expand Up @@ -81,6 +81,8 @@ const MCInst *MCOperand_getInst(const MCOperand *op);

void MCOperand_setInst(MCOperand *op, const MCInst *Val);

MCExpr *MCOperand_getExpr(const MCOperand *MC);

// create Reg operand in the next slot
void MCOperand_CreateReg0(MCInst *inst, unsigned Reg);

Expand Down
6 changes: 0 additions & 6 deletions MCRegisterInfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,3 @@ bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg)

return (c->RegSet[Byte] & (1 << InByte)) != 0;
}

MCExpr *MCOperand_getExpr(const MCOperand *MC)
{
assert(0 && "unimplemented expr");
return NULL;
}
4 changes: 0 additions & 4 deletions MCRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@
#define CS_LLVM_MC_MCREGISTERINFO_H

#include "capstone/platform.h"
#include "MCInst.h"
#include "SStream.h"

/// An unsigned integer type large enough to represent all physical registers,
/// but not necessarily virtual registers.
typedef int16_t MCPhysReg;
typedef const MCPhysReg* iterator;
typedef uint16_t MCRegister;
typedef void MCExpr;

typedef struct MCRegisterClass2 {
iterator RegsBegin;
Expand Down Expand Up @@ -117,6 +115,4 @@ const MCRegisterClass* MCRegisterInfo_getRegClass(const MCRegisterInfo *RI, unsi

bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg);

MCExpr *MCOperand_getExpr(const MCOperand *MC);

#endif
21 changes: 19 additions & 2 deletions arch/Xtensa/XtensaDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,15 @@ static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
static DecodeStatus decodeCallOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 18)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 2), 20)));
return MCDisassembler_Success;
}

static DecodeStatus decodeJumpOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 18)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 18)));
return MCDisassembler_Success;
}
Expand All @@ -114,14 +116,14 @@ static DecodeStatus decodeBranchOperand(MCInst *Inst, uint64_t Imm,
case Xtensa_BGEZ:
case Xtensa_BLTZ:
case Xtensa_BNEZ:

CS_ASSERT(CONCAT(isUInt, 12)(Imm) && "Invalid immediate");
if (!tryAddingSymbolicOperand(
SignExtend64((Imm), 12) + 4 + Address, true,
Address, 0, 3, Inst, Decoder))
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 12)));
break;
default:

CS_ASSERT(CONCAT(isUInt, 8)(Imm) && "Invalid immediate");
if (!tryAddingSymbolicOperand(
SignExtend64((Imm), 8) + 4 + Address, true, Address,
0, 3, Inst, Decoder))
Expand All @@ -133,6 +135,7 @@ static DecodeStatus decodeBranchOperand(MCInst *Inst, uint64_t Imm,
static DecodeStatus decodeL32ROperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 16)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(
Inst,
(SignExtend64(((Imm << 2) + 0x40000 + (Address & 0x3)), 17)));
Expand All @@ -142,48 +145,55 @@ static DecodeStatus decodeL32ROperand(MCInst *Inst, uint64_t Imm,
static DecodeStatus decodeImm8Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 8)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 8)));
return MCDisassembler_Success;
}

static DecodeStatus decodeImm8_sh8Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 8)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 8), 16)));
return MCDisassembler_Success;
}

static DecodeStatus decodeImm12Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 12)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 12)));
return MCDisassembler_Success;
}

static DecodeStatus decodeUimm4Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 4)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}

static DecodeStatus decodeUimm5Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 5)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}

static DecodeStatus decodeImm1_16Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 4)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (Imm + 1));
return MCDisassembler_Success;
}

static DecodeStatus decodeShimm1_31Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 5)(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (32 - Imm));
return MCDisassembler_Success;
}
Expand All @@ -193,6 +203,8 @@ static int64_t TableB4const[16] = { -1, 1, 2, 3, 4, 5, 6, 7,
static DecodeStatus decodeB4constOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 4)(Imm) && "Invalid immediate");

MCOperand_CreateImm0(Inst, (TableB4const[Imm]));
return MCDisassembler_Success;
}
Expand All @@ -202,13 +214,16 @@ static int64_t TableB4constu[16] = { 32768, 65536, 2, 3, 4, 5, 6, 7,
static DecodeStatus decodeB4constuOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 4)(Imm) && "Invalid immediate");

MCOperand_CreateImm0(Inst, (TableB4constu[Imm]));
return MCDisassembler_Success;
}

static DecodeStatus decodeMem8Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 12)(Imm) && "Invalid immediate");
DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
MCOperand_CreateImm0(Inst, ((Imm >> 4) & 0xff));
return MCDisassembler_Success;
Expand All @@ -217,6 +232,7 @@ static DecodeStatus decodeMem8Operand(MCInst *Inst, uint64_t Imm,
static DecodeStatus decodeMem16Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 12)(Imm) && "Invalid immediate");
DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
MCOperand_CreateImm0(Inst, ((Imm >> 3) & 0x1fe));
return MCDisassembler_Success;
Expand All @@ -225,6 +241,7 @@ static DecodeStatus decodeMem16Operand(MCInst *Inst, uint64_t Imm,
static DecodeStatus decodeMem32Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(CONCAT(isUInt, 12)(Imm) && "Invalid immediate");
DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
MCOperand_CreateImm0(Inst, ((Imm >> 2) & 0x3fc));
return MCDisassembler_Success;
Expand Down
46 changes: 36 additions & 10 deletions arch/Xtensa/XtensaInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "../../SStream.h"
#include "./priv.h"
#include "../../Mapping.h"
#include "XtensaMapping.h"

#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b
Expand All @@ -59,6 +60,7 @@ static void printOperand(MCInst *MI, int OpNum, SStream *O)

static inline void printMemOperand(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_MEMOPERAND, OpNum);
SStream_concat0(OS, getRegisterName(MCOperand_getReg(
MCInst_getOperand(MI, (OpNum)))));
SStream_concat0(OS, ", ");
Expand All @@ -67,6 +69,7 @@ static inline void printMemOperand(MCInst *MI, int OpNum, SStream *OS)

static inline void printBranchTarget(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_BRANCHTARGET, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Val = MCOperand_getImm(MC) + 4;
Expand All @@ -81,6 +84,7 @@ static inline void printBranchTarget(MCInst *MI, int OpNum, SStream *OS)

static inline void printJumpTarget(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_JUMPTARGET, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MC)) {
int64_t Val = MCOperand_getImm(MC) + 4;
Expand All @@ -96,6 +100,7 @@ static inline void printJumpTarget(MCInst *MI, int OpNum, SStream *OS)

static inline void printCallOperand(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_CALLOPERAND, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MC)) {
int64_t Val = MCOperand_getImm(MC) + 4;
Expand All @@ -110,13 +115,16 @@ static inline void printCallOperand(MCInst *MI, int OpNum, SStream *OS)

static inline void printL32RTarget(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_L32RTARGET, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MC)) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
int64_t InstrOff = Value & 0x3;
Value -= InstrOff;

CS_ASSERT(
(Value >= -262144 && Value <= -4) &&
"Invalid argument, value must be in ranges [-262144,-4]");
Value += ((InstrOff + 0x3) & 0x4) - InstrOff;
SStream_concat0(O, ". ");
printInt64(O, Value);
Expand All @@ -126,10 +134,13 @@ static inline void printL32RTarget(MCInst *MI, int OpNum, SStream *O)

static inline void printImm8_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM8_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT(
CONCAT(isInt, 8)(Value) &&
"Invalid argument, value must be in ranges [-128,127]");
printInt64(O, Value);
} else {
printOperand(MI, OpNum, O);
Expand All @@ -138,72 +149,86 @@ static inline void printImm8_AsmOperand(MCInst *MI, int OpNum, SStream *O)

static inline void printImm8_sh8_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM8_SH8_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT(
(CONCAT(isInt, 16)(Value) && ((Value & 0xFF) == 0)) &&
"Invalid argument, value must be multiples of 256 in range "
"[-32768,32512]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}

static inline void printImm12m_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM12M_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT(
(Value >= -2048 && Value <= 2047) &&
"Invalid argument, value must be in ranges [-2048,2047]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}

static inline void printUimm4_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_UIMM4_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT((Value >= 0 && Value <= 15) && "Invalid argument");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}

static inline void printUimm5_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_UIMM5_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT((Value >= 0 && Value <= 31) && "Invalid argument");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}

static inline void printShimm1_31_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_SHIMM1_31_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT((Value >= 1 && Value <= 31) &&
"Invalid argument, value must be in range [1,31]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}

static inline void printImm1_16_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM1_16_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT((Value >= 1 && Value <= 16) &&
"Invalid argument, value must be in range [1,16]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}

static inline void printB4const_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_B4CONST_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
Expand All @@ -227,7 +252,7 @@ static inline void printB4const_AsmOperand(MCInst *MI, int OpNum, SStream *O)
case 256:
break;
default:
break;
CS_ASSERT((0) && "Invalid B4const argument");
}
printInt64(O, Value);
} else
Expand All @@ -236,6 +261,7 @@ static inline void printB4const_AsmOperand(MCInst *MI, int OpNum, SStream *O)

static inline void printB4constu_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_B4CONSTU_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
Expand All @@ -259,7 +285,7 @@ static inline void printB4constu_AsmOperand(MCInst *MI, int OpNum, SStream *O)
case 256:
break;
default:
break;
CS_ASSERT((0) && "Invalid B4constu argument");
}
printInt64(O, Value);
} else
Expand Down
Loading

0 comments on commit 4120266

Please sign in to comment.