Skip to content

Commit

Permalink
[skip-ci] xtensa: add add_cs_detail
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow committed Jul 6, 2024
1 parent c75ea7a commit 778c1b6
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 12 deletions.
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
41 changes: 31 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 Down Expand Up @@ -110,13 +112,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 +131,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 +146,84 @@ 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_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 printImm12m_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 printUimm4_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 printUimm5_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 printShimm1_31_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_OFFSET8M8_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT((Value >= 0 && Value <= 255) &&
"Invalid argument, value must be in range [0,255]");
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_OFFSET8M16_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));

CS_ASSERT(
(Value >= 0 && Value <= 510 && ((Value & 0x1) == 0)) &&
"Invalid argument, value must be multiples of two in range [0,510]");
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 +247,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 +256,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 +280,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
39 changes: 39 additions & 0 deletions arch/Xtensa/XtensaMapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "XtensaDisassembler.h"
#include "XtensaInstPrinter.h"
#include "priv.h"
#include "XtensaMapping.h"

#ifndef CAPSTONE_DIET

Expand Down Expand Up @@ -207,3 +208,41 @@ void Xtensa_reg_access(const cs_insn *insn, cs_regs regs_read,
*regs_write_count = write_count;
}
#endif

void Xtensa_add_cs_detail(MCInst *MI, xtensa_op_group op_group, va_list args)
{
CS_ASSERT(0 && "unimplemented");
switch (op_group) {
case XTENSA_OP_GROUP_OPERAND:
break;
case XTENSA_OP_GROUP_IMM8_ASMOPERAND: {
unsigned OpNum = va_arg(args, unsigned);
}
case XTENSA_OP_GROUP_IMM8_SH8_ASMOPERAND:
break;
case XTENSA_OP_GROUP_BRANCHTARGET:
break;
case XTENSA_OP_GROUP_UIMM5_ASMOPERAND:
break;
case XTENSA_OP_GROUP_B4CONST_ASMOPERAND:
break;
case XTENSA_OP_GROUP_B4CONSTU_ASMOPERAND:
break;
case XTENSA_OP_GROUP_CALLOPERAND:
break;
case XTENSA_OP_GROUP_IMM1_16_ASMOPERAND:
break;
case XTENSA_OP_GROUP_JUMPTARGET:
break;
case XTENSA_OP_GROUP_MEMOPERAND:
break;
case XTENSA_OP_GROUP_L32RTARGET:
break;
case XTENSA_OP_GROUP_IMM12M_ASMOPERAND:
break;
case XTENSA_OP_GROUP_SHIMM1_31_ASMOPERAND:
break;
case XTENSA_OP_GROUP_UIMM4_ASMOPERAND:
break;
}
}
12 changes: 12 additions & 0 deletions arch/Xtensa/XtensaMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,16 @@ void Xtensa_reg_access(const cs_insn *insn, cs_regs regs_read,
uint8_t *regs_write_count);
#endif

void Xtensa_add_cs_detail(MCInst *MI, xtensa_op_group op_group, va_list args);

static inline void add_cs_detail(MCInst *MI, xtensa_op_group op_group, ...)
{
if (!MI->flat_insn->detail)
return;
va_list args;
va_start(args, op_group);
Xtensa_add_cs_detail(MI, op_group, args);
va_end(args);
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ def get_Xtensa_includes(filename: str) -> bytes:
return """
#include "../../MCInstPrinter.h"
#include "../../SStream.h"
#include "XtensaMapping.h"
#include "priv.h"
"""
case _:
Expand Down
Loading

0 comments on commit 778c1b6

Please sign in to comment.