mirror of
https://github.com/capstone-engine/capstone
synced 2026-08-11 16:26:07 -04:00
Add workflow to check for C code formatting and format all code with clang-format-17 (#2744)
* Add workflow to check for C formatting Rename run-clang-tidy.sh for consistency with clang-format script Don't align trailing comments. It leads to unreproducable formatting. Reformat some comments leading in-compilable up code after clang-format Format generated compatibility header. Add clang-format script Be more verbose with clean-up scripts and fail early. Pass clang-format via command line Install clang-format for the HeaderPatcher * Format code with clang-format-17
This commit is contained in:
parent
f557fa229e
commit
40f54ce821
241 changed files with 23565 additions and 18800 deletions
|
|
@ -15,9 +15,7 @@ AlignConsecutiveAssignments: false
|
|||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: true
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 2
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
|
|
|
|||
11
.github/workflows/CITest.yml
vendored
11
.github/workflows/CITest.yml
vendored
|
|
@ -170,12 +170,17 @@ jobs:
|
|||
valgrind cstest tests
|
||||
|
||||
- name: Comaptibility header generation
|
||||
if: startsWith(matrix.config.build-system, 'cmake')
|
||||
# clang-format-17 is only available in Ubuntu 24.04
|
||||
# Hence the check only happens for it.
|
||||
if: startsWith(matrix.config.build-system, 'cmake') && startsWith(matrix.config.os, 'ubuntu-24.04')
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install clang-format-17
|
||||
clang-format-17 --version
|
||||
cp ./include/capstone/arm64.h arm64_compat_current.h
|
||||
cp ./include/capstone/systemz_compatibility.h systemz_compat_current.h
|
||||
./suite/auto-sync/src/autosync/HeaderPatcher.py -c --v6 ./include/capstone/aarch64.h --v5 ./include/capstone/arm64.h
|
||||
./suite/auto-sync/src/autosync/HeaderPatcher.py -c --v6 ./include/capstone/systemz.h --v5 ./include/capstone/systemz_compatibility.h
|
||||
./suite/auto-sync/src/autosync/HeaderPatcher.py -C ./.clang-format -c --v6 ./include/capstone/aarch64.h --v5 ./include/capstone/arm64.h
|
||||
./suite/auto-sync/src/autosync/HeaderPatcher.py -C ./.clang-format -c --v6 ./include/capstone/systemz.h --v5 ./include/capstone/systemz_compatibility.h
|
||||
diff ./include/capstone/arm64.h arm64_compat_current.h &&
|
||||
diff ./include/capstone/systemz_compatibility.h systemz_compat_current.h
|
||||
|
||||
|
|
|
|||
33
.github/workflows/clang-format.yml
vendored
Normal file
33
.github/workflows/clang-format.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: Run clang-format-17
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
# Ignore
|
||||
- '!suite/auto-sync/**'
|
||||
pull_request:
|
||||
|
||||
# Stop previous runs on the same branch on new push
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
name: clang-format-17
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install clang-format-17
|
||||
run: |
|
||||
sudo apt update -y
|
||||
sudo apt install -y clang-format-17
|
||||
clang-format-17 --version
|
||||
|
||||
- name: Check formatting
|
||||
run: |
|
||||
./suite/run_clang_format.sh
|
||||
2
.github/workflows/clang-tidy.yml
vendored
2
.github/workflows/clang-tidy.yml
vendored
|
|
@ -40,7 +40,7 @@ jobs:
|
|||
base_sha: ${{ github.event.pull_request.base.sha }}
|
||||
head_sha: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
./run-clang-tidy.sh build
|
||||
./suite/run_clang_tidy.sh build
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ failure() }}
|
||||
|
|
|
|||
2
LEB128.h
2
LEB128.h
|
|
@ -35,4 +35,4 @@ static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n)
|
|||
return Value;
|
||||
}
|
||||
|
||||
#endif // LLVM_SYSTEM_LEB128_H
|
||||
#endif // LLVM_SYSTEM_LEB128_H
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
#define CS_MCASMINFO_H
|
||||
|
||||
typedef enum {
|
||||
SYSTEMZASMDIALECT_AD_ATT = 0,
|
||||
SYSTEMZASMDIALECT_AD_HLASM = 1,
|
||||
SYSTEMZASMDIALECT_AD_ATT = 0,
|
||||
SYSTEMZASMDIALECT_AD_HLASM = 1,
|
||||
} MCAsmInfoAssemblerDialect;
|
||||
|
||||
typedef struct {
|
||||
MCAsmInfoAssemblerDialect assemblerDialect;
|
||||
MCAsmInfoAssemblerDialect assemblerDialect;
|
||||
} MCAsmInfo;
|
||||
|
||||
#endif // CS_MCASMINFO_H
|
||||
|
|
|
|||
|
|
@ -11,4 +11,3 @@ typedef enum DecodeStatus {
|
|||
} DecodeStatus;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -17,16 +17,17 @@
|
|||
|
||||
// Disassembler state machine opcodes.
|
||||
enum DecoderOps {
|
||||
MCD_OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len)
|
||||
MCD_OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
|
||||
MCD_OPC_CheckField, // OPC_CheckField(uint8_t Start, uint8_t Len,
|
||||
// uleb128 Val, uint16_t NumToSkip)
|
||||
MCD_OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
|
||||
MCD_OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
|
||||
MCD_OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
|
||||
// uint16_t NumToSkip)
|
||||
MCD_OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
|
||||
MCD_OPC_Fail // OPC_Fail()
|
||||
MCD_OPC_ExtractField =
|
||||
1, // OPC_ExtractField(uint8_t Start, uint8_t Len)
|
||||
MCD_OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
|
||||
MCD_OPC_CheckField, // OPC_CheckField(uint8_t Start, uint8_t Len,
|
||||
// uleb128 Val, uint16_t NumToSkip)
|
||||
MCD_OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
|
||||
MCD_OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
|
||||
MCD_OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
|
||||
// uint16_t NumToSkip)
|
||||
MCD_OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
|
||||
MCD_OPC_Fail // OPC_Fail()
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
25
MCInst.c
25
MCInst.c
|
|
@ -60,9 +60,9 @@ void MCInst_insert0(MCInst *inst, int index, MCOperand *Op)
|
|||
CS_ASSERT_RET(index < MAX_MC_OPS);
|
||||
int i;
|
||||
|
||||
for(i = inst->size; i > index; i--)
|
||||
for (i = inst->size; i > index; i--)
|
||||
//memcpy(&(inst->Operands[i]), &(inst->Operands[i-1]), sizeof(MCOperand));
|
||||
inst->Operands[i] = inst->Operands[i-1];
|
||||
inst->Operands[i] = inst->Operands[i - 1];
|
||||
|
||||
inst->Operands[index] = *Op;
|
||||
inst->size++;
|
||||
|
|
@ -239,20 +239,21 @@ bool MCInst_isPredicable(const MCInstrDesc *MIDesc)
|
|||
/// Checks if tied operands exist in the instruction and sets
|
||||
/// - The writeback flag in detail
|
||||
/// - Saves the indices of the tied destination operands.
|
||||
void MCInst_handleWriteback(MCInst *MI, const MCInstrDesc *InstDescTable, unsigned tbl_size)
|
||||
void MCInst_handleWriteback(MCInst *MI, const MCInstrDesc *InstDescTable,
|
||||
unsigned tbl_size)
|
||||
{
|
||||
const MCInstrDesc *InstDesc = NULL;
|
||||
const MCOperandInfo *OpInfo = NULL;
|
||||
unsigned short NumOps = 0;
|
||||
InstDesc = MCInstrDesc_get(MCInst_getOpcode(MI), InstDescTable, tbl_size);
|
||||
InstDesc =
|
||||
MCInstrDesc_get(MCInst_getOpcode(MI), InstDescTable, tbl_size);
|
||||
OpInfo = InstDesc->OpInfo;
|
||||
NumOps = InstDesc->NumOperands;
|
||||
|
||||
for (unsigned i = 0; i < NumOps; ++i) {
|
||||
if (MCOperandInfo_isTiedToOp(&OpInfo[i])) {
|
||||
int idx = MCOperandInfo_getOperandConstraint(
|
||||
InstDesc, i,
|
||||
MCOI_TIED_TO);
|
||||
InstDesc, i, MCOI_TIED_TO);
|
||||
|
||||
if (idx == -1)
|
||||
continue;
|
||||
|
|
@ -303,7 +304,8 @@ uint64_t MCInst_getOpVal(MCInst *MI, unsigned OpNum)
|
|||
return MCOperand_getImm(op);
|
||||
}
|
||||
|
||||
void MCInst_setIsAlias(MCInst *MI, bool Flag) {
|
||||
void MCInst_setIsAlias(MCInst *MI, bool Flag)
|
||||
{
|
||||
assert(MI);
|
||||
MI->isAliasInstr = Flag;
|
||||
MI->flat_insn->is_alias = Flag;
|
||||
|
|
@ -313,11 +315,13 @@ void MCInst_setIsAlias(MCInst *MI, bool Flag) {
|
|||
/// the main MCInst. This is used if TryDecode was run on a temporary MCInst.
|
||||
/// @param MI The main MCInst
|
||||
/// @param TmpMI The temporary MCInst.
|
||||
void MCInst_updateWithTmpMI(MCInst *MI, MCInst *TmpMI) {
|
||||
void MCInst_updateWithTmpMI(MCInst *MI, MCInst *TmpMI)
|
||||
{
|
||||
MI->size = TmpMI->size;
|
||||
MI->Opcode = TmpMI->Opcode;
|
||||
assert(MI->size < MAX_MC_OPS);
|
||||
memcpy(MI->Operands, TmpMI->Operands, sizeof(MI->Operands[0]) * MI->size);
|
||||
memcpy(MI->Operands, TmpMI->Operands,
|
||||
sizeof(MI->Operands[0]) * MI->size);
|
||||
}
|
||||
|
||||
/// @brief Sets the softfail/illegal flag in the cs_insn.
|
||||
|
|
@ -325,7 +329,8 @@ void MCInst_updateWithTmpMI(MCInst *MI, MCInst *TmpMI) {
|
|||
/// due to not allowed operands or an illegal context.
|
||||
///
|
||||
/// @param MI The MCInst holding the cs_insn currently decoded.
|
||||
void MCInst_setSoftFail(MCInst *MI) {
|
||||
void MCInst_setSoftFail(MCInst *MI)
|
||||
{
|
||||
assert(MI && MI->flat_insn);
|
||||
MI->flat_insn->illegal = true;
|
||||
}
|
||||
|
|
|
|||
54
MCInst.h
54
MCInst.h
|
|
@ -33,13 +33,13 @@ typedef void MCExpr;
|
|||
/// This is a simple discriminated union.
|
||||
struct MCOperand {
|
||||
enum {
|
||||
kInvalid = 0, ///< Uninitialized.
|
||||
kRegister, ///< Register operand.
|
||||
kImmediate, ///< Immediate operand.
|
||||
kFPImmediate, ///< Floating-point immediate operand.
|
||||
kInvalid = 0, ///< Uninitialized.
|
||||
kRegister, ///< Register operand.
|
||||
kImmediate, ///< Immediate operand.
|
||||
kFPImmediate, ///< Floating-point immediate operand.
|
||||
kDFPImmediate, ///< Double-Floating-point immediate operand.
|
||||
kExpr, ///< Relocatable immediate operand.
|
||||
kInst ///< Sub-instruction operand.
|
||||
kExpr, ///< Relocatable immediate operand.
|
||||
kInst ///< Sub-instruction operand.
|
||||
} MachineOperandType;
|
||||
unsigned char Kind;
|
||||
|
||||
|
|
@ -101,16 +101,16 @@ MCOperand *MCOperand_CreateImm1(MCInst *inst, int64_t Val);
|
|||
/// MCInst - Instances of this class represent a single low-level machine
|
||||
/// instruction.
|
||||
struct MCInst {
|
||||
unsigned OpcodePub; // public opcode (<arch>_INS_yyy in header files <arch>.h)
|
||||
uint8_t size; // number of operands
|
||||
bool has_imm; // indicate this instruction has an X86_OP_IMM operand - used for ATT syntax
|
||||
unsigned OpcodePub; // public opcode (<arch>_INS_yyy in header files <arch>.h)
|
||||
uint8_t size; // number of operands
|
||||
bool has_imm; // indicate this instruction has an X86_OP_IMM operand - used for ATT syntax
|
||||
uint8_t op1_size; // size of 1st operand - for X86 Intel syntax
|
||||
unsigned Opcode; // private opcode
|
||||
unsigned Opcode; // private opcode
|
||||
MCOperand Operands[MAX_MC_OPS];
|
||||
cs_insn *flat_insn; // insn to be exposed to public
|
||||
uint64_t address; // address of this insn
|
||||
cs_struct *csh; // save the main csh
|
||||
uint8_t x86opsize; // opsize for [mem] operand
|
||||
cs_insn *flat_insn; // insn to be exposed to public
|
||||
uint64_t address; // address of this insn
|
||||
cs_struct *csh; // save the main csh
|
||||
uint8_t x86opsize; // opsize for [mem] operand
|
||||
|
||||
// These flags could be used to pass some info from one target subcomponent
|
||||
// to another, for example, from disassembler to asm printer. The values of
|
||||
|
|
@ -121,21 +121,21 @@ struct MCInst {
|
|||
// A prefix byte gets value 0 when irrelevant.
|
||||
// This is copied from cs_x86 struct
|
||||
uint8_t x86_prefix[4];
|
||||
uint8_t imm_size; // immediate size for X86_OP_IMM operand
|
||||
bool writeback; // writeback for ARM
|
||||
uint8_t imm_size; // immediate size for X86_OP_IMM operand
|
||||
bool writeback; // writeback for ARM
|
||||
int8_t tied_op_idx
|
||||
[MAX_MC_OPS]; ///< Tied operand indices. Index = Src op; Value: Dest op
|
||||
// operand access index for list of registers sharing the same access right (for ARM)
|
||||
uint8_t ac_idx;
|
||||
uint8_t popcode_adjust; // Pseudo X86 instruction adjust
|
||||
char assembly[8]; // for special instruction, so that we don't need printer
|
||||
unsigned char evm_data[32]; // for EVM PUSH operand
|
||||
cs_wasm_op wasm_data; // for WASM operand
|
||||
uint8_t popcode_adjust; // Pseudo X86 instruction adjust
|
||||
char assembly[8]; // for special instruction, so that we don't need printer
|
||||
unsigned char evm_data[32]; // for EVM PUSH operand
|
||||
cs_wasm_op wasm_data; // for WASM operand
|
||||
MCRegisterInfo *MRI;
|
||||
uint8_t xAcquireRelease; // X86 xacquire/xrelease
|
||||
uint8_t xAcquireRelease; // X86 xacquire/xrelease
|
||||
bool isAliasInstr; // Flag if this MCInst is an alias.
|
||||
bool fillDetailOps; // If set, detail->operands gets filled.
|
||||
hppa_ext hppa_ext; ///< for HPPA operand. Contains info about modifiers and their effect on the instruction
|
||||
hppa_ext hppa_ext; ///< for HPPA operand. Contains info about modifiers and their effect on the instruction
|
||||
MCAsmInfo MAI; ///< The equivalent to MCAsmInfo in LLVM. It holds flags relevant for the asm style to print.
|
||||
};
|
||||
|
||||
|
|
@ -148,11 +148,11 @@ void MCInst_insert0(MCInst *inst, int index, MCOperand *Op);
|
|||
|
||||
void MCInst_setOpcode(MCInst *inst, unsigned Op);
|
||||
|
||||
unsigned MCInst_getOpcode(const MCInst*);
|
||||
unsigned MCInst_getOpcode(const MCInst *);
|
||||
|
||||
void MCInst_setOpcodePub(MCInst *inst, unsigned Op);
|
||||
|
||||
unsigned MCInst_getOpcodePub(const MCInst*);
|
||||
unsigned MCInst_getOpcodePub(const MCInst *);
|
||||
|
||||
MCOperand *MCInst_getOperand(MCInst *inst, unsigned i);
|
||||
|
||||
|
|
@ -163,7 +163,8 @@ void MCInst_addOperand2(MCInst *inst, MCOperand *Op);
|
|||
|
||||
bool MCInst_isPredicable(const MCInstrDesc *MIDesc);
|
||||
|
||||
void MCInst_handleWriteback(MCInst *MI, const MCInstrDesc *InstDescTable, unsigned tbl_size);
|
||||
void MCInst_handleWriteback(MCInst *MI, const MCInstrDesc *InstDescTable,
|
||||
unsigned tbl_size);
|
||||
|
||||
bool MCInst_opIsTied(const MCInst *MI, unsigned OpNum);
|
||||
|
||||
|
|
@ -173,7 +174,8 @@ uint64_t MCInst_getOpVal(MCInst *MI, unsigned OpNum);
|
|||
|
||||
void MCInst_setIsAlias(MCInst *MI, bool Flag);
|
||||
|
||||
static inline bool MCInst_isAlias(const MCInst *MI) {
|
||||
static inline bool MCInst_isAlias(const MCInst *MI)
|
||||
{
|
||||
return MI->isAliasInstr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ static bool testFeatureBits(const MCInst *MI, uint32_t Value)
|
|||
}
|
||||
|
||||
static bool matchAliasCondition(MCInst *MI, const MCRegisterInfo *MRI,
|
||||
unsigned *OpIdx, const AliasMatchingData *M,
|
||||
const AliasPatternCond *C,
|
||||
bool *OrPredicateResult)
|
||||
unsigned *OpIdx, const AliasMatchingData *M,
|
||||
const AliasPatternCond *C,
|
||||
bool *OrPredicateResult)
|
||||
{
|
||||
// Feature tests are special, they don't consume operands.
|
||||
if (C->Kind == AliasPatternCond_K_Feature)
|
||||
|
|
@ -84,25 +84,28 @@ static bool matchAliasCondition(MCInst *MI, const MCRegisterInfo *MRI,
|
|||
case AliasPatternCond_K_Imm:
|
||||
// Operand must be a specific immediate.
|
||||
return MCOperand_isImm(Opnd) &&
|
||||
MCOperand_getImm(Opnd) == (int32_t)C->Value;
|
||||
MCOperand_getImm(Opnd) == (int32_t)C->Value;
|
||||
case AliasPatternCond_K_Reg:
|
||||
// Operand must be a specific register.
|
||||
return MCOperand_isReg(Opnd) && MCOperand_getReg(Opnd) == C->Value;
|
||||
return MCOperand_isReg(Opnd) &&
|
||||
MCOperand_getReg(Opnd) == C->Value;
|
||||
case AliasPatternCond_K_TiedReg:
|
||||
// Operand must match the register of another operand.
|
||||
return MCOperand_isReg(Opnd) &&
|
||||
MCOperand_getReg(Opnd) ==
|
||||
MCOperand_getReg(MCInst_getOperand(MI, C->Value));
|
||||
MCOperand_getReg(Opnd) ==
|
||||
MCOperand_getReg(
|
||||
MCInst_getOperand(MI, C->Value));
|
||||
case AliasPatternCond_K_RegClass:
|
||||
// Operand must be a register in this class. Value is a register class
|
||||
// id.
|
||||
return MCOperand_isReg(Opnd) &&
|
||||
MCRegisterClass_contains(
|
||||
MCRegisterInfo_getRegClass(MRI, C->Value),
|
||||
MCOperand_getReg(Opnd));
|
||||
MCRegisterClass_contains(
|
||||
MCRegisterInfo_getRegClass(MRI, C->Value),
|
||||
MCOperand_getReg(Opnd));
|
||||
case AliasPatternCond_K_Custom:
|
||||
// Operand must match some custom criteria.
|
||||
assert(M->ValidateMCOperand && "A custom validator should be set but isn't.");
|
||||
assert(M->ValidateMCOperand &&
|
||||
"A custom validator should be set but isn't.");
|
||||
return M->ValidateMCOperand(Opnd, C->Value);
|
||||
case AliasPatternCond_K_Ignore:
|
||||
// Operand can be anything.
|
||||
|
|
@ -141,25 +144,30 @@ const char *matchAliasPatterns(MCInst *MI, const AliasMatchingData *M)
|
|||
uint32_t PatternOpcode = M->OpToPatterns[i].Opcode;
|
||||
while (PatternOpcode < MIOpcode && validOpToPatter(&M->OpToPatterns[i]))
|
||||
PatternOpcode = M->OpToPatterns[++i].Opcode;
|
||||
if (PatternOpcode != MI->Opcode || !validOpToPatter(&M->OpToPatterns[i]))
|
||||
if (PatternOpcode != MI->Opcode ||
|
||||
!validOpToPatter(&M->OpToPatterns[i]))
|
||||
return NULL;
|
||||
|
||||
// // Try all patterns for this opcode.
|
||||
uint32_t AsmStrOffset = ~0U;
|
||||
const AliasPattern *Patterns = M->Patterns + M->OpToPatterns[i].PatternStart;
|
||||
const AliasPattern *Patterns =
|
||||
M->Patterns + M->OpToPatterns[i].PatternStart;
|
||||
for (const AliasPattern *P = Patterns;
|
||||
P != Patterns + M->OpToPatterns[i].NumPatterns; ++P) {
|
||||
P != Patterns + M->OpToPatterns[i].NumPatterns; ++P) {
|
||||
// Check operand count first.
|
||||
if (MCInst_getNumOperands(MI) != P->NumOperands)
|
||||
return NULL;
|
||||
|
||||
// Test all conditions for this pattern.
|
||||
const AliasPatternCond *Conds = M->PatternConds + P->AliasCondStart;
|
||||
const AliasPatternCond *Conds =
|
||||
M->PatternConds + P->AliasCondStart;
|
||||
unsigned OpIdx = 0;
|
||||
bool OrPredicateResult = false;
|
||||
bool allMatch = true;
|
||||
for (const AliasPatternCond *C = Conds; C != Conds + P->NumConds; ++C) {
|
||||
if (!matchAliasCondition(MI, MI->MRI, &OpIdx, M, C, &OrPredicateResult)) {
|
||||
for (const AliasPatternCond *C = Conds;
|
||||
C != Conds + P->NumConds; ++C) {
|
||||
if (!matchAliasCondition(MI, MI->MRI, &OpIdx, M, C,
|
||||
&OrPredicateResult)) {
|
||||
allMatch = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -180,7 +188,10 @@ const char *matchAliasPatterns(MCInst *MI, const AliasMatchingData *M)
|
|||
}
|
||||
|
||||
// TODO Add functionality to toggle the flag.
|
||||
bool getUseMarkup(void) { return false; }
|
||||
bool getUseMarkup(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Utility functions to make adding mark ups simpler.
|
||||
const char *markup(const char *s)
|
||||
|
|
@ -194,7 +205,8 @@ const char *markup(const char *s)
|
|||
|
||||
// binary search for encoding in IndexType array
|
||||
// return -1 if not found, or index if found
|
||||
unsigned int binsearch_IndexTypeEncoding(const struct IndexType *index, size_t size, uint16_t encoding)
|
||||
unsigned int binsearch_IndexTypeEncoding(const struct IndexType *index,
|
||||
size_t size, uint16_t encoding)
|
||||
{
|
||||
// binary searching since the index is sorted in encoding order
|
||||
size_t left, right, m;
|
||||
|
|
@ -207,7 +219,7 @@ unsigned int binsearch_IndexTypeEncoding(const struct IndexType *index, size_t s
|
|||
|
||||
left = 0;
|
||||
|
||||
while(left <= right) {
|
||||
while (left <= right) {
|
||||
m = (left + right) / 2;
|
||||
if (encoding == index[m].encoding) {
|
||||
// LLVM actually uses lower_bound for the index table search
|
||||
|
|
@ -230,7 +242,8 @@ unsigned int binsearch_IndexTypeEncoding(const struct IndexType *index, size_t s
|
|||
|
||||
// binary search for encoding in IndexTypeStr array
|
||||
// return -1 if not found, or index if found
|
||||
unsigned int binsearch_IndexTypeStrEncoding(const struct IndexTypeStr *index, size_t size, const char *name)
|
||||
unsigned int binsearch_IndexTypeStrEncoding(const struct IndexTypeStr *index,
|
||||
size_t size, const char *name)
|
||||
{
|
||||
// binary searching since the index is sorted in encoding order
|
||||
size_t left, right, m;
|
||||
|
|
@ -245,7 +258,7 @@ unsigned int binsearch_IndexTypeStrEncoding(const struct IndexTypeStr *index, si
|
|||
|
||||
left = 0;
|
||||
|
||||
while(left <= right) {
|
||||
while (left <= right) {
|
||||
m = (left + right) / 2;
|
||||
if (strcmp(name, index[m].name) == 0) {
|
||||
// LLVM actually uses lower_bound for the index table search
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
/// Returned by getMnemonic() of the AsmPrinters.
|
||||
typedef struct {
|
||||
const char *first; // Mnemonic
|
||||
uint64_t second; // Bits
|
||||
uint64_t second; // Bits
|
||||
} MnemonicBitsInfo;
|
||||
|
||||
/// Map from opcode to pattern list by binary search.
|
||||
|
|
@ -31,19 +31,19 @@ typedef struct {
|
|||
} AliasPattern;
|
||||
|
||||
typedef enum {
|
||||
AliasPatternCond_K_Feature, // Match only if a feature is enabled.
|
||||
AliasPatternCond_K_Feature, // Match only if a feature is enabled.
|
||||
AliasPatternCond_K_NegFeature, // Match only if a feature is disabled.
|
||||
AliasPatternCond_K_OrFeature, // Match only if one of a set of features is
|
||||
// enabled.
|
||||
AliasPatternCond_K_OrNegFeature, // Match only if one of a set of features
|
||||
// is disabled.
|
||||
AliasPatternCond_K_OrFeature, // Match only if one of a set of features is
|
||||
// enabled.
|
||||
AliasPatternCond_K_OrNegFeature, // Match only if one of a set of features
|
||||
// is disabled.
|
||||
AliasPatternCond_K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features.
|
||||
AliasPatternCond_K_Ignore, // Match any operand.
|
||||
AliasPatternCond_K_Reg, // Match a specific register.
|
||||
AliasPatternCond_K_TiedReg, // Match another already matched register.
|
||||
AliasPatternCond_K_Imm, // Match a specific immediate.
|
||||
AliasPatternCond_K_RegClass, // Match registers in a class.
|
||||
AliasPatternCond_K_Custom, // Call custom matcher by index.
|
||||
AliasPatternCond_K_Ignore, // Match any operand.
|
||||
AliasPatternCond_K_Reg, // Match a specific register.
|
||||
AliasPatternCond_K_TiedReg, // Match another already matched register.
|
||||
AliasPatternCond_K_Imm, // Match a specific immediate.
|
||||
AliasPatternCond_K_RegClass, // Match registers in a class.
|
||||
AliasPatternCond_K_Custom, // Call custom matcher by index.
|
||||
} AliasPatternCond_CondKind;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -51,7 +51,8 @@ typedef struct {
|
|||
uint32_t Value;
|
||||
} AliasPatternCond;
|
||||
|
||||
typedef bool (*ValidateMCOperandFunc)(const MCOperand *MCOp, unsigned PredicateIndex);
|
||||
typedef bool (*ValidateMCOperandFunc)(const MCOperand *MCOp,
|
||||
unsigned PredicateIndex);
|
||||
|
||||
/// Tablegenerated data structures needed to match alias patterns.
|
||||
typedef struct {
|
||||
|
|
@ -78,7 +79,9 @@ struct IndexTypeStr {
|
|||
|
||||
// binary search for encoding in IndexType array
|
||||
// return -1 if not found, or index if found
|
||||
unsigned int binsearch_IndexTypeEncoding(const struct IndexType *index, size_t size, uint16_t encoding);
|
||||
unsigned int binsearch_IndexTypeStrEncoding(const struct IndexTypeStr *index, size_t size, const char *name);
|
||||
unsigned int binsearch_IndexTypeEncoding(const struct IndexType *index,
|
||||
size_t size, uint16_t encoding);
|
||||
unsigned int binsearch_IndexTypeStrEncoding(const struct IndexTypeStr *index,
|
||||
size_t size, const char *name);
|
||||
|
||||
#endif // CS_MCINSTPRINTER_H
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ int MCOperandInfo_getOperandConstraint(const MCInstrDesc *InstrDesc,
|
|||
/// Returns the instruction description for the given MCInst opcode.
|
||||
/// Function should be called like:
|
||||
/// MCInstrDesc_get(MCInst_getOpcode(MI), ARCHInstDesc, ARR_SIZE(ARCHInstDesc));
|
||||
const MCInstrDesc *MCInstrDesc_get(unsigned opcode, const MCInstrDesc *table, unsigned tbl_size) {
|
||||
const MCInstrDesc *MCInstrDesc_get(unsigned opcode, const MCInstrDesc *table,
|
||||
unsigned tbl_size)
|
||||
{
|
||||
return &table[tbl_size - 1 - opcode];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,16 +30,15 @@
|
|||
/// corresponding high-order hex digit specifying the constraint value.
|
||||
/// This allows for a maximum of 3 constraints.
|
||||
typedef enum {
|
||||
MCOI_TIED_TO = 0, // Operand tied to another operand.
|
||||
MCOI_EARLY_CLOBBER // Operand is an early clobber register operand
|
||||
MCOI_TIED_TO = 0, // Operand tied to another operand.
|
||||
MCOI_EARLY_CLOBBER // Operand is an early clobber register operand
|
||||
} MCOI_OperandConstraint;
|
||||
|
||||
// Define a macro to produce each constraint value.
|
||||
#define CONSTRAINT_MCOI_TIED_TO(op) \
|
||||
((1 << MCOI_TIED_TO) | ((op) << (4 + MCOI_TIED_TO * 4)))
|
||||
((1 << MCOI_TIED_TO) | ((op) << (4 + MCOI_TIED_TO * 4)))
|
||||
|
||||
#define CONSTRAINT_MCOI_EARLY_CLOBBER \
|
||||
(1 << MCOI_EARLY_CLOBBER)
|
||||
#define CONSTRAINT_MCOI_EARLY_CLOBBER (1 << MCOI_EARLY_CLOBBER)
|
||||
|
||||
/// OperandFlags - These are flags set on operands, but should be considered
|
||||
/// private, all access should go through the MCOperandInfo accessors.
|
||||
|
|
@ -74,7 +73,6 @@ enum MCOI_OperandType {
|
|||
MCOI_OPERAND_FIRST_TARGET = 13,
|
||||
};
|
||||
|
||||
|
||||
/// MCOperandInfo - This holds information about one operand of a machine
|
||||
/// instruction, indicating the register class for register operands, etc.
|
||||
///
|
||||
|
|
@ -97,7 +95,6 @@ typedef struct MCOperandInfo {
|
|||
/// Currently no other information.
|
||||
} MCOperandInfo;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Machine Instruction Flags and Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
@ -150,8 +147,8 @@ enum {
|
|||
/// for each target instruction class, and the MachineInstr class points to
|
||||
/// this struct directly to describe itself.
|
||||
typedef struct MCInstrDesc {
|
||||
unsigned char NumOperands; // Num of args (may be more if variable_ops)
|
||||
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
|
||||
unsigned char NumOperands; // Num of args (may be more if variable_ops)
|
||||
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
|
||||
} MCInstrDesc;
|
||||
|
||||
bool MCOperandInfo_isPredicate(const MCOperandInfo *m);
|
||||
|
|
@ -163,9 +160,7 @@ bool MCOperandInfo_isTiedToOp(const MCOperandInfo *m);
|
|||
int MCOperandInfo_getOperandConstraint(const MCInstrDesc *OpInfo,
|
||||
unsigned OpNum,
|
||||
MCOI_OperandConstraint Constraint);
|
||||
const MCInstrDesc *MCInstrDesc_get(unsigned opcode,
|
||||
const MCInstrDesc *table,
|
||||
unsigned tbl_size);
|
||||
|
||||
const MCInstrDesc *MCInstrDesc_get(unsigned opcode, const MCInstrDesc *table,
|
||||
unsigned tbl_size);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,14 +26,13 @@ typedef struct DiffListIterator {
|
|||
} DiffListIterator;
|
||||
|
||||
void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
|
||||
const MCRegisterDesc *D, unsigned NR,
|
||||
unsigned RA, unsigned PC,
|
||||
const MCRegisterClass *C, unsigned NC,
|
||||
uint16_t (*RURoots)[2], unsigned NRU,
|
||||
const MCPhysReg *DL,
|
||||
const char *Strings,
|
||||
const uint16_t *SubIndices, unsigned NumIndices,
|
||||
const uint16_t *RET)
|
||||
const MCRegisterDesc *D, unsigned NR,
|
||||
unsigned RA, unsigned PC,
|
||||
const MCRegisterClass *C, unsigned NC,
|
||||
uint16_t (*RURoots)[2], unsigned NRU,
|
||||
const MCPhysReg *DL, const char *Strings,
|
||||
const uint16_t *SubIndices,
|
||||
unsigned NumIndices, const uint16_t *RET)
|
||||
{
|
||||
RI->Desc = D;
|
||||
RI->NumRegs = NR;
|
||||
|
|
@ -50,7 +49,8 @@ void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
|
|||
RI->RegEncodingTable = RET;
|
||||
}
|
||||
|
||||
static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, const MCPhysReg *DiffList)
|
||||
static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal,
|
||||
const MCPhysReg *DiffList)
|
||||
{
|
||||
d->Val = InitVal;
|
||||
d->List = DiffList;
|
||||
|
|
@ -83,7 +83,9 @@ static bool DiffListIterator_isValid(DiffListIterator *d)
|
|||
return (d->List != 0);
|
||||
}
|
||||
|
||||
unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC)
|
||||
unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI,
|
||||
unsigned Reg, unsigned SubIdx,
|
||||
const MCRegisterClass *RC)
|
||||
{
|
||||
DiffListIterator iter;
|
||||
|
||||
|
|
@ -91,12 +93,14 @@ unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned R
|
|||
return 0;
|
||||
}
|
||||
|
||||
DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs);
|
||||
DiffListIterator_init(&iter, (MCPhysReg)Reg,
|
||||
RI->DiffLists + RI->Desc[Reg].SuperRegs);
|
||||
DiffListIterator_next(&iter);
|
||||
|
||||
while(DiffListIterator_isValid(&iter)) {
|
||||
while (DiffListIterator_isValid(&iter)) {
|
||||
uint16_t val = DiffListIterator_getVal(&iter);
|
||||
if (MCRegisterClass_contains(RC, val) && Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx))
|
||||
if (MCRegisterClass_contains(RC, val) &&
|
||||
Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx))
|
||||
return val;
|
||||
|
||||
DiffListIterator_next(&iter);
|
||||
|
|
@ -105,15 +109,17 @@ unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned R
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg, unsigned Idx)
|
||||
unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg,
|
||||
unsigned Idx)
|
||||
{
|
||||
DiffListIterator iter;
|
||||
const uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices;
|
||||
|
||||
DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs);
|
||||
DiffListIterator_init(&iter, (MCPhysReg)Reg,
|
||||
RI->DiffLists + RI->Desc[Reg].SubRegs);
|
||||
DiffListIterator_next(&iter);
|
||||
|
||||
while(DiffListIterator_isValid(&iter)) {
|
||||
while (DiffListIterator_isValid(&iter)) {
|
||||
if (*SRI == Idx)
|
||||
return DiffListIterator_getVal(&iter);
|
||||
DiffListIterator_next(&iter);
|
||||
|
|
@ -123,7 +129,8 @@ unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg, unsign
|
|||
return 0;
|
||||
}
|
||||
|
||||
const MCRegisterClass* MCRegisterInfo_getRegClass(const MCRegisterInfo *RI, unsigned i)
|
||||
const MCRegisterClass *MCRegisterInfo_getRegClass(const MCRegisterInfo *RI,
|
||||
unsigned i)
|
||||
{
|
||||
//assert(i < getNumRegClasses() && "Register Class ID out of range");
|
||||
if (i >= RI->NumClasses)
|
||||
|
|
@ -138,7 +145,7 @@ bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg)
|
|||
|
||||
// Make sure that MCRegisterInfo_getRegClass didn't return 0
|
||||
// (for calls to GETREGCLASS_CONTAIN0)
|
||||
if(!c)
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
InByte = Reg % 8;
|
||||
|
|
@ -150,6 +157,7 @@ bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg)
|
|||
return (c->RegSet[Byte] & (1 << InByte)) != 0;
|
||||
}
|
||||
|
||||
unsigned MCRegisterClass_getRegister(const MCRegisterClass *c, unsigned RegNo) {
|
||||
return c->RegsBegin[RegNo];
|
||||
unsigned MCRegisterClass_getRegister(const MCRegisterClass *c, unsigned RegNo)
|
||||
{
|
||||
return c->RegsBegin[RegNo];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
/// 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 const MCPhysReg *iterator;
|
||||
typedef uint16_t MCRegister;
|
||||
|
||||
typedef struct MCRegisterClass2 {
|
||||
|
|
@ -47,8 +47,8 @@ typedef struct MCRegisterClass {
|
|||
/// of AX. The SuperRegs field is a zero terminated array of registers that are
|
||||
/// super-registers of AX.
|
||||
typedef struct MCRegisterDesc {
|
||||
uint32_t Name; // Printable name for the reg (for debugging)
|
||||
uint32_t SubRegs; // Sub-register set, described above
|
||||
uint32_t Name; // Printable name for the reg (for debugging)
|
||||
uint32_t SubRegs; // Sub-register set, described above
|
||||
uint32_t SuperRegs; // Super-register set, described above
|
||||
|
||||
// Offset into MCRI::SubRegIndices of a list of sub-register indices for each
|
||||
|
|
@ -61,7 +61,7 @@ typedef struct MCRegisterDesc {
|
|||
|
||||
/// Index into list with lane mask sequences. The sequence contains a lanemask
|
||||
/// for every register unit.
|
||||
uint16_t RegUnitLaneMasks; // ???
|
||||
uint16_t RegUnitLaneMasks; // ???
|
||||
} MCRegisterDesc;
|
||||
|
||||
/// MCRegisterInfo base class - We assume that the target defines a static
|
||||
|
|
@ -76,42 +76,41 @@ typedef struct MCRegisterDesc {
|
|||
/// TableGen generated physical register data. It must not be extended with
|
||||
/// virtual methods.
|
||||
typedef struct MCRegisterInfo {
|
||||
const MCRegisterDesc *Desc; // Pointer to the descriptor array
|
||||
unsigned NumRegs; // Number of entries in the array
|
||||
unsigned RAReg; // Return address register
|
||||
unsigned PCReg; // Program counter register
|
||||
const MCRegisterClass *Classes; // Pointer to the regclass array
|
||||
unsigned NumClasses; // Number of entries in the array
|
||||
unsigned NumRegUnits; // Number of regunits.
|
||||
uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table.
|
||||
const MCPhysReg *DiffLists; // Pointer to the difflists array
|
||||
const MCRegisterDesc *Desc; // Pointer to the descriptor array
|
||||
unsigned NumRegs; // Number of entries in the array
|
||||
unsigned RAReg; // Return address register
|
||||
unsigned PCReg; // Program counter register
|
||||
const MCRegisterClass *Classes; // Pointer to the regclass array
|
||||
unsigned NumClasses; // Number of entries in the array
|
||||
unsigned NumRegUnits; // Number of regunits.
|
||||
uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table.
|
||||
const MCPhysReg *DiffLists; // Pointer to the difflists array
|
||||
// const LaneBitmask *RegUnitMaskSequences; // Pointer to lane mask sequences
|
||||
const char *RegStrings; // Pointer to the string table.
|
||||
const char *RegStrings; // Pointer to the string table.
|
||||
// const char *RegClassStrings; // Pointer to the class strings.
|
||||
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
|
||||
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
|
||||
// array.
|
||||
unsigned NumSubRegIndices; // Number of subreg indices.
|
||||
const uint16_t *RegEncodingTable; // Pointer to array of register
|
||||
unsigned NumSubRegIndices; // Number of subreg indices.
|
||||
const uint16_t *RegEncodingTable; // Pointer to array of register
|
||||
// encodings.
|
||||
} MCRegisterInfo;
|
||||
|
||||
void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
|
||||
const MCRegisterDesc *D, unsigned NR, unsigned RA,
|
||||
unsigned PC,
|
||||
const MCRegisterClass *C, unsigned NC,
|
||||
uint16_t (*RURoots)[2],
|
||||
unsigned NRU,
|
||||
const MCPhysReg *DL,
|
||||
const char *Strings,
|
||||
const uint16_t *SubIndices,
|
||||
unsigned NumIndices,
|
||||
const uint16_t *RET);
|
||||
void MCRegisterInfo_InitMCRegisterInfo(
|
||||
MCRegisterInfo *RI, const MCRegisterDesc *D, unsigned NR, unsigned RA,
|
||||
unsigned PC, const MCRegisterClass *C, unsigned NC,
|
||||
uint16_t (*RURoots)[2], unsigned NRU, const MCPhysReg *DL,
|
||||
const char *Strings, const uint16_t *SubIndices, unsigned NumIndices,
|
||||
const uint16_t *RET);
|
||||
|
||||
unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC);
|
||||
unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI,
|
||||
unsigned Reg, unsigned SubIdx,
|
||||
const MCRegisterClass *RC);
|
||||
|
||||
unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg, unsigned Idx);
|
||||
unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg,
|
||||
unsigned Idx);
|
||||
|
||||
const MCRegisterClass* MCRegisterInfo_getRegClass(const MCRegisterInfo *RI, unsigned i);
|
||||
const MCRegisterClass *MCRegisterInfo_getRegClass(const MCRegisterInfo *RI,
|
||||
unsigned i);
|
||||
|
||||
bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg);
|
||||
|
||||
|
|
|
|||
32
Mapping.c
32
Mapping.c
|
|
@ -338,7 +338,9 @@ const cs_ac_type mapping_get_op_access(MCInst *MI, unsigned OpNum,
|
|||
if (!MI->flat_insn->detail) \
|
||||
return NULL; \
|
||||
int OpIdx = MI->flat_insn->detail->arch.op_count + offset; \
|
||||
if (OpIdx < 0 || OpIdx >= NUM_##ARCH_UPPER##_OPS) { return NULL; } \
|
||||
if (OpIdx < 0 || OpIdx >= NUM_##ARCH_UPPER##_OPS) { \
|
||||
return NULL; \
|
||||
} \
|
||||
return &MI->flat_insn->detail->arch.operands[OpIdx]; \
|
||||
}
|
||||
|
||||
|
|
@ -361,14 +363,17 @@ DEFINE_get_detail_op(sparc, Sparc, SPARC);
|
|||
/// alias operands should be filled.
|
||||
/// TODO: Replace this with a proper option.
|
||||
/// So it can be toggled between disas() calls.
|
||||
bool map_use_alias_details(const MCInst *MI) {
|
||||
bool map_use_alias_details(const MCInst *MI)
|
||||
{
|
||||
assert(MI);
|
||||
return (MI->csh->detail_opt & CS_OPT_ON) && !(MI->csh->detail_opt & CS_OPT_DETAIL_REAL);
|
||||
return (MI->csh->detail_opt & CS_OPT_ON) &&
|
||||
!(MI->csh->detail_opt & CS_OPT_DETAIL_REAL);
|
||||
}
|
||||
|
||||
/// Sets the setDetailOps flag to @p Val.
|
||||
/// If detail == NULLit refuses to set the flag to true.
|
||||
void map_set_fill_detail_ops(MCInst *MI, bool Val) {
|
||||
void map_set_fill_detail_ops(MCInst *MI, bool Val)
|
||||
{
|
||||
CS_ASSERT_RET(MI);
|
||||
if (!detail_is_set(MI)) {
|
||||
MI->fillDetailOps = false;
|
||||
|
|
@ -379,14 +384,16 @@ void map_set_fill_detail_ops(MCInst *MI, bool Val) {
|
|||
}
|
||||
|
||||
/// Sets the instruction alias flags and the given alias id.
|
||||
void map_set_is_alias_insn(MCInst *MI, bool Val, uint64_t Alias) {
|
||||
void map_set_is_alias_insn(MCInst *MI, bool Val, uint64_t Alias)
|
||||
{
|
||||
CS_ASSERT_RET(MI);
|
||||
MI->isAliasInstr = Val;
|
||||
MI->flat_insn->is_alias = Val;
|
||||
MI->flat_insn->alias_id = Alias;
|
||||
}
|
||||
|
||||
static inline bool char_ends_mnem(const char c, cs_arch arch) {
|
||||
static inline bool char_ends_mnem(const char c, cs_arch arch)
|
||||
{
|
||||
switch (arch) {
|
||||
default:
|
||||
return (!c || c == ' ' || c == '\t' || c == '.');
|
||||
|
|
@ -394,13 +401,15 @@ static inline bool char_ends_mnem(const char c, cs_arch arch) {
|
|||
return (!c || c == ' ' || c == '\t');
|
||||
case CS_ARCH_SPARC:
|
||||
return (!c || c == ' ' || c == '\t' || c == ',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets an alternative id for some instruction.
|
||||
/// Or -1 if it fails.
|
||||
/// You must add (<ARCH>_INS_ALIAS_BEGIN + 1) to the id to get the real id.
|
||||
void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_id_map, int map_size) {
|
||||
void map_set_alias_id(MCInst *MI, const SStream *O,
|
||||
const name_map *alias_mnem_id_map, int map_size)
|
||||
{
|
||||
if (!MCInst_isAlias(MI))
|
||||
return;
|
||||
|
||||
|
|
@ -421,7 +430,8 @@ void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_i
|
|||
alias_mnem[j] = asm_str_buf[i];
|
||||
}
|
||||
|
||||
MI->flat_insn->alias_id = name2id(alias_mnem_id_map, map_size, alias_mnem);
|
||||
MI->flat_insn->alias_id =
|
||||
name2id(alias_mnem_id_map, map_size, alias_mnem);
|
||||
}
|
||||
|
||||
/// Does a binary search over the given map and searches for @id.
|
||||
|
|
@ -456,7 +466,8 @@ uint64_t enum_map_bin_search(const cs_enum_id_map *map, size_t map_len,
|
|||
} else if (id[i] > map[m].str[j]) {
|
||||
l = m + 1;
|
||||
}
|
||||
if ((m == 0 && id[i] < map[m].str[j]) || (l + r) / 2 >= map_len) {
|
||||
if ((m == 0 && id[i] < map[m].str[j]) ||
|
||||
(l + r) / 2 >= map_len) {
|
||||
// Break before we go out of bounds.
|
||||
break;
|
||||
}
|
||||
|
|
@ -464,4 +475,3 @@ uint64_t enum_map_bin_search(const cs_enum_id_map *map, size_t map_len,
|
|||
*found = false;
|
||||
return UINT64_MAX;
|
||||
}
|
||||
|
||||
|
|
|
|||
47
Mapping.h
47
Mapping.h
|
|
@ -17,17 +17,17 @@
|
|||
|
||||
// map instruction to its characteristics
|
||||
typedef struct insn_map {
|
||||
unsigned short id; // The LLVM instruction id
|
||||
unsigned short mapid; // The Capstone instruction id
|
||||
unsigned short id; // The LLVM instruction id
|
||||
unsigned short mapid; // The Capstone instruction id
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint16_t regs_use[MAX_IMPL_R_REGS]; ///< list of implicit registers used by
|
||||
///< this instruction
|
||||
///< this instruction
|
||||
uint16_t regs_mod[MAX_IMPL_W_REGS]; ///< list of implicit registers modified
|
||||
///< by this instruction
|
||||
///< by this instruction
|
||||
unsigned char groups
|
||||
[MAX_NUM_GROUPS]; ///< list of group this instruction belong to
|
||||
bool branch; // branch instruction?
|
||||
bool indirect_branch; // indirect branch instruction?
|
||||
bool branch; // branch instruction?
|
||||
bool indirect_branch; // indirect branch instruction?
|
||||
union {
|
||||
ppc_suppl_info ppc;
|
||||
loongarch_suppl_info loongarch;
|
||||
|
|
@ -52,11 +52,10 @@ unsigned int find_cs_id(unsigned MC_Opcode, const insn_map *imap,
|
|||
|
||||
///< A LLVM<->CS Mapping entry of an MCOperand.
|
||||
typedef struct {
|
||||
uint8_t /* cs_op_type */ type; ///< Operand type (e.g.: reg, imm, mem)
|
||||
uint8_t /* cs_op_type */ type; ///< Operand type (e.g.: reg, imm, mem)
|
||||
uint8_t /* cs_ac_type */ access; ///< The access type (read, write)
|
||||
uint8_t /* cs_data_type */
|
||||
dtypes[MAX_NO_DATA_TYPES]; ///< List of op types. Terminated by
|
||||
///< CS_DATA_TYPE_LAST
|
||||
/// List of op types. Terminated by CS_DATA_TYPE_LAST
|
||||
uint8_t /* cs_data_type */ dtypes[MAX_NO_DATA_TYPES];
|
||||
} mapping_op;
|
||||
|
||||
#define MAX_NO_INSN_MAP_OPS 16
|
||||
|
|
@ -85,8 +84,7 @@ const cs_ac_type mapping_get_op_access(MCInst *MI, unsigned OpNum,
|
|||
mapping_get_op_type(MI, OpNum, (const map_insn_ops *)insn_operands, \
|
||||
sizeof(insn_operands) / sizeof(insn_operands[0]))
|
||||
#else
|
||||
#define map_get_op_type(MI, OpNum) \
|
||||
CS_OP_INVALID
|
||||
#define map_get_op_type(MI, OpNum) CS_OP_INVALID
|
||||
#endif
|
||||
|
||||
/// Macro for easier access of operand access flags from the map.
|
||||
|
|
@ -98,8 +96,7 @@ const cs_ac_type mapping_get_op_access(MCInst *MI, unsigned OpNum,
|
|||
sizeof(insn_operands) / \
|
||||
sizeof(insn_operands[0]))
|
||||
#else
|
||||
#define map_get_op_access(MI, OpNum) \
|
||||
CS_AC_INVALID
|
||||
#define map_get_op_access(MI, OpNum) CS_AC_INVALID
|
||||
#endif
|
||||
|
||||
///< Map for ids to their string
|
||||
|
|
@ -229,8 +226,10 @@ DEFINE_get_arch_detail(bpf, BPF);
|
|||
DEFINE_get_arch_detail(sparc, Sparc);
|
||||
|
||||
#define DEFINE_check_safe_inc(Arch, ARCH) \
|
||||
static inline void Arch##_check_safe_inc(const MCInst *MI) { \
|
||||
assert(Arch##_get_detail(MI)->op_count + 1 < NUM_##ARCH##_OPS); \
|
||||
static inline void Arch##_check_safe_inc(const MCInst *MI) \
|
||||
{ \
|
||||
assert(Arch##_get_detail(MI)->op_count + 1 < \
|
||||
NUM_##ARCH##_OPS); \
|
||||
}
|
||||
|
||||
DEFINE_check_safe_inc(ARM, ARM);
|
||||
|
|
@ -261,14 +260,15 @@ static inline cs_detail *get_detail(const MCInst *MI)
|
|||
|
||||
/// Returns if the given instruction is an alias instruction.
|
||||
#define RETURN_IF_INSN_IS_ALIAS(MI) \
|
||||
do { \
|
||||
if (MI->isAliasInstr) \
|
||||
return; \
|
||||
} while(0)
|
||||
do { \
|
||||
if (MI->isAliasInstr) \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
void map_set_fill_detail_ops(MCInst *MI, bool Val);
|
||||
|
||||
static inline bool map_fill_detail_ops(MCInst *MI) {
|
||||
static inline bool map_fill_detail_ops(MCInst *MI)
|
||||
{
|
||||
assert(MI);
|
||||
return MI->fillDetailOps;
|
||||
}
|
||||
|
|
@ -277,7 +277,8 @@ void map_set_is_alias_insn(MCInst *MI, bool Val, uint64_t Alias);
|
|||
|
||||
bool map_use_alias_details(const MCInst *MI);
|
||||
|
||||
void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_id_map, int map_size);
|
||||
void map_set_alias_id(MCInst *MI, const SStream *O,
|
||||
const name_map *alias_mnem_id_map, int map_size);
|
||||
|
||||
/// Mapping from Capstone enumeration identifiers and their values.
|
||||
///
|
||||
|
|
@ -296,7 +297,7 @@ void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_i
|
|||
/// ```
|
||||
typedef struct {
|
||||
const char *str; ///< The name of the enumeration identifier
|
||||
uint64_t val; ///< The value of the identifier
|
||||
uint64_t val; ///< The value of the identifier
|
||||
} cs_enum_id_map;
|
||||
|
||||
uint64_t enum_map_bin_search(const cs_enum_id_map *map, size_t map_len,
|
||||
|
|
|
|||
193
MathExtras.h
193
MathExtras.h
|
|
@ -36,57 +36,67 @@
|
|||
// ambiguity.
|
||||
|
||||
/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
|
||||
static inline uint32_t Hi_32(uint64_t Value) {
|
||||
static inline uint32_t Hi_32(uint64_t Value)
|
||||
{
|
||||
return (uint32_t)(Value >> 32);
|
||||
}
|
||||
|
||||
/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
|
||||
static inline uint32_t Lo_32(uint64_t Value) {
|
||||
static inline uint32_t Lo_32(uint64_t Value)
|
||||
{
|
||||
return (uint32_t)(Value);
|
||||
}
|
||||
|
||||
/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
|
||||
/// bit width.
|
||||
static inline bool isUIntN(unsigned N, uint64_t x) {
|
||||
static inline bool isUIntN(unsigned N, uint64_t x)
|
||||
{
|
||||
return x == (x & (~0ULL >> (64 - N)));
|
||||
}
|
||||
|
||||
/// isIntN - Checks if an signed integer fits into the given (dynamic)
|
||||
/// bit width.
|
||||
static inline bool isIntN(unsigned N, int64_t x) {
|
||||
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
|
||||
static inline bool isIntN(unsigned N, int64_t x)
|
||||
{
|
||||
return N >= 64 ||
|
||||
(-(INT64_C(1) << (N - 1)) <= x && x < (INT64_C(1) << (N - 1)));
|
||||
}
|
||||
|
||||
/// isMask_32 - This function returns true if the argument is a sequence of ones
|
||||
/// starting at the least significant bit with the remainder zero (32 bit
|
||||
/// version). Ex. isMask_32(0x0000FFFFU) == true.
|
||||
static inline bool isMask_32(uint32_t Value) {
|
||||
static inline bool isMask_32(uint32_t Value)
|
||||
{
|
||||
return Value && ((Value + 1) & Value) == 0;
|
||||
}
|
||||
|
||||
/// isMask_64 - This function returns true if the argument is a sequence of ones
|
||||
/// starting at the least significant bit with the remainder zero (64 bit
|
||||
/// version).
|
||||
static inline bool isMask_64(uint64_t Value) {
|
||||
static inline bool isMask_64(uint64_t Value)
|
||||
{
|
||||
return Value && ((Value + 1) & Value) == 0;
|
||||
}
|
||||
|
||||
/// isShiftedMask_32 - This function returns true if the argument contains a
|
||||
/// sequence of ones with the remainder zero (32 bit version.)
|
||||
/// Ex. isShiftedMask_32(0x0000FF00U) == true.
|
||||
static inline bool isShiftedMask_32(uint32_t Value) {
|
||||
static inline bool isShiftedMask_32(uint32_t Value)
|
||||
{
|
||||
return isMask_32((Value - 1) | Value);
|
||||
}
|
||||
|
||||
/// isShiftedMask_64 - This function returns true if the argument contains a
|
||||
/// sequence of ones with the remainder zero (64 bit version.)
|
||||
static inline bool isShiftedMask_64(uint64_t Value) {
|
||||
static inline bool isShiftedMask_64(uint64_t Value)
|
||||
{
|
||||
return isMask_64((Value - 1) | Value);
|
||||
}
|
||||
|
||||
/// isPowerOf2_32 - This function returns true if the argument is a power of
|
||||
/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
|
||||
static inline bool isPowerOf2_32(uint32_t Value) {
|
||||
static inline bool isPowerOf2_32(uint32_t Value)
|
||||
{
|
||||
return Value && !(Value & (Value - 1));
|
||||
}
|
||||
|
||||
|
|
@ -94,17 +104,20 @@ static inline bool isPowerOf2_32(uint32_t Value) {
|
|||
/// counting the number of zeros from the most significant bit to the first one
|
||||
/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8.
|
||||
/// Returns 32 if the word is zero.
|
||||
static inline unsigned CountLeadingZeros_32(uint32_t Value) {
|
||||
static inline unsigned CountLeadingZeros_32(uint32_t Value)
|
||||
{
|
||||
unsigned Count; // result
|
||||
#if __GNUC__ >= 4
|
||||
// PowerPC is defined for __builtin_clz(0)
|
||||
#if !defined(__ppc__) && !defined(__ppc64__)
|
||||
if (!Value) return 32;
|
||||
if (!Value)
|
||||
return 32;
|
||||
#endif
|
||||
Count = __builtin_clz(Value);
|
||||
#else
|
||||
unsigned Shift;
|
||||
if (!Value) return 32;
|
||||
if (!Value)
|
||||
return 32;
|
||||
Count = 0;
|
||||
// bisection method for count leading zeros
|
||||
for (Shift = 32 >> 1; Shift; Shift >>= 1) {
|
||||
|
|
@ -123,7 +136,8 @@ static inline unsigned CountLeadingZeros_32(uint32_t Value) {
|
|||
/// counting the number of ones from the most significant bit to the first zero
|
||||
/// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
|
||||
/// Returns 32 if the word is all ones.
|
||||
static inline unsigned CountLeadingOnes_32(uint32_t Value) {
|
||||
static inline unsigned CountLeadingOnes_32(uint32_t Value)
|
||||
{
|
||||
return CountLeadingZeros_32(~Value);
|
||||
}
|
||||
|
||||
|
|
@ -131,20 +145,22 @@ static inline unsigned CountLeadingOnes_32(uint32_t Value) {
|
|||
/// of counting the number of zeros from the most significant bit to the first
|
||||
/// one bit (64 bit edition.)
|
||||
/// Returns 64 if the word is zero.
|
||||
static inline unsigned CountLeadingZeros_64(uint64_t Value) {
|
||||
static inline unsigned CountLeadingZeros_64(uint64_t Value)
|
||||
{
|
||||
unsigned Count; // result
|
||||
#if __GNUC__ >= 4
|
||||
// PowerPC is defined for __builtin_clzll(0)
|
||||
#if !defined(__ppc__) && !defined(__ppc64__)
|
||||
if (!Value) return 64;
|
||||
if (!Value)
|
||||
return 64;
|
||||
#endif
|
||||
Count = __builtin_clzll(Value);
|
||||
#else
|
||||
#ifndef _MSC_VER
|
||||
unsigned Shift;
|
||||
if (sizeof(long) == sizeof(int64_t))
|
||||
{
|
||||
if (!Value) return 64;
|
||||
if (sizeof(long) == sizeof(int64_t)) {
|
||||
if (!Value)
|
||||
return 64;
|
||||
Count = 0;
|
||||
// bisection method for count leading zeros
|
||||
for (Shift = 64 >> 1; Shift; Shift >>= 1) {
|
||||
|
|
@ -155,8 +171,7 @@ static inline unsigned CountLeadingZeros_64(uint64_t Value) {
|
|||
Count |= Shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// get hi portion
|
||||
|
|
@ -170,7 +185,7 @@ static inline unsigned CountLeadingZeros_64(uint64_t Value) {
|
|||
// get lo portion
|
||||
uint32_t Lo = Lo_32(Value);
|
||||
// same as 32 bit value
|
||||
Count = CountLeadingZeros_32(Lo)+32;
|
||||
Count = CountLeadingZeros_32(Lo) + 32;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -181,7 +196,8 @@ static inline unsigned CountLeadingZeros_64(uint64_t Value) {
|
|||
/// of counting the number of ones from the most significant bit to the first
|
||||
/// zero bit (64 bit edition.)
|
||||
/// Returns 64 if the word is all ones.
|
||||
static inline unsigned CountLeadingOnes_64(uint64_t Value) {
|
||||
static inline unsigned CountLeadingOnes_64(uint64_t Value)
|
||||
{
|
||||
return CountLeadingZeros_64(~Value);
|
||||
}
|
||||
|
||||
|
|
@ -189,16 +205,17 @@ static inline unsigned CountLeadingOnes_64(uint64_t Value) {
|
|||
/// counting the number of zeros from the least significant bit to the first one
|
||||
/// bit. Ex. CountTrailingZeros_32(0xFF00FF00) == 8.
|
||||
/// Returns 32 if the word is zero.
|
||||
static inline unsigned CountTrailingZeros_32(uint32_t Value) {
|
||||
static inline unsigned CountTrailingZeros_32(uint32_t Value)
|
||||
{
|
||||
#if __GNUC__ >= 4
|
||||
return Value ? __builtin_ctz(Value) : 32;
|
||||
#else
|
||||
static const unsigned Mod37BitPosition[] = {
|
||||
32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13,
|
||||
4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
|
||||
5, 20, 8, 19, 18
|
||||
32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28,
|
||||
11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10,
|
||||
12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18
|
||||
};
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// MSVC warning C4146
|
||||
// return Mod37BitPosition[(-Value & Value) % 37];
|
||||
return Mod37BitPosition[((1 + ~Value) & Value) % 37];
|
||||
|
|
@ -207,13 +224,18 @@ static inline unsigned CountTrailingZeros_32(uint32_t Value) {
|
|||
|
||||
// Count trailing zeros as in:
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightParallel
|
||||
static inline unsigned CountTrailingZeros_8(uint8_t Value) {
|
||||
static inline unsigned CountTrailingZeros_8(uint8_t Value)
|
||||
{
|
||||
uint8_t c = 8;
|
||||
Value &= -((int8_t)Value);
|
||||
if (Value) c--;
|
||||
if (Value & 0x0F) c -= 4;
|
||||
if (Value & 0x33) c -= 2;
|
||||
if (Value & 0x55) c -= 1;
|
||||
if (Value)
|
||||
c--;
|
||||
if (Value & 0x0F)
|
||||
c -= 4;
|
||||
if (Value & 0x33)
|
||||
c -= 2;
|
||||
if (Value & 0x55)
|
||||
c -= 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +243,8 @@ static inline unsigned CountTrailingZeros_8(uint8_t Value) {
|
|||
/// counting the number of ones from the least significant bit to the first zero
|
||||
/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
|
||||
/// Returns 32 if the word is all ones.
|
||||
static inline unsigned CountTrailingOnes_32(uint32_t Value) {
|
||||
static inline unsigned CountTrailingOnes_32(uint32_t Value)
|
||||
{
|
||||
return CountTrailingZeros_32(~Value);
|
||||
}
|
||||
|
||||
|
|
@ -229,18 +252,19 @@ static inline unsigned CountTrailingOnes_32(uint32_t Value) {
|
|||
/// of counting the number of zeros from the least significant bit to the first
|
||||
/// one bit (64 bit edition.)
|
||||
/// Returns 64 if the word is zero.
|
||||
static inline unsigned CountTrailingZeros_64(uint64_t Value) {
|
||||
static inline unsigned CountTrailingZeros_64(uint64_t Value)
|
||||
{
|
||||
#if __GNUC__ >= 4
|
||||
return Value ? __builtin_ctzll(Value) : 64;
|
||||
#else
|
||||
static const unsigned Mod67Position[] = {
|
||||
64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54,
|
||||
4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55,
|
||||
47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27,
|
||||
29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
|
||||
7, 48, 35, 6, 34, 33, 0
|
||||
64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19,
|
||||
24, 54, 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51,
|
||||
25, 44, 55, 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53,
|
||||
63, 9, 61, 27, 29, 50, 43, 46, 31, 37, 21, 57, 52, 8,
|
||||
26, 49, 45, 36, 56, 7, 48, 35, 6, 34, 33, 0
|
||||
};
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// MSVC warning C4146
|
||||
// return Mod67Position[(-Value & Value) % 67];
|
||||
return Mod67Position[((1 + ~Value) & Value) % 67];
|
||||
|
|
@ -251,14 +275,16 @@ static inline unsigned CountTrailingZeros_64(uint64_t Value) {
|
|||
/// of counting the number of ones from the least significant bit to the first
|
||||
/// zero bit (64 bit edition.)
|
||||
/// Returns 64 if the word is all ones.
|
||||
static inline unsigned CountTrailingOnes_64(uint64_t Value) {
|
||||
static inline unsigned CountTrailingOnes_64(uint64_t Value)
|
||||
{
|
||||
return CountTrailingZeros_64(~Value);
|
||||
}
|
||||
|
||||
/// CountPopulation_32 - this function counts the number of set bits in a value.
|
||||
/// Ex. CountPopulation(0xF000F000) = 8
|
||||
/// Returns 0 if the word is zero.
|
||||
static inline unsigned CountPopulation_32(uint32_t Value) {
|
||||
static inline unsigned CountPopulation_32(uint32_t Value)
|
||||
{
|
||||
#if __GNUC__ >= 4
|
||||
return __builtin_popcount(Value);
|
||||
#else
|
||||
|
|
@ -270,7 +296,8 @@ static inline unsigned CountPopulation_32(uint32_t Value) {
|
|||
|
||||
/// CountPopulation_64 - this function counts the number of set bits in a value,
|
||||
/// (64 bit edition.)
|
||||
static inline unsigned CountPopulation_64(uint64_t Value) {
|
||||
static inline unsigned CountPopulation_64(uint64_t Value)
|
||||
{
|
||||
#if __GNUC__ >= 4
|
||||
return __builtin_popcountll(Value);
|
||||
#else
|
||||
|
|
@ -284,7 +311,8 @@ static inline unsigned CountPopulation_64(uint64_t Value) {
|
|||
/// Log2_32 - This function returns the floor log base 2 of the specified value,
|
||||
/// UINT_MAX if the value is zero. (32 bit edition.)
|
||||
/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
|
||||
static inline unsigned Log2_32(uint32_t Value) {
|
||||
static inline unsigned Log2_32(uint32_t Value)
|
||||
{
|
||||
if (Value == 0) {
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
|
@ -293,7 +321,8 @@ static inline unsigned Log2_32(uint32_t Value) {
|
|||
|
||||
/// Log2_64 - This function returns the floor log base 2 of the specified value,
|
||||
/// UINT_MAX if the value is zero. (64 bit edition.)
|
||||
static inline unsigned Log2_64(uint64_t Value) {
|
||||
static inline unsigned Log2_64(uint64_t Value)
|
||||
{
|
||||
if (Value == 0) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
|
@ -303,19 +332,22 @@ static inline unsigned Log2_64(uint64_t Value) {
|
|||
/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
|
||||
/// value, 32 if the value is zero. (32 bit edition).
|
||||
/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
|
||||
static inline unsigned Log2_32_Ceil(uint32_t Value) {
|
||||
return 32-CountLeadingZeros_32(Value-1);
|
||||
static inline unsigned Log2_32_Ceil(uint32_t Value)
|
||||
{
|
||||
return 32 - CountLeadingZeros_32(Value - 1);
|
||||
}
|
||||
|
||||
/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
|
||||
/// value, 64 if the value is zero. (64 bit edition.)
|
||||
static inline unsigned Log2_64_Ceil(uint64_t Value) {
|
||||
return 64-CountLeadingZeros_64(Value-1);
|
||||
static inline unsigned Log2_64_Ceil(uint64_t Value)
|
||||
{
|
||||
return 64 - CountLeadingZeros_64(Value - 1);
|
||||
}
|
||||
|
||||
/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
|
||||
/// values using Euclid's algorithm.
|
||||
static inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
|
||||
static inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B)
|
||||
{
|
||||
while (B) {
|
||||
uint64_t T = B;
|
||||
B = A % B;
|
||||
|
|
@ -326,7 +358,8 @@ static inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
|
|||
|
||||
/// BitsToDouble - This function takes a 64-bit integer and returns the bit
|
||||
/// equivalent double.
|
||||
static inline double BitsToDouble(uint64_t Bits) {
|
||||
static inline double BitsToDouble(uint64_t Bits)
|
||||
{
|
||||
union {
|
||||
uint64_t L;
|
||||
double D;
|
||||
|
|
@ -337,7 +370,8 @@ static inline double BitsToDouble(uint64_t Bits) {
|
|||
|
||||
/// BitsToFloat - This function takes a 32-bit integer and returns the bit
|
||||
/// equivalent float.
|
||||
static inline float BitsToFloat(uint32_t Bits) {
|
||||
static inline float BitsToFloat(uint32_t Bits)
|
||||
{
|
||||
union {
|
||||
uint32_t I;
|
||||
float F;
|
||||
|
|
@ -350,7 +384,8 @@ static inline float BitsToFloat(uint32_t Bits) {
|
|||
/// equivalent 64-bit integer. Note that copying doubles around
|
||||
/// changes the bits of NaNs on some hosts, notably x86, so this
|
||||
/// routine cannot be used if these bits are needed.
|
||||
static inline uint64_t DoubleToBits(double Double) {
|
||||
static inline uint64_t DoubleToBits(double Double)
|
||||
{
|
||||
union {
|
||||
uint64_t L;
|
||||
double D;
|
||||
|
|
@ -363,7 +398,8 @@ static inline uint64_t DoubleToBits(double Double) {
|
|||
/// equivalent 32-bit integer. Note that copying floats around
|
||||
/// changes the bits of NaNs on some hosts, notably x86, so this
|
||||
/// routine cannot be used if these bits are needed.
|
||||
static inline uint32_t FloatToBits(float Float) {
|
||||
static inline uint32_t FloatToBits(float Float)
|
||||
{
|
||||
union {
|
||||
uint32_t I;
|
||||
float F;
|
||||
|
|
@ -374,10 +410,11 @@ static inline uint32_t FloatToBits(float Float) {
|
|||
|
||||
/// MinAlign - A and B are either alignments or offsets. Return the minimum
|
||||
/// alignment that may be assumed after adding the two together.
|
||||
static inline uint64_t MinAlign(uint64_t A, uint64_t B) {
|
||||
static inline uint64_t MinAlign(uint64_t A, uint64_t B)
|
||||
{
|
||||
// The largest power of 2 that divides both A and B.
|
||||
//
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// MSVC warning C4146
|
||||
// return (A | B) & -(A | B);
|
||||
return (A | B) & (1 + ~(A | B));
|
||||
|
|
@ -385,7 +422,8 @@ static inline uint64_t MinAlign(uint64_t A, uint64_t B) {
|
|||
|
||||
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
|
||||
/// that is strictly greater than A. Returns zero on overflow.
|
||||
static inline uint64_t NextPowerOf2(uint64_t A) {
|
||||
static inline uint64_t NextPowerOf2(uint64_t A)
|
||||
{
|
||||
A |= (A >> 1);
|
||||
A |= (A >> 2);
|
||||
A |= (A >> 4);
|
||||
|
|
@ -404,21 +442,24 @@ static inline uint64_t NextPowerOf2(uint64_t A) {
|
|||
/// RoundUpToAlignment(17, 8) = 24
|
||||
/// RoundUpToAlignment(~0LL, 8) = 0
|
||||
/// \endcode
|
||||
static inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
|
||||
static inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
|
||||
{
|
||||
return ((Value + Align - 1) / Align) * Align;
|
||||
}
|
||||
|
||||
/// Returns the offset to the next integer (mod 2**64) that is greater than
|
||||
/// or equal to \p Value and is a multiple of \p Align. \p Align must be
|
||||
/// non-zero.
|
||||
static inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
|
||||
static inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
|
||||
{
|
||||
return RoundUpToAlignment(Value, Align) - Value;
|
||||
}
|
||||
|
||||
/// abs64 - absolute value of a 64-bit int. Not all environments support
|
||||
/// "abs" on whatever their name for the 64-bit int type is. The absolute
|
||||
/// value of the largest negative number is undefined, as with "abs".
|
||||
static inline int64_t abs64(int64_t x) {
|
||||
static inline int64_t abs64(int64_t x)
|
||||
{
|
||||
return (x < 0) ? -x : x;
|
||||
}
|
||||
|
||||
|
|
@ -426,7 +467,8 @@ static inline int64_t abs64(int64_t x) {
|
|||
/// Requires 0 < B <= 32.
|
||||
/// Note that this implementation relies on right shift of signed
|
||||
/// integers being an arithmetic shift.
|
||||
static inline int32_t SignExtend32(uint32_t X, unsigned B) {
|
||||
static inline int32_t SignExtend32(uint32_t X, unsigned B)
|
||||
{
|
||||
return (int32_t)(X << (32 - B)) >> (32 - B);
|
||||
}
|
||||
|
||||
|
|
@ -434,25 +476,29 @@ static inline int32_t SignExtend32(uint32_t X, unsigned B) {
|
|||
/// Requires 0 < B <= 64.
|
||||
/// Note that this implementation relies on right shift of signed
|
||||
/// integers being an arithmetic shift.
|
||||
static inline int64_t SignExtend64(uint64_t X, unsigned B) {
|
||||
static inline int64_t SignExtend64(uint64_t X, unsigned B)
|
||||
{
|
||||
return (int64_t)(X << (64 - B)) >> (64 - B);
|
||||
}
|
||||
|
||||
/// \brief Removes the rightmost bit of x and extends the field to the left with that
|
||||
/// bit to form a 64-bit quantity. The field is of size len
|
||||
static inline int64_t LowSignExtend64(uint64_t x, unsigned len) {
|
||||
return (x >> 1) - ((x & 1) << (len - 1));
|
||||
static inline int64_t LowSignExtend64(uint64_t x, unsigned len)
|
||||
{
|
||||
return (x >> 1) - ((x & 1) << (len - 1));
|
||||
}
|
||||
|
||||
/// \brief One extend number X starting at bit B and returns it as int32_t.
|
||||
/// Requires 0 < B <= 32.
|
||||
static inline int32_t OneExtend32(uint32_t X, unsigned B) {
|
||||
static inline int32_t OneExtend32(uint32_t X, unsigned B)
|
||||
{
|
||||
return (~0U << B) | X;
|
||||
}
|
||||
|
||||
/// \brief One extend number X starting at bit B and returns it as int64_t.
|
||||
/// Requires 0 < B <= 64.
|
||||
static inline int64_t OneExtend64(uint64_t X, unsigned B) {
|
||||
static inline int64_t OneExtend64(uint64_t X, unsigned B)
|
||||
{
|
||||
return (~0ULL << B) | X;
|
||||
}
|
||||
|
||||
|
|
@ -472,8 +518,9 @@ static inline unsigned int countLeadingZeros(int x)
|
|||
if (x < 0) {
|
||||
return 0;
|
||||
}
|
||||
for (i = bits; --i; ) {
|
||||
if (x == 0) break;
|
||||
for (i = bits; --i;) {
|
||||
if (x == 0)
|
||||
break;
|
||||
count--;
|
||||
x >>= 1;
|
||||
}
|
||||
|
|
@ -483,7 +530,7 @@ static inline unsigned int countLeadingZeros(int x)
|
|||
|
||||
/// \brief Get specified field from 32-bit instruction. Returns bits from the segment [from, to]
|
||||
/// The right most bit of insn is bit 31.
|
||||
static inline uint32_t get_insn_field(uint32_t insn, uint8_t from, uint8_t to)
|
||||
static inline uint32_t get_insn_field(uint32_t insn, uint8_t from, uint8_t to)
|
||||
{
|
||||
return insn >> (31 - to) & ((1 << (to - from + 1)) - 1);
|
||||
}
|
||||
|
|
@ -496,17 +543,17 @@ static inline uint32_t get_insn_field_r(uint32_t insn, uint8_t from, uint8_t to)
|
|||
}
|
||||
|
||||
/// \brief Get specified bit from 32-bit instruction
|
||||
static inline uint32_t get_insn_bit(uint32_t insn, uint8_t bit)
|
||||
static inline uint32_t get_insn_bit(uint32_t insn, uint8_t bit)
|
||||
{
|
||||
return get_insn_field(insn, bit, bit);
|
||||
}
|
||||
|
||||
/// \brief Create a bitmask with the N right-most bits set to 1, and all other
|
||||
/// bits set to 0. Only unsigned types are allowed.
|
||||
static inline uint32_t maskTrailingOnes32(uint32_t N)
|
||||
static inline uint32_t maskTrailingOnes32(uint32_t N)
|
||||
{
|
||||
const unsigned Bits = CHAR_BIT * sizeof(uint32_t);
|
||||
return N == 0 ? 0 : (((uint32_t) -1) >> (Bits - N));
|
||||
return N == 0 ? 0 : (((uint32_t)-1) >> (Bits - N));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
85
SStream.c
85
SStream.c
|
|
@ -37,7 +37,8 @@ void SStream_opt_unum(SStream *ss, bool print_unsigned_numbers)
|
|||
|
||||
/// Returns the a pointer to the internal string buffer of the stream.
|
||||
/// For reading only.
|
||||
const char *SStream_rbuf(const SStream *ss) {
|
||||
const char *SStream_rbuf(const SStream *ss)
|
||||
{
|
||||
assert(ss);
|
||||
return ss->buffer;
|
||||
}
|
||||
|
|
@ -47,7 +48,8 @@ const char *SStream_rbuf(const SStream *ss) {
|
|||
/// or NULL if no character was replaced.
|
||||
///
|
||||
/// It will never replace the final \0 byte in the stream buffer.
|
||||
const char *SStream_replc(const SStream *ss, char elem, char repl) {
|
||||
const char *SStream_replc(const SStream *ss, char elem, char repl)
|
||||
{
|
||||
assert(ss);
|
||||
char *found = strchr(ss->buffer, elem);
|
||||
if (!found || found == ss->buffer + (SSTREAM_BUF_LEN - 1)) {
|
||||
|
|
@ -60,7 +62,8 @@ const char *SStream_replc(const SStream *ss, char elem, char repl) {
|
|||
|
||||
/// Searches in the stream for the first (from the left) occurrence of @chr and replaces
|
||||
/// it with @rstr.
|
||||
void SStream_replc_str(SStream *ss, char chr, const char *rstr) {
|
||||
void SStream_replc_str(SStream *ss, char chr, const char *rstr)
|
||||
{
|
||||
assert(ss && rstr);
|
||||
char *found = strchr(ss->buffer, chr);
|
||||
if (!found || found == ss->buffer + (SSTREAM_BUF_LEN - 1)) {
|
||||
|
|
@ -78,7 +81,8 @@ void SStream_replc_str(SStream *ss, char chr, const char *rstr) {
|
|||
}
|
||||
|
||||
/// Removes the space characters '\t' and ' ' from the beginning of the stream buffer.
|
||||
void SStream_trimls(SStream *ss) {
|
||||
void SStream_trimls(SStream *ss)
|
||||
{
|
||||
assert(ss);
|
||||
size_t buf_off = 0;
|
||||
/// Remove leading spaces
|
||||
|
|
@ -86,7 +90,8 @@ void SStream_trimls(SStream *ss) {
|
|||
buf_off++;
|
||||
}
|
||||
if (buf_off > 0) {
|
||||
memmove(ss->buffer, ss->buffer + buf_off, SSTREAM_BUF_LEN - buf_off);
|
||||
memmove(ss->buffer, ss->buffer + buf_off,
|
||||
SSTREAM_BUF_LEN - buf_off);
|
||||
ss->index -= buf_off;
|
||||
}
|
||||
}
|
||||
|
|
@ -94,11 +99,16 @@ void SStream_trimls(SStream *ss) {
|
|||
/// Extract the mnemonic to @mnem_buf and the operand string into @op_str_buf from the stream buffer.
|
||||
/// The mnemonic is everything up until the first ' ' or '\t' character.
|
||||
/// The operand string is everything after the first ' ' or '\t' sequence.
|
||||
void SStream_extract_mnem_opstr(const SStream *ss, char *mnem_buf, size_t mnem_buf_size, char *op_str_buf, size_t op_str_buf_size) {
|
||||
assert(ss && mnem_buf && mnem_buf_size > 0 && op_str_buf && op_str_buf_size > 0);
|
||||
void SStream_extract_mnem_opstr(const SStream *ss, char *mnem_buf,
|
||||
size_t mnem_buf_size, char *op_str_buf,
|
||||
size_t op_str_buf_size)
|
||||
{
|
||||
assert(ss && mnem_buf && mnem_buf_size > 0 && op_str_buf &&
|
||||
op_str_buf_size > 0);
|
||||
size_t off = 0;
|
||||
// Copy all non space chars to as mnemonic.
|
||||
while (ss->buffer[off] && ss->buffer[off] != ' ' && ss->buffer[off] != '\t') {
|
||||
while (ss->buffer[off] && ss->buffer[off] != ' ' &&
|
||||
ss->buffer[off] != '\t') {
|
||||
if (off < mnem_buf_size - 1) {
|
||||
// Only copy if there is space left.
|
||||
mnem_buf[off] = ss->buffer[off];
|
||||
|
|
@ -112,7 +122,8 @@ void SStream_extract_mnem_opstr(const SStream *ss, char *mnem_buf, size_t mnem_b
|
|||
// Iterate until next non space char.
|
||||
do {
|
||||
off++;
|
||||
} while (ss->buffer[off] && (ss->buffer[off] == ' ' || ss->buffer[off] == '\t'));
|
||||
} while (ss->buffer[off] &&
|
||||
(ss->buffer[off] == ' ' || ss->buffer[off] == '\t'));
|
||||
|
||||
if (!ss->buffer[off]) {
|
||||
return;
|
||||
|
|
@ -141,7 +152,8 @@ void SStream_Flush(SStream *ss, FILE *file)
|
|||
/**
|
||||
* Open the output stream. Every write attempt is accepted again.
|
||||
*/
|
||||
void SStream_Open(SStream *ss) {
|
||||
void SStream_Open(SStream *ss)
|
||||
{
|
||||
assert(ss);
|
||||
ss->is_closed = false;
|
||||
}
|
||||
|
|
@ -149,7 +161,8 @@ void SStream_Open(SStream *ss) {
|
|||
/**
|
||||
* Closes the output stream. Every write attempt is ignored.
|
||||
*/
|
||||
void SStream_Close(SStream *ss) {
|
||||
void SStream_Close(SStream *ss)
|
||||
{
|
||||
assert(ss);
|
||||
ss->is_closed = true;
|
||||
}
|
||||
|
|
@ -164,7 +177,7 @@ void SStream_concat0(SStream *ss, const char *s)
|
|||
SSTREAM_RETURN_IF_CLOSED(ss);
|
||||
if (s[0] == '\0')
|
||||
return;
|
||||
unsigned int len = (unsigned int) strlen(s);
|
||||
unsigned int len = (unsigned int)strlen(s);
|
||||
|
||||
SSTREAM_OVERFLOW_CHECK(ss, len);
|
||||
|
||||
|
|
@ -216,7 +229,8 @@ void SStream_concat(SStream *ss, const char *fmt, ...)
|
|||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
|
||||
ret = cs_vsnprintf(ss->buffer + ss->index,
|
||||
sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
|
||||
va_end(ap);
|
||||
ss->index += ret;
|
||||
if (ss->markup_stream && ss->prefixed_by_markup) {
|
||||
|
|
@ -259,17 +273,19 @@ void printInt64(SStream *ss, int64_t val)
|
|||
SSTREAM_RETURN_IF_CLOSED(ss);
|
||||
if (val >= 0) {
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(ss, "0x%"PRIx64, val);
|
||||
SStream_concat(ss, "0x%" PRIx64, val);
|
||||
else
|
||||
SStream_concat(ss, "%"PRIu64, val);
|
||||
SStream_concat(ss, "%" PRIu64, val);
|
||||
} else {
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
if (val == INT64_MIN)
|
||||
SStream_concat(ss, "-0x%"PRIx64, (uint64_t) INT64_MAX + 1);
|
||||
SStream_concat(ss, "-0x%" PRIx64,
|
||||
(uint64_t)INT64_MAX + 1);
|
||||
else
|
||||
SStream_concat(ss, "-0x%"PRIx64, (uint64_t)-val);
|
||||
SStream_concat(ss, "-0x%" PRIx64,
|
||||
(uint64_t)-val);
|
||||
} else
|
||||
SStream_concat(ss, "-%"PRIu64, -val);
|
||||
SStream_concat(ss, "-%" PRIu64, -val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,9 +294,9 @@ void printUInt64(SStream *ss, uint64_t val)
|
|||
assert(ss);
|
||||
SSTREAM_RETURN_IF_CLOSED(ss);
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(ss, "0x%"PRIx64, val);
|
||||
SStream_concat(ss, "0x%" PRIx64, val);
|
||||
else
|
||||
SStream_concat(ss, "%"PRIu64, val);
|
||||
SStream_concat(ss, "%" PRIu64, val);
|
||||
}
|
||||
|
||||
// print number in decimal mode
|
||||
|
|
@ -314,18 +330,18 @@ void printUInt8(SStream *ss, uint8_t val)
|
|||
{
|
||||
assert(ss);
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(ss, "0x%"PRIx8, val);
|
||||
SStream_concat(ss, "0x%" PRIx8, val);
|
||||
else
|
||||
SStream_concat(ss, "%"PRIu8, val);
|
||||
SStream_concat(ss, "%" PRIu8, val);
|
||||
}
|
||||
|
||||
void printUInt16(SStream *ss, uint16_t val)
|
||||
{
|
||||
assert(ss);
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(ss, "0x%"PRIx16, val);
|
||||
SStream_concat(ss, "0x%" PRIx16, val);
|
||||
else
|
||||
SStream_concat(ss, "%"PRIu16, val);
|
||||
SStream_concat(ss, "%" PRIu16, val);
|
||||
}
|
||||
|
||||
void printInt8(SStream *ss, int8_t val)
|
||||
|
|
@ -344,7 +360,8 @@ void printInt8(SStream *ss, int8_t val)
|
|||
} else {
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
if (val == INT8_MIN)
|
||||
SStream_concat(ss, "-0x%" PRIx8, (uint8_t) INT8_MAX + 1);
|
||||
SStream_concat(ss, "-0x%" PRIx8,
|
||||
(uint8_t)INT8_MAX + 1);
|
||||
else
|
||||
SStream_concat(ss, "-0x%" PRIx8, (int8_t)-val);
|
||||
} else
|
||||
|
|
@ -368,9 +385,11 @@ void printInt16(SStream *ss, int16_t val)
|
|||
} else {
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
if (val == INT16_MIN)
|
||||
SStream_concat(ss, "-0x%" PRIx16, (uint16_t) INT16_MAX + 1);
|
||||
SStream_concat(ss, "-0x%" PRIx16,
|
||||
(uint16_t)INT16_MAX + 1);
|
||||
else
|
||||
SStream_concat(ss, "-0x%" PRIx16, (int16_t)-val);
|
||||
SStream_concat(ss, "-0x%" PRIx16,
|
||||
(int16_t)-val);
|
||||
} else
|
||||
SStream_concat(ss, "-%" PRIu16, -val);
|
||||
}
|
||||
|
|
@ -395,7 +414,6 @@ void printInt16HexOffset(SStream *ss, int16_t val)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void printInt32(SStream *ss, int32_t val)
|
||||
{
|
||||
assert(ss);
|
||||
|
|
@ -412,9 +430,11 @@ void printInt32(SStream *ss, int32_t val)
|
|||
} else {
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
if (val == INT32_MIN)
|
||||
SStream_concat(ss, "-0x%" PRIx32, (uint32_t) INT32_MAX + 1);
|
||||
SStream_concat(ss, "-0x%" PRIx32,
|
||||
(uint32_t)INT32_MAX + 1);
|
||||
else
|
||||
SStream_concat(ss, "-0x%" PRIx32, (int32_t)-val);
|
||||
SStream_concat(ss, "-0x%" PRIx32,
|
||||
(int32_t)-val);
|
||||
} else {
|
||||
SStream_concat(ss, "-%" PRIu32, (uint32_t)-val);
|
||||
}
|
||||
|
|
@ -491,10 +511,11 @@ void printExpr(SStream *ss, uint64_t val)
|
|||
{
|
||||
assert(ss);
|
||||
SSTREAM_RETURN_IF_CLOSED(ss);
|
||||
SStream_concat(ss, "%"PRIu64, val);
|
||||
SStream_concat(ss, "%" PRIu64, val);
|
||||
}
|
||||
|
||||
SStream *markup_OS(SStream *OS, SStreamMarkup style) {
|
||||
SStream *markup_OS(SStream *OS, SStreamMarkup style)
|
||||
{
|
||||
assert(OS);
|
||||
|
||||
if (OS->is_closed || !OS->markup_stream) {
|
||||
|
|
|
|||
24
SStream.h
24
SStream.h
|
|
@ -26,18 +26,18 @@ typedef struct SStream {
|
|||
} SStream;
|
||||
|
||||
#define SSTREAM_OVERFLOW_CHECK(OS, len) \
|
||||
do { \
|
||||
if (OS->index + len + 1 > SSTREAM_BUF_LEN) { \
|
||||
fprintf(stderr, "Buffer overflow caught!\n"); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
do { \
|
||||
if (OS->index + len + 1 > SSTREAM_BUF_LEN) { \
|
||||
fprintf(stderr, "Buffer overflow caught!\n"); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SSTREAM_RETURN_IF_CLOSED(OS) \
|
||||
do { \
|
||||
if (OS->is_closed) \
|
||||
return; \
|
||||
} while(0)
|
||||
do { \
|
||||
if (OS->is_closed) \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
void SStream_Init(SStream *ss);
|
||||
void SStream_opt_unum(SStream *ss, bool print_unsigned_numbers);
|
||||
|
|
@ -48,7 +48,9 @@ void SStream_replc_str(SStream *ss, char chr, const char *rstr);
|
|||
|
||||
const char *SStream_rbuf(const SStream *ss);
|
||||
|
||||
void SStream_extract_mnem_opstr(const SStream *ss, char *mnem_buf, size_t mnem_buf_size, char *op_str_buf, size_t op_str_buf_size);
|
||||
void SStream_extract_mnem_opstr(const SStream *ss, char *mnem_buf,
|
||||
size_t mnem_buf_size, char *op_str_buf,
|
||||
size_t op_str_buf_size);
|
||||
|
||||
void SStream_trimls(SStream *ss);
|
||||
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ static inline bool AArch64_AM_isValidDecodeLogicalImmediate(uint64_t val,
|
|||
if (regSize == 32 && N != 0) // undefined logical immediate encoding
|
||||
return false;
|
||||
int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
|
||||
if (len < 0) // undefined logical immediate encoding
|
||||
if (len < 0) // undefined logical immediate encoding
|
||||
return false;
|
||||
unsigned size = (1 << len);
|
||||
unsigned S = imms & (size - 1);
|
||||
|
|
|
|||
|
|
@ -353,7 +353,8 @@ static DecodeStatus getInstruction(csh handle, const uint8_t *Bytes,
|
|||
|
||||
// Table is indexed backwards
|
||||
const MCInstrDesc Desc =
|
||||
AArch64Descs.Insts[ARR_SIZE(AArch64Descs.Insts) - 1 - MCInst_getOpcode(MI)];
|
||||
AArch64Descs.Insts[ARR_SIZE(AArch64Descs.Insts) - 1 -
|
||||
MCInst_getOpcode(MI)];
|
||||
|
||||
// For Scalable Matrix Extension (SME) instructions that have an
|
||||
// implicit operand for the accumulator (ZA) or implicit immediate zero
|
||||
|
|
@ -414,7 +415,8 @@ DecodeStatus AArch64_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
|||
DecodeStatus Result = MCDisassembler_Fail;
|
||||
Result =
|
||||
getInstruction(handle, Bytes, ByteLen, MI, Size, Address, Info);
|
||||
MCInst_handleWriteback(MI, AArch64Descs.Insts, ARR_SIZE(AArch64Descs.Insts));
|
||||
MCInst_handleWriteback(MI, AArch64Descs.Insts,
|
||||
ARR_SIZE(AArch64Descs.Insts));
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
@ -1922,8 +1924,8 @@ static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn,
|
|||
static bool isInvalidPState(uint64_t Op1, uint64_t Op2)
|
||||
{
|
||||
return Op1 == 0 && (Op2 == 0 || // CFINV
|
||||
Op2 == 1 || // XAFlag
|
||||
Op2 == 2); // AXFlag
|
||||
Op2 == 1 || // XAFlag
|
||||
Op2 == 2); // AXFlag
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeSystemPStateImm0_15Instruction(MCInst *Inst,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
bool AArch64_getFeatureBits(unsigned int mode, unsigned int feature)
|
||||
{
|
||||
if (feature == AArch64_FeatureAMX || feature == AArch64_FeatureMUL53 ||
|
||||
feature == AArch64_FeatureAppleSys) {
|
||||
feature == AArch64_FeatureAppleSys) {
|
||||
return mode & CS_MODE_APPLE_PROPRIETARY;
|
||||
}
|
||||
// we support everything
|
||||
|
|
|
|||
|
|
@ -464,7 +464,8 @@ void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
|
|||
MCOperand_isExpr(MCInst_getOperand(MI, (1)))) {
|
||||
printUInt64Bang(O, MCInst_getOpVal(MI, 1));
|
||||
if (detail_is_set(MI) && useAliasDetails) {
|
||||
AArch64_set_detail_op_imm(MI, 1, AARCH64_OP_IMM, MCInst_getOpVal(MI, 1));
|
||||
AArch64_set_detail_op_imm(MI, 1, AARCH64_OP_IMM,
|
||||
MCInst_getOpVal(MI, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -472,7 +473,8 @@ void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
|
|||
MCOperand_isExpr(MCInst_getOperand(MI, (2)))) {
|
||||
printUInt64Bang(O, MCInst_getOpVal(MI, 2));
|
||||
if (detail_is_set(MI) && useAliasDetails) {
|
||||
AArch64_set_detail_op_imm(MI, 2, AARCH64_OP_IMM, MCInst_getOpVal(MI, 2));
|
||||
AArch64_set_detail_op_imm(MI, 2, AARCH64_OP_IMM,
|
||||
MCInst_getOpVal(MI, 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -640,10 +642,10 @@ bool printRangePrefetchAlias(MCInst *MI, SStream *O, const char *Annot)
|
|||
if (RPRFM) {
|
||||
SStream_concat0(O, RPRFM->Name);
|
||||
} else {
|
||||
printUInt32Bang(O, RPRFOp);
|
||||
SStream_concat(O, ", ");
|
||||
printUInt32Bang(O, RPRFOp);
|
||||
SStream_concat(O, ", ");
|
||||
}
|
||||
SStream_concat0(O, getRegisterName(Rm, AArch64_NoRegAltName));
|
||||
SStream_concat0(O, getRegisterName(Rm, AArch64_NoRegAltName));
|
||||
SStream_concat0(O, ", [");
|
||||
printOperand(MI, 1, O); // "Rn".
|
||||
SStream_concat0(O, "]");
|
||||
|
|
@ -1058,7 +1060,8 @@ void printPostIncOperand(MCInst *MI, unsigned OpNo, unsigned Imm, SStream *O)
|
|||
} else
|
||||
printRegName(O, Reg);
|
||||
} else
|
||||
CS_ASSERT_RET(0 && "unknown operand kind in printPostIncOperand64");
|
||||
CS_ASSERT_RET(0 &&
|
||||
"unknown operand kind in printPostIncOperand64");
|
||||
}
|
||||
|
||||
void printVRegOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
|
|
@ -1105,7 +1108,8 @@ void printAddSubImm(MCInst *MI, unsigned OpNum, SStream *O)
|
|||
SStream *O) \
|
||||
{ \
|
||||
AArch64_add_cs_detail_1( \
|
||||
MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, sizeof(T)); \
|
||||
MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
|
||||
sizeof(T)); \
|
||||
uint64_t Val = \
|
||||
MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
|
||||
SStream_concat(O, "%s", markup("<imm:")); \
|
||||
|
|
@ -1236,7 +1240,7 @@ void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind,
|
|||
SStream_concat1(O, '\0'); \
|
||||
} else \
|
||||
CS_ASSERT_RET((CHAR(Suffix) == '0') && \
|
||||
"Unsupported suffix size"); \
|
||||
"Unsupported suffix size"); \
|
||||
bool DoShift = ExtWidth != 8; \
|
||||
if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
|
||||
SStream_concat0(O, ", "); \
|
||||
|
|
@ -1286,8 +1290,9 @@ DEFINE_printRegWithShiftExtend(false, 128, x, 0);
|
|||
unsigned Reg = \
|
||||
MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
|
||||
if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
|
||||
CS_ASSERT_RET(0 && \
|
||||
"Unsupported predicate-as-counter register"); \
|
||||
CS_ASSERT_RET( \
|
||||
0 && \
|
||||
"Unsupported predicate-as-counter register"); \
|
||||
SStream_concat(O, "%s", "pn"); \
|
||||
printUInt32(O, (Reg - AArch64_PN0)); \
|
||||
switch (EltSize) { \
|
||||
|
|
@ -1768,7 +1773,7 @@ static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride /* = 1 */)
|
|||
size), \
|
||||
OpNum, size); \
|
||||
CS_ASSERT_RET((size == 64 || size == 32) && \
|
||||
"Template parameter must be either 32 or 64"); \
|
||||
"Template parameter must be either 32 or 64"); \
|
||||
unsigned Reg = \
|
||||
MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
|
||||
\
|
||||
|
|
@ -1790,8 +1795,9 @@ DEFINE_printGPRSeqPairsClassOperand(64);
|
|||
void CONCAT(printMatrixIndex, Scale)(MCInst * MI, unsigned OpNum, \
|
||||
SStream *O) \
|
||||
{ \
|
||||
AArch64_add_cs_detail_1(MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
|
||||
OpNum, Scale); \
|
||||
AArch64_add_cs_detail_1( \
|
||||
MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
|
||||
OpNum, Scale); \
|
||||
printInt64(O, Scale *MCOperand_getImm( \
|
||||
MCInst_getOperand(MI, (OpNum)))); \
|
||||
}
|
||||
|
|
@ -2085,18 +2091,19 @@ void printAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
|
|||
printUInt64Bang(O, MCOperand_getImm(Op));
|
||||
}
|
||||
|
||||
void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O) {
|
||||
void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
|
||||
{
|
||||
AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AdrAdrpLabel, OpNum);
|
||||
MCOperand *Op = MCInst_getOperand(MI, (OpNum));
|
||||
|
||||
// If the label has already been resolved to an immediate offset (say, when
|
||||
// we're running the disassembler), just print the immediate.
|
||||
// If the label has already been resolved to an immediate offset (say, when
|
||||
// we're running the disassembler), just print the immediate.
|
||||
if (MCOperand_isImm(Op)) {
|
||||
int64_t Offset = MCOperand_getImm(Op);
|
||||
if (MCInst_getOpcode(MI) == AArch64_ADRP) {
|
||||
Offset = Offset * 4096;
|
||||
Address = Address & -4096;
|
||||
}
|
||||
if (MCInst_getOpcode(MI) == AArch64_ADRP) {
|
||||
Offset = Offset * 4096;
|
||||
Address = Address & -4096;
|
||||
}
|
||||
SStream_concat0(O, markup(">"));
|
||||
if (MI->csh->PrintBranchImmAsAddress)
|
||||
printUInt64(O, (Address + Offset));
|
||||
|
|
@ -2104,8 +2111,8 @@ void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
|
|||
printUInt64Bang(O, Offset);
|
||||
}
|
||||
SStream_concat0(O, markup(">"));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
printUInt64Bang(O, MCOperand_getImm(Op));
|
||||
}
|
||||
|
|
@ -2115,7 +2122,8 @@ void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
|
|||
/// https://github.com/AsahiLinux/docs/blob/main/docs/hw/cpu/apple-instructions.md
|
||||
void printAppleSysBarrierOption(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
{
|
||||
AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AppleSysBarrierOption, OpNo);
|
||||
AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AppleSysBarrierOption,
|
||||
OpNo);
|
||||
unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
|
||||
switch (Val) {
|
||||
default:
|
||||
|
|
@ -2428,7 +2436,8 @@ DEFINE_isSignedType(uint64_t);
|
|||
SStream *O) \
|
||||
{ \
|
||||
AArch64_add_cs_detail_1( \
|
||||
MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
|
||||
MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
|
||||
sizeof(T)); \
|
||||
unsigned UnscaledVal = \
|
||||
MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
|
||||
unsigned Shift = \
|
||||
|
|
|
|||
|
|
@ -76,9 +76,9 @@ void printPostIncOperand(MCInst *MI, unsigned OpNo, unsigned Imm, SStream *O);
|
|||
static inline void CONCAT(printPostIncOperand, Amount)( \
|
||||
MCInst * MI, unsigned OpNo, SStream *O) \
|
||||
{ \
|
||||
AArch64_add_cs_detail_1(MI, \
|
||||
CONCAT(AArch64_OP_GROUP_PostIncOperand, Amount), \
|
||||
OpNo, Amount); \
|
||||
AArch64_add_cs_detail_1( \
|
||||
MI, CONCAT(AArch64_OP_GROUP_PostIncOperand, Amount), \
|
||||
OpNo, Amount); \
|
||||
printPostIncOperand(MI, OpNo, Amount, O); \
|
||||
}
|
||||
DEFINE_printPostIncOperand(64);
|
||||
|
|
@ -182,9 +182,9 @@ void printAMIndexedWB(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O);
|
|||
static inline void CONCAT(printUImm12Offset, Scale)( \
|
||||
MCInst * MI, unsigned OpNum, SStream *O) \
|
||||
{ \
|
||||
AArch64_add_cs_detail_1(MI, \
|
||||
CONCAT(AArch64_OP_GROUP_UImm12Offset, Scale), \
|
||||
OpNum, Scale); \
|
||||
AArch64_add_cs_detail_1( \
|
||||
MI, CONCAT(AArch64_OP_GROUP_UImm12Offset, Scale), \
|
||||
OpNum, Scale); \
|
||||
printUImm12Offset(MI, OpNum, Scale, O); \
|
||||
}
|
||||
DEFINE_printUImm12Offset(1);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
|
||||
#define CHAR(c) #c[0]
|
||||
|
||||
static float aarch64_exact_fp_to_fp(aarch64_exactfpimm exact) {
|
||||
static float aarch64_exact_fp_to_fp(aarch64_exactfpimm exact)
|
||||
{
|
||||
switch (exact) {
|
||||
default:
|
||||
CS_ASSERT(0 && "Not handled.");
|
||||
|
|
@ -104,7 +105,6 @@ void AArch64_init_mri(MCRegisterInfo *MRI)
|
|||
ARR_SIZE(AArch64SubRegIdxLists), 0);
|
||||
}
|
||||
|
||||
|
||||
/// Sets up a new SME matrix operand at the currently active detail operand.
|
||||
static void setup_sme_operand(MCInst *MI)
|
||||
{
|
||||
|
|
@ -115,9 +115,12 @@ static void setup_sme_operand(MCInst *MI)
|
|||
AArch64_get_detail_op(MI, 0)->sme.type = AARCH64_SME_OP_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.tile = AARCH64_REG_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_reg = AARCH64_REG_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm = AARCH64_SLICE_IMM_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.first = AARCH64_SLICE_IMM_RANGE_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.offset = AARCH64_SLICE_IMM_RANGE_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm =
|
||||
AARCH64_SLICE_IMM_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.first =
|
||||
AARCH64_SLICE_IMM_RANGE_INVALID;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.offset =
|
||||
AARCH64_SLICE_IMM_RANGE_INVALID;
|
||||
}
|
||||
|
||||
static void setup_pred_operand(MCInst *MI)
|
||||
|
|
@ -179,7 +182,8 @@ void AArch64_add_vas(MCInst *MI, const SStream *OS)
|
|||
if (AArch64_get_detail(MI)->op_count == 0) {
|
||||
return;
|
||||
}
|
||||
if (MCInst_getOpcode(MI) == AArch64_MUL53HI || MCInst_getOpcode(MI) == AArch64_MUL53LO) {
|
||||
if (MCInst_getOpcode(MI) == AArch64_MUL53HI ||
|
||||
MCInst_getOpcode(MI) == AArch64_MUL53LO) {
|
||||
// Proprietary Apple instrucions.
|
||||
AArch64_get_detail(MI)->operands[0].vas = AARCH64LAYOUT_VL_2D;
|
||||
AArch64_get_detail(MI)->operands[1].vas = AARCH64LAYOUT_VL_2D;
|
||||
|
|
@ -375,7 +379,8 @@ static void AArch64_check_updates_flags(MCInst *MI)
|
|||
#endif // CAPSTONE_DIET
|
||||
}
|
||||
|
||||
static aarch64_shifter id_to_shifter(unsigned Opcode) {
|
||||
static aarch64_shifter id_to_shifter(unsigned Opcode)
|
||||
{
|
||||
switch (Opcode) {
|
||||
default:
|
||||
return AARCH64_SFT_INVALID;
|
||||
|
|
@ -411,7 +416,8 @@ static void add_non_alias_details(MCInst *MI)
|
|||
if (AArch64_get_detail(MI)->op_count != 3) {
|
||||
return;
|
||||
}
|
||||
CS_ASSERT_RET(AArch64_get_detail_op(MI, -1)->type == AARCH64_OP_REG);
|
||||
CS_ASSERT_RET(AArch64_get_detail_op(MI, -1)->type ==
|
||||
AARCH64_OP_REG);
|
||||
|
||||
// The shift by register instructions don't set the shift value properly.
|
||||
// Correct it here.
|
||||
|
|
@ -540,70 +546,74 @@ static void add_non_alias_details(MCInst *MI)
|
|||
}
|
||||
|
||||
#define ADD_ZA0_S \
|
||||
{ aarch64_op_sme za0_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS0, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za0_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
{ \
|
||||
aarch64_op_sme za0_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS0, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za0_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
#define ADD_ZA1_S \
|
||||
{ aarch64_op_sme za1_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS1, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za1_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
{ \
|
||||
aarch64_op_sme za1_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS1, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za1_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
#define ADD_ZA2_S \
|
||||
{ aarch64_op_sme za2_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS2, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za2_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
{ \
|
||||
aarch64_op_sme za2_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS2, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za2_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
#define ADD_ZA3_S \
|
||||
{ aarch64_op_sme za3_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS3, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za3_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
{ \
|
||||
aarch64_op_sme za3_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZAS3, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za3_op); \
|
||||
AArch64_get_detail_op(MI, -1)->vas = AARCH64LAYOUT_VL_S; \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
#define ADD_ZA \
|
||||
{ aarch64_op_sme za_op = \
|
||||
{ \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZA, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za_op); \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
{ \
|
||||
aarch64_op_sme za_op = { \
|
||||
.type = AARCH64_SME_OP_TILE, \
|
||||
.tile = AARCH64_REG_ZA, \
|
||||
.slice_reg = AARCH64_REG_INVALID, \
|
||||
.slice_offset = { -1 }, \
|
||||
.has_range_offset = false, \
|
||||
.is_vertical = false, \
|
||||
}; \
|
||||
AArch64_insert_detail_op_sme(MI, -1, za_op); \
|
||||
AArch64_get_detail_op(MI, -1)->access = CS_AC_WRITE; \
|
||||
}
|
||||
|
||||
static void AArch64_add_not_defined_ops(MCInst *MI, const SStream *OS)
|
||||
{
|
||||
|
|
@ -625,10 +635,14 @@ static void AArch64_add_not_defined_ops(MCInst *MI, const SStream *OS)
|
|||
}
|
||||
// The ROR alias doesn't set the shift value properly.
|
||||
// Correct it here.
|
||||
bool reg_shift = AArch64_get_detail_op(MI, -1)->type == AARCH64_OP_REG;
|
||||
uint64_t shift = reg_shift ? AArch64_get_detail_op(MI, -1)->reg : AArch64_get_detail_op(MI, -1)->imm;
|
||||
bool reg_shift = AArch64_get_detail_op(MI, -1)->type ==
|
||||
AARCH64_OP_REG;
|
||||
uint64_t shift = reg_shift ?
|
||||
AArch64_get_detail_op(MI, -1)->reg :
|
||||
AArch64_get_detail_op(MI, -1)->imm;
|
||||
cs_aarch64_op *op1 = AArch64_get_detail_op(MI, -2);
|
||||
op1->shift.type = reg_shift ? AARCH64_SFT_ROR_REG : AARCH64_SFT_ROR;
|
||||
op1->shift.type = reg_shift ? AARCH64_SFT_ROR_REG :
|
||||
AARCH64_SFT_ROR;
|
||||
op1->shift.value = shift;
|
||||
AArch64_dec_op_count(MI);
|
||||
break;
|
||||
|
|
@ -676,7 +690,7 @@ static void AArch64_add_not_defined_ops(MCInst *MI, const SStream *OS)
|
|||
sysop.alias.svcr = AARCH64_SVCR_SVCRZA;
|
||||
sysop.sub_type = AARCH64_OP_SVCR;
|
||||
AArch64_insert_detail_op_sys(MI, -1, sysop,
|
||||
AARCH64_OP_SYSALIAS);
|
||||
AARCH64_OP_SYSALIAS);
|
||||
return;
|
||||
}
|
||||
disp_off = strstr(OS->buffer, "smstart\tsm");
|
||||
|
|
@ -685,7 +699,7 @@ static void AArch64_add_not_defined_ops(MCInst *MI, const SStream *OS)
|
|||
sysop.alias.svcr = AARCH64_SVCR_SVCRSM;
|
||||
sysop.sub_type = AARCH64_OP_SVCR;
|
||||
AArch64_insert_detail_op_sys(MI, -1, sysop,
|
||||
AARCH64_OP_SYSALIAS);
|
||||
AARCH64_OP_SYSALIAS);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
@ -701,8 +715,7 @@ static void AArch64_add_not_defined_ops(MCInst *MI, const SStream *OS)
|
|||
}
|
||||
disp_off = strstr(OS->buffer, "{za1.h}");
|
||||
if (disp_off) {
|
||||
aarch64_op_sme op =
|
||||
{
|
||||
aarch64_op_sme op = {
|
||||
.type = AARCH64_SME_OP_TILE,
|
||||
.tile = AARCH64_REG_ZAH1,
|
||||
.slice_reg = AARCH64_REG_INVALID,
|
||||
|
|
@ -717,8 +730,7 @@ static void AArch64_add_not_defined_ops(MCInst *MI, const SStream *OS)
|
|||
}
|
||||
disp_off = strstr(OS->buffer, "{za0.h}");
|
||||
if (disp_off) {
|
||||
aarch64_op_sme op =
|
||||
{
|
||||
aarch64_op_sme op = {
|
||||
.type = AARCH64_SME_OP_TILE,
|
||||
.tile = AARCH64_REG_ZAH0,
|
||||
.slice_reg = AARCH64_REG_INVALID,
|
||||
|
|
@ -821,9 +833,8 @@ bool AArch64_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
|||
void *info)
|
||||
{
|
||||
AArch64_init_cs_detail(MI);
|
||||
DecodeStatus Result = AArch64_LLVM_getInstruction(handle, code, code_len, MI,
|
||||
size, address,
|
||||
info);
|
||||
DecodeStatus Result = AArch64_LLVM_getInstruction(
|
||||
handle, code, code_len, MI, size, address, info);
|
||||
AArch64_set_instr_map_data(MI);
|
||||
if (Result == MCDisassembler_SoftFail) {
|
||||
MCInst_setSoftFail(MI);
|
||||
|
|
@ -887,10 +898,12 @@ static void AArch64_add_cs_groups(MCInst *MI)
|
|||
}
|
||||
}
|
||||
|
||||
static void AArch64_correct_mem_access(MCInst *MI) {
|
||||
static void AArch64_correct_mem_access(MCInst *MI)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
cs_ac_type access = aarch64_insns[MI->Opcode].suppl_info.aarch64.mem_acc;
|
||||
cs_ac_type access =
|
||||
aarch64_insns[MI->Opcode].suppl_info.aarch64.mem_acc;
|
||||
if (access == CS_AC_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1064,40 +1077,46 @@ void AArch64_reg_access(const cs_insn *insn, cs_regs regs_read,
|
|||
}
|
||||
break;
|
||||
case AARCH64_OP_SME:
|
||||
if ((op->access & CS_AC_READ) &&
|
||||
(op->sme.tile != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_read, read_count, op->sme.tile)) {
|
||||
regs_read[read_count] = (uint16_t)op->sme.tile;
|
||||
read_count++;
|
||||
}
|
||||
if ((op->access & CS_AC_WRITE) &&
|
||||
(op->sme.tile != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_write, write_count, op->sme.tile)) {
|
||||
regs_write[write_count] = (uint16_t)op->sme.tile;
|
||||
write_count++;
|
||||
}
|
||||
if ((op->sme.slice_reg != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_read, read_count, op->sme.slice_reg)) {
|
||||
regs_read[read_count] = (uint16_t)op->sme.slice_reg;
|
||||
read_count++;
|
||||
}
|
||||
break;
|
||||
if ((op->access & CS_AC_READ) &&
|
||||
(op->sme.tile != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_read, read_count, op->sme.tile)) {
|
||||
regs_read[read_count] = (uint16_t)op->sme.tile;
|
||||
read_count++;
|
||||
}
|
||||
if ((op->access & CS_AC_WRITE) &&
|
||||
(op->sme.tile != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_write, write_count, op->sme.tile)) {
|
||||
regs_write[write_count] =
|
||||
(uint16_t)op->sme.tile;
|
||||
write_count++;
|
||||
}
|
||||
if ((op->sme.slice_reg != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_read, read_count,
|
||||
op->sme.slice_reg)) {
|
||||
regs_read[read_count] =
|
||||
(uint16_t)op->sme.slice_reg;
|
||||
read_count++;
|
||||
}
|
||||
break;
|
||||
case AARCH64_OP_PRED:
|
||||
if ((op->access & CS_AC_READ) &&
|
||||
(op->pred.reg != AARCH64_REG_INVALID) &&
|
||||
(op->pred.reg != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_read, read_count, op->pred.reg)) {
|
||||
regs_read[read_count] = (uint16_t)op->pred.reg;
|
||||
read_count++;
|
||||
}
|
||||
if ((op->access & CS_AC_WRITE) &&
|
||||
(op->pred.reg != AARCH64_REG_INVALID) &&
|
||||
(op->pred.reg != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_write, write_count, op->pred.reg)) {
|
||||
regs_write[write_count] = (uint16_t)op->pred.reg;
|
||||
regs_write[write_count] =
|
||||
(uint16_t)op->pred.reg;
|
||||
write_count++;
|
||||
}
|
||||
if ((op->pred.vec_select != AARCH64_REG_INVALID) &&
|
||||
!arr_exist(regs_read, read_count, op->pred.vec_select)) {
|
||||
regs_read[read_count] = (uint16_t)op->pred.vec_select;
|
||||
!arr_exist(regs_read, read_count,
|
||||
op->pred.vec_select)) {
|
||||
regs_read[read_count] =
|
||||
(uint16_t)op->pred.vec_select;
|
||||
read_count++;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1105,8 +1124,10 @@ void AArch64_reg_access(const cs_insn *insn, cs_regs regs_read,
|
|||
break;
|
||||
}
|
||||
if (op->shift.type >= AARCH64_SFT_LSL_REG) {
|
||||
if (!arr_exist(regs_read, read_count, op->shift.value)) {
|
||||
regs_read[read_count] = (uint16_t)op->shift.value;
|
||||
if (!arr_exist(regs_read, read_count,
|
||||
op->shift.value)) {
|
||||
regs_read[read_count] =
|
||||
(uint16_t)op->shift.value;
|
||||
read_count++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1378,7 +1399,7 @@ static bool add_cs_detail_begin(MCInst *MI, unsigned op_num)
|
|||
/// This function handles operands which's original printer function has no
|
||||
/// specialities.
|
||||
void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum)
|
||||
unsigned OpNum)
|
||||
{
|
||||
if (!add_cs_detail_begin(MI, OpNum))
|
||||
return;
|
||||
|
|
@ -1431,8 +1452,9 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
(MI->address & -4) + Offset);
|
||||
} else {
|
||||
// Expression
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
AArch64_set_detail_op_imm(
|
||||
MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1440,27 +1462,30 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
if (MCOperand_isImm(MCInst_getOperand(MI, OpNum))) {
|
||||
int64_t Offset = MCInst_getOpVal(MI, OpNum) * 4096;
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
(MI->address & -4096) + Offset);
|
||||
(MI->address & -4096) +
|
||||
Offset);
|
||||
} else {
|
||||
// Expression
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
AArch64_set_detail_op_imm(
|
||||
MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AArch64_OP_GROUP_AdrAdrpLabel: {
|
||||
if (!MCOperand_isImm(MCInst_getOperand(MI, OpNum))) {
|
||||
// Expression
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
AArch64_set_detail_op_imm(
|
||||
MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
break;
|
||||
}
|
||||
int64_t Offset = MCInst_getOpVal(MI, OpNum);
|
||||
uint64_t Address = MI->address;
|
||||
if (MCInst_getOpcode(MI) == AArch64_ADRP) {
|
||||
Offset = Offset * 4096;
|
||||
Address = Address & -4096;
|
||||
}
|
||||
if (MCInst_getOpcode(MI) == AArch64_ADRP) {
|
||||
Offset = Offset * 4096;
|
||||
Address = Address & -4096;
|
||||
}
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
Address + Offset);
|
||||
break;
|
||||
|
|
@ -1472,8 +1497,9 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
MI->address + Offset);
|
||||
} else {
|
||||
// Expression
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
AArch64_set_detail_op_imm(
|
||||
MI, OpNum, AARCH64_OP_IMM,
|
||||
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1499,7 +1525,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
const AArch64DBnXS_DBnXS *DB =
|
||||
AArch64DBnXS_lookupDBnXSByEncoding(Val);
|
||||
if (DB)
|
||||
sysop.imm.dbnxs = (aarch64_dbnxs) DB->SysImm.dbnxs;
|
||||
sysop.imm.dbnxs = (aarch64_dbnxs)DB->SysImm.dbnxs;
|
||||
else
|
||||
sysop.imm.raw_val = Val;
|
||||
sysop.sub_type = AARCH64_OP_DBNXS;
|
||||
|
|
@ -1522,7 +1548,8 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
const AArch64ISB_ISB *ISB =
|
||||
AArch64ISB_lookupISBByEncoding(Val);
|
||||
if (ISB)
|
||||
sysop.alias.isb = (aarch64_isb) ISB->SysAlias.isb;
|
||||
sysop.alias.isb =
|
||||
(aarch64_isb)ISB->SysAlias.isb;
|
||||
else
|
||||
sysop.alias.raw_val = Val;
|
||||
sysop.sub_type = AARCH64_OP_ISB;
|
||||
|
|
@ -1532,7 +1559,8 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
const AArch64TSB_TSB *TSB =
|
||||
AArch64TSB_lookupTSBByEncoding(Val);
|
||||
if (TSB)
|
||||
sysop.alias.tsb = (aarch64_tsb) TSB->SysAlias.tsb;
|
||||
sysop.alias.tsb =
|
||||
(aarch64_tsb)TSB->SysAlias.tsb;
|
||||
else
|
||||
sysop.alias.raw_val = Val;
|
||||
sysop.sub_type = AARCH64_OP_TSB;
|
||||
|
|
@ -1542,7 +1570,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
const AArch64DB_DB *DB =
|
||||
AArch64DB_lookupDBByEncoding(Val);
|
||||
if (DB)
|
||||
sysop.alias.db = (aarch64_db) DB->SysAlias.db;
|
||||
sysop.alias.db = (aarch64_db)DB->SysAlias.db;
|
||||
else
|
||||
sysop.alias.raw_val = Val;
|
||||
sysop.sub_type = AARCH64_OP_DB;
|
||||
|
|
@ -1557,7 +1585,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
const AArch64BTIHint_BTI *BTI =
|
||||
AArch64BTIHint_lookupBTIByEncoding(btihintop);
|
||||
if (BTI)
|
||||
sysop.alias.bti = (aarch64_bti) BTI->SysAlias.bti;
|
||||
sysop.alias.bti = (aarch64_bti)BTI->SysAlias.bti;
|
||||
else
|
||||
sysop.alias.raw_val = btihintop;
|
||||
sysop.sub_type = AARCH64_OP_BTI;
|
||||
|
|
@ -1601,8 +1629,8 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
break;
|
||||
case AArch64_OP_GROUP_ImplicitlyTypedVectorList:
|
||||
// The TypedVectorList implements the logic of implicitly typed operand.
|
||||
AArch64_add_cs_detail_2(MI, AArch64_OP_GROUP_TypedVectorList_0_b, OpNum,
|
||||
0, 0);
|
||||
AArch64_add_cs_detail_2(
|
||||
MI, AArch64_OP_GROUP_TypedVectorList_0_b, OpNum, 0, 0);
|
||||
break;
|
||||
case AArch64_OP_GROUP_InverseCondCode: {
|
||||
AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(
|
||||
|
|
@ -1638,7 +1666,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
AArch64_set_detail_op_sme(MI, OpNum,
|
||||
AARCH64_SME_MATRIX_TILE_LIST,
|
||||
AARCH64LAYOUT_VL_D,
|
||||
(int) (AARCH64_REG_ZAD0 + I));
|
||||
(int)(AARCH64_REG_ZAD0 + I));
|
||||
AArch64_inc_op_count(MI);
|
||||
}
|
||||
AArch64_get_detail(MI)->is_doing_sme = false;
|
||||
|
|
@ -1663,7 +1691,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
aarch64_sysop sysop = { 0 };
|
||||
// If Reg is NULL it is a generic system register.
|
||||
if (Reg)
|
||||
sysop.reg.sysreg = (aarch64_sysreg) Reg->SysReg.sysreg;
|
||||
sysop.reg.sysreg = (aarch64_sysreg)Reg->SysReg.sysreg;
|
||||
else {
|
||||
sysop.reg.raw_val = Val;
|
||||
}
|
||||
|
|
@ -1681,7 +1709,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
AArch64PSBHint_lookupPSBByEncoding(psbhintop);
|
||||
aarch64_sysop sysop = { 0 };
|
||||
if (PSB)
|
||||
sysop.alias.psb = (aarch64_psb) PSB->SysAlias.psb;
|
||||
sysop.alias.psb = (aarch64_psb)PSB->SysAlias.psb;
|
||||
else
|
||||
sysop.alias.raw_val = psbhintop;
|
||||
sysop.sub_type = AARCH64_OP_PSB;
|
||||
|
|
@ -1695,7 +1723,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
AArch64PRFM_lookupPRFMByEncoding(prfop);
|
||||
aarch64_sysop sysop = { 0 };
|
||||
if (PRFM)
|
||||
sysop.alias.prfm = (aarch64_prfm) PRFM->SysAlias.prfm;
|
||||
sysop.alias.prfm = (aarch64_prfm)PRFM->SysAlias.prfm;
|
||||
else
|
||||
sysop.alias.raw_val = prfop;
|
||||
sysop.sub_type = AARCH64_OP_PRFM;
|
||||
|
|
@ -1732,7 +1760,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
AArch64SVCR_lookupSVCRByEncoding(svcrop);
|
||||
aarch64_sysop sysop = { 0 };
|
||||
if (SVCR)
|
||||
sysop.alias.svcr = (aarch64_svcr) SVCR->SysAlias.svcr;
|
||||
sysop.alias.svcr = (aarch64_svcr)SVCR->SysAlias.svcr;
|
||||
else
|
||||
sysop.alias.raw_val = svcrop;
|
||||
sysop.sub_type = AARCH64_OP_SVCR;
|
||||
|
|
@ -1745,7 +1773,8 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
const AArch64SVEPredPattern_SVEPREDPAT *Pat =
|
||||
AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val);
|
||||
if (!Pat) {
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, Val);
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
Val);
|
||||
break;
|
||||
}
|
||||
aarch64_sysop sysop = { 0 };
|
||||
|
|
@ -1825,7 +1854,7 @@ void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
|||
/// This function handles operands which original printer function is a template
|
||||
/// with one argument.
|
||||
void AArch64_add_cs_detail_1(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum, uint64_t temp_arg_0)
|
||||
unsigned OpNum, uint64_t temp_arg_0)
|
||||
{
|
||||
if (!add_cs_detail_begin(MI, OpNum))
|
||||
return;
|
||||
|
|
@ -1866,22 +1895,23 @@ void AArch64_add_cs_detail_1(MCInst *MI, aarch64_op_group op_group,
|
|||
break;
|
||||
}
|
||||
|
||||
#define SCALE_SET(T) \
|
||||
do { \
|
||||
T Val; \
|
||||
if (CHAR(T) == 'i') /* Signed */ \
|
||||
Val = (int8_t)UnscaledVal * \
|
||||
(1 << AArch64_AM_getShiftValue(Shift)); \
|
||||
else \
|
||||
Val = (uint8_t)UnscaledVal * \
|
||||
(1 << AArch64_AM_getShiftValue(Shift)); \
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, Val); \
|
||||
} while (0)
|
||||
#define SCALE_SET(T) \
|
||||
do { \
|
||||
T Val; \
|
||||
if (CHAR(T) == 'i') /* Signed */ \
|
||||
Val = (int8_t)UnscaledVal * \
|
||||
(1 << AArch64_AM_getShiftValue(Shift)); \
|
||||
else \
|
||||
Val = (uint8_t)UnscaledVal * \
|
||||
(1 << AArch64_AM_getShiftValue(Shift)); \
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, Val); \
|
||||
} while (0)
|
||||
|
||||
switch (op_group) {
|
||||
default:
|
||||
CS_ASSERT_RET(0 &&
|
||||
"Operand group for Imm8OptLsl not handled.");
|
||||
CS_ASSERT_RET(
|
||||
0 &&
|
||||
"Operand group for Imm8OptLsl not handled.");
|
||||
case AArch64_OP_GROUP_Imm8OptLsl_int16_t: {
|
||||
SCALE_SET(int16_t);
|
||||
break;
|
||||
|
|
@ -1951,20 +1981,21 @@ void AArch64_add_cs_detail_1(MCInst *MI, aarch64_op_group op_group,
|
|||
case AArch64_OP_GROUP_MatrixIndex_1:
|
||||
case AArch64_OP_GROUP_MatrixIndex_8: {
|
||||
unsigned scale = temp_arg_0;
|
||||
if (AArch64_get_detail_op(MI, 0)->type ==
|
||||
AARCH64_OP_SME) {
|
||||
// The index is part of an SME matrix
|
||||
AArch64_set_detail_op_sme(MI, OpNum,
|
||||
AARCH64_SME_MATRIX_SLICE_OFF,
|
||||
AARCH64LAYOUT_INVALID,
|
||||
(uint32_t) (MCInst_getOpVal(MI, OpNum) * scale));
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) {
|
||||
if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME) {
|
||||
// The index is part of an SME matrix
|
||||
AArch64_set_detail_op_sme(
|
||||
MI, OpNum, AARCH64_SME_MATRIX_SLICE_OFF,
|
||||
AARCH64LAYOUT_INVALID,
|
||||
(uint32_t)(MCInst_getOpVal(MI, OpNum) * scale));
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type ==
|
||||
AARCH64_OP_PRED) {
|
||||
// The index is part of a predicate
|
||||
AArch64_set_detail_op_pred(MI, OpNum);
|
||||
} else {
|
||||
// The index is used for an SVE2 instruction.
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
scale * MCInst_getOpVal(MI, OpNum));
|
||||
AArch64_set_detail_op_imm(
|
||||
MI, OpNum, AARCH64_OP_IMM,
|
||||
scale * MCInst_getOpVal(MI, OpNum));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2017,8 +2048,8 @@ void AArch64_add_cs_detail_1(MCInst *MI, aarch64_op_group op_group,
|
|||
case AArch64_OP_GROUP_PredicateAsCounter_8: {
|
||||
unsigned EltSize = temp_arg_0;
|
||||
AArch64_get_detail_op(MI, 0)->vas = EltSize;
|
||||
AArch64_set_detail_op_reg(
|
||||
MI, OpNum, MCInst_getOpVal(MI, OpNum));
|
||||
AArch64_set_detail_op_reg(MI, OpNum,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
break;
|
||||
}
|
||||
case AArch64_OP_GROUP_PrefetchOp_0:
|
||||
|
|
@ -2092,7 +2123,9 @@ void AArch64_add_cs_detail_1(MCInst *MI, aarch64_op_group op_group,
|
|||
case AArch64_OP_GROUP_UImm12Offset_4:
|
||||
case AArch64_OP_GROUP_UImm12Offset_8: {
|
||||
// Otherwise it is an expression. For which we only add the immediate
|
||||
unsigned Scale = MCOperand_isImm(MCInst_getOperand(MI, OpNum)) ? temp_arg_0 : 1;
|
||||
unsigned Scale = MCOperand_isImm(MCInst_getOperand(MI, OpNum)) ?
|
||||
temp_arg_0 :
|
||||
1;
|
||||
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
|
||||
Scale * MCInst_getOpVal(MI, OpNum));
|
||||
break;
|
||||
|
|
@ -2153,8 +2186,8 @@ void AArch64_add_cs_detail_1(MCInst *MI, aarch64_op_group op_group,
|
|||
/// This function handles operands which original printer function is a template
|
||||
/// with two arguments.
|
||||
void AArch64_add_cs_detail_2(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1)
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1)
|
||||
{
|
||||
if (!add_cs_detail_begin(MI, OpNum))
|
||||
return;
|
||||
|
|
@ -2191,7 +2224,8 @@ void AArch64_add_cs_detail_2(MCInst *MI, aarch64_op_group op_group,
|
|||
uint64_t Scale = temp_arg_0;
|
||||
uint64_t Offset = temp_arg_1;
|
||||
unsigned FirstImm = Scale * MCInst_getOpVal(MI, (OpNum));
|
||||
AArch64_set_detail_op_imm_range(MI, OpNum, FirstImm, FirstImm + Offset);
|
||||
AArch64_set_detail_op_imm_range(MI, OpNum, FirstImm,
|
||||
FirstImm + Offset);
|
||||
break;
|
||||
}
|
||||
case AArch64_OP_GROUP_MemExtend_w_128:
|
||||
|
|
@ -2301,26 +2335,30 @@ void AArch64_add_cs_detail_2(MCInst *MI, aarch64_op_group op_group,
|
|||
if (NumRegs > 1) {
|
||||
// Add all registers of the list to the details.
|
||||
for (size_t i = 0; i < NumRegs - 1; ++i) {
|
||||
AArch64_get_detail_op(MI, 0)->is_list_member =
|
||||
true;
|
||||
AArch64_get_detail_op(MI, 0)
|
||||
->is_list_member = true;
|
||||
AArch64_get_detail_op(MI, 0)->vas = vas;
|
||||
AArch64_set_detail_op_reg(
|
||||
MI, OpNum,
|
||||
getNextVectorRegister(Reg + i, 1));
|
||||
getNextVectorRegister(Reg + i,
|
||||
1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < NumRegs;
|
||||
++i, Reg = getNextVectorRegister(Reg, Stride)) {
|
||||
if (!(MCRegisterClass_contains(
|
||||
MCRegisterInfo_getRegClass(
|
||||
MI->MRI, AArch64_ZPRRegClassID),
|
||||
Reg) ||
|
||||
MCRegisterClass_contains(
|
||||
MCRegisterInfo_getRegClass(
|
||||
MI->MRI, AArch64_PPRRegClassID),
|
||||
Reg))) {
|
||||
AArch64_get_detail_op(MI, 0)->is_vreg = true;
|
||||
MCRegisterInfo_getRegClass(
|
||||
MI->MRI,
|
||||
AArch64_ZPRRegClassID),
|
||||
Reg) ||
|
||||
MCRegisterClass_contains(
|
||||
MCRegisterInfo_getRegClass(
|
||||
MI->MRI,
|
||||
AArch64_PPRRegClassID),
|
||||
Reg))) {
|
||||
AArch64_get_detail_op(MI, 0)->is_vreg =
|
||||
true;
|
||||
}
|
||||
AArch64_get_detail_op(MI, 0)->is_list_member =
|
||||
true;
|
||||
|
|
@ -2336,9 +2374,9 @@ void AArch64_add_cs_detail_2(MCInst *MI, aarch64_op_group op_group,
|
|||
/// This function handles operands which original printer function is a template
|
||||
/// with four arguments.
|
||||
void AArch64_add_cs_detail_4(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1, uint64_t temp_arg_2,
|
||||
uint64_t temp_arg_3)
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1, uint64_t temp_arg_2,
|
||||
uint64_t temp_arg_3)
|
||||
{
|
||||
if (!add_cs_detail_begin(MI, OpNum))
|
||||
return;
|
||||
|
|
@ -2417,7 +2455,7 @@ void AArch64_set_detail_op_reg(MCInst *MI, unsigned OpNum, aarch64_reg Reg)
|
|||
sme_reg_to_vas(Reg));
|
||||
return;
|
||||
} else if (((Reg >= AARCH64_REG_P0) && (Reg <= AARCH64_REG_P15)) ||
|
||||
((Reg >= AARCH64_REG_PN0) && (Reg <= AARCH64_REG_PN15))) {
|
||||
((Reg >= AARCH64_REG_PN0) && (Reg <= AARCH64_REG_PN15))) {
|
||||
// SME/SVE predicate register.
|
||||
AArch64_set_detail_op_pred(MI, OpNum);
|
||||
return;
|
||||
|
|
@ -2427,7 +2465,8 @@ void AArch64_set_detail_op_reg(MCInst *MI, unsigned OpNum, aarch64_reg Reg)
|
|||
AArch64_set_detail_op_sme(MI, OpNum,
|
||||
AARCH64_SME_MATRIX_SLICE_REG,
|
||||
AARCH64LAYOUT_INVALID);
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) {
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type ==
|
||||
AARCH64_OP_PRED) {
|
||||
AArch64_set_detail_op_pred(MI, OpNum);
|
||||
} else {
|
||||
CS_ASSERT_RET(0 && "Unkown SME/SVE operand type");
|
||||
|
|
@ -2454,7 +2493,8 @@ void AArch64_set_detail_op_reg(MCInst *MI, unsigned OpNum, aarch64_reg Reg)
|
|||
/// is write-back.
|
||||
/// This indicates the following immediate is a post-indexed
|
||||
/// memory offset.
|
||||
static bool prev_is_membase_wb(MCInst *MI) {
|
||||
static bool prev_is_membase_wb(MCInst *MI)
|
||||
{
|
||||
return AArch64_get_detail(MI)->op_count > 0 &&
|
||||
AArch64_get_detail_op(MI, -1)->type == AARCH64_OP_MEM &&
|
||||
AArch64_get_detail_op(MI, -1)->mem.disp == 0 &&
|
||||
|
|
@ -2475,8 +2515,10 @@ void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum,
|
|||
if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME) {
|
||||
AArch64_set_detail_op_sme(MI, OpNum,
|
||||
AARCH64_SME_MATRIX_SLICE_OFF,
|
||||
AARCH64LAYOUT_INVALID, (uint32_t) 1);
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) {
|
||||
AARCH64LAYOUT_INVALID,
|
||||
(uint32_t)1);
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type ==
|
||||
AARCH64_OP_PRED) {
|
||||
AArch64_set_detail_op_pred(MI, OpNum);
|
||||
} else {
|
||||
CS_ASSERT_RET(0 && "Unkown SME operand type");
|
||||
|
|
@ -2508,12 +2550,14 @@ void AArch64_set_detail_op_imm_range(MCInst *MI, unsigned OpNum,
|
|||
if (AArch64_get_detail(MI)->is_doing_sme) {
|
||||
CS_ASSERT_RET(map_get_op_type(MI, OpNum) & CS_OP_BOUND);
|
||||
if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME) {
|
||||
AArch64_set_detail_op_sme(MI, OpNum,
|
||||
AARCH64_SME_MATRIX_SLICE_OFF_RANGE,
|
||||
AARCH64LAYOUT_INVALID, (uint32_t) FirstImm,
|
||||
(uint32_t) Offset);
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) {
|
||||
CS_ASSERT_RET(0 && "Unkown SME predicate imm range type");
|
||||
AArch64_set_detail_op_sme(
|
||||
MI, OpNum, AARCH64_SME_MATRIX_SLICE_OFF_RANGE,
|
||||
AARCH64LAYOUT_INVALID, (uint32_t)FirstImm,
|
||||
(uint32_t)Offset);
|
||||
} else if (AArch64_get_detail_op(MI, 0)->type ==
|
||||
AARCH64_OP_PRED) {
|
||||
CS_ASSERT_RET(0 &&
|
||||
"Unkown SME predicate imm range type");
|
||||
} else {
|
||||
CS_ASSERT_RET(0 && "Unkown SME operand type");
|
||||
}
|
||||
|
|
@ -2639,12 +2683,14 @@ void AArch64_set_detail_op_sys(MCInst *MI, unsigned OpNum, aarch64_sysop sys_op,
|
|||
AArch64_get_detail_op(MI, 0)->type = type;
|
||||
AArch64_get_detail_op(MI, 0)->sysop = sys_op;
|
||||
if (sys_op.sub_type == AARCH64_OP_EXACTFPIMM) {
|
||||
AArch64_get_detail_op(MI, 0)->fp = aarch64_exact_fp_to_fp(sys_op.imm.exactfpimm);
|
||||
AArch64_get_detail_op(MI, 0)->fp =
|
||||
aarch64_exact_fp_to_fp(sys_op.imm.exactfpimm);
|
||||
}
|
||||
AArch64_inc_op_count(MI);
|
||||
}
|
||||
|
||||
void AArch64_set_detail_op_pred(MCInst *MI, unsigned OpNum) {
|
||||
void AArch64_set_detail_op_pred(MCInst *MI, unsigned OpNum)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
AArch64_check_safe_inc(MI);
|
||||
|
|
@ -2655,7 +2701,8 @@ void AArch64_set_detail_op_pred(MCInst *MI, unsigned OpNum) {
|
|||
aarch64_op_pred *p = &AArch64_get_detail_op(MI, 0)->pred;
|
||||
if (p->reg == AARCH64_REG_INVALID) {
|
||||
p->reg = MCInst_getOpVal(MI, OpNum);
|
||||
AArch64_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
|
||||
AArch64_get_detail_op(MI, 0)->access =
|
||||
map_get_op_access(MI, OpNum);
|
||||
AArch64_get_detail(MI)->is_doing_sme = true;
|
||||
return;
|
||||
} else if (p->vec_select == AARCH64_REG_INVALID) {
|
||||
|
|
@ -2686,12 +2733,15 @@ void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum,
|
|||
setup_sme_operand(MI);
|
||||
va_list args;
|
||||
va_start(args, vas);
|
||||
int Tile = va_arg(args, int); // NOLINT(clang-analyzer-valist.Uninitialized)
|
||||
// NOLINTBEGIN(clang-analyzer-valist.Uninitialized)
|
||||
int Tile = va_arg(args, int);
|
||||
// NOLINTEND(clang-analyzer-valist.Uninitialized)
|
||||
va_end(args);
|
||||
AArch64_get_detail_op(MI, 0)->sme.type = AARCH64_SME_OP_TILE;
|
||||
AArch64_get_detail_op(MI, 0)->sme.tile = Tile;
|
||||
AArch64_get_detail_op(MI, 0)->vas = vas;
|
||||
AArch64_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
|
||||
AArch64_get_detail_op(MI, 0)->access =
|
||||
map_get_op_access(MI, OpNum);
|
||||
AArch64_get_detail(MI)->is_doing_sme = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2703,12 +2753,15 @@ void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum,
|
|||
AArch64_get_detail_op(MI, 0)->sme.tile =
|
||||
MCInst_getOpVal(MI, OpNum);
|
||||
AArch64_get_detail_op(MI, 0)->vas = vas;
|
||||
AArch64_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
|
||||
AArch64_get_detail_op(MI, 0)->access =
|
||||
map_get_op_access(MI, OpNum);
|
||||
AArch64_get_detail(MI)->is_doing_sme = true;
|
||||
break;
|
||||
case AARCH64_SME_MATRIX_SLICE_REG:
|
||||
CS_ASSERT_RET((map_get_op_type(MI, OpNum) & ~(CS_OP_MEM | CS_OP_BOUND)) == CS_OP_REG);
|
||||
CS_ASSERT_RET(AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME);
|
||||
CS_ASSERT_RET((map_get_op_type(MI, OpNum) &
|
||||
~(CS_OP_MEM | CS_OP_BOUND)) == CS_OP_REG);
|
||||
CS_ASSERT_RET(AArch64_get_detail_op(MI, 0)->type ==
|
||||
AARCH64_OP_SME);
|
||||
|
||||
// SME operand already present. Add the slice to it.
|
||||
AArch64_get_detail_op(MI, 0)->sme.type =
|
||||
|
|
@ -2717,25 +2770,30 @@ void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum,
|
|||
MCInst_getOpVal(MI, OpNum);
|
||||
break;
|
||||
case AARCH64_SME_MATRIX_SLICE_OFF: {
|
||||
CS_ASSERT_RET((map_get_op_type(MI, OpNum) & ~(CS_OP_MEM | CS_OP_BOUND)) == CS_OP_IMM);
|
||||
CS_ASSERT_RET((map_get_op_type(MI, OpNum) &
|
||||
~(CS_OP_MEM | CS_OP_BOUND)) == CS_OP_IMM);
|
||||
// Because we took care of the slice register before, the op at -1 must be a SME operand.
|
||||
CS_ASSERT_RET(AArch64_get_detail_op(MI, 0)->type ==
|
||||
AARCH64_OP_SME);
|
||||
CS_ASSERT_RET(AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm ==
|
||||
AARCH64_SLICE_IMM_INVALID);
|
||||
AARCH64_OP_SME);
|
||||
CS_ASSERT_RET(
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm ==
|
||||
AARCH64_SLICE_IMM_INVALID);
|
||||
va_list args;
|
||||
va_start(args, vas);
|
||||
uint16_t offset = va_arg(args, uint32_t); // NOLINT(clang-analyzer-valist.Uninitialized)
|
||||
// NOLINTBEGIN(clang-analyzer-valist.Uninitialized)
|
||||
uint16_t offset = va_arg(args, uint32_t);
|
||||
// NOLINTEND(clang-analyzer-valist.Uninitialized)
|
||||
va_end(args);
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm =
|
||||
offset;
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm = offset;
|
||||
break;
|
||||
}
|
||||
case AARCH64_SME_MATRIX_SLICE_OFF_RANGE: {
|
||||
va_list args;
|
||||
va_start(args, vas);
|
||||
uint8_t First = va_arg(args, uint32_t); // NOLINT(clang-analyzer-valist.Uninitialized)
|
||||
uint8_t Offset = va_arg(args, uint32_t); // NOLINT(clang-analyzer-valist.Uninitialized)
|
||||
// NOLINTBEGIN(clang-analyzer-valist.Uninitialized)
|
||||
uint8_t First = va_arg(args, uint32_t);
|
||||
uint8_t Offset = va_arg(args, uint32_t);
|
||||
// NOLINTEND(clang-analyzer-valist.Uninitialized)
|
||||
va_end(args);
|
||||
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.first =
|
||||
First;
|
||||
|
|
@ -2826,8 +2884,8 @@ void AArch64_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Imm)
|
|||
insert_op(MI, index, op);
|
||||
}
|
||||
|
||||
void AArch64_insert_detail_op_sys(MCInst *MI, unsigned index, aarch64_sysop sys_op,
|
||||
aarch64_op_type type)
|
||||
void AArch64_insert_detail_op_sys(MCInst *MI, unsigned index,
|
||||
aarch64_sysop sys_op, aarch64_op_type type)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
|
@ -2843,8 +2901,8 @@ void AArch64_insert_detail_op_sys(MCInst *MI, unsigned index, aarch64_sysop sys_
|
|||
insert_op(MI, index, op);
|
||||
}
|
||||
|
||||
|
||||
void AArch64_insert_detail_op_sme(MCInst *MI, unsigned index, aarch64_op_sme sme_op)
|
||||
void AArch64_insert_detail_op_sme(MCInst *MI, unsigned index,
|
||||
aarch64_op_sme sme_op)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -37,16 +37,16 @@ void AArch64_reg_access(const cs_insn *insn, cs_regs regs_read,
|
|||
uint8_t *regs_write_count);
|
||||
|
||||
void AArch64_add_cs_detail_0(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum);
|
||||
unsigned OpNum);
|
||||
void AArch64_add_cs_detail_1(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum, uint64_t temp_arg_0);
|
||||
unsigned OpNum, uint64_t temp_arg_0);
|
||||
void AArch64_add_cs_detail_2(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1);
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1);
|
||||
void AArch64_add_cs_detail_4(MCInst *MI, aarch64_op_group op_group,
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1, uint64_t temp_arg_2,
|
||||
uint64_t temp_arg_3);
|
||||
unsigned OpNum, uint64_t temp_arg_0,
|
||||
uint64_t temp_arg_1, uint64_t temp_arg_2,
|
||||
uint64_t temp_arg_3);
|
||||
|
||||
void AArch64_init_mri(MCRegisterInfo *MRI);
|
||||
|
||||
|
|
@ -82,9 +82,10 @@ void AArch64_insert_detail_op_reg_at(MCInst *MI, unsigned index,
|
|||
void AArch64_insert_detail_op_float_at(MCInst *MI, unsigned index, double val,
|
||||
cs_ac_type access);
|
||||
void AArch64_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Imm);
|
||||
void AArch64_insert_detail_op_sys(MCInst *MI, unsigned index, aarch64_sysop sys_op,
|
||||
aarch64_op_type type);
|
||||
void AArch64_insert_detail_op_sme(MCInst *MI, unsigned index, aarch64_op_sme sme_op);
|
||||
void AArch64_insert_detail_op_sys(MCInst *MI, unsigned index,
|
||||
aarch64_sysop sys_op, aarch64_op_type type);
|
||||
void AArch64_insert_detail_op_sme(MCInst *MI, unsigned index,
|
||||
aarch64_op_sme sme_op);
|
||||
void AArch64_add_vas(MCInst *MI, const SStream *OS);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@
|
|||
#define DEBUG_TYPE "arc-disassembler"
|
||||
|
||||
/// A disassembler class for ARC.
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address,
|
||||
SStream *CStream);
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size,
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CStream);
|
||||
|
||||
// end anonymous namespace
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ static bool readInstruction32(const uint8_t *Bytes, size_t BytesLen,
|
|||
*Size = 4;
|
||||
// Read 2 16-bit values, but swap hi/lo parts.
|
||||
*Insn = (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) |
|
||||
(Bytes[3] << 8);
|
||||
(Bytes[3] << 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -65,9 +65,9 @@ static bool readInstruction64(const uint8_t *Bytes, size_t BytesLen,
|
|||
{
|
||||
*Size = 8;
|
||||
*Insn = ((uint64_t)Bytes[0] << 16) | ((uint64_t)Bytes[1] << 24) |
|
||||
((uint64_t)Bytes[2] << 0) | ((uint64_t)Bytes[3] << 8) |
|
||||
((uint64_t)Bytes[4] << 48) | ((uint64_t)Bytes[5] << 56) |
|
||||
((uint64_t)Bytes[6] << 32) | ((uint64_t)Bytes[7] << 40);
|
||||
((uint64_t)Bytes[2] << 0) | ((uint64_t)Bytes[3] << 8) |
|
||||
((uint64_t)Bytes[4] << 48) | ((uint64_t)Bytes[5] << 56) |
|
||||
((uint64_t)Bytes[6] << 32) | ((uint64_t)Bytes[7] << 40);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -76,8 +76,8 @@ static bool readInstruction48(const uint8_t *Bytes, size_t BytesLen,
|
|||
{
|
||||
*Size = 6;
|
||||
*Insn = ((uint64_t)Bytes[0] << 0) | ((uint64_t)Bytes[1] << 8) |
|
||||
((uint64_t)Bytes[2] << 32) | ((uint64_t)Bytes[3] << 40) |
|
||||
((uint64_t)Bytes[4] << 16) | ((uint64_t)Bytes[5] << 24);
|
||||
((uint64_t)Bytes[2] << 32) | ((uint64_t)Bytes[3] << 40) |
|
||||
((uint64_t)Bytes[4] << 16) | ((uint64_t)Bytes[5] << 24);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -90,18 +90,18 @@ static bool readInstruction16(const uint8_t *Bytes, size_t BytesLen,
|
|||
}
|
||||
|
||||
#define DECLARE_DecodeSignedOperand(B) \
|
||||
static DecodeStatus CONCAT(DecodeSignedOperand, B)( \
|
||||
MCInst * Inst, unsigned InsnS, uint64_t Address, \
|
||||
const void *Decoder);
|
||||
static DecodeStatus CONCAT(DecodeSignedOperand, \
|
||||
B)(MCInst * Inst, unsigned InsnS, \
|
||||
uint64_t Address, const void *Decoder);
|
||||
DECLARE_DecodeSignedOperand(11);
|
||||
DECLARE_DecodeSignedOperand(9);
|
||||
DECLARE_DecodeSignedOperand(10);
|
||||
DECLARE_DecodeSignedOperand(12);
|
||||
|
||||
#define DECLARE_DecodeFromCyclicRange(B) \
|
||||
static DecodeStatus CONCAT(DecodeFromCyclicRange, B)( \
|
||||
MCInst * Inst, unsigned InsnS, uint64_t Address, \
|
||||
const void *Decoder);
|
||||
static DecodeStatus CONCAT(DecodeFromCyclicRange, \
|
||||
B)(MCInst * Inst, unsigned InsnS, \
|
||||
uint64_t Address, const void *Decoder);
|
||||
DECLARE_DecodeFromCyclicRange(3);
|
||||
|
||||
#define DECLARE_DecodeBranchTargetS(B) \
|
||||
|
|
@ -116,8 +116,7 @@ DECLARE_DecodeBranchTargetS(21);
|
|||
DECLARE_DecodeBranchTargetS(25);
|
||||
DECLARE_DecodeBranchTargetS(9);
|
||||
|
||||
static DecodeStatus DecodeMEMrs9(MCInst *, unsigned, uint64_t,
|
||||
const void *);
|
||||
static DecodeStatus DecodeMEMrs9(MCInst *, unsigned, uint64_t, const void *);
|
||||
|
||||
static DecodeStatus DecodeLdLImmInstruction(MCInst *, uint64_t, uint64_t,
|
||||
const void *);
|
||||
|
|
@ -200,7 +199,8 @@ static DecodeStatus DecodeMEMrs9(MCInst *Inst, unsigned Insn, uint64_t Address,
|
|||
// We have the 9-bit immediate in the low bits, 6-bit register in high bits.
|
||||
unsigned S9 = Insn & 0x1ff;
|
||||
unsigned R = (Insn & (0x7fff & ~0x1ff)) >> 9;
|
||||
if (DecodeGPR32RegisterClass(Inst, R, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, R, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
MCOperand_CreateImm0(Inst, (SignExtend32((S9), 9)));
|
||||
|
|
@ -234,15 +234,13 @@ DEFINE_DecodeBranchTargetS(25);
|
|||
DEFINE_DecodeBranchTargetS(9);
|
||||
|
||||
#define DEFINE_DecodeSignedOperand(B) \
|
||||
static DecodeStatus CONCAT(DecodeSignedOperand, B)( \
|
||||
MCInst * Inst, unsigned InsnS, uint64_t Address, \
|
||||
const void * Decoder) \
|
||||
static DecodeStatus CONCAT(DecodeSignedOperand, \
|
||||
B)(MCInst * Inst, unsigned InsnS, \
|
||||
uint64_t Address, const void *Decoder) \
|
||||
{ \
|
||||
CS_ASSERT(B > 0 && "field is empty"); \
|
||||
MCOperand_CreateImm0( \
|
||||
Inst, SignExtend32(maskTrailingOnes32(B) & \
|
||||
InsnS, B) \
|
||||
); \
|
||||
Inst, SignExtend32(maskTrailingOnes32(B) & InsnS, B)); \
|
||||
return MCDisassembler_Success; \
|
||||
}
|
||||
DEFINE_DecodeSignedOperand(11);
|
||||
|
|
@ -251,9 +249,9 @@ DEFINE_DecodeSignedOperand(10);
|
|||
DEFINE_DecodeSignedOperand(12);
|
||||
|
||||
#define DEFINE_DecodeFromCyclicRange(B) \
|
||||
static DecodeStatus CONCAT(DecodeFromCyclicRange, B)( \
|
||||
MCInst * Inst, unsigned InsnS, uint64_t Address, \
|
||||
const void * Decoder) \
|
||||
static DecodeStatus CONCAT(DecodeFromCyclicRange, \
|
||||
B)(MCInst * Inst, unsigned InsnS, \
|
||||
uint64_t Address, const void *Decoder) \
|
||||
{ \
|
||||
CS_ASSERT(B > 0 && "field is empty"); \
|
||||
const unsigned max = (1u << B) - 1; \
|
||||
|
|
@ -272,7 +270,8 @@ static DecodeStatus DecodeStLImmInstruction(MCInst *Inst, uint64_t Insn,
|
|||
return MCDisassembler_Fail;
|
||||
}
|
||||
SrcC = decodeCField(Insn);
|
||||
if (DecodeGPR32RegisterClass(Inst, SrcC, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, SrcC, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
LImm = (Insn >> 32);
|
||||
|
|
@ -293,7 +292,8 @@ static DecodeStatus DecodeLdLImmInstruction(MCInst *Inst, uint64_t Insn,
|
|||
return MCDisassembler_Fail;
|
||||
}
|
||||
DstA = decodeAField(Insn);
|
||||
if (DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
LImm = (Insn >> 32);
|
||||
|
|
@ -309,11 +309,13 @@ static DecodeStatus DecodeLdRLImmInstruction(MCInst *Inst, uint64_t Insn,
|
|||
unsigned DstA, SrcB;
|
||||
;
|
||||
DstA = decodeAField(Insn);
|
||||
if (DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
SrcB = decodeBField(Insn);
|
||||
if (DecodeGPR32RegisterClass(Inst, SrcB, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, SrcB, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
if (decodeCField(Insn) != 62) {
|
||||
|
|
@ -324,9 +326,9 @@ static DecodeStatus DecodeLdRLImmInstruction(MCInst *Inst, uint64_t Insn,
|
|||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeRegisterOrImm(MCInst *Inst, uint64_t Address,
|
||||
const void *Decoder, uint64_t RegNum,
|
||||
uint64_t Value)
|
||||
static DecodeStatus DecodeRegisterOrImm(MCInst *Inst, uint64_t Address,
|
||||
const void *Decoder, uint64_t RegNum,
|
||||
uint64_t Value)
|
||||
{
|
||||
if (30 == RegNum) {
|
||||
MCOperand_CreateImm0(Inst, (Value));
|
||||
|
|
@ -335,7 +337,6 @@ static DecodeStatus DecodeRegisterOrImm(MCInst *Inst, uint64_t Address,
|
|||
return DecodeGPR32RegisterClass(Inst, RegNum, Address, Decoder);
|
||||
}
|
||||
|
||||
|
||||
static DecodeStatus DecodeMoveHRegInstruction(MCInst *Inst, uint64_t Insn,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
|
|
@ -343,12 +344,12 @@ static DecodeStatus DecodeMoveHRegInstruction(MCInst *Inst, uint64_t Insn,
|
|||
;
|
||||
|
||||
uint64_t H = fieldFromInstruction_8(Insn, 5, 3) |
|
||||
(fieldFromInstruction_8(Insn, 0, 2) << 3);
|
||||
(fieldFromInstruction_8(Insn, 0, 2) << 3);
|
||||
uint64_t G = fieldFromInstruction_8(Insn, 8, 3) |
|
||||
(fieldFromInstruction_8(Insn, 3, 2) << 3);
|
||||
(fieldFromInstruction_8(Insn, 3, 2) << 3);
|
||||
|
||||
if (MCDisassembler_Success != DecodeRegisterOrImm(Inst, Address,
|
||||
Decoder, G, 0))
|
||||
if (MCDisassembler_Success !=
|
||||
DecodeRegisterOrImm(Inst, Address, Decoder, G, 0))
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
return DecodeRegisterOrImm(Inst, Address, Decoder, H, Insn >> 16u);
|
||||
|
|
@ -361,7 +362,8 @@ static DecodeStatus DecodeCCRU6Instruction(MCInst *Inst, uint64_t Insn,
|
|||
unsigned DstB;
|
||||
;
|
||||
DstB = decodeBField(Insn);
|
||||
if (DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +378,8 @@ static DecodeStatus DecodeSOPwithRU6(MCInst *Inst, uint64_t Insn,
|
|||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
unsigned DstB = decodeBField(Insn);
|
||||
if (DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +392,8 @@ static DecodeStatus DecodeSOPwithRS12(MCInst *Inst, uint64_t Insn,
|
|||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
unsigned DstB = decodeBField(Insn);
|
||||
if (DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder) == MCDisassembler_Fail) {
|
||||
if (DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder) ==
|
||||
MCDisassembler_Fail) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
|
|
@ -401,8 +405,9 @@ static DecodeStatus DecodeSOPwithRS12(MCInst *Inst, uint64_t Insn,
|
|||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address, SStream *cStream)
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size,
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *cStream)
|
||||
{
|
||||
DecodeStatus Result;
|
||||
if (BytesLen < 2) {
|
||||
|
|
@ -422,17 +427,19 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
if (BytesLen >= 8) {
|
||||
// Attempt to decode 64-bit instruction.
|
||||
uint64_t Insn64;
|
||||
if (!readInstruction64(Bytes, BytesLen, Address, Size, &Insn64))
|
||||
if (!readInstruction64(Bytes, BytesLen, Address, Size,
|
||||
&Insn64))
|
||||
return MCDisassembler_Fail;
|
||||
Result = decodeInstruction_8(DecoderTable64, Instr,
|
||||
Insn64, Address, NULL);
|
||||
Insn64, Address, NULL);
|
||||
if (MCDisassembler_Success == Result) {
|
||||
;
|
||||
return Result;
|
||||
};
|
||||
}
|
||||
uint32_t Insn32;
|
||||
if (!readInstruction32(Bytes, BytesLen, Address, Size, &Insn32)) {
|
||||
if (!readInstruction32(Bytes, BytesLen, Address, Size,
|
||||
&Insn32)) {
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
// Calling the auto-generated decoder function.
|
||||
|
|
@ -442,10 +449,11 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
if (BytesLen >= 6) {
|
||||
// Attempt to treat as instr. with limm data.
|
||||
uint64_t Insn48;
|
||||
if (!readInstruction48(Bytes, BytesLen, Address, Size, &Insn48))
|
||||
if (!readInstruction48(Bytes, BytesLen, Address, Size,
|
||||
&Insn48))
|
||||
return MCDisassembler_Fail;
|
||||
Result = decodeInstruction_8(DecoderTable48, Instr,
|
||||
Insn48, Address, NULL);
|
||||
Insn48, Address, NULL);
|
||||
if (MCDisassembler_Success == Result) {
|
||||
;
|
||||
return Result;
|
||||
|
|
@ -463,9 +471,8 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
}
|
||||
|
||||
DecodeStatus ARC_LLVM_getInstruction(MCInst *MI, uint64_t *Size,
|
||||
const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address,
|
||||
SStream *CS)
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CS)
|
||||
{
|
||||
return getInstruction(MI, Size, Bytes, BytesLen, Address, CS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,7 +116,8 @@ static void printRegName(SStream *OS, MCRegister Reg)
|
|||
SStream_concat0(OS, getRegisterName(Reg));
|
||||
}
|
||||
|
||||
static void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
|
||||
static void printInst(MCInst *MI, uint64_t Address, const char *Annot,
|
||||
SStream *O)
|
||||
{
|
||||
printInstruction(MI, Address, O);
|
||||
}
|
||||
|
|
@ -134,7 +135,8 @@ static void printOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|||
}
|
||||
}
|
||||
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum,
|
||||
SStream *O)
|
||||
{
|
||||
printOperand(MI, OpNum, O);
|
||||
}
|
||||
|
|
@ -177,7 +179,8 @@ static void printCCOperand(MCInst *MI, int OpNum, SStream *O)
|
|||
MCInst_getOperand(MI, (OpNum)))));
|
||||
}
|
||||
|
||||
static void printU6ShiftedBy(unsigned ShiftBy, MCInst *MI, int OpNum, SStream *O)
|
||||
static void printU6ShiftedBy(unsigned ShiftBy, MCInst *MI, int OpNum,
|
||||
SStream *O)
|
||||
{
|
||||
MCOperand *MO = MCInst_getOperand(MI, (OpNum));
|
||||
if (MCOperand_isImm(MO)) {
|
||||
|
|
@ -197,7 +200,7 @@ static void printU6(MCInst *MI, int OpNum, SStream *O)
|
|||
}
|
||||
|
||||
void ARC_LLVM_printInst(MCInst *MI, uint64_t Address, const char *Annot,
|
||||
SStream *O)
|
||||
SStream *O)
|
||||
{
|
||||
printInst(MI, Address, Annot, O);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,15 +43,18 @@
|
|||
// Autogenerated by tblgen.
|
||||
static void printInstruction(MCInst *MI, uint64_t Address, SStream *O);
|
||||
static void printRegName(SStream *OS, MCRegister Reg);
|
||||
static void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O);
|
||||
static void printInst(MCInst *MI, uint64_t Address, const char *Annot,
|
||||
SStream *O);
|
||||
static void printCCOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU6(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printMemOperandRI(MCInst *MI, unsigned OpNum, SStream *O);
|
||||
static void printOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O);
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum,
|
||||
SStream *O);
|
||||
static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
||||
static void printBRCCPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
||||
static void printU6ShiftedBy(unsigned ShiftBy, MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU6ShiftedBy(unsigned ShiftBy, MCInst *MI, int OpNum,
|
||||
SStream *O);
|
||||
;
|
||||
// end namespace llvm
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,9 @@
|
|||
|
||||
const char *ARC_LLVM_getRegisterName(unsigned RegNo);
|
||||
void ARC_LLVM_printInst(MCInst *MI, uint64_t Address, const char *Annot,
|
||||
SStream *O);
|
||||
SStream *O);
|
||||
DecodeStatus ARC_LLVM_getInstruction(MCInst *MI, uint64_t *Size,
|
||||
const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address,
|
||||
SStream *CS);
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CS);
|
||||
|
||||
#endif // CS_ARC_LINKAGE_H
|
||||
|
|
|
|||
|
|
@ -26,12 +26,10 @@
|
|||
|
||||
void ARC_init_mri(MCRegisterInfo *MRI)
|
||||
{
|
||||
MCRegisterInfo_InitMCRegisterInfo(MRI, ARCRegDesc,
|
||||
sizeof(ARCRegDesc), 0, 0,
|
||||
ARCMCRegisterClasses,
|
||||
ARR_SIZE(ARCMCRegisterClasses),
|
||||
0, 0, ARCRegDiffLists, 0,
|
||||
ARCSubRegIdxLists,
|
||||
MCRegisterInfo_InitMCRegisterInfo(MRI, ARCRegDesc, sizeof(ARCRegDesc),
|
||||
0, 0, ARCMCRegisterClasses,
|
||||
ARR_SIZE(ARCMCRegisterClasses), 0, 0,
|
||||
ARCRegDiffLists, 0, ARCSubRegIdxLists,
|
||||
ARR_SIZE(ARCSubRegIdxLists), 0);
|
||||
}
|
||||
|
||||
|
|
@ -83,8 +81,8 @@ const char *ARC_group_name(csh handle, unsigned int id)
|
|||
}
|
||||
|
||||
void ARC_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count)
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t read_count, write_count;
|
||||
|
|
@ -137,13 +135,13 @@ void ARC_set_instr_map_data(MCInst *MI)
|
|||
}
|
||||
|
||||
bool ARC_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info)
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info)
|
||||
{
|
||||
uint64_t temp_size;
|
||||
ARC_init_cs_detail(instr);
|
||||
DecodeStatus Result = ARC_LLVM_getInstruction(instr, &temp_size, code,
|
||||
code_len, address, info);
|
||||
code_len, address, info);
|
||||
ARC_set_instr_map_data(instr);
|
||||
*size = temp_size;
|
||||
if (Result == MCDisassembler_SoftFail) {
|
||||
|
|
@ -152,8 +150,7 @@ bool ARC_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
|||
return Result != MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
void ARC_printer(MCInst *MI, SStream *O,
|
||||
void * /* MCRegisterInfo* */ info)
|
||||
void ARC_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
|
||||
{
|
||||
MCRegisterInfo *MRI = (MCRegisterInfo *)info;
|
||||
MI->MRI = MRI;
|
||||
|
|
@ -174,21 +171,18 @@ void ARC_init_cs_detail(MCInst *MI)
|
|||
}
|
||||
unsigned int i;
|
||||
|
||||
memset(get_detail(MI), 0,
|
||||
offsetof(cs_detail, arc) + sizeof(cs_arc));
|
||||
memset(get_detail(MI), 0, offsetof(cs_detail, arc) + sizeof(cs_arc));
|
||||
|
||||
for (i = 0; i < ARR_SIZE(ARC_get_detail(MI)->operands);
|
||||
i++)
|
||||
ARC_setup_op(
|
||||
&ARC_get_detail(MI)->operands[i]);
|
||||
for (i = 0; i < ARR_SIZE(ARC_get_detail(MI)->operands); i++)
|
||||
ARC_setup_op(&ARC_get_detail(MI)->operands[i]);
|
||||
}
|
||||
|
||||
static const map_insn_ops insn_operands[] = {
|
||||
#include "ARCGenCSMappingInsnOp.inc"
|
||||
};
|
||||
|
||||
void ARC_set_detail_op_imm(MCInst *MI, unsigned OpNum,
|
||||
arc_op_type ImmType, int64_t Imm)
|
||||
void ARC_set_detail_op_imm(MCInst *MI, unsigned OpNum, arc_op_type ImmType,
|
||||
int64_t Imm)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
|
@ -215,8 +209,7 @@ void ARC_set_detail_op_reg(MCInst *MI, unsigned OpNum, arc_reg Reg)
|
|||
ARC_inc_op_count(MI);
|
||||
}
|
||||
|
||||
void ARC_add_cs_detail(MCInst *MI, int op_group,
|
||||
va_list args)
|
||||
void ARC_add_cs_detail(MCInst *MI, int op_group, va_list args)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
|
@ -233,57 +226,58 @@ void ARC_add_cs_detail(MCInst *MI, int op_group,
|
|||
case ARC_OP_GROUP_Operand:
|
||||
if (op_type == CS_OP_IMM) {
|
||||
ARC_set_detail_op_imm(MI, OpNum, ARC_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
} else if (op_type == CS_OP_REG) {
|
||||
ARC_set_detail_op_reg(MI, OpNum,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
} else {
|
||||
// Expression
|
||||
ARC_set_detail_op_imm(MI, OpNum, ARC_OP_IMM,
|
||||
MCOperand_getImm(MCInst_getOperand(MI, OpNum)));
|
||||
ARC_set_detail_op_imm(
|
||||
MI, OpNum, ARC_OP_IMM,
|
||||
MCOperand_getImm(MCInst_getOperand(MI, OpNum)));
|
||||
}
|
||||
break;
|
||||
case ARC_OP_GROUP_PredicateOperand:
|
||||
if (op_type == CS_OP_IMM) {
|
||||
ARC_set_detail_op_imm(MI, OpNum, ARC_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
} else
|
||||
CS_ASSERT(0 && "Op type not handled.");
|
||||
break;
|
||||
case ARC_OP_GROUP_MemOperandRI:
|
||||
if (base_op_type == CS_OP_REG) {
|
||||
ARC_set_detail_op_reg(MI, OpNum,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
} else
|
||||
CS_ASSERT(0 && "Op type not handled.");
|
||||
offset_op_type = map_get_op_type(MI, OpNum+1);
|
||||
offset_op_type = map_get_op_type(MI, OpNum + 1);
|
||||
if (offset_op_type == CS_OP_IMM) {
|
||||
ARC_set_detail_op_imm(MI, OpNum+1, ARC_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum+1));
|
||||
ARC_set_detail_op_imm(MI, OpNum + 1, ARC_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum + 1));
|
||||
} else
|
||||
CS_ASSERT(0 && "Op type not handled.");
|
||||
break;
|
||||
case ARC_OP_GROUP_BRCCPredicateOperand:
|
||||
if (op_type == CS_OP_IMM) {
|
||||
ARC_set_detail_op_imm(MI, OpNum, ARC_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
} else
|
||||
CS_ASSERT(0 && "Op type not handled.");
|
||||
break;
|
||||
case ARC_OP_GROUP_CCOperand:
|
||||
if (op_type == CS_OP_IMM) {
|
||||
ARC_set_detail_op_imm(MI, OpNum, ARC_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
} else
|
||||
CS_ASSERT(0 && "Op type not handled.");
|
||||
break;
|
||||
case ARC_OP_GROUP_U6:
|
||||
if (op_type == CS_OP_IMM) {
|
||||
ARC_set_detail_op_imm(MI, OpNum, ARC_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
} else
|
||||
CS_ASSERT(0 && "Op type not handled.");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ void ARC_init_mri(MCRegisterInfo *MRI);
|
|||
// return name of register in friendly string
|
||||
const char *ARC_reg_name(csh handle, unsigned int reg);
|
||||
|
||||
void ARC_printer(MCInst *MI, SStream *O,
|
||||
void * /* MCRegisterInfo* */ info);
|
||||
void ARC_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info);
|
||||
|
||||
// given internal insn id, return public instruction ID
|
||||
void ARC_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
||||
|
|
@ -28,21 +27,21 @@ const char *ARC_insn_name(csh handle, unsigned int id);
|
|||
const char *ARC_group_name(csh handle, unsigned int id);
|
||||
|
||||
void ARC_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
|
||||
bool ARC_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
|
||||
// cs_detail related functions
|
||||
void ARC_init_cs_detail(MCInst *MI);
|
||||
void ARC_set_detail_op_imm(MCInst *MI, unsigned OpNum,
|
||||
arc_op_type ImmType, int64_t Imm);
|
||||
void ARC_set_detail_op_imm(MCInst *MI, unsigned OpNum, arc_op_type ImmType,
|
||||
int64_t Imm);
|
||||
void ARC_add_cs_detail(MCInst *MI, int /* arc_op_group */ op_group,
|
||||
va_list args);
|
||||
static inline void add_cs_detail(MCInst *MI,
|
||||
int /* arc_op_group */ op_group, ...)
|
||||
va_list args);
|
||||
static inline void add_cs_detail(MCInst *MI, int /* arc_op_group */ op_group,
|
||||
...)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ static inline unsigned ARM_AM_rotr32(unsigned Val, unsigned Amt)
|
|||
if (Amt == 32) {
|
||||
return Val;
|
||||
}
|
||||
return (Val >> Amt) |
|
||||
(Val << ((32 - Amt) &
|
||||
31)); // NOLINT(clang-analyzer-core.BitwiseShift)
|
||||
// NOLINTBEGIN(clang-analyzer-core.BitwiseShift)
|
||||
return (Val >> Amt) | (Val << ((32 - Amt) & 31));
|
||||
// NOLINTEND(clang-analyzer-core.BitwiseShift)
|
||||
}
|
||||
|
||||
static inline unsigned ARM_AM_rotl32(unsigned Val, unsigned Amt)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,9 @@ inline static const char *ARM_TSB_TraceSyncBOptToString(unsigned val)
|
|||
{
|
||||
switch (val) {
|
||||
default:
|
||||
CS_ASSERT_RET_VAL("Unknown trace synchronization barrier operation", NULL);
|
||||
CS_ASSERT_RET_VAL(
|
||||
"Unknown trace synchronization barrier operation",
|
||||
NULL);
|
||||
case ARM_TSB_CSYNC:
|
||||
return "csync";
|
||||
}
|
||||
|
|
@ -272,20 +274,20 @@ typedef enum AddrMode {
|
|||
ARMII_AddrModeT1_1 = 7,
|
||||
ARMII_AddrModeT1_2 = 8,
|
||||
ARMII_AddrModeT1_4 = 9,
|
||||
ARMII_AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
|
||||
ARMII_AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
|
||||
ARMII_AddrModeT2_i12 = 11,
|
||||
ARMII_AddrModeT2_i8 = 12, // +/- i8
|
||||
ARMII_AddrModeT2_i8 = 12, // +/- i8
|
||||
ARMII_AddrModeT2_i8pos = 13, // + i8
|
||||
ARMII_AddrModeT2_i8neg = 14, // - i8
|
||||
ARMII_AddrModeT2_so = 15,
|
||||
ARMII_AddrModeT2_pc = 16, // +/- i12 for pc relative data
|
||||
ARMII_AddrModeT2_i8s4 = 17, // i8 * 4
|
||||
ARMII_AddrModeT2_pc = 16, // +/- i12 for pc relative data
|
||||
ARMII_AddrModeT2_i8s4 = 17, // i8 * 4
|
||||
ARMII_AddrMode_i12 = 18,
|
||||
ARMII_AddrMode5FP16 = 19, // i8 * 2
|
||||
ARMII_AddrMode5FP16 = 19, // i8 * 2
|
||||
ARMII_AddrModeT2_ldrex = 20, // i8 * 4, with unscaled offset in MCInst
|
||||
ARMII_AddrModeT2_i7s4 = 21, // i7 * 4
|
||||
ARMII_AddrModeT2_i7s2 = 22, // i7 * 2
|
||||
ARMII_AddrModeT2_i7 = 23, // i7 * 1
|
||||
ARMII_AddrModeT2_i7s4 = 21, // i7 * 4
|
||||
ARMII_AddrModeT2_i7s2 = 22, // i7 * 2
|
||||
ARMII_AddrModeT2_i7 = 23, // i7 * 1
|
||||
} ARMII_AddrMode;
|
||||
|
||||
inline static const char *ARMII_AddrModeToString(ARMII_AddrMode addrmode)
|
||||
|
|
|
|||
|
|
@ -1105,7 +1105,7 @@ static DecodeStatus getThumbInstruction(csh ud, const uint8_t *Bytes,
|
|||
uint32_t NEONDataInsn = Insn32;
|
||||
NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
|
||||
NEONDataInsn |= (NEONDataInsn & 0x10000000) >>
|
||||
4; // Move bit 28 to bit 24
|
||||
4; // Move bit 28 to bit 24
|
||||
NEONDataInsn |= 0x12000000; // Set bits 28 and 25
|
||||
Result = decodeInstruction_4(DecoderTableNEONData32, MI,
|
||||
NEONDataInsn, Address, NULL);
|
||||
|
|
@ -1118,7 +1118,7 @@ static DecodeStatus getThumbInstruction(csh ud, const uint8_t *Bytes,
|
|||
uint32_t NEONCryptoInsn = Insn32;
|
||||
NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
|
||||
NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >>
|
||||
4; // Move bit 28 to bit 24
|
||||
4; // Move bit 28 to bit 24
|
||||
NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
|
||||
Result = decodeInstruction_4(DecoderTablev8Crypto32, MI,
|
||||
NEONCryptoInsn, Address, NULL);
|
||||
|
|
@ -5063,15 +5063,15 @@ static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Val, uint64_t Address,
|
|||
|
||||
// Validate the SYSm value first.
|
||||
switch (ValLow) {
|
||||
case 0: // apsr
|
||||
case 1: // iapsr
|
||||
case 2: // eapsr
|
||||
case 3: // xpsr
|
||||
case 5: // ipsr
|
||||
case 6: // epsr
|
||||
case 7: // iepsr
|
||||
case 8: // msp
|
||||
case 9: // psp
|
||||
case 0: // apsr
|
||||
case 1: // iapsr
|
||||
case 2: // eapsr
|
||||
case 3: // xpsr
|
||||
case 5: // ipsr
|
||||
case 6: // epsr
|
||||
case 7: // iepsr
|
||||
case 8: // msp
|
||||
case 9: // psp
|
||||
case 16: // primask
|
||||
case 20: // control
|
||||
break;
|
||||
|
|
@ -5092,8 +5092,8 @@ static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Val, uint64_t Address,
|
|||
ARM_HasV8MMainlineOps)))
|
||||
return MCDisassembler_Fail;
|
||||
// fall through
|
||||
case 10: // msplim
|
||||
case 11: // psplim
|
||||
case 10: // msplim
|
||||
case 11: // psplim
|
||||
case 0x88: // msp_ns
|
||||
case 0x89: // psp_ns
|
||||
case 0x90: // primask_ns
|
||||
|
|
@ -7286,7 +7286,7 @@ static DecodeStatus DecodeT2AddSubSPImm(MCInst *Inst, unsigned Insn,
|
|||
MCInst_setOpcode(Inst,
|
||||
(sign1 ? ARM_t2SUBspImm : ARM_t2ADDspImm));
|
||||
if (!Check(&DS, DecodeT2SOImm(Inst, Imm12, Address,
|
||||
Decoder))) // imm12
|
||||
Decoder))) // imm12
|
||||
return MCDisassembler_Fail;
|
||||
if (!Check(&DS, DecodeCCOutOperand(Inst, S, Address,
|
||||
Decoder))) // cc_out
|
||||
|
|
|
|||
|
|
@ -23,21 +23,14 @@
|
|||
#include "ARMMapping.h"
|
||||
|
||||
static const name_map insn_alias_mnem_map[] = {
|
||||
#include "ARMGenCSAliasMnemMap.inc"
|
||||
{ ARM_INS_ALIAS_ASR, "asr" },
|
||||
{ ARM_INS_ALIAS_LSL, "lsl" },
|
||||
{ ARM_INS_ALIAS_LSR, "lsr" },
|
||||
{ ARM_INS_ALIAS_ROR, "ror" },
|
||||
{ ARM_INS_ALIAS_RRX, "rrx" },
|
||||
{ ARM_INS_ALIAS_UXTW, "uxtw" },
|
||||
{ ARM_INS_ALIAS_LDM, "ldm" },
|
||||
{ ARM_INS_ALIAS_POP, "pop" },
|
||||
{ ARM_INS_ALIAS_PUSH, "push" },
|
||||
{ ARM_INS_ALIAS_POPW, "pop.w" },
|
||||
{ ARM_INS_ALIAS_PUSHW, "push.w" },
|
||||
{ ARM_INS_ALIAS_VPOP, "vpop" },
|
||||
{ ARM_INS_ALIAS_VPUSH, "vpush" },
|
||||
{ ARM_INS_ALIAS_END, NULL }
|
||||
#include "ARMGenCSAliasMnemMap.inc"
|
||||
{ ARM_INS_ALIAS_ASR, "asr" }, { ARM_INS_ALIAS_LSL, "lsl" },
|
||||
{ ARM_INS_ALIAS_LSR, "lsr" }, { ARM_INS_ALIAS_ROR, "ror" },
|
||||
{ ARM_INS_ALIAS_RRX, "rrx" }, { ARM_INS_ALIAS_UXTW, "uxtw" },
|
||||
{ ARM_INS_ALIAS_LDM, "ldm" }, { ARM_INS_ALIAS_POP, "pop" },
|
||||
{ ARM_INS_ALIAS_PUSH, "push" }, { ARM_INS_ALIAS_POPW, "pop.w" },
|
||||
{ ARM_INS_ALIAS_PUSHW, "push.w" }, { ARM_INS_ALIAS_VPOP, "vpop" },
|
||||
{ ARM_INS_ALIAS_VPUSH, "vpush" }, { ARM_INS_ALIAS_END, NULL }
|
||||
};
|
||||
|
||||
static const char *get_custom_reg_alias(unsigned reg)
|
||||
|
|
@ -161,10 +154,12 @@ static void patch_cs_reg_alias(char *asm_str)
|
|||
|
||||
/// Check if PC is updated from stack. Those POP instructions
|
||||
/// are considered of group RETURN.
|
||||
static void check_pop_return(MCInst *MI) {
|
||||
static void check_pop_return(MCInst *MI)
|
||||
{
|
||||
if (!MI->flat_insn->detail)
|
||||
return;
|
||||
if (MI->flat_insn->id != ARM_INS_POP && MI->flat_insn->alias_id != ARM_INS_ALIAS_POP) {
|
||||
if (MI->flat_insn->id != ARM_INS_POP &&
|
||||
MI->flat_insn->alias_id != ARM_INS_ALIAS_POP) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < ARM_get_detail(MI)->op_count; ++i) {
|
||||
|
|
@ -178,12 +173,14 @@ static void check_pop_return(MCInst *MI) {
|
|||
|
||||
/// Check if PC is directly written.Those instructions
|
||||
/// are considered of group BRANCH.
|
||||
static void check_writes_to_pc(MCInst *MI) {
|
||||
static void check_writes_to_pc(MCInst *MI)
|
||||
{
|
||||
if (!MI->flat_insn->detail)
|
||||
return;
|
||||
for (size_t i = 0; i < ARM_get_detail(MI)->op_count; ++i) {
|
||||
cs_arm_op *op = &ARM_get_detail(MI)->operands[i];
|
||||
if (op->type == ARM_OP_REG && op->reg == ARM_REG_PC && (op->access & CS_AC_WRITE)) {
|
||||
if (op->type == ARM_OP_REG && op->reg == ARM_REG_PC &&
|
||||
(op->access & CS_AC_WRITE)) {
|
||||
add_group(MI, ARM_GRP_JUMP);
|
||||
return;
|
||||
}
|
||||
|
|
@ -218,7 +215,8 @@ static void ARM_add_cs_groups(MCInst *MI)
|
|||
}
|
||||
}
|
||||
|
||||
static void add_alias_details(MCInst *MI) {
|
||||
static void add_alias_details(MCInst *MI)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
switch (MI->flat_insn->alias_id) {
|
||||
|
|
@ -227,7 +225,9 @@ static void add_alias_details(MCInst *MI) {
|
|||
case ARM_INS_ALIAS_POP:
|
||||
// Doesn't get set because memop is not printed.
|
||||
if (ARM_get_detail(MI)->op_count == 1) {
|
||||
CS_ASSERT_RET(MI->flat_insn->usesAliasDetails && "Not valid assumption for non alias details.");
|
||||
CS_ASSERT_RET(
|
||||
MI->flat_insn->usesAliasDetails &&
|
||||
"Not valid assumption for non alias details.");
|
||||
// Only single register pop is post-indexed
|
||||
// Assumes only alias details are passed here.
|
||||
ARM_get_detail(MI)->post_index = true;
|
||||
|
|
@ -260,23 +260,29 @@ static void add_alias_details(MCInst *MI) {
|
|||
arm_shifter shift_type = ARM_SFT_INVALID;
|
||||
switch (MCInst_getOpcode(MI)) {
|
||||
default:
|
||||
CS_ASSERT_RET(0 && "ASR, LSL, LSR, ROR alias not handled");
|
||||
CS_ASSERT_RET(0 &&
|
||||
"ASR, LSL, LSR, ROR alias not handled");
|
||||
return;
|
||||
case ARM_MOVsi: {
|
||||
MCOperand *MO2 = MCInst_getOperand(MI, 2);
|
||||
shift_type = (arm_shifter) ARM_AM_getSORegShOp(MCOperand_getImm(MO2));
|
||||
shift_type = (arm_shifter)ARM_AM_getSORegShOp(
|
||||
MCOperand_getImm(MO2));
|
||||
|
||||
if (ARM_AM_getSORegShOp(MCOperand_getImm(MO2)) == ARM_AM_rrx) {
|
||||
if (ARM_AM_getSORegShOp(MCOperand_getImm(MO2)) ==
|
||||
ARM_AM_rrx) {
|
||||
break;
|
||||
}
|
||||
shift_value = translateShiftImm(ARM_AM_getSORegOffset(
|
||||
MCOperand_getImm(MO2)));
|
||||
ARM_insert_detail_op_imm_at(MI, -1, shift_value, CS_AC_READ);
|
||||
shift_value = translateShiftImm(
|
||||
ARM_AM_getSORegOffset(MCOperand_getImm(MO2)));
|
||||
ARM_insert_detail_op_imm_at(MI, -1, shift_value,
|
||||
CS_AC_READ);
|
||||
break;
|
||||
}
|
||||
case ARM_MOVsr: {
|
||||
MCOperand *MO3 = MCInst_getOperand(MI, (3));
|
||||
shift_type = ARM_AM_getSORegShOp(MCOperand_getImm(MO3)) + ARM_SFT_REG;
|
||||
shift_type =
|
||||
ARM_AM_getSORegShOp(MCOperand_getImm(MO3)) +
|
||||
ARM_SFT_REG;
|
||||
shift_value = MCInst_getOpVal(MI, 2);
|
||||
break;
|
||||
}
|
||||
|
|
@ -533,7 +539,8 @@ static void ARM_add_not_defined_ops(MCInst *MI)
|
|||
// Add shift information
|
||||
ARM_get_detail(MI)->operands[1].shift.type =
|
||||
(arm_shifter)ARM_AM_getSORegShOp(
|
||||
MCInst_getOpVal(MI, 3)) + ARM_SFT_REG;
|
||||
MCInst_getOpVal(MI, 3)) +
|
||||
ARM_SFT_REG;
|
||||
ARM_get_detail(MI)->operands[1].shift.value =
|
||||
MCInst_getOpVal(MI, 2);
|
||||
break;
|
||||
|
|
@ -627,7 +634,8 @@ static void ARM_post_index_detection(MCInst *MI)
|
|||
|
||||
cs_arm_op *op = &ARM_get_detail(MI)->operands[i];
|
||||
cs_arm_op op_next = ARM_get_detail(MI)->operands[i + 1];
|
||||
if (op_next.type == ARM_OP_INVALID || op->mem.disp != 0 || op->mem.index != ARM_REG_INVALID)
|
||||
if (op_next.type == ARM_OP_INVALID || op->mem.disp != 0 ||
|
||||
op->mem.index != ARM_REG_INVALID)
|
||||
return;
|
||||
|
||||
if (op_next.type & CS_OP_IMM)
|
||||
|
|
@ -653,7 +661,8 @@ void ARM_check_mem_access_validity(MCInst *MI)
|
|||
}
|
||||
cs_detail *detail = get_detail(MI);
|
||||
for (int i = 0; i < detail->arm.op_count; ++i) {
|
||||
if (detail->arm.operands[i].type == ARM_OP_MEM && detail->arm.operands[i].access != suppl->mem_acc) {
|
||||
if (detail->arm.operands[i].type == ARM_OP_MEM &&
|
||||
detail->arm.operands[i].access != suppl->mem_acc) {
|
||||
detail->arm.operands[i].access = suppl->mem_acc;
|
||||
return;
|
||||
}
|
||||
|
|
@ -670,7 +679,8 @@ void ARM_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
|
|||
MI->fillDetailOps = detail_is_set(MI);
|
||||
MI->flat_insn->usesAliasDetails = map_use_alias_details(MI);
|
||||
ARM_LLVM_printInstruction(MI, O, info);
|
||||
map_set_alias_id(MI, O, insn_alias_mnem_map, ARR_SIZE(insn_alias_mnem_map) - 1);
|
||||
map_set_alias_id(MI, O, insn_alias_mnem_map,
|
||||
ARR_SIZE(insn_alias_mnem_map) - 1);
|
||||
ARM_add_not_defined_ops(MI);
|
||||
ARM_post_index_detection(MI);
|
||||
ARM_check_mem_access_validity(MI);
|
||||
|
|
@ -816,9 +826,8 @@ bool ARM_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
|||
void *info)
|
||||
{
|
||||
ARM_init_cs_detail(instr);
|
||||
DecodeStatus Result = ARM_LLVM_getInstruction(handle, code, code_len, instr,
|
||||
size, address,
|
||||
info);
|
||||
DecodeStatus Result = ARM_LLVM_getInstruction(
|
||||
handle, code, code_len, instr, size, address, info);
|
||||
ARM_set_instr_map_data(instr);
|
||||
if (Result == MCDisassembler_SoftFail) {
|
||||
MCInst_setSoftFail(instr);
|
||||
|
|
@ -1102,9 +1111,10 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
|
|||
if (doing_mem(MI)) {
|
||||
bool is_index_reg = map_get_op_type(MI, OpNum) &
|
||||
CS_OP_MEM;
|
||||
ARM_set_detail_op_mem(
|
||||
MI, OpNum, is_index_reg, is_index_reg ? 1 : 0,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
ARM_set_detail_op_mem(MI, OpNum, is_index_reg,
|
||||
is_index_reg ? 1 : 0,
|
||||
MCInst_getOpVal(MI,
|
||||
OpNum));
|
||||
} else {
|
||||
ARM_set_detail_op_reg(
|
||||
MI, OpNum, MCInst_getOpVal(MI, OpNum));
|
||||
|
|
@ -1477,7 +1487,8 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
|
|||
case ARM_OP_GROUP_PostIdxImm8s4Operand: {
|
||||
unsigned Imm8s = MCInst_getOpVal(MI, OpNum);
|
||||
bool sub = !(Imm8s & 256);
|
||||
ARM_set_detail_op_mem_offset(MI, OpNum, (Imm8s & 0xff) << 2, sub);
|
||||
ARM_set_detail_op_mem_offset(MI, OpNum, (Imm8s & 0xff) << 2,
|
||||
sub);
|
||||
ARM_get_detail(MI)->post_index = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1514,7 +1525,8 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
|
|||
ARM_set_mem_access(MI, false);
|
||||
break;
|
||||
}
|
||||
ARM_set_detail_op_mem(MI, OpNum + 1, true, subtracted == ARM_AM_sub ? -1 : 1,
|
||||
ARM_set_detail_op_mem(MI, OpNum + 1, true,
|
||||
subtracted == ARM_AM_sub ? -1 : 1,
|
||||
MCInst_getOpVal(MI, OpNum + 1));
|
||||
add_cs_detail_RegImmShift(MI, ARM_AM_getAM2ShiftOpc(imm3),
|
||||
ARM_AM_getAM2Offset(imm3));
|
||||
|
|
@ -1575,8 +1587,9 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
|
|||
unsigned Scale = 0;
|
||||
switch (op_group) {
|
||||
default:
|
||||
CS_ASSERT_RET(0 &&
|
||||
"Cannot determine scale. Operand group not handled.");
|
||||
CS_ASSERT_RET(
|
||||
0 &&
|
||||
"Cannot determine scale. Operand group not handled.");
|
||||
case ARM_OP_GROUP_ThumbAddrModeImm5S1Operand:
|
||||
Scale = 1;
|
||||
break;
|
||||
|
|
@ -1605,8 +1618,7 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
|
|||
MCInst_getOpVal(MI, OpNum));
|
||||
arm_reg RegNum = MCInst_getOpVal(MI, OpNum + 1);
|
||||
if (RegNum)
|
||||
ARM_set_detail_op_mem(MI, OpNum + 1, true, 1,
|
||||
RegNum);
|
||||
ARM_set_detail_op_mem(MI, OpNum + 1, true, 1, RegNum);
|
||||
ARM_set_mem_access(MI, false);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1842,7 +1854,8 @@ static void add_cs_detail_template_1(MCInst *MI, arm_op_group op_group,
|
|||
ARM_AM_getAM3Op(MCInst_getOpVal(MI, OpNum + 2));
|
||||
|
||||
if (MCOperand_getReg(MO2)) {
|
||||
ARM_set_detail_op_mem(MI, OpNum + 1, true, Sign == ARM_AM_sub ? -1 : 1,
|
||||
ARM_set_detail_op_mem(MI, OpNum + 1, true,
|
||||
Sign == ARM_AM_sub ? -1 : 1,
|
||||
MCInst_getOpVal(MI, OpNum + 1));
|
||||
ARM_get_detail_op(MI, 0)->subtracted = Sign ==
|
||||
ARM_AM_sub;
|
||||
|
|
@ -1853,8 +1866,7 @@ static void add_cs_detail_template_1(MCInst *MI, arm_op_group op_group,
|
|||
ARM_AM_getAM3Offset(MCInst_getOpVal(MI, OpNum + 2));
|
||||
|
||||
if (AlwaysPrintImm0 || ImmOffs || Sign == ARM_AM_sub) {
|
||||
ARM_set_detail_op_mem(MI, OpNum + 2, false, 0,
|
||||
ImmOffs);
|
||||
ARM_set_detail_op_mem(MI, OpNum + 2, false, 0, ImmOffs);
|
||||
ARM_get_detail_op(MI, 0)->subtracted = Sign ==
|
||||
ARM_AM_sub;
|
||||
}
|
||||
|
|
@ -1943,7 +1955,8 @@ static void add_cs_detail_template_2(MCInst *MI, arm_op_group op_group,
|
|||
case ARM_OP_GROUP_ComplexRotationOp_180_90: {
|
||||
unsigned Angle = temp_arg_0;
|
||||
unsigned Remainder = temp_arg_1;
|
||||
unsigned Rotation = (MCInst_getOpVal(MI, OpNum) * Angle) + Remainder;
|
||||
unsigned Rotation =
|
||||
(MCInst_getOpVal(MI, OpNum) * Angle) + Remainder;
|
||||
ARM_set_detail_op_imm(MI, OpNum, ARM_OP_IMM, Rotation);
|
||||
break;
|
||||
}
|
||||
|
|
@ -2087,7 +2100,7 @@ void ARM_set_detail_op_imm(MCInst *MI, unsigned OpNum, arm_op_type ImmType,
|
|||
CS_ASSERT_RET(!(map_get_op_type(MI, OpNum) & CS_OP_MEM));
|
||||
CS_ASSERT_RET(map_get_op_type(MI, OpNum) == CS_OP_IMM);
|
||||
CS_ASSERT_RET(ImmType == ARM_OP_IMM || ImmType == ARM_OP_PIMM ||
|
||||
ImmType == ARM_OP_CIMM);
|
||||
ImmType == ARM_OP_CIMM);
|
||||
|
||||
ARM_get_detail_op(MI, 0)->type = ImmType;
|
||||
ARM_get_detail_op(MI, 0)->imm = Imm;
|
||||
|
|
@ -2103,14 +2116,15 @@ void ARM_set_detail_op_mem_offset(MCInst *MI, unsigned OpNum, uint64_t Val,
|
|||
|
||||
if (!doing_mem(MI)) {
|
||||
CS_ASSERT_RET((ARM_get_detail_op(MI, -1) != NULL) &&
|
||||
(ARM_get_detail_op(MI, -1)->type == ARM_OP_MEM));
|
||||
(ARM_get_detail_op(MI, -1)->type == ARM_OP_MEM));
|
||||
ARM_dec_op_count(MI);
|
||||
}
|
||||
|
||||
if ((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_IMM)
|
||||
ARM_set_detail_op_mem(MI, OpNum, false, 0, Val);
|
||||
else if ((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_REG)
|
||||
ARM_set_detail_op_mem(MI, OpNum, true, subtracted ? -1 : 1, Val);
|
||||
ARM_set_detail_op_mem(MI, OpNum, true, subtracted ? -1 : 1,
|
||||
Val);
|
||||
else
|
||||
CS_ASSERT_RET(0 && "Memory type incorrect.");
|
||||
ARM_get_detail_op(MI, 0)->subtracted = subtracted;
|
||||
|
|
@ -2135,7 +2149,8 @@ void ARM_set_detail_op_mem(MCInst *MI, unsigned OpNum, bool is_index_reg,
|
|||
CS_ASSERT_RET(secondary_type == CS_OP_REG);
|
||||
if (!is_index_reg) {
|
||||
ARM_get_detail_op(MI, 0)->mem.base = Val;
|
||||
if (MCInst_opIsTying(MI, OpNum) || MCInst_opIsTied(MI, OpNum)) {
|
||||
if (MCInst_opIsTying(MI, OpNum) ||
|
||||
MCInst_opIsTied(MI, OpNum)) {
|
||||
// Base registers can be writeback registers.
|
||||
// For this they tie an MC operand which has write
|
||||
// access. But this one is never processed in the printer
|
||||
|
|
@ -2143,7 +2158,8 @@ void ARM_set_detail_op_mem(MCInst *MI, unsigned OpNum, bool is_index_reg,
|
|||
// added to the modified list.
|
||||
// Here we check for this case and add the memory register
|
||||
// to the modified list.
|
||||
map_add_implicit_write(MI, MCInst_getOpVal(MI, OpNum));
|
||||
map_add_implicit_write(
|
||||
MI, MCInst_getOpVal(MI, OpNum));
|
||||
MI->flat_insn->detail->writeback = true;
|
||||
} else {
|
||||
// If the base register is not tied, set the writebak flag to false.
|
||||
|
|
@ -2199,7 +2215,9 @@ void ARM_set_detail_op_sysop(MCInst *MI, int Val, arm_op_type type,
|
|||
default:
|
||||
CS_ASSERT_RET(0 && "Unknown system operand type.");
|
||||
case ARM_OP_SYSREG:
|
||||
ARM_get_detail_op(MI, 0)->sysop.reg.mclasssysreg = Val; // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
// NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
ARM_get_detail_op(MI, 0)->sysop.reg.mclasssysreg = Val;
|
||||
// NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
break;
|
||||
case ARM_OP_BANKEDREG:
|
||||
ARM_get_detail_op(MI, 0)->sysop.reg.bankedreg = Val;
|
||||
|
|
@ -2208,7 +2226,9 @@ void ARM_set_detail_op_sysop(MCInst *MI, int Val, arm_op_type type,
|
|||
case ARM_OP_CPSR:
|
||||
ARM_get_detail_op(MI, 0)->reg =
|
||||
type == ARM_OP_SPSR ? ARM_REG_SPSR : ARM_REG_CPSR;
|
||||
ARM_get_detail_op(MI, 0)->sysop.psr_bits = Val; // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
// NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
ARM_get_detail_op(MI, 0)->sysop.psr_bits = Val;
|
||||
// NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
break;
|
||||
}
|
||||
ARM_get_detail_op(MI, 0)->sysop.sysm = Sysm;
|
||||
|
|
|
|||
|
|
@ -16,16 +16,16 @@
|
|||
#include "AlphaLinkage.h"
|
||||
|
||||
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, unsigned RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, unsigned RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, unsigned RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
#include "AlphaGenDisassemblerTables.inc"
|
||||
|
||||
|
|
@ -35,8 +35,8 @@ static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, unsigned RegNo,
|
|||
#include "AlphaGenRegisterInfo.inc"
|
||||
|
||||
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, unsigned RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
if (RegNo > 31)
|
||||
return MCDisassembler_Fail;
|
||||
|
|
@ -47,8 +47,8 @@ static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, unsigned RegNo,
|
|||
}
|
||||
|
||||
static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, unsigned RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
if (RegNo > 31)
|
||||
return MCDisassembler_Fail;
|
||||
|
|
@ -59,8 +59,8 @@ static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, unsigned RegNo,
|
|||
}
|
||||
|
||||
static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, unsigned RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
if (RegNo > 31)
|
||||
return MCDisassembler_Fail;
|
||||
|
|
@ -75,9 +75,9 @@ static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, unsigned RegNo,
|
|||
#include "AlphaGenInstrInfo.inc"
|
||||
|
||||
DecodeStatus Alpha_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||
size_t ByteLen, MCInst *MI,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
void *Info)
|
||||
size_t ByteLen, MCInst *MI,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
void *Info)
|
||||
{
|
||||
if (!handle) {
|
||||
return MCDisassembler_Fail;
|
||||
|
|
@ -105,9 +105,9 @@ DecodeStatus Alpha_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
|||
void Alpha_init(MCRegisterInfo *MRI)
|
||||
{
|
||||
MCRegisterInfo_InitMCRegisterInfo(
|
||||
MRI, AlphaRegDesc, ARR_SIZE(AlphaRegDesc), 0, 0, AlphaMCRegisterClasses,
|
||||
ARR_SIZE(AlphaMCRegisterClasses), 0, 0, AlphaRegDiffLists, 0,
|
||||
AlphaSubRegIdxLists, 1, 0);
|
||||
MRI, AlphaRegDesc, ARR_SIZE(AlphaRegDesc), 0, 0,
|
||||
AlphaMCRegisterClasses, ARR_SIZE(AlphaMCRegisterClasses), 0, 0,
|
||||
AlphaRegDiffLists, 0, AlphaSubRegIdxLists, 1, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -19,7 +19,8 @@ static const char *getRegisterName(unsigned RegNo);
|
|||
|
||||
static void printInstruction(MCInst *, uint64_t, SStream *);
|
||||
static void printOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O);
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum,
|
||||
SStream *O);
|
||||
|
||||
#define GET_INSTRINFO_ENUM
|
||||
|
||||
|
|
@ -35,7 +36,7 @@ static void printOperand(MCInst *MI, int OpNum, SStream *O)
|
|||
return;
|
||||
|
||||
Alpha_add_cs_detail(MI, OpNum);
|
||||
|
||||
|
||||
MCOperand *Op;
|
||||
Op = MCInst_getOperand(MI, OpNum);
|
||||
if (MCOperand_isReg(Op)) {
|
||||
|
|
@ -57,12 +58,13 @@ static void printOperand(MCInst *MI, int OpNum, SStream *O)
|
|||
}
|
||||
}
|
||||
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
|
||||
static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum,
|
||||
SStream *O)
|
||||
{
|
||||
MCOperand *Op = MCInst_getOperand(MI, (OpNum));
|
||||
|
||||
uint64_t Imm = MCOperand_getImm(Op);
|
||||
uint64_t Target = Address + 4 + (int16_t) (Imm << 2);
|
||||
uint64_t Target = Address + 4 + (int16_t)(Imm << 2);
|
||||
|
||||
Alpha_set_detail_op_imm(MI, OpNum, ALPHA_OP_IMM, Target);
|
||||
printUInt64(O, Target);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
const char *Alpha_LLVM_getRegisterName(csh handle, unsigned int id);
|
||||
void Alpha_LLVM_printInstruction(MCInst *MI, SStream *O, void *Info);
|
||||
DecodeStatus Alpha_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||
size_t ByteLen, MCInst *MI,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
void *Info);
|
||||
size_t ByteLen, MCInst *MI,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
void *Info);
|
||||
|
||||
#endif // CS_ALPHA_LINKAGE_H
|
||||
|
|
@ -31,7 +31,7 @@ void Alpha_init_cs_detail(MCInst *MI)
|
|||
{
|
||||
if (detail_is_set(MI)) {
|
||||
memset(get_detail(MI), 0,
|
||||
offsetof(cs_detail, alpha) + sizeof(cs_alpha));
|
||||
offsetof(cs_detail, alpha) + sizeof(cs_alpha));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ void Alpha_add_cs_detail(MCInst *MI, unsigned OpNum)
|
|||
cs_op_type op_type = map_get_op_type(MI, OpNum);
|
||||
if (op_type == CS_OP_IMM)
|
||||
Alpha_set_detail_op_imm(MI, OpNum, ALPHA_OP_IMM,
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
MCInst_getOpVal(MI, OpNum));
|
||||
else if (op_type == CS_OP_REG)
|
||||
Alpha_set_detail_op_reg(MI, OpNum, MCInst_getOpVal(MI, OpNum));
|
||||
else
|
||||
|
|
@ -51,7 +51,7 @@ void Alpha_add_cs_detail(MCInst *MI, unsigned OpNum)
|
|||
}
|
||||
|
||||
void Alpha_set_detail_op_imm(MCInst *MI, unsigned OpNum, alpha_op_type ImmType,
|
||||
int64_t Imm)
|
||||
int64_t Imm)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
|
@ -84,23 +84,25 @@ void Alpha_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
|||
unsigned short i;
|
||||
|
||||
i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
|
||||
if (i == 0) { return; }
|
||||
if (i == 0) {
|
||||
return;
|
||||
}
|
||||
insn->id = insns[i].mapid;
|
||||
|
||||
if (insn->detail) {
|
||||
#ifndef CAPSTONE_DIET
|
||||
memcpy(insn->detail->regs_read, insns[i].regs_use,
|
||||
sizeof(insns[i].regs_use));
|
||||
sizeof(insns[i].regs_use));
|
||||
insn->detail->regs_read_count =
|
||||
(uint8_t)count_positive(insns[i].regs_use);
|
||||
|
||||
memcpy(insn->detail->regs_write, insns[i].regs_mod,
|
||||
sizeof(insns[i].regs_mod));
|
||||
sizeof(insns[i].regs_mod));
|
||||
insn->detail->regs_write_count =
|
||||
(uint8_t)count_positive(insns[i].regs_mod);
|
||||
|
||||
memcpy(insn->detail->groups, insns[i].groups,
|
||||
sizeof(insns[i].groups));
|
||||
sizeof(insns[i].groups));
|
||||
insn->detail->groups_count =
|
||||
(uint8_t)count_positive8(insns[i].groups);
|
||||
#endif
|
||||
|
|
@ -109,7 +111,7 @@ void Alpha_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
|||
|
||||
#ifndef CAPSTONE_DIET
|
||||
|
||||
static const char * const insn_names[] = {
|
||||
static const char *const insn_names[] = {
|
||||
#include "AlphaGenCSMappingInsnName.inc"
|
||||
};
|
||||
|
||||
|
|
@ -134,10 +136,10 @@ const char *Alpha_insn_name(csh handle, unsigned int id)
|
|||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map group_name_maps[] = {
|
||||
{Alpha_GRP_INVALID, NULL},
|
||||
{Alpha_GRP_CALL, "call"},
|
||||
{Alpha_GRP_JUMP, "jump"},
|
||||
{Alpha_GRP_BRANCH_RELATIVE, "branch_relative"},
|
||||
{ Alpha_GRP_INVALID, NULL },
|
||||
{ Alpha_GRP_CALL, "call" },
|
||||
{ Alpha_GRP_JUMP, "jump" },
|
||||
{ Alpha_GRP_BRANCH_RELATIVE, "branch_relative" },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -160,7 +162,7 @@ void Alpha_printInst(MCInst *MI, SStream *O, void *Info)
|
|||
Alpha_LLVM_printInstruction(MI, O, Info);
|
||||
}
|
||||
|
||||
void Alpha_set_instr_map_data(MCInst *MI)
|
||||
void Alpha_set_instr_map_data(MCInst *MI)
|
||||
{
|
||||
map_cs_id(MI, insns, ARR_SIZE(insns));
|
||||
map_implicit_reads(MI, insns);
|
||||
|
|
@ -168,13 +170,13 @@ void Alpha_set_instr_map_data(MCInst *MI)
|
|||
map_groups(MI, insns);
|
||||
}
|
||||
|
||||
bool Alpha_getInstruction(csh handle, const uint8_t *code,
|
||||
size_t code_len, MCInst *instr,
|
||||
uint16_t *size, uint64_t address, void *info)
|
||||
bool Alpha_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info)
|
||||
{
|
||||
Alpha_init_cs_detail(instr);
|
||||
DecodeStatus Result = Alpha_LLVM_getInstruction(handle, code, code_len, instr, size,
|
||||
address, info);
|
||||
DecodeStatus Result = Alpha_LLVM_getInstruction(
|
||||
handle, code, code_len, instr, size, address, info);
|
||||
Alpha_set_instr_map_data(instr);
|
||||
if (Result == MCDisassembler_SoftFail) {
|
||||
MCInst_setSoftFail(instr);
|
||||
|
|
@ -184,8 +186,8 @@ bool Alpha_getInstruction(csh handle, const uint8_t *code,
|
|||
|
||||
#ifndef CAPSTONE_DIET
|
||||
void Alpha_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count)
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t read_count, write_count;
|
||||
|
|
|
|||
|
|
@ -21,19 +21,19 @@ const char *Alpha_group_name(csh handle, unsigned int id);
|
|||
void Alpha_printInst(MCInst *MI, SStream *O, void *Info);
|
||||
|
||||
const char *Alpha_getRegisterName(csh handle, unsigned int id);
|
||||
bool Alpha_getInstruction(csh handle, const uint8_t *code,
|
||||
size_t code_len, MCInst *instr,
|
||||
uint16_t *size, uint64_t address, void *info);
|
||||
bool Alpha_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
void Alpha_init_cs_detail(MCInst *MI);
|
||||
void Alpha_add_cs_detail(MCInst *MI, unsigned OpNum);
|
||||
|
||||
void Alpha_set_instr_map_data(MCInst *MI);
|
||||
void Alpha_set_detail_op_imm(MCInst *MI, unsigned OpNum, alpha_op_type ImmType,
|
||||
int64_t Imm);
|
||||
int64_t Imm);
|
||||
void Alpha_set_detail_op_reg(MCInst *MI, unsigned OpNum, alpha_op_type Reg);
|
||||
|
||||
void Alpha_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,18 +10,21 @@
|
|||
|
||||
#define BPF_CLASS(code) ((code) & 0x7)
|
||||
|
||||
///< Instruction classes
|
||||
/// Instruction classes
|
||||
#define BPF_CLASS_LD 0x00
|
||||
#define BPF_CLASS_LDX 0x01
|
||||
#define BPF_CLASS_ST 0x02
|
||||
#define BPF_CLASS_STX 0x03
|
||||
#define BPF_CLASS_ALU 0x04
|
||||
#define BPF_CLASS_JMP 0x05
|
||||
#define BPF_CLASS_RET 0x06 ///< cBPF only
|
||||
#define BPF_CLASS_JMP32 0x06 ///< eBPF only
|
||||
#define BPF_CLASS_MISC 0x07 ///< cBPF only
|
||||
#define BPF_CLASS_ALU64 0x07 ///< eBPF only
|
||||
|
||||
/// cBPF only
|
||||
#define BPF_CLASS_RET 0x06
|
||||
/// eBPF only
|
||||
#define BPF_CLASS_JMP32 0x06
|
||||
/// cBPF only
|
||||
#define BPF_CLASS_MISC 0x07
|
||||
/// eBPF only
|
||||
#define BPF_CLASS_ALU64 0x07
|
||||
#define BPF_OP(code) ((code) & 0xf0)
|
||||
|
||||
///< Types of ALU instruction
|
||||
|
|
@ -36,46 +39,71 @@
|
|||
#define BPF_ALU_NEG 0x80
|
||||
#define BPF_ALU_MOD 0x90
|
||||
#define BPF_ALU_XOR 0xa0
|
||||
#define BPF_ALU_MOV 0xb0 ///< eBPF only: mov reg to reg
|
||||
#define BPF_ALU_ARSH 0xc0 ///< eBPF only: sign extending shift right
|
||||
#define BPF_ALU_END 0xd0 ///< eBPF only: endianness conversion
|
||||
/// eBPF only: mov reg to reg
|
||||
#define BPF_ALU_MOV 0xb0
|
||||
/// eBPF only: sign extending shift right
|
||||
#define BPF_ALU_ARSH 0xc0
|
||||
/// eBPF only: endianness conversion
|
||||
#define BPF_ALU_END 0xd0
|
||||
|
||||
///< Types of jmp instruction
|
||||
#define BPF_JUMP_JA 0x00 ///< goto
|
||||
#define BPF_JUMP_JEQ 0x10 ///< '=='
|
||||
#define BPF_JUMP_JGT 0x20 ///< unsigned '>'
|
||||
#define BPF_JUMP_JGE 0x30 ///< unsigned '>='
|
||||
#define BPF_JUMP_JSET 0x40 ///< '&'
|
||||
#define BPF_JUMP_JNE 0x50 ///< eBPF only: '!=' */
|
||||
#define BPF_JUMP_JSGT 0x60 ///< eBPF only: signed '>'
|
||||
#define BPF_JUMP_JSGE 0x70 ///< eBPF only: signed '>='
|
||||
#define BPF_JUMP_CALL 0x80 ///< eBPF only: function call
|
||||
#define BPF_JUMP_EXIT 0x90 ///< eBPF only: exit
|
||||
#define BPF_JUMP_JLT 0xa0 ///< eBPF only: unsigned '<'
|
||||
#define BPF_JUMP_JLE 0xb0 ///< eBPF only: unsigned '<='
|
||||
#define BPF_JUMP_JSLT 0xc0 ///< eBPF only: signed '<'
|
||||
#define BPF_JUMP_JSLE 0xd0 ///< eBPF only: signed '<='
|
||||
/// goto
|
||||
#define BPF_JUMP_JA 0x00
|
||||
/// '=='
|
||||
#define BPF_JUMP_JEQ 0x10
|
||||
/// unsigned '>'
|
||||
#define BPF_JUMP_JGT 0x20
|
||||
/// unsigned '>='
|
||||
#define BPF_JUMP_JGE 0x30
|
||||
/// '&'
|
||||
#define BPF_JUMP_JSET 0x40
|
||||
/// eBPF only: '!=' */
|
||||
#define BPF_JUMP_JNE 0x50
|
||||
/// eBPF only: signed '>'
|
||||
#define BPF_JUMP_JSGT 0x60
|
||||
/// eBPF only: signed '>='
|
||||
#define BPF_JUMP_JSGE 0x70
|
||||
/// eBPF only: function call
|
||||
#define BPF_JUMP_CALL 0x80
|
||||
/// eBPF only: exit
|
||||
#define BPF_JUMP_EXIT 0x90
|
||||
/// eBPF only: unsigned '<'
|
||||
#define BPF_JUMP_JLT 0xa0
|
||||
/// eBPF only: unsigned '<='
|
||||
#define BPF_JUMP_JLE 0xb0
|
||||
/// eBPF only: signed '<'
|
||||
#define BPF_JUMP_JSLT 0xc0
|
||||
/// eBPF only: signed '<='
|
||||
#define BPF_JUMP_JSLE 0xd0
|
||||
|
||||
///< Types of complex atomic instructions
|
||||
#define BPF_ATOMIC_XCHG 0xe0 ///< eBPF only: atomic exchange
|
||||
#define BPF_ATOMIC_CMPXCHG 0xf0 ///< eBPF only: atomic compare and exchange
|
||||
/// Types of complex atomic instructions
|
||||
/// eBPF only: atomic exchange
|
||||
#define BPF_ATOMIC_XCHG 0xe0
|
||||
/// eBPF only: atomic compare and exchange
|
||||
#define BPF_ATOMIC_CMPXCHG 0xf0
|
||||
|
||||
#define BPF_SRC(code) ((code) & 0x08)
|
||||
#define BPF_RVAL(code) ((code) & 0x18) /* cBPF only: for return types */
|
||||
///< Source operand
|
||||
/// cBPF only: for return types
|
||||
#define BPF_RVAL(code) ((code) & 0x18)
|
||||
/// Source operand
|
||||
#define BPF_SRC_K 0x00
|
||||
#define BPF_SRC_X 0x08
|
||||
#define BPF_SRC_A 0x10 /* cBPF only */
|
||||
/// cBPF only
|
||||
#define BPF_SRC_A 0x10
|
||||
|
||||
#define BPF_SRC_LITTLE BPF_SRC_K
|
||||
#define BPF_SRC_BIG BPF_SRC_X
|
||||
|
||||
#define BPF_SIZE(code) ((code) & 0x18)
|
||||
///< Size modifier
|
||||
#define BPF_SIZE_W 0x00 ///< word
|
||||
#define BPF_SIZE_H 0x08 ///< half word
|
||||
#define BPF_SIZE_B 0x10 ///< byte
|
||||
#define BPF_SIZE_DW 0x18 ///< eBPF only: double word
|
||||
/// Size modifier
|
||||
/// word
|
||||
#define BPF_SIZE_W 0x00
|
||||
/// half word
|
||||
#define BPF_SIZE_H 0x08
|
||||
/// byte
|
||||
#define BPF_SIZE_B 0x10
|
||||
/// eBPF only: double word
|
||||
#define BPF_SIZE_DW 0x18
|
||||
|
||||
#define BPF_MODE(code) ((code) & 0xe0)
|
||||
///< Mode modifier
|
||||
|
|
@ -85,18 +113,19 @@
|
|||
#define BPF_MODE_IND \
|
||||
0x40 ///< indirect indexing of socket buffer. eBPF only, but deprecated in new versions
|
||||
#define BPF_MODE_MEM 0x60
|
||||
#define BPF_MODE_LEN 0x80 ///< cBPF only, reserved in eBPF
|
||||
#define BPF_MODE_MSH 0xa0 ///< cBPF only, reserved in eBPF
|
||||
#define BPF_MODE_ATOMIC \
|
||||
0xc0 ///< eBPF only: atomic operations. Originally BPF_MODE_XADD
|
||||
|
||||
#define BPF_MODE_FETCH \
|
||||
0x01 /* eBPF only: overwrite 'src' with what was in the modified mem address before it was modified.
|
||||
NOTE: in contrast to regular modifiers, this one is encoded in the 'imm' field, not opcode!
|
||||
Must be used for BPF_XCHG and BPF_CMPXCHG. Optional for the other atomic operations. */
|
||||
/// cBPF only, reserved in eBPF
|
||||
#define BPF_MODE_LEN 0x80
|
||||
/// cBPF only, reserved in eBPF
|
||||
#define BPF_MODE_MSH 0xa0
|
||||
/// eBPF only: atomic operations. Originally BPF_MODE_XADD
|
||||
#define BPF_MODE_ATOMIC 0xc0
|
||||
|
||||
/// eBPF only: overwrite 'src' with what was in the modified mem address before it was modified.
|
||||
/// NOTE: in contrast to regular modifiers, this one is encoded in the 'imm' field, not opcode!
|
||||
/// Must be used for BPF_XCHG and BPF_CMPXCHG. Optional for the other atomic operations.
|
||||
#define BPF_MODE_FETCH 0x01
|
||||
#define BPF_MISCOP(code) ((code) & 0x80)
|
||||
///< Operation of misc
|
||||
/// Operation of misc
|
||||
#define BPF_MISCOP_TAX 0x00
|
||||
#define BPF_MISCOP_TXA 0x80
|
||||
|
||||
|
|
|
|||
|
|
@ -688,8 +688,8 @@ static bpf_insn op2insn_jmp(unsigned opcode)
|
|||
|
||||
#ifndef CAPSTONE_DIET
|
||||
|
||||
static void update_regs_access(MCInst *MI, cs_detail *detail,
|
||||
bpf_insn insn_id, unsigned int opcode)
|
||||
static void update_regs_access(MCInst *MI, cs_detail *detail, bpf_insn insn_id,
|
||||
unsigned int opcode)
|
||||
{
|
||||
if (insn_id == BPF_INS_INVALID)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ static void convert_operands(MCInst *MI, cs_bpf *bpf)
|
|||
case BPF_MODE_ABS:
|
||||
op = MCInst_getOperand(MI, 0);
|
||||
push_op_mem(bpf, BPF_REG_INVALID,
|
||||
(uint32_t)MCOperand_getImm(op), EBPF_MODE(MI->csh->mode), true);
|
||||
(uint32_t)MCOperand_getImm(op),
|
||||
EBPF_MODE(MI->csh->mode), true);
|
||||
break;
|
||||
case BPF_MODE_IND:
|
||||
op = MCInst_getOperand(MI, 0);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
/* By Andelf, 2025 */
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h> // offsetof macro
|
||||
// alternatively #include "../../utils.h" like everyone else
|
||||
#include <stddef.h>
|
||||
|
||||
#include "EVMDisassembler.h"
|
||||
#include "EVMMapping.h"
|
||||
|
|
@ -269,7 +268,8 @@ static const short opcodes[256] = {
|
|||
};
|
||||
|
||||
bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
|
||||
MCInst *MI, uint16_t *size, uint64_t address,
|
||||
void *inst_info)
|
||||
{
|
||||
unsigned char opcode;
|
||||
|
||||
|
|
@ -299,87 +299,105 @@ bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||
*size = 1;
|
||||
|
||||
if (MI->flat_insn->detail) {
|
||||
memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm));
|
||||
memset(MI->flat_insn->detail, 0,
|
||||
offsetof(cs_detail, evm) + sizeof(cs_evm));
|
||||
EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
|
||||
|
||||
if (MI->flat_insn->detail->evm.pop) {
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ;
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_STACK_READ;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
}
|
||||
|
||||
if (MI->flat_insn->detail->evm.push) {
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_WRITE;
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_STACK_WRITE;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
}
|
||||
|
||||
// setup groups
|
||||
switch(opcode) {
|
||||
default:
|
||||
break;
|
||||
case EVM_INS_ADD:
|
||||
case EVM_INS_MUL:
|
||||
case EVM_INS_SUB:
|
||||
case EVM_INS_DIV:
|
||||
case EVM_INS_SDIV:
|
||||
case EVM_INS_MOD:
|
||||
case EVM_INS_SMOD:
|
||||
case EVM_INS_ADDMOD:
|
||||
case EVM_INS_MULMOD:
|
||||
case EVM_INS_EXP:
|
||||
case EVM_INS_SIGNEXTEND:
|
||||
case EVM_INS_SHL:
|
||||
case EVM_INS_SHR:
|
||||
case EVM_INS_SAR:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
switch (opcode) {
|
||||
default:
|
||||
break;
|
||||
case EVM_INS_ADD:
|
||||
case EVM_INS_MUL:
|
||||
case EVM_INS_SUB:
|
||||
case EVM_INS_DIV:
|
||||
case EVM_INS_SDIV:
|
||||
case EVM_INS_MOD:
|
||||
case EVM_INS_SMOD:
|
||||
case EVM_INS_ADDMOD:
|
||||
case EVM_INS_MULMOD:
|
||||
case EVM_INS_EXP:
|
||||
case EVM_INS_SIGNEXTEND:
|
||||
case EVM_INS_SHL:
|
||||
case EVM_INS_SHR:
|
||||
case EVM_INS_SAR:
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_MATH;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
||||
case EVM_INS_MSTORE:
|
||||
case EVM_INS_MSTORE8:
|
||||
case EVM_INS_CALLDATACOPY:
|
||||
case EVM_INS_CODECOPY:
|
||||
case EVM_INS_EXTCODECOPY:
|
||||
case EVM_INS_MCOPY:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
case EVM_INS_MSTORE:
|
||||
case EVM_INS_MSTORE8:
|
||||
case EVM_INS_CALLDATACOPY:
|
||||
case EVM_INS_CODECOPY:
|
||||
case EVM_INS_EXTCODECOPY:
|
||||
case EVM_INS_MCOPY:
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_MEM_WRITE;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
||||
case EVM_INS_MLOAD:
|
||||
case EVM_INS_CREATE:
|
||||
case EVM_INS_CALL:
|
||||
case EVM_INS_CALLCODE:
|
||||
case EVM_INS_RETURN:
|
||||
case EVM_INS_DELEGATECALL:
|
||||
case EVM_INS_REVERT:
|
||||
case EVM_INS_CREATE2:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_READ;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
case EVM_INS_MLOAD:
|
||||
case EVM_INS_CREATE:
|
||||
case EVM_INS_CALL:
|
||||
case EVM_INS_CALLCODE:
|
||||
case EVM_INS_RETURN:
|
||||
case EVM_INS_DELEGATECALL:
|
||||
case EVM_INS_REVERT:
|
||||
case EVM_INS_CREATE2:
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_MEM_READ;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
||||
case EVM_INS_SSTORE:
|
||||
case EVM_INS_TSTORE:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_WRITE;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
case EVM_INS_SSTORE:
|
||||
case EVM_INS_TSTORE:
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_STORE_WRITE;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
||||
case EVM_INS_SLOAD:
|
||||
case EVM_INS_TLOAD:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
case EVM_INS_SLOAD:
|
||||
case EVM_INS_TLOAD:
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_STORE_READ;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
||||
case EVM_INS_JUMP:
|
||||
case EVM_INS_JUMPI:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_JUMP;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
||||
case EVM_INS_STOP:
|
||||
case EVM_INS_SELFDESTRUCT:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
case EVM_INS_JUMP:
|
||||
case EVM_INS_JUMPI:
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_JUMP;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
||||
case EVM_INS_STOP:
|
||||
case EVM_INS_SELFDESTRUCT:
|
||||
MI->flat_insn->detail
|
||||
->groups[MI->flat_insn->detail->groups_count] =
|
||||
EVM_GRP_HALT;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "../../MCInst.h"
|
||||
|
||||
bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address, void *info);
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include "EVMInstPrinter.h"
|
||||
#include "EVMMapping.h"
|
||||
|
||||
|
||||
void EVM_printInst(MCInst *MI, struct SStream *O, void *PrinterInfo)
|
||||
{
|
||||
SStream_concat0(O, EVM_insn_name((csh)MI->csh, MI->Opcode));
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#ifndef CS_EVMINSTPRINTER_H
|
||||
#define CS_EVMINSTPRINTER_H
|
||||
|
||||
|
||||
#include "capstone/capstone.h"
|
||||
#include "../../MCInst.h"
|
||||
#include "../../SStream.h"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ void EVM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
|||
#ifndef CAPSTONE_DIET
|
||||
if (evm_insn_find(insns, ARR_SIZE(insns), id) > 0) {
|
||||
if (h->detail_opt) {
|
||||
memcpy(&insn->detail->evm, &insns[id], sizeof(insns[id]));
|
||||
memcpy(&insn->detail->evm, &insns[id],
|
||||
sizeof(insns[id]));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -322,9 +323,9 @@ const char *EVM_insn_name(csh handle, unsigned int id)
|
|||
static const name_map group_name_maps[] = {
|
||||
// generic groups
|
||||
{ EVM_GRP_INVALID, NULL },
|
||||
{ EVM_GRP_JUMP, "jump" },
|
||||
{ EVM_GRP_JUMP, "jump" },
|
||||
// special groups
|
||||
{ EVM_GRP_MATH, "math" },
|
||||
{ EVM_GRP_MATH, "math" },
|
||||
{ EVM_GRP_STACK_WRITE, "stack_write" },
|
||||
{ EVM_GRP_STACK_READ, "stack_read" },
|
||||
{ EVM_GRP_MEM_WRITE, "mem_write" },
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#define CS_HPPA_CONSTANTS_H
|
||||
|
||||
#define HPPA_OP_TYPE(byte) (byte) >> 2
|
||||
#define MODE_IS_HPPA_20(mode) (((mode)&CS_MODE_HPPA_20) != 0)
|
||||
#define MODE_IS_HPPA_20(mode) (((mode) & CS_MODE_HPPA_20) != 0)
|
||||
#define MODE_IS_HPPA_20W(mode) (((mode) & (1 << 3)) != 0)
|
||||
|
||||
///> HPPA opcode types
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "../../MathExtras.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
#define CMPLT_HAS_MODIFY_BIT(CMPLT) (((CMPLT)&1) == 1)
|
||||
#define CMPLT_HAS_MODIFY_BIT(CMPLT) (((CMPLT) & 1) == 1)
|
||||
|
||||
#define HPPA_EXT_REF(MI) (&MI->hppa_ext)
|
||||
|
||||
|
|
@ -177,17 +177,18 @@ static int32_t extract_21(unsigned word)
|
|||
val |= get_insn_field(word, 0, 4);
|
||||
val <<= 2;
|
||||
val |= get_insn_field(word, 7, 8);
|
||||
return (uint32_t) SignExtend32(val, 21) << 11;
|
||||
return (uint32_t)SignExtend32(val, 21) << 11;
|
||||
}
|
||||
|
||||
/* Extract a 12 bit constant from branch instructions. */
|
||||
|
||||
static int32_t extract_12(unsigned word)
|
||||
{
|
||||
return (uint32_t) SignExtend32(get_insn_field(word, 19, 28) |
|
||||
get_insn_field(word, 29, 29) << 10 |
|
||||
(word & 0x1) << 11,
|
||||
12)
|
||||
return (uint32_t)SignExtend32(get_insn_field(word, 19, 28) |
|
||||
get_insn_field(word, 29, 29)
|
||||
<< 10 |
|
||||
(word & 0x1) << 11,
|
||||
12)
|
||||
<< 2;
|
||||
}
|
||||
|
||||
|
|
@ -196,22 +197,24 @@ static int32_t extract_12(unsigned word)
|
|||
|
||||
static int32_t extract_17(unsigned word)
|
||||
{
|
||||
return (uint32_t) SignExtend32(get_insn_field(word, 19, 28) |
|
||||
get_insn_field(word, 29, 29) << 10 |
|
||||
get_insn_field(word, 11, 15) << 11 |
|
||||
(word & 0x1) << 16,
|
||||
17)
|
||||
return (uint32_t)SignExtend32(
|
||||
get_insn_field(word, 19, 28) |
|
||||
get_insn_field(word, 29, 29) << 10 |
|
||||
get_insn_field(word, 11, 15) << 11 |
|
||||
(word & 0x1) << 16,
|
||||
17)
|
||||
<< 2;
|
||||
}
|
||||
|
||||
static int32_t extract_22(unsigned word)
|
||||
{
|
||||
return (uint32_t) SignExtend32(get_insn_field(word, 19, 28) |
|
||||
get_insn_field(word, 29, 29) << 10 |
|
||||
get_insn_field(word, 11, 15) << 11 |
|
||||
get_insn_field(word, 6, 10) << 16 |
|
||||
(word & 0x1) << 21,
|
||||
22)
|
||||
return (uint32_t)SignExtend32(
|
||||
get_insn_field(word, 19, 28) |
|
||||
get_insn_field(word, 29, 29) << 10 |
|
||||
get_insn_field(word, 11, 15) << 11 |
|
||||
get_insn_field(word, 6, 10) << 16 |
|
||||
(word & 0x1) << 21,
|
||||
22)
|
||||
<< 2;
|
||||
}
|
||||
|
||||
|
|
@ -2888,7 +2891,7 @@ static bool decode_copr(const cs_struct *ud, MCInst *MI, uint32_t insn)
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
subop = get_insn_field(insn, 16, 18);
|
||||
switch (subop) {
|
||||
case 0x00:
|
||||
|
|
|
|||
|
|
@ -702,7 +702,7 @@ static void fill_operands(MCInst *MI, cs_hppa *hppa)
|
|||
idx++);
|
||||
}
|
||||
CS_ASSERT_RET(space_reg_idx <
|
||||
ARR_SIZE(space_regs));
|
||||
ARR_SIZE(space_regs));
|
||||
space_regs[space_reg_idx] =
|
||||
MCOperand_getReg(op);
|
||||
if (*fmt == 'R') {
|
||||
|
|
|
|||
|
|
@ -258,26 +258,26 @@ void LoongArch_rewrite_memory_operand(MCInst *MI)
|
|||
}
|
||||
|
||||
switch (suppl_info->form) {
|
||||
case LOONGARCH_INSN_FORM_FMT2RI12: // ld, ldl, ldr, st, stl, str
|
||||
case LOONGARCH_INSN_FORM_FMT2RI14: // ll, sc, ldptr, stptr
|
||||
case LOONGARCH_INSN_FORM_FMT2RI9_VRI: // vldrepl.d
|
||||
case LOONGARCH_INSN_FORM_FMT2RI10_VRI: // vldrepl.w
|
||||
case LOONGARCH_INSN_FORM_FMT2RI11_VRI: // vldrepl.h
|
||||
case LOONGARCH_INSN_FORM_FMT2RI12_VRI: // vld, vldrepl, vst
|
||||
case LOONGARCH_INSN_FORM_FMT2RI12: // ld, ldl, ldr, st, stl, str
|
||||
case LOONGARCH_INSN_FORM_FMT2RI14: // ll, sc, ldptr, stptr
|
||||
case LOONGARCH_INSN_FORM_FMT2RI9_VRI: // vldrepl.d
|
||||
case LOONGARCH_INSN_FORM_FMT2RI10_VRI: // vldrepl.w
|
||||
case LOONGARCH_INSN_FORM_FMT2RI11_VRI: // vldrepl.h
|
||||
case LOONGARCH_INSN_FORM_FMT2RI12_VRI: // vld, vldrepl, vst
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I1_VRII: // vstelm.d
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I2_VRII: // vstelm.w
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I3_VRII: // vstelm.h
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I4_VRII: // vstelm.b
|
||||
case LOONGARCH_INSN_FORM_FMT2RI9_XRI: // xvldrepl.d
|
||||
case LOONGARCH_INSN_FORM_FMT2RI10_XRI: // xvldrepl.w
|
||||
case LOONGARCH_INSN_FORM_FMT2RI11_XRI: // xvldrepl.h
|
||||
case LOONGARCH_INSN_FORM_FMT2RI12_XRI: // xvld, xvldrepl, xvst
|
||||
case LOONGARCH_INSN_FORM_FMT2RI9_XRI: // xvldrepl.d
|
||||
case LOONGARCH_INSN_FORM_FMT2RI10_XRI: // xvldrepl.w
|
||||
case LOONGARCH_INSN_FORM_FMT2RI11_XRI: // xvldrepl.h
|
||||
case LOONGARCH_INSN_FORM_FMT2RI12_XRI: // xvld, xvldrepl, xvst
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I2_XRII: // xvstelm.d
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I3_XRII: // xvstelm.w
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I4_XRII: // xvstelm.h
|
||||
case LOONGARCH_INSN_FORM_FMT2RI8I5_XRII: // xvstelm.b
|
||||
case LOONGARCH_INSN_FORM_FMTPRELD: // preld
|
||||
case LOONGARCH_INSN_FORM_FPFMT2RI12: // fld, fst
|
||||
case LOONGARCH_INSN_FORM_FMTPRELD: // preld
|
||||
case LOONGARCH_INSN_FORM_FPFMT2RI12: // fld, fst
|
||||
// immediate offset
|
||||
LoongArch_get_detail_op(MI, -2)->type = LOONGARCH_OP_MEM;
|
||||
base = LoongArch_get_detail_op(MI, -2)->reg;
|
||||
|
|
@ -303,7 +303,7 @@ void LoongArch_rewrite_memory_operand(MCInst *MI)
|
|||
}
|
||||
// fallthrough
|
||||
|
||||
case LOONGARCH_INSN_FORM_FPFMTMEM: // fldx, fstx
|
||||
case LOONGARCH_INSN_FORM_FPFMTMEM: // fldx, fstx
|
||||
case LOONGARCH_INSN_FORM_FMT3R_VRR: // vldx, vstx
|
||||
case LOONGARCH_INSN_FORM_FMT3R_XRR: // xvldx, xvstx
|
||||
case LOONGARCH_INSN_FORM_FMTPRELDX: // preldx
|
||||
|
|
@ -386,8 +386,8 @@ bool LoongArch_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
|||
{
|
||||
uint64_t temp_size;
|
||||
LoongArch_init_cs_detail(instr);
|
||||
DecodeStatus Result = LoongArch_LLVM_getInstruction(instr, &temp_size, code,
|
||||
code_len, address, info);
|
||||
DecodeStatus Result = LoongArch_LLVM_getInstruction(
|
||||
instr, &temp_size, code, code_len, address, info);
|
||||
LoongArch_set_instr_map_data(instr);
|
||||
*size = temp_size;
|
||||
if (Result == MCDisassembler_SoftFail) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -7,11 +7,11 @@
|
|||
#include "../../MCInst.h"
|
||||
|
||||
bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address, void *info);
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
void M680X_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
||||
void M680X_reg_access(const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
void M680X_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -9,17 +9,17 @@
|
|||
|
||||
typedef enum e_cpu_type {
|
||||
M680X_CPU_TYPE_INVALID,
|
||||
M680X_CPU_TYPE_6301, // M680X Hitachi HD6301,HD6303 mode
|
||||
M680X_CPU_TYPE_6309, // M680X Hitachi HD6309 mode
|
||||
M680X_CPU_TYPE_6800, // M680X Motorola 6800,6802 mode
|
||||
M680X_CPU_TYPE_6801, // M680X Motorola 6801,6803 mode
|
||||
M680X_CPU_TYPE_6805, // M680X Motorola/Freescale M68HC05 mode
|
||||
M680X_CPU_TYPE_6808, // M680X Motorola/Freescale M68HC08 mode
|
||||
M680X_CPU_TYPE_6809, // M680X Motorola 6809 mode
|
||||
M680X_CPU_TYPE_6811, // M680X Motorola/Freescale M68HC11 mode
|
||||
M680X_CPU_TYPE_CPU12, // M680X Motorola/Freescale CPU12 mode
|
||||
M680X_CPU_TYPE_6301, // M680X Hitachi HD6301,HD6303 mode
|
||||
M680X_CPU_TYPE_6309, // M680X Hitachi HD6309 mode
|
||||
M680X_CPU_TYPE_6800, // M680X Motorola 6800,6802 mode
|
||||
M680X_CPU_TYPE_6801, // M680X Motorola 6801,6803 mode
|
||||
M680X_CPU_TYPE_6805, // M680X Motorola/Freescale M68HC05 mode
|
||||
M680X_CPU_TYPE_6808, // M680X Motorola/Freescale M68HC08 mode
|
||||
M680X_CPU_TYPE_6809, // M680X Motorola 6809 mode
|
||||
M680X_CPU_TYPE_6811, // M680X Motorola/Freescale M68HC11 mode
|
||||
M680X_CPU_TYPE_CPU12, // M680X Motorola/Freescale CPU12 mode
|
||||
// used on M68HC12/HCS12
|
||||
M680X_CPU_TYPE_HCS08, // M680X Freescale HCS08 mode
|
||||
M680X_CPU_TYPE_HCS08, // M680X Freescale HCS08 mode
|
||||
M680X_CPU_TYPE_ENDING,
|
||||
} e_cpu_type;
|
||||
|
||||
|
|
@ -40,18 +40,17 @@ typedef struct {
|
|||
|
||||
/* Private, For internal use only */
|
||||
typedef struct m680x_info {
|
||||
const uint8_t *code; // code buffer
|
||||
uint32_t size; // byte size of code
|
||||
uint16_t offset; // address offset of first byte in code buffer
|
||||
e_cpu_type cpu_type; // The CPU type to be used for disassembling
|
||||
cs_m680x m680x; // M680X specific properties
|
||||
const uint8_t *code; // code buffer
|
||||
uint32_t size; // byte size of code
|
||||
uint16_t offset; // address offset of first byte in code buffer
|
||||
e_cpu_type cpu_type; // The CPU type to be used for disassembling
|
||||
cs_m680x m680x; // M680X specific properties
|
||||
const cpu_tables *cpu;
|
||||
m680x_insn insn; // Instruction ID
|
||||
uint8_t insn_size; // byte size of instruction
|
||||
m680x_insn insn; // Instruction ID
|
||||
uint8_t insn_size; // byte size of instruction
|
||||
} m680x_info;
|
||||
|
||||
extern cs_err M680X_disassembler_init(cs_struct *ud);
|
||||
extern cs_err M680X_instprinter_init(cs_struct *ud);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -20,84 +20,67 @@
|
|||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const char s_reg_names[][10] = {
|
||||
"<invalid>", "a", "b", "e", "f", "0", "d", "w", "cc", "dp", "md",
|
||||
"hx", "h", "x", "y", "s", "u", "v", "q", "pc", "tmp2", "tmp3",
|
||||
"<invalid>", "a", "b", "e", "f", "0", "d", "w", "cc", "dp", "md",
|
||||
"hx", "h", "x", "y", "s", "u", "v", "q", "pc", "tmp2", "tmp3",
|
||||
};
|
||||
|
||||
static const char s_instruction_names[][6] = {
|
||||
"invld", "aba", "abx", "aby", "adc", "adca", "adcb", "adcd", "adcr",
|
||||
"add", "adda", "addb", "addd", "adde", "addf", "addr", "addw",
|
||||
"aim", "ais", "aix", "and", "anda", "andb", "andcc", "andd", "andr",
|
||||
"asl", "asla", "aslb", "asld",
|
||||
"asr", "asra", "asrb", "asrd", "asrx",
|
||||
"band",
|
||||
"bcc", "bclr", "bcs", "beor", "beq", "bge", "bgnd", "bgt", "bhcc",
|
||||
"bhcs", "bhi",
|
||||
"biand", "bieor", "bih", "bil",
|
||||
"bior", "bit", "bita", "bitb", "bitd", "bitmd", "ble", "bls", "blt",
|
||||
"bmc",
|
||||
"bmi", "bms",
|
||||
"bne", "bor", "bpl", "brclr", "brset", "bra", "brn", "bset", "bsr",
|
||||
"bvc", "bvs",
|
||||
"call", "cba", "cbeq", "cbeqa", "cbeqx", "clc", "cli",
|
||||
"clr", "clra", "clrb", "clrd", "clre", "clrf", "clrh", "clrw", "clrx",
|
||||
"clv", "cmp",
|
||||
"cmpa", "cmpb", "cmpd", "cmpe", "cmpf", "cmpr", "cmps", "cmpu", "cmpw",
|
||||
"cmpx", "cmpy",
|
||||
"com", "coma", "comb", "comd", "come", "comf", "comw", "comx", "cpd",
|
||||
"cphx", "cps", "cpx", "cpy",
|
||||
"cwai", "daa", "dbeq", "dbne", "dbnz", "dbnza", "dbnzx",
|
||||
"dec", "deca", "decb", "decd", "dece", "decf", "decw",
|
||||
"decx", "des", "dex", "dey",
|
||||
"div", "divd", "divq", "ediv", "edivs", "eim", "emacs", "emaxd",
|
||||
"emaxm", "emind", "eminm", "emul", "emuls",
|
||||
"eor", "eora", "eorb", "eord", "eorr", "etbl",
|
||||
"exg", "fdiv", "ibeq", "ibne", "idiv", "idivs", "illgl",
|
||||
"inc", "inca", "incb", "incd", "ince", "incf", "incw", "incx",
|
||||
"ins", "inx", "iny",
|
||||
"jmp", "jsr",
|
||||
"lbcc", "lbcs", "lbeq", "lbge", "lbgt", "lbhi", "lble", "lbls", "lblt",
|
||||
"lbmi", "lbne", "lbpl", "lbra", "lbrn", "lbsr", "lbvc", "lbvs",
|
||||
"lda", "ldaa", "ldab", "ldb", "ldbt", "ldd", "lde", "ldf", "ldhx",
|
||||
"ldmd",
|
||||
"ldq", "lds", "ldu", "ldw", "ldx", "ldy",
|
||||
"leas", "leau", "leax", "leay",
|
||||
"lsl", "lsla", "lslb", "lsld", "lslx",
|
||||
"lsr", "lsra", "lsrb", "lsrd", "lsrw", "lsrx",
|
||||
"maxa", "maxm", "mem", "mina", "minm", "mov", "movb", "movw", "mul",
|
||||
"muld",
|
||||
"neg", "nega", "negb", "negd", "negx",
|
||||
"nop", "nsa", "oim", "ora", "oraa", "orab", "orb", "orcc", "ord", "orr",
|
||||
"psha", "pshb", "pshc", "pshd", "pshh", "pshs", "pshsw", "pshu",
|
||||
"pshuw", "pshx", "pshy",
|
||||
"pula", "pulb", "pulc", "puld", "pulh", "puls", "pulsw", "pulu",
|
||||
"puluw", "pulx", "puly", "rev", "revw",
|
||||
"rol", "rola", "rolb", "rold", "rolw", "rolx",
|
||||
"ror", "rora", "rorb", "rord", "rorw", "rorx",
|
||||
"rsp", "rtc", "rti", "rts", "sba", "sbc", "sbca", "sbcb", "sbcd",
|
||||
"sbcr",
|
||||
"sec", "sei", "sev", "sex", "sexw", "slp", "sta", "staa", "stab", "stb",
|
||||
"stbt", "std", "ste", "stf", "stop", "sthx",
|
||||
"stq", "sts", "stu", "stw", "stx", "sty",
|
||||
"sub", "suba", "subb", "subd", "sube", "subf", "subr", "subw",
|
||||
"swi", "swi2", "swi3",
|
||||
"sync", "tab", "tap", "tax", "tba", "tbeq", "tbl", "tbne", "test",
|
||||
"tfm", "tfr",
|
||||
"tim", "tpa",
|
||||
"tst", "tsta", "tstb", "tstd", "tste", "tstf", "tstw", "tstx",
|
||||
"tsx", "tsy", "txa", "txs", "tys", "wai", "wait", "wav", "wavr",
|
||||
"xgdx", "xgdy",
|
||||
"invld", "aba", "abx", "aby", "adc", "adca", "adcb", "adcd",
|
||||
"adcr", "add", "adda", "addb", "addd", "adde", "addf", "addr",
|
||||
"addw", "aim", "ais", "aix", "and", "anda", "andb", "andcc",
|
||||
"andd", "andr", "asl", "asla", "aslb", "asld", "asr", "asra",
|
||||
"asrb", "asrd", "asrx", "band", "bcc", "bclr", "bcs", "beor",
|
||||
"beq", "bge", "bgnd", "bgt", "bhcc", "bhcs", "bhi", "biand",
|
||||
"bieor", "bih", "bil", "bior", "bit", "bita", "bitb", "bitd",
|
||||
"bitmd", "ble", "bls", "blt", "bmc", "bmi", "bms", "bne",
|
||||
"bor", "bpl", "brclr", "brset", "bra", "brn", "bset", "bsr",
|
||||
"bvc", "bvs", "call", "cba", "cbeq", "cbeqa", "cbeqx", "clc",
|
||||
"cli", "clr", "clra", "clrb", "clrd", "clre", "clrf", "clrh",
|
||||
"clrw", "clrx", "clv", "cmp", "cmpa", "cmpb", "cmpd", "cmpe",
|
||||
"cmpf", "cmpr", "cmps", "cmpu", "cmpw", "cmpx", "cmpy", "com",
|
||||
"coma", "comb", "comd", "come", "comf", "comw", "comx", "cpd",
|
||||
"cphx", "cps", "cpx", "cpy", "cwai", "daa", "dbeq", "dbne",
|
||||
"dbnz", "dbnza", "dbnzx", "dec", "deca", "decb", "decd", "dece",
|
||||
"decf", "decw", "decx", "des", "dex", "dey", "div", "divd",
|
||||
"divq", "ediv", "edivs", "eim", "emacs", "emaxd", "emaxm", "emind",
|
||||
"eminm", "emul", "emuls", "eor", "eora", "eorb", "eord", "eorr",
|
||||
"etbl", "exg", "fdiv", "ibeq", "ibne", "idiv", "idivs", "illgl",
|
||||
"inc", "inca", "incb", "incd", "ince", "incf", "incw", "incx",
|
||||
"ins", "inx", "iny", "jmp", "jsr", "lbcc", "lbcs", "lbeq",
|
||||
"lbge", "lbgt", "lbhi", "lble", "lbls", "lblt", "lbmi", "lbne",
|
||||
"lbpl", "lbra", "lbrn", "lbsr", "lbvc", "lbvs", "lda", "ldaa",
|
||||
"ldab", "ldb", "ldbt", "ldd", "lde", "ldf", "ldhx", "ldmd",
|
||||
"ldq", "lds", "ldu", "ldw", "ldx", "ldy", "leas", "leau",
|
||||
"leax", "leay", "lsl", "lsla", "lslb", "lsld", "lslx", "lsr",
|
||||
"lsra", "lsrb", "lsrd", "lsrw", "lsrx", "maxa", "maxm", "mem",
|
||||
"mina", "minm", "mov", "movb", "movw", "mul", "muld", "neg",
|
||||
"nega", "negb", "negd", "negx", "nop", "nsa", "oim", "ora",
|
||||
"oraa", "orab", "orb", "orcc", "ord", "orr", "psha", "pshb",
|
||||
"pshc", "pshd", "pshh", "pshs", "pshsw", "pshu", "pshuw", "pshx",
|
||||
"pshy", "pula", "pulb", "pulc", "puld", "pulh", "puls", "pulsw",
|
||||
"pulu", "puluw", "pulx", "puly", "rev", "revw", "rol", "rola",
|
||||
"rolb", "rold", "rolw", "rolx", "ror", "rora", "rorb", "rord",
|
||||
"rorw", "rorx", "rsp", "rtc", "rti", "rts", "sba", "sbc",
|
||||
"sbca", "sbcb", "sbcd", "sbcr", "sec", "sei", "sev", "sex",
|
||||
"sexw", "slp", "sta", "staa", "stab", "stb", "stbt", "std",
|
||||
"ste", "stf", "stop", "sthx", "stq", "sts", "stu", "stw",
|
||||
"stx", "sty", "sub", "suba", "subb", "subd", "sube", "subf",
|
||||
"subr", "subw", "swi", "swi2", "swi3", "sync", "tab", "tap",
|
||||
"tax", "tba", "tbeq", "tbl", "tbne", "test", "tfm", "tfr",
|
||||
"tim", "tpa", "tst", "tsta", "tstb", "tstd", "tste", "tstf",
|
||||
"tstw", "tstx", "tsx", "tsy", "txa", "txs", "tys", "wai",
|
||||
"wait", "wav", "wavr", "xgdx", "xgdy",
|
||||
};
|
||||
|
||||
static const name_map s_group_names[] = {
|
||||
{ M680X_GRP_INVALID, "<invalid>" },
|
||||
{ M680X_GRP_JUMP, "jump" },
|
||||
{ M680X_GRP_CALL, "call" },
|
||||
{ M680X_GRP_JUMP, "jump" },
|
||||
{ M680X_GRP_CALL, "call" },
|
||||
{ M680X_GRP_RET, "return" },
|
||||
{ M680X_GRP_INT, "interrupt" },
|
||||
{ M680X_GRP_IRET, "interrupt_return" },
|
||||
{ M680X_GRP_PRIV, "privileged" },
|
||||
{ M680X_GRP_BRAREL, "branch_relative" },
|
||||
{ M680X_GRP_IRET, "interrupt_return" },
|
||||
{ M680X_GRP_PRIV, "privileged" },
|
||||
{ M680X_GRP_BRAREL, "branch_relative" },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -109,7 +92,7 @@ static void printRegName(cs_struct *handle, SStream *OS, unsigned int reg)
|
|||
}
|
||||
|
||||
static void printInstructionName(cs_struct *handle, SStream *OS,
|
||||
unsigned int insn)
|
||||
unsigned int insn)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
SStream_concat0(OS, handle->insn_name((csh)handle, insn));
|
||||
|
|
@ -132,7 +115,7 @@ static uint32_t get_unsigned(int32_t value, int byte_size)
|
|||
}
|
||||
|
||||
static void printIncDec(bool isPost, SStream *O, m680x_info *info,
|
||||
cs_m680x_op *op)
|
||||
cs_m680x_op *op)
|
||||
{
|
||||
static const char s_inc_dec[][3] = { "--", "-", "", "+", "++" };
|
||||
|
||||
|
|
@ -140,7 +123,7 @@ static void printIncDec(bool isPost, SStream *O, m680x_info *info,
|
|||
return;
|
||||
|
||||
if ((!isPost && !(op->idx.flags & M680X_IDX_POST_INC_DEC)) ||
|
||||
(isPost && (op->idx.flags & M680X_IDX_POST_INC_DEC))) {
|
||||
(isPost && (op->idx.flags & M680X_IDX_POST_INC_DEC))) {
|
||||
const char *prePostfix = "";
|
||||
|
||||
if (info->cpu_type == M680X_CPU_TYPE_CPU12)
|
||||
|
|
@ -154,7 +137,7 @@ static void printIncDec(bool isPost, SStream *O, m680x_info *info,
|
|||
}
|
||||
|
||||
static void printOperand(MCInst *MI, SStream *O, m680x_info *info,
|
||||
cs_m680x_op *op)
|
||||
cs_m680x_op *op)
|
||||
{
|
||||
switch (op->type) {
|
||||
case M680X_OP_REGISTER:
|
||||
|
|
@ -168,7 +151,7 @@ static void printOperand(MCInst *MI, SStream *O, m680x_info *info,
|
|||
case M680X_OP_IMMEDIATE:
|
||||
if (MI->csh->imm_unsigned)
|
||||
SStream_concat(O, "#%u",
|
||||
get_unsigned(op->imm, op->size));
|
||||
get_unsigned(op->imm, op->size));
|
||||
else
|
||||
SStream_concat(O, "#%d", op->imm);
|
||||
|
||||
|
|
@ -185,9 +168,8 @@ static void printOperand(MCInst *MI, SStream *O, m680x_info *info,
|
|||
SStream_concat(O, "$%04x", op->idx.offset_addr);
|
||||
else
|
||||
SStream_concat(O, "%d", op->idx.offset);
|
||||
}
|
||||
else if (op->idx.inc_dec != 0 &&
|
||||
info->cpu_type == M680X_CPU_TYPE_CPU12)
|
||||
} else if (op->idx.inc_dec != 0 &&
|
||||
info->cpu_type == M680X_CPU_TYPE_CPU12)
|
||||
SStream_concat(O, "%d", abs(op->idx.inc_dec));
|
||||
|
||||
if (!(op->idx.flags & M680X_IDX_NO_COMMA))
|
||||
|
|
@ -198,7 +180,7 @@ static void printOperand(MCInst *MI, SStream *O, m680x_info *info,
|
|||
printRegName(MI->csh, O, op->idx.base_reg);
|
||||
|
||||
if (op->idx.base_reg == M680X_REG_PC &&
|
||||
(op->idx.offset_bits > 0))
|
||||
(op->idx.offset_bits > 0))
|
||||
SStream_concat(O, "r");
|
||||
|
||||
printIncDec(true, O, info, op);
|
||||
|
|
@ -222,8 +204,7 @@ static void printOperand(MCInst *MI, SStream *O, m680x_info *info,
|
|||
else {
|
||||
if (op->ext.address < 256) {
|
||||
SStream_concat(O, ">$%04x", op->ext.address);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SStream_concat(O, "$%04x", op->ext.address);
|
||||
}
|
||||
}
|
||||
|
|
@ -246,7 +227,7 @@ static const char *getDelimiter(m680x_info *info, cs_m680x *m680x)
|
|||
return ", ";
|
||||
|
||||
if (m680x->op_count > 1) {
|
||||
for (i = 0; i < m680x->op_count; ++i) {
|
||||
for (i = 0; i < m680x->op_count; ++i) {
|
||||
if (m680x->operands[i].type == M680X_OP_INDEXED)
|
||||
indexed = true;
|
||||
|
||||
|
|
@ -288,7 +269,7 @@ void M680X_printInst(MCInst *MI, SStream *O, void *PrinterInfo)
|
|||
if ((m680x->flags & M680X_SECOND_OP_IN_MNEM) != 0)
|
||||
suppress_operands++;
|
||||
|
||||
for (i = 0; i < m680x->op_count; ++i) {
|
||||
for (i = 0; i < m680x->op_count; ++i) {
|
||||
if (i >= suppress_operands) {
|
||||
printOperand(MI, O, info, &m680x->operands[i]);
|
||||
|
||||
|
|
@ -359,4 +340,3 @@ cs_err M680X_instprinter_init(cs_struct *ud)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#ifndef CS_M680XINSTPRINTER_H
|
||||
#define CS_M680XINSTPRINTER_H
|
||||
|
||||
|
||||
#include "capstone/capstone.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "../../MCInst.h"
|
||||
|
|
@ -18,8 +17,6 @@ const char *M680X_reg_name(csh handle, unsigned int reg);
|
|||
const char *M680X_insn_name(csh handle, unsigned int id);
|
||||
const char *M680X_group_name(csh handle, unsigned int id);
|
||||
void M680X_post_printer(csh handle, cs_insn *flat_insn, char *insn_asm,
|
||||
MCInst *mci);
|
||||
MCInst *mci);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,26 +21,26 @@ cs_err M680X_global_init(cs_struct *ud)
|
|||
if (errcode != CS_ERR_OK)
|
||||
return errcode;
|
||||
|
||||
errcode = M680X_instprinter_init(ud);
|
||||
errcode = M680X_instprinter_init(ud);
|
||||
|
||||
if (errcode != CS_ERR_OK)
|
||||
return errcode;
|
||||
|
||||
// verify if requested mode is valid
|
||||
if (ud->mode & ~(CS_MODE_M680X_6800 | CS_MODE_M680X_6801 |
|
||||
CS_MODE_M680X_6805 | CS_MODE_M680X_6808 |
|
||||
CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
|
||||
CS_MODE_M680X_6301 | CS_MODE_M680X_6309 |
|
||||
CS_MODE_M680X_CPU12 | CS_MODE_M680X_HCS08)) {
|
||||
if (ud->mode &
|
||||
~(CS_MODE_M680X_6800 | CS_MODE_M680X_6801 | CS_MODE_M680X_6805 |
|
||||
CS_MODE_M680X_6808 | CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
|
||||
CS_MODE_M680X_6301 | CS_MODE_M680X_6309 | CS_MODE_M680X_CPU12 |
|
||||
CS_MODE_M680X_HCS08)) {
|
||||
// At least one mode is not supported by M680X
|
||||
return CS_ERR_MODE;
|
||||
}
|
||||
|
||||
if (!(ud->mode & (CS_MODE_M680X_6800 | CS_MODE_M680X_6801 |
|
||||
CS_MODE_M680X_6805 | CS_MODE_M680X_6808 |
|
||||
CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
|
||||
CS_MODE_M680X_6301 | CS_MODE_M680X_6309 |
|
||||
CS_MODE_M680X_CPU12 | CS_MODE_M680X_HCS08))) {
|
||||
if (!(ud->mode &
|
||||
(CS_MODE_M680X_6800 | CS_MODE_M680X_6801 | CS_MODE_M680X_6805 |
|
||||
CS_MODE_M680X_6808 | CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
|
||||
CS_MODE_M680X_6301 | CS_MODE_M680X_6309 | CS_MODE_M680X_CPU12 |
|
||||
CS_MODE_M680X_HCS08))) {
|
||||
// At least the cpu type has to be selected. No default.
|
||||
return CS_ERR_MODE;
|
||||
}
|
||||
|
|
@ -74,4 +74,3 @@ cs_err M680X_option(cs_struct *handle, cs_opt_type type, size_t value)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -12,19 +12,23 @@ typedef struct m68k_info {
|
|||
size_t code_len;
|
||||
uint64_t baseAddress;
|
||||
MCInst *inst;
|
||||
unsigned int pc; /* program counter */
|
||||
unsigned int ir; /* instruction register */
|
||||
unsigned int pc; /* program counter */
|
||||
unsigned int ir; /* instruction register */
|
||||
unsigned int type;
|
||||
unsigned int address_mask; /* Address mask to simulate address lines */
|
||||
cs_m68k extension;
|
||||
uint16_t regs_read[MAX_IMPL_R_REGS]; // list of implicit registers read by this insn
|
||||
uint16_t regs_read
|
||||
[MAX_IMPL_R_REGS]; // list of implicit registers read by this insn
|
||||
uint8_t regs_read_count; // number of implicit registers read by this insn
|
||||
uint16_t regs_write[MAX_IMPL_W_REGS]; // list of implicit registers modified by this insn
|
||||
uint16_t regs_write
|
||||
[MAX_IMPL_W_REGS]; // list of implicit registers modified by this insn
|
||||
uint8_t regs_write_count; // number of implicit registers modified by this insn
|
||||
uint8_t groups[MAX_NUM_GROUPS];
|
||||
uint8_t groups_count;
|
||||
} m68k_info;
|
||||
|
||||
bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* instr, uint16_t* size, uint64_t address, void* info);
|
||||
bool M68K_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Capstone Disassembly Engine */
|
||||
/* M68K Backend by Daniel Collin <daniel@collin.com> 2015-2016 */
|
||||
|
||||
#include <stdio.h> // DEBUG
|
||||
#include <stdio.h> // DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -20,54 +20,92 @@
|
|||
#ifndef CAPSTONE_DIET
|
||||
static const char s_spacing[] = " ";
|
||||
|
||||
static const char* const s_reg_names[] = {
|
||||
"invalid",
|
||||
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
|
||||
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
|
||||
"fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
|
||||
"pc",
|
||||
"sr", "ccr", "sfc", "dfc", "usp", "vbr", "cacr",
|
||||
"caar", "msp", "isp", "tc", "itt0", "itt1", "dtt0",
|
||||
"dtt1", "mmusr", "urp", "srp",
|
||||
static const char *const s_reg_names[] = {
|
||||
"invalid", "d0", "d1", "d2", "d3", "d4", "d5", "d6",
|
||||
"d7", "a0", "a1", "a2", "a3", "a4", "a5", "a6",
|
||||
"a7", "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6",
|
||||
"fp7", "pc", "sr", "ccr", "sfc", "dfc", "usp", "vbr",
|
||||
"cacr", "caar", "msp", "isp", "tc", "itt0", "itt1", "dtt0",
|
||||
"dtt1", "mmusr", "urp", "srp",
|
||||
|
||||
"fpcr", "fpsr", "fpiar",
|
||||
"fpcr", "fpsr", "fpiar",
|
||||
};
|
||||
|
||||
static const char* const s_instruction_names[] = {
|
||||
"invalid",
|
||||
"abcd", "add", "adda", "addi", "addq", "addx", "and", "andi", "asl", "asr", "bhs", "blo", "bhi", "bls", "bcc", "bcs", "bne", "beq", "bvc",
|
||||
"bvs", "bpl", "bmi", "bge", "blt", "bgt", "ble", "bra", "bsr", "bchg", "bclr", "bset", "btst", "bfchg", "bfclr", "bfexts", "bfextu", "bfffo", "bfins",
|
||||
"bfset", "bftst", "bkpt", "callm", "cas", "cas2", "chk", "chk2", "clr", "cmp", "cmpa", "cmpi", "cmpm", "cmp2", "cinvl", "cinvp", "cinva", "cpushl", "cpushp",
|
||||
"cpusha", "dbt", "dbf", "dbhi", "dbls", "dbcc", "dbcs", "dbne", "dbeq", "dbvc", "dbvs", "dbpl", "dbmi", "dbge", "dblt", "dbgt", "dble", "dbra",
|
||||
"divs", "divsl", "divu", "divul", "eor", "eori", "exg", "ext", "extb", "fabs", "fsabs", "fdabs", "facos", "fadd", "fsadd", "fdadd", "fasin",
|
||||
"fatan", "fatanh", "fbf", "fbeq", "fbogt", "fboge", "fbolt", "fbole", "fbogl", "fbor", "fbun", "fbueq", "fbugt", "fbuge", "fbult", "fbule", "fbne", "fbt",
|
||||
"fbsf", "fbseq", "fbgt", "fbge", "fblt", "fble", "fbgl", "fbgle", "fbngle", "fbngl", "fbnle", "fbnlt", "fbnge", "fbngt", "fbsne", "fbst", "fcmp", "fcos",
|
||||
"fcosh", "fdbf", "fdbeq", "fdbogt", "fdboge", "fdbolt", "fdbole", "fdbogl", "fdbor", "fdbun", "fdbueq", "fdbugt", "fdbuge", "fdbult", "fdbule", "fdbne",
|
||||
"fdbt", "fdbsf", "fdbseq", "fdbgt", "fdbge", "fdblt", "fdble", "fdbgl", "fdbgle", "fdbngle", "fdbngl", "fdbnle", "fdbnlt", "fdbnge", "fdbngt", "fdbsne",
|
||||
"fdbst", "fdiv", "fsdiv", "fddiv", "fetox", "fetoxm1", "fgetexp", "fgetman", "fint", "fintrz", "flog10", "flog2", "flogn", "flognp1", "fmod", "fmove",
|
||||
"fsmove", "fdmove", "fmovecr", "fmovem", "fmul", "fsmul", "fdmul", "fneg", "fsneg", "fdneg", "fnop", "frem", "frestore", "fsave", "fscale", "fsgldiv",
|
||||
"fsglmul", "fsin", "fsincos", "fsinh", "fsqrt", "fssqrt", "fdsqrt", "fsf", "fseq", "fsogt", "fsoge", "fsolt", "fsole", "fsogl", "fsor", "fsun", "fsueq",
|
||||
"fsugt", "fsuge", "fsult", "fsule", "fsne", "fst", "fssf", "fsseq", "fsgt", "fsge", "fslt", "fsle", "fsgl", "fsgle", "fsngle",
|
||||
"fsngl", "fsnle", "fsnlt", "fsnge", "fsngt", "fssne", "fsst", "fsub", "fssub", "fdsub", "ftan", "ftanh", "ftentox", "ftrapf", "ftrapeq", "ftrapogt",
|
||||
"ftrapoge", "ftrapolt", "ftrapole", "ftrapogl", "ftrapor", "ftrapun", "ftrapueq", "ftrapugt", "ftrapuge", "ftrapult", "ftrapule", "ftrapne", "ftrapt",
|
||||
"ftrapsf", "ftrapseq", "ftrapgt", "ftrapge", "ftraplt", "ftraple", "ftrapgl", "ftrapgle", "ftrapngle", "ftrapngl", "ftrapnle", "ftrapnlt", "ftrapnge",
|
||||
"ftrapngt", "ftrapsne", "ftrapst", "ftst", "ftwotox", "halt", "illegal", "jmp", "jsr", "lea", "link", "lpstop", "lsl", "lsr", "move", "movea", "movec",
|
||||
"movem", "movep", "moveq", "moves", "move16", "muls", "mulu", "nbcd", "neg", "negx", "nop", "not", "or", "ori", "pack", "pea", "pflush", "pflusha",
|
||||
"pflushan", "pflushn", "ploadr", "ploadw", "plpar", "plpaw", "pmove", "pmovefd", "ptestr", "ptestw", "pulse", "rems", "remu", "reset", "rol", "ror",
|
||||
"roxl", "roxr", "rtd", "rte", "rtm", "rtr", "rts", "sbcd", "st", "sf", "shi", "sls", "scc", "shs", "scs", "slo", "sne", "seq", "svc", "svs", "spl", "smi",
|
||||
"sge", "slt", "sgt", "sle", "stop", "sub", "suba", "subi", "subq", "subx", "swap", "tas", "trap", "trapv", "trapt", "trapf", "traphi", "trapls",
|
||||
"trapcc", "traphs", "trapcs", "traplo", "trapne", "trapeq", "trapvc", "trapvs", "trappl", "trapmi", "trapge", "traplt", "trapgt", "traple", "tst", "unlk", "unpk",
|
||||
static const char *const s_instruction_names[] = {
|
||||
"invalid", "abcd", "add", "adda", "addi", "addq",
|
||||
"addx", "and", "andi", "asl", "asr", "bhs",
|
||||
"blo", "bhi", "bls", "bcc", "bcs", "bne",
|
||||
"beq", "bvc", "bvs", "bpl", "bmi", "bge",
|
||||
"blt", "bgt", "ble", "bra", "bsr", "bchg",
|
||||
"bclr", "bset", "btst", "bfchg", "bfclr", "bfexts",
|
||||
"bfextu", "bfffo", "bfins", "bfset", "bftst", "bkpt",
|
||||
"callm", "cas", "cas2", "chk", "chk2", "clr",
|
||||
"cmp", "cmpa", "cmpi", "cmpm", "cmp2", "cinvl",
|
||||
"cinvp", "cinva", "cpushl", "cpushp", "cpusha", "dbt",
|
||||
"dbf", "dbhi", "dbls", "dbcc", "dbcs", "dbne",
|
||||
"dbeq", "dbvc", "dbvs", "dbpl", "dbmi", "dbge",
|
||||
"dblt", "dbgt", "dble", "dbra", "divs", "divsl",
|
||||
"divu", "divul", "eor", "eori", "exg", "ext",
|
||||
"extb", "fabs", "fsabs", "fdabs", "facos", "fadd",
|
||||
"fsadd", "fdadd", "fasin", "fatan", "fatanh", "fbf",
|
||||
"fbeq", "fbogt", "fboge", "fbolt", "fbole", "fbogl",
|
||||
"fbor", "fbun", "fbueq", "fbugt", "fbuge", "fbult",
|
||||
"fbule", "fbne", "fbt", "fbsf", "fbseq", "fbgt",
|
||||
"fbge", "fblt", "fble", "fbgl", "fbgle", "fbngle",
|
||||
"fbngl", "fbnle", "fbnlt", "fbnge", "fbngt", "fbsne",
|
||||
"fbst", "fcmp", "fcos", "fcosh", "fdbf", "fdbeq",
|
||||
"fdbogt", "fdboge", "fdbolt", "fdbole", "fdbogl", "fdbor",
|
||||
"fdbun", "fdbueq", "fdbugt", "fdbuge", "fdbult", "fdbule",
|
||||
"fdbne", "fdbt", "fdbsf", "fdbseq", "fdbgt", "fdbge",
|
||||
"fdblt", "fdble", "fdbgl", "fdbgle", "fdbngle", "fdbngl",
|
||||
"fdbnle", "fdbnlt", "fdbnge", "fdbngt", "fdbsne", "fdbst",
|
||||
"fdiv", "fsdiv", "fddiv", "fetox", "fetoxm1", "fgetexp",
|
||||
"fgetman", "fint", "fintrz", "flog10", "flog2", "flogn",
|
||||
"flognp1", "fmod", "fmove", "fsmove", "fdmove", "fmovecr",
|
||||
"fmovem", "fmul", "fsmul", "fdmul", "fneg", "fsneg",
|
||||
"fdneg", "fnop", "frem", "frestore", "fsave", "fscale",
|
||||
"fsgldiv", "fsglmul", "fsin", "fsincos", "fsinh", "fsqrt",
|
||||
"fssqrt", "fdsqrt", "fsf", "fseq", "fsogt", "fsoge",
|
||||
"fsolt", "fsole", "fsogl", "fsor", "fsun", "fsueq",
|
||||
"fsugt", "fsuge", "fsult", "fsule", "fsne", "fst",
|
||||
"fssf", "fsseq", "fsgt", "fsge", "fslt", "fsle",
|
||||
"fsgl", "fsgle", "fsngle", "fsngl", "fsnle", "fsnlt",
|
||||
"fsnge", "fsngt", "fssne", "fsst", "fsub", "fssub",
|
||||
"fdsub", "ftan", "ftanh", "ftentox", "ftrapf", "ftrapeq",
|
||||
"ftrapogt", "ftrapoge", "ftrapolt", "ftrapole", "ftrapogl", "ftrapor",
|
||||
"ftrapun", "ftrapueq", "ftrapugt", "ftrapuge", "ftrapult", "ftrapule",
|
||||
"ftrapne", "ftrapt", "ftrapsf", "ftrapseq", "ftrapgt", "ftrapge",
|
||||
"ftraplt", "ftraple", "ftrapgl", "ftrapgle", "ftrapngle", "ftrapngl",
|
||||
"ftrapnle", "ftrapnlt", "ftrapnge", "ftrapngt", "ftrapsne", "ftrapst",
|
||||
"ftst", "ftwotox", "halt", "illegal", "jmp", "jsr",
|
||||
"lea", "link", "lpstop", "lsl", "lsr", "move",
|
||||
"movea", "movec", "movem", "movep", "moveq", "moves",
|
||||
"move16", "muls", "mulu", "nbcd", "neg", "negx",
|
||||
"nop", "not", "or", "ori", "pack", "pea",
|
||||
"pflush", "pflusha", "pflushan", "pflushn", "ploadr", "ploadw",
|
||||
"plpar", "plpaw", "pmove", "pmovefd", "ptestr", "ptestw",
|
||||
"pulse", "rems", "remu", "reset", "rol", "ror",
|
||||
"roxl", "roxr", "rtd", "rte", "rtm", "rtr",
|
||||
"rts", "sbcd", "st", "sf", "shi", "sls",
|
||||
"scc", "shs", "scs", "slo", "sne", "seq",
|
||||
"svc", "svs", "spl", "smi", "sge", "slt",
|
||||
"sgt", "sle", "stop", "sub", "suba", "subi",
|
||||
"subq", "subx", "swap", "tas", "trap", "trapv",
|
||||
"trapt", "trapf", "traphi", "trapls", "trapcc", "traphs",
|
||||
"trapcs", "traplo", "trapne", "trapeq", "trapvc", "trapvs",
|
||||
"trappl", "trapmi", "trapge", "traplt", "trapgt", "traple",
|
||||
"tst", "unlk", "unpk",
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const char* getRegName(m68k_reg reg)
|
||||
static const char *getRegName(m68k_reg reg)
|
||||
{
|
||||
return s_reg_names[(int)reg];
|
||||
}
|
||||
|
||||
static void printRegbitsRange(char* buffer, size_t buf_len, uint32_t data, const char* prefix)
|
||||
static void printRegbitsRange(char *buffer, size_t buf_len, uint32_t data,
|
||||
const char *prefix)
|
||||
{
|
||||
unsigned int first = 0;
|
||||
unsigned int run_length = 0;
|
||||
|
|
@ -86,14 +124,16 @@ static void printRegbitsRange(char* buffer, size_t buf_len, uint32_t data, const
|
|||
if (buffer[0] != 0)
|
||||
strncat(buffer, "/", buf_len - 1);
|
||||
|
||||
snprintf(buffer + strlen(buffer), buf_len, "%s%d", prefix, first);
|
||||
snprintf(buffer + strlen(buffer), buf_len, "%s%d",
|
||||
prefix, first);
|
||||
if (run_length > 0)
|
||||
snprintf(buffer + strlen(buffer), buf_len, "-%s%d", prefix, first + run_length);
|
||||
snprintf(buffer + strlen(buffer), buf_len,
|
||||
"-%s%d", prefix, first + run_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void registerBits(SStream* O, const cs_m68k_op* op)
|
||||
static void registerBits(SStream *O, const cs_m68k_op *op)
|
||||
{
|
||||
char buffer[128];
|
||||
unsigned int data = op->register_bits;
|
||||
|
|
@ -112,133 +152,176 @@ static void registerBits(SStream* O, const cs_m68k_op* op)
|
|||
SStream_concat(O, "%s", buffer);
|
||||
}
|
||||
|
||||
static void registerPair(SStream* O, const cs_m68k_op* op)
|
||||
static void registerPair(SStream *O, const cs_m68k_op *op)
|
||||
{
|
||||
SStream_concat(O, "%s:%s", s_reg_names[op->reg_pair.reg_0],
|
||||
s_reg_names[op->reg_pair.reg_1]);
|
||||
s_reg_names[op->reg_pair.reg_1]);
|
||||
}
|
||||
|
||||
static void printAddressingMode(SStream* O, unsigned int pc, const cs_m68k* inst, const cs_m68k_op* op)
|
||||
static void printAddressingMode(SStream *O, unsigned int pc,
|
||||
const cs_m68k *inst, const cs_m68k_op *op)
|
||||
{
|
||||
switch (op->address_mode) {
|
||||
case M68K_AM_NONE:
|
||||
switch (op->type) {
|
||||
case M68K_OP_REG_BITS:
|
||||
registerBits(O, op);
|
||||
break;
|
||||
case M68K_OP_REG_PAIR:
|
||||
registerPair(O, op);
|
||||
break;
|
||||
case M68K_OP_REG:
|
||||
SStream_concat(O, "%s", s_reg_names[op->reg]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case M68K_AM_NONE:
|
||||
switch (op->type) {
|
||||
case M68K_OP_REG_BITS:
|
||||
registerBits(O, op);
|
||||
break;
|
||||
|
||||
case M68K_AM_REG_DIRECT_DATA: SStream_concat(O, "d%d", (op->reg - M68K_REG_D0)); break;
|
||||
case M68K_AM_REG_DIRECT_ADDR: SStream_concat(O, "a%d", (op->reg - M68K_REG_A0)); break;
|
||||
case M68K_AM_REGI_ADDR: SStream_concat(O, "(a%d)", (op->reg - M68K_REG_A0)); break;
|
||||
case M68K_AM_REGI_ADDR_POST_INC: SStream_concat(O, "(a%d)+", (op->reg - M68K_REG_A0)); break;
|
||||
case M68K_AM_REGI_ADDR_PRE_DEC: SStream_concat(O, "-(a%d)", (op->reg - M68K_REG_A0)); break;
|
||||
case M68K_AM_REGI_ADDR_DISP: SStream_concat(O, "%s$%x(a%d)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), (op->mem.base_reg - M68K_REG_A0)); break;
|
||||
case M68K_AM_PCI_DISP: SStream_concat(O, "$%x(pc)", pc + 2 + op->mem.disp); break;
|
||||
case M68K_AM_ABSOLUTE_DATA_SHORT: SStream_concat(O, "$%x.w", op->imm); break;
|
||||
case M68K_AM_ABSOLUTE_DATA_LONG: SStream_concat(O, "$%x.l", op->imm); break;
|
||||
case M68K_AM_IMMEDIATE:
|
||||
if (inst->op_size.type == M68K_SIZE_TYPE_FPU) {
|
||||
#if defined(_KERNEL_MODE)
|
||||
// Issue #681: Windows kernel does not support formatting float point
|
||||
SStream_concat(O, "#<float_point_unsupported>");
|
||||
break;
|
||||
#else
|
||||
if (inst->op_size.fpu_size == M68K_FPU_SIZE_SINGLE)
|
||||
SStream_concat(O, "#%f", op->simm);
|
||||
else if (inst->op_size.fpu_size == M68K_FPU_SIZE_DOUBLE)
|
||||
SStream_concat(O, "#%f", op->dimm);
|
||||
else
|
||||
SStream_concat(O, "#<unsupported>");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
SStream_concat(O, "#$%x", op->imm);
|
||||
break;
|
||||
case M68K_AM_PCI_INDEX_8_BIT_DISP:
|
||||
SStream_concat(O, "$%x(pc,%s%s.%c)", pc + 2 + op->mem.disp, s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
|
||||
case M68K_OP_REG_PAIR:
|
||||
registerPair(O, op);
|
||||
break;
|
||||
case M68K_AM_AREGI_INDEX_8_BIT_DISP:
|
||||
SStream_concat(O, "%s$%x(%s,%s%s.%c)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), getRegName(op->mem.base_reg), s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
|
||||
case M68K_OP_REG:
|
||||
SStream_concat(O, "%s", s_reg_names[op->reg]);
|
||||
break;
|
||||
case M68K_AM_PCI_INDEX_BASE_DISP:
|
||||
case M68K_AM_AREGI_INDEX_BASE_DISP:
|
||||
|
||||
if (op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP) {
|
||||
SStream_concat(O, "$%x", pc + 2 + op->mem.in_disp);
|
||||
} else {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
}
|
||||
|
||||
SStream_concat0(O, "(");
|
||||
|
||||
if (op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP) {
|
||||
SStream_concat(O, "pc,%s.%c", getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
|
||||
} else {
|
||||
if (op->mem.base_reg != M68K_REG_INVALID)
|
||||
SStream_concat(O, "a%d,%s", op->mem.base_reg - M68K_REG_A0, s_spacing);
|
||||
SStream_concat(O, "%s.%c", getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
|
||||
}
|
||||
|
||||
if (op->mem.scale > 0)
|
||||
SStream_concat(O, "%s*%s%d)", s_spacing, s_spacing, op->mem.scale);
|
||||
else
|
||||
SStream_concat0(O, ")");
|
||||
break;
|
||||
// It's ok to just use PCMI here as is as we set base_reg to PC in the disassembler. While this is not strictly correct it makes the code
|
||||
// easier and that is what actually happens when the code is executed anyway.
|
||||
|
||||
case M68K_AM_PC_MEMI_POST_INDEX:
|
||||
case M68K_AM_PC_MEMI_PRE_INDEX:
|
||||
case M68K_AM_MEMI_PRE_INDEX:
|
||||
case M68K_AM_MEMI_POST_INDEX:
|
||||
SStream_concat0(O, "([");
|
||||
|
||||
if (op->address_mode == M68K_AM_PC_MEMI_POST_INDEX || op->address_mode == M68K_AM_PC_MEMI_PRE_INDEX) {
|
||||
SStream_concat(O, "$%x", pc + 2 + op->mem.in_disp);
|
||||
} else {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
}
|
||||
|
||||
if (op->mem.base_reg != M68K_REG_INVALID) {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, ",%s%s", s_spacing, getRegName(op->mem.base_reg));
|
||||
else
|
||||
SStream_concat(O, "%s", getRegName(op->mem.base_reg));
|
||||
}
|
||||
|
||||
if (op->address_mode == M68K_AM_MEMI_POST_INDEX || op->address_mode == M68K_AM_PC_MEMI_POST_INDEX)
|
||||
SStream_concat0(O, "]");
|
||||
|
||||
if (op->mem.index_reg != M68K_REG_INVALID)
|
||||
SStream_concat(O, ",%s%s.%c", s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
|
||||
|
||||
if (op->mem.scale > 0)
|
||||
SStream_concat(O, "%s*%s%d", s_spacing, s_spacing, op->mem.scale);
|
||||
|
||||
if (op->address_mode == M68K_AM_MEMI_PRE_INDEX || op->address_mode == M68K_AM_PC_MEMI_PRE_INDEX)
|
||||
SStream_concat0(O, "]");
|
||||
|
||||
if (op->mem.out_disp > 0)
|
||||
SStream_concat(O, ",%s$%x", s_spacing, op->mem.out_disp);
|
||||
|
||||
SStream_concat0(O, ")");
|
||||
break;
|
||||
case M68K_AM_BRANCH_DISPLACEMENT:
|
||||
SStream_concat(O, "$%x", pc + 2 + op->br_disp.disp);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case M68K_AM_REG_DIRECT_DATA:
|
||||
SStream_concat(O, "d%d", (op->reg - M68K_REG_D0));
|
||||
break;
|
||||
case M68K_AM_REG_DIRECT_ADDR:
|
||||
SStream_concat(O, "a%d", (op->reg - M68K_REG_A0));
|
||||
break;
|
||||
case M68K_AM_REGI_ADDR:
|
||||
SStream_concat(O, "(a%d)", (op->reg - M68K_REG_A0));
|
||||
break;
|
||||
case M68K_AM_REGI_ADDR_POST_INC:
|
||||
SStream_concat(O, "(a%d)+", (op->reg - M68K_REG_A0));
|
||||
break;
|
||||
case M68K_AM_REGI_ADDR_PRE_DEC:
|
||||
SStream_concat(O, "-(a%d)", (op->reg - M68K_REG_A0));
|
||||
break;
|
||||
case M68K_AM_REGI_ADDR_DISP:
|
||||
SStream_concat(O, "%s$%x(a%d)", op->mem.disp < 0 ? "-" : "",
|
||||
abs(op->mem.disp),
|
||||
(op->mem.base_reg - M68K_REG_A0));
|
||||
break;
|
||||
case M68K_AM_PCI_DISP:
|
||||
SStream_concat(O, "$%x(pc)", pc + 2 + op->mem.disp);
|
||||
break;
|
||||
case M68K_AM_ABSOLUTE_DATA_SHORT:
|
||||
SStream_concat(O, "$%x.w", op->imm);
|
||||
break;
|
||||
case M68K_AM_ABSOLUTE_DATA_LONG:
|
||||
SStream_concat(O, "$%x.l", op->imm);
|
||||
break;
|
||||
case M68K_AM_IMMEDIATE:
|
||||
if (inst->op_size.type == M68K_SIZE_TYPE_FPU) {
|
||||
#if defined(_KERNEL_MODE)
|
||||
// Issue #681: Windows kernel does not support formatting float point
|
||||
SStream_concat(O, "#<float_point_unsupported>");
|
||||
break;
|
||||
#else
|
||||
if (inst->op_size.fpu_size == M68K_FPU_SIZE_SINGLE)
|
||||
SStream_concat(O, "#%f", op->simm);
|
||||
else if (inst->op_size.fpu_size == M68K_FPU_SIZE_DOUBLE)
|
||||
SStream_concat(O, "#%f", op->dimm);
|
||||
else
|
||||
SStream_concat(O, "#<unsupported>");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
SStream_concat(O, "#$%x", op->imm);
|
||||
break;
|
||||
case M68K_AM_PCI_INDEX_8_BIT_DISP:
|
||||
SStream_concat(O, "$%x(pc,%s%s.%c)", pc + 2 + op->mem.disp,
|
||||
s_spacing, getRegName(op->mem.index_reg),
|
||||
op->mem.index_size ? 'l' : 'w');
|
||||
break;
|
||||
case M68K_AM_AREGI_INDEX_8_BIT_DISP:
|
||||
SStream_concat(O, "%s$%x(%s,%s%s.%c)",
|
||||
op->mem.disp < 0 ? "-" : "", abs(op->mem.disp),
|
||||
getRegName(op->mem.base_reg), s_spacing,
|
||||
getRegName(op->mem.index_reg),
|
||||
op->mem.index_size ? 'l' : 'w');
|
||||
break;
|
||||
case M68K_AM_PCI_INDEX_BASE_DISP:
|
||||
case M68K_AM_AREGI_INDEX_BASE_DISP:
|
||||
|
||||
if (op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP) {
|
||||
SStream_concat(O, "$%x", pc + 2 + op->mem.in_disp);
|
||||
} else {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
}
|
||||
|
||||
SStream_concat0(O, "(");
|
||||
|
||||
if (op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP) {
|
||||
SStream_concat(O, "pc,%s.%c",
|
||||
getRegName(op->mem.index_reg),
|
||||
op->mem.index_size ? 'l' : 'w');
|
||||
} else {
|
||||
if (op->mem.base_reg != M68K_REG_INVALID)
|
||||
SStream_concat(O, "a%d,%s",
|
||||
op->mem.base_reg - M68K_REG_A0,
|
||||
s_spacing);
|
||||
SStream_concat(O, "%s.%c",
|
||||
getRegName(op->mem.index_reg),
|
||||
op->mem.index_size ? 'l' : 'w');
|
||||
}
|
||||
|
||||
if (op->mem.scale > 0)
|
||||
SStream_concat(O, "%s*%s%d)", s_spacing, s_spacing,
|
||||
op->mem.scale);
|
||||
else
|
||||
SStream_concat0(O, ")");
|
||||
break;
|
||||
// It's ok to just use PCMI here as is as we set base_reg to PC in the disassembler. While this is not strictly correct it makes the code
|
||||
// easier and that is what actually happens when the code is executed anyway.
|
||||
|
||||
case M68K_AM_PC_MEMI_POST_INDEX:
|
||||
case M68K_AM_PC_MEMI_PRE_INDEX:
|
||||
case M68K_AM_MEMI_PRE_INDEX:
|
||||
case M68K_AM_MEMI_POST_INDEX:
|
||||
SStream_concat0(O, "([");
|
||||
|
||||
if (op->address_mode == M68K_AM_PC_MEMI_POST_INDEX ||
|
||||
op->address_mode == M68K_AM_PC_MEMI_PRE_INDEX) {
|
||||
SStream_concat(O, "$%x", pc + 2 + op->mem.in_disp);
|
||||
} else {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
}
|
||||
|
||||
if (op->mem.base_reg != M68K_REG_INVALID) {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, ",%s%s", s_spacing,
|
||||
getRegName(op->mem.base_reg));
|
||||
else
|
||||
SStream_concat(O, "%s",
|
||||
getRegName(op->mem.base_reg));
|
||||
}
|
||||
|
||||
if (op->address_mode == M68K_AM_MEMI_POST_INDEX ||
|
||||
op->address_mode == M68K_AM_PC_MEMI_POST_INDEX)
|
||||
SStream_concat0(O, "]");
|
||||
|
||||
if (op->mem.index_reg != M68K_REG_INVALID)
|
||||
SStream_concat(O, ",%s%s.%c", s_spacing,
|
||||
getRegName(op->mem.index_reg),
|
||||
op->mem.index_size ? 'l' : 'w');
|
||||
|
||||
if (op->mem.scale > 0)
|
||||
SStream_concat(O, "%s*%s%d", s_spacing, s_spacing,
|
||||
op->mem.scale);
|
||||
|
||||
if (op->address_mode == M68K_AM_MEMI_PRE_INDEX ||
|
||||
op->address_mode == M68K_AM_PC_MEMI_PRE_INDEX)
|
||||
SStream_concat0(O, "]");
|
||||
|
||||
if (op->mem.out_disp > 0)
|
||||
SStream_concat(O, ",%s$%x", s_spacing,
|
||||
op->mem.out_disp);
|
||||
|
||||
SStream_concat0(O, ")");
|
||||
break;
|
||||
case M68K_AM_BRANCH_DISPLACEMENT:
|
||||
SStream_concat(O, "$%x", pc + 2 + op->br_disp.disp);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (op->mem.bitfield)
|
||||
|
|
@ -246,10 +329,10 @@ static void printAddressingMode(SStream* O, unsigned int pc, const cs_m68k* inst
|
|||
}
|
||||
#endif
|
||||
|
||||
#define m68k_sizeof_array(array) (int)(sizeof(array)/sizeof(array[0]))
|
||||
#define m68k_sizeof_array(array) (int)(sizeof(array) / sizeof(array[0]))
|
||||
#define m68k_min(a, b) (a < b) ? a : b
|
||||
|
||||
void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
||||
void M68K_printInst(MCInst *MI, SStream *O, void *PrinterInfo)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
m68k_info *info = (m68k_info *)PrinterInfo;
|
||||
|
|
@ -259,16 +342,23 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
|
||||
detail = MI->flat_insn->detail;
|
||||
if (detail) {
|
||||
int regs_read_count = m68k_min(m68k_sizeof_array(detail->regs_read), info->regs_read_count);
|
||||
int regs_write_count = m68k_min(m68k_sizeof_array(detail->regs_write), info->regs_write_count);
|
||||
int groups_count = m68k_min(m68k_sizeof_array(detail->groups), info->groups_count);
|
||||
int regs_read_count =
|
||||
m68k_min(m68k_sizeof_array(detail->regs_read),
|
||||
info->regs_read_count);
|
||||
int regs_write_count =
|
||||
m68k_min(m68k_sizeof_array(detail->regs_write),
|
||||
info->regs_write_count);
|
||||
int groups_count = m68k_min(m68k_sizeof_array(detail->groups),
|
||||
info->groups_count);
|
||||
|
||||
memcpy(&detail->m68k, ext, sizeof(cs_m68k));
|
||||
|
||||
memcpy(&detail->regs_read, &info->regs_read, regs_read_count * sizeof(info->regs_read[0]));
|
||||
memcpy(&detail->regs_read, &info->regs_read,
|
||||
regs_read_count * sizeof(info->regs_read[0]));
|
||||
detail->regs_read_count = regs_read_count;
|
||||
|
||||
memcpy(&detail->regs_write, &info->regs_write, regs_write_count * sizeof(info->regs_write[0]));
|
||||
memcpy(&detail->regs_write, &info->regs_write,
|
||||
regs_write_count * sizeof(info->regs_write[0]));
|
||||
detail->regs_write_count = regs_write_count;
|
||||
|
||||
memcpy(&detail->groups, &info->groups, groups_count);
|
||||
|
|
@ -283,29 +373,43 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
return;
|
||||
}
|
||||
|
||||
SStream_concat0(O, (char*)s_instruction_names[MI->Opcode]);
|
||||
SStream_concat0(O, (char *)s_instruction_names[MI->Opcode]);
|
||||
|
||||
switch (ext->op_size.type) {
|
||||
case M68K_SIZE_TYPE_INVALID :
|
||||
break;
|
||||
case M68K_SIZE_TYPE_INVALID:
|
||||
break;
|
||||
|
||||
case M68K_SIZE_TYPE_CPU :
|
||||
switch (ext->op_size.cpu_size) {
|
||||
case M68K_CPU_SIZE_BYTE: SStream_concat0(O, ".b"); break;
|
||||
case M68K_CPU_SIZE_WORD: SStream_concat0(O, ".w"); break;
|
||||
case M68K_CPU_SIZE_LONG: SStream_concat0(O, ".l"); break;
|
||||
case M68K_CPU_SIZE_NONE: break;
|
||||
}
|
||||
case M68K_SIZE_TYPE_CPU:
|
||||
switch (ext->op_size.cpu_size) {
|
||||
case M68K_CPU_SIZE_BYTE:
|
||||
SStream_concat0(O, ".b");
|
||||
break;
|
||||
case M68K_CPU_SIZE_WORD:
|
||||
SStream_concat0(O, ".w");
|
||||
break;
|
||||
case M68K_CPU_SIZE_LONG:
|
||||
SStream_concat0(O, ".l");
|
||||
break;
|
||||
case M68K_CPU_SIZE_NONE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case M68K_SIZE_TYPE_FPU :
|
||||
switch (ext->op_size.fpu_size) {
|
||||
case M68K_FPU_SIZE_SINGLE: SStream_concat0(O, ".s"); break;
|
||||
case M68K_FPU_SIZE_DOUBLE: SStream_concat0(O, ".d"); break;
|
||||
case M68K_FPU_SIZE_EXTENDED: SStream_concat0(O, ".x"); break;
|
||||
case M68K_FPU_SIZE_NONE: break;
|
||||
}
|
||||
case M68K_SIZE_TYPE_FPU:
|
||||
switch (ext->op_size.fpu_size) {
|
||||
case M68K_FPU_SIZE_SINGLE:
|
||||
SStream_concat0(O, ".s");
|
||||
break;
|
||||
case M68K_FPU_SIZE_DOUBLE:
|
||||
SStream_concat0(O, ".d");
|
||||
break;
|
||||
case M68K_FPU_SIZE_EXTENDED:
|
||||
SStream_concat0(O, ".x");
|
||||
break;
|
||||
case M68K_FPU_SIZE_NONE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SStream_concat0(O, " ");
|
||||
|
|
@ -314,15 +418,19 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
|
||||
if (MI->Opcode == M68K_INS_CAS2) {
|
||||
int reg_value_0, reg_value_1;
|
||||
printAddressingMode(O, info->pc, ext, &ext->operands[0]); SStream_concat0(O, ",");
|
||||
printAddressingMode(O, info->pc, ext, &ext->operands[1]); SStream_concat0(O, ",");
|
||||
printAddressingMode(O, info->pc, ext, &ext->operands[0]);
|
||||
SStream_concat0(O, ",");
|
||||
printAddressingMode(O, info->pc, ext, &ext->operands[1]);
|
||||
SStream_concat0(O, ",");
|
||||
reg_value_0 = ext->operands[2].register_bits >> 4;
|
||||
reg_value_1 = ext->operands[2].register_bits & 0xf;
|
||||
SStream_concat(O, "(%s):(%s)", s_reg_names[M68K_REG_D0 + reg_value_0], s_reg_names[M68K_REG_D0 + reg_value_1]);
|
||||
SStream_concat(O, "(%s):(%s)",
|
||||
s_reg_names[M68K_REG_D0 + reg_value_0],
|
||||
s_reg_names[M68K_REG_D0 + reg_value_1]);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ext->op_count; ++i) {
|
||||
for (i = 0; i < ext->op_count; ++i) {
|
||||
printAddressingMode(O, info->pc, ext, &ext->operands[i]);
|
||||
if ((i + 1) != ext->op_count)
|
||||
SStream_concat(O, ",%s", s_spacing);
|
||||
|
|
@ -330,7 +438,7 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
#endif
|
||||
}
|
||||
|
||||
const char* M68K_reg_name(csh handle, unsigned int reg)
|
||||
const char *M68K_reg_name(csh handle, unsigned int reg)
|
||||
{
|
||||
#ifdef CAPSTONE_DIET
|
||||
return NULL;
|
||||
|
|
@ -342,12 +450,12 @@ const char* M68K_reg_name(csh handle, unsigned int reg)
|
|||
#endif
|
||||
}
|
||||
|
||||
void M68K_get_insn_id(cs_struct* h, cs_insn* insn, unsigned int id)
|
||||
void M68K_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
||||
{
|
||||
insn->id = id; // These id's matches for 68k
|
||||
}
|
||||
|
||||
const char* M68K_insn_name(csh handle, unsigned int id)
|
||||
const char *M68K_insn_name(csh handle, unsigned int id)
|
||||
{
|
||||
#ifdef CAPSTONE_DIET
|
||||
return NULL;
|
||||
|
|
@ -358,9 +466,9 @@ const char* M68K_insn_name(csh handle, unsigned int id)
|
|||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map group_name_maps[] = {
|
||||
{ M68K_GRP_INVALID , NULL },
|
||||
{ M68K_GRP_INVALID, NULL },
|
||||
{ M68K_GRP_JUMP, "jump" },
|
||||
{ M68K_GRP_RET , "ret" },
|
||||
{ M68K_GRP_RET, "ret" },
|
||||
{ M68K_GRP_IRET, "iret" },
|
||||
{ M68K_GRP_BRANCH_RELATIVE, "branch_relative" },
|
||||
};
|
||||
|
|
@ -376,9 +484,9 @@ const char *M68K_group_name(csh handle, unsigned int id)
|
|||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
void M68K_reg_access(const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count)
|
||||
void M68K_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count)
|
||||
{
|
||||
uint8_t read_count, write_count;
|
||||
|
||||
|
|
@ -395,4 +503,3 @@ void M68K_reg_access(const cs_insn *insn,
|
|||
*regs_write_count = write_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,17 @@
|
|||
struct SStream;
|
||||
|
||||
void M68K_init(MCRegisterInfo *MRI);
|
||||
void M68K_printInst(MCInst* MI, struct SStream* O, void* Info);
|
||||
const char* M68K_reg_name(csh handle, unsigned int reg);
|
||||
void M68K_get_insn_id(cs_struct* h, cs_insn* insn, unsigned int id);
|
||||
void M68K_printInst(MCInst *MI, struct SStream *O, void *Info);
|
||||
const char *M68K_reg_name(csh handle, unsigned int reg);
|
||||
void M68K_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
||||
const char *M68K_insn_name(csh handle, unsigned int id);
|
||||
const char* M68K_group_name(csh handle, unsigned int id);
|
||||
void M68K_post_printer(csh handle, cs_insn* flat_insn, char* insn_asm, MCInst* mci);
|
||||
const char *M68K_group_name(csh handle, unsigned int id);
|
||||
void M68K_post_printer(csh handle, cs_insn *flat_insn, char *insn_asm,
|
||||
MCInst *mci);
|
||||
#ifndef CAPSTONE_DIET
|
||||
void M68K_reg_access(const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
void M68K_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -42,4 +42,3 @@ cs_err M68K_option(cs_struct *handle, cs_opt_type type, size_t value)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ typedef struct OpInfo {
|
|||
int operand_bytes;
|
||||
} OpInfo;
|
||||
|
||||
static const struct OpInfo OpInfoTable[]= {
|
||||
static const struct OpInfo OpInfoTable[] = {
|
||||
|
||||
#include "m6502.inc"
|
||||
#include "m65c02.inc"
|
||||
|
|
@ -21,28 +21,21 @@ static const struct OpInfo OpInfoTable[]= {
|
|||
};
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const char* const RegNames[] = {
|
||||
"invalid", "A", "X", "Y", "P", "SP", "DP", "B", "K"
|
||||
};
|
||||
static const char *const RegNames[] = { "invalid", "A", "X", "Y", "P",
|
||||
"SP", "DP", "B", "K" };
|
||||
|
||||
static const char* const GroupNames[] = {
|
||||
NULL,
|
||||
"jump",
|
||||
"call",
|
||||
"ret",
|
||||
"int",
|
||||
"iret",
|
||||
"branch_relative"
|
||||
static const char *const GroupNames[] = {
|
||||
NULL, "jump", "call", "ret", "int", "iret", "branch_relative"
|
||||
};
|
||||
|
||||
typedef struct InstructionInfo {
|
||||
const char* name;
|
||||
const char *name;
|
||||
mos65xx_group_type group_type;
|
||||
mos65xx_reg write, read;
|
||||
bool modifies_status;
|
||||
} InstructionInfo;
|
||||
|
||||
static const struct InstructionInfo InstructionInfoTable[]= {
|
||||
static const struct InstructionInfo InstructionInfoTable[] = {
|
||||
|
||||
#include "instruction_info.inc"
|
||||
|
||||
|
|
@ -70,21 +63,25 @@ static void fillDetails(MCInst *MI, struct OpInfo opinfo, int cpu_type)
|
|||
}
|
||||
|
||||
if (opinfo.am == MOS65XX_AM_REL || opinfo.am == MOS65XX_AM_ZP_REL) {
|
||||
detail->groups[detail->groups_count] = MOS65XX_GRP_BRANCH_RELATIVE;
|
||||
detail->groups_count++;
|
||||
detail->groups[detail->groups_count] =
|
||||
MOS65XX_GRP_BRANCH_RELATIVE;
|
||||
detail->groups_count++;
|
||||
}
|
||||
|
||||
if (insinfo.read != MOS65XX_REG_INVALID) {
|
||||
detail->regs_read[detail->regs_read_count++] = insinfo.read;
|
||||
} else switch(opinfo.am) {
|
||||
} else
|
||||
switch (opinfo.am) {
|
||||
case MOS65XX_AM_ACC:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_ACC;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_ACC;
|
||||
break;
|
||||
case MOS65XX_AM_ZP_Y:
|
||||
case MOS65XX_AM_ZP_IND_Y:
|
||||
case MOS65XX_AM_ABS_Y:
|
||||
case MOS65XX_AM_ZP_IND_LONG_Y:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_Y;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_Y;
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_X:
|
||||
|
|
@ -92,105 +89,120 @@ static void fillDetails(MCInst *MI, struct OpInfo opinfo, int cpu_type)
|
|||
case MOS65XX_AM_ABS_X:
|
||||
case MOS65XX_AM_ABS_X_IND:
|
||||
case MOS65XX_AM_ABS_LONG_X:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_X;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_X;
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_SR:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_SP;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_SP;
|
||||
break;
|
||||
case MOS65XX_AM_SR_IND_Y:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_SP;
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_Y;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_SP;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_Y;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (insinfo.write != MOS65XX_REG_INVALID) {
|
||||
detail->regs_write[detail->regs_write_count++] = insinfo.write;
|
||||
} else if (opinfo.am == MOS65XX_AM_ACC) {
|
||||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_ACC;
|
||||
detail->regs_write[detail->regs_write_count++] =
|
||||
MOS65XX_REG_ACC;
|
||||
}
|
||||
|
||||
|
||||
switch(opinfo.ins) {
|
||||
case MOS65XX_INS_ADC:
|
||||
case MOS65XX_INS_SBC:
|
||||
case MOS65XX_INS_ROL:
|
||||
case MOS65XX_INS_ROR:
|
||||
/* these read carry flag (and decimal for ADC/SBC) */
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_P;
|
||||
break;
|
||||
/* stack operations */
|
||||
case MOS65XX_INS_JSL:
|
||||
case MOS65XX_INS_JSR:
|
||||
case MOS65XX_INS_PEA:
|
||||
case MOS65XX_INS_PEI:
|
||||
case MOS65XX_INS_PER:
|
||||
case MOS65XX_INS_PHA:
|
||||
case MOS65XX_INS_PHB:
|
||||
case MOS65XX_INS_PHD:
|
||||
case MOS65XX_INS_PHK:
|
||||
case MOS65XX_INS_PHP:
|
||||
case MOS65XX_INS_PHX:
|
||||
case MOS65XX_INS_PHY:
|
||||
case MOS65XX_INS_PLA:
|
||||
case MOS65XX_INS_PLB:
|
||||
case MOS65XX_INS_PLD:
|
||||
case MOS65XX_INS_PLP:
|
||||
case MOS65XX_INS_PLX:
|
||||
case MOS65XX_INS_PLY:
|
||||
case MOS65XX_INS_RTI:
|
||||
case MOS65XX_INS_RTL:
|
||||
case MOS65XX_INS_RTS:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_SP;
|
||||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_SP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (opinfo.ins) {
|
||||
case MOS65XX_INS_ADC:
|
||||
case MOS65XX_INS_SBC:
|
||||
case MOS65XX_INS_ROL:
|
||||
case MOS65XX_INS_ROR:
|
||||
/* these read carry flag (and decimal for ADC/SBC) */
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_P;
|
||||
break;
|
||||
/* stack operations */
|
||||
case MOS65XX_INS_JSL:
|
||||
case MOS65XX_INS_JSR:
|
||||
case MOS65XX_INS_PEA:
|
||||
case MOS65XX_INS_PEI:
|
||||
case MOS65XX_INS_PER:
|
||||
case MOS65XX_INS_PHA:
|
||||
case MOS65XX_INS_PHB:
|
||||
case MOS65XX_INS_PHD:
|
||||
case MOS65XX_INS_PHK:
|
||||
case MOS65XX_INS_PHP:
|
||||
case MOS65XX_INS_PHX:
|
||||
case MOS65XX_INS_PHY:
|
||||
case MOS65XX_INS_PLA:
|
||||
case MOS65XX_INS_PLB:
|
||||
case MOS65XX_INS_PLD:
|
||||
case MOS65XX_INS_PLP:
|
||||
case MOS65XX_INS_PLX:
|
||||
case MOS65XX_INS_PLY:
|
||||
case MOS65XX_INS_RTI:
|
||||
case MOS65XX_INS_RTL:
|
||||
case MOS65XX_INS_RTS:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_SP;
|
||||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_SP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (cpu_type == MOS65XX_CPU_TYPE_65816) {
|
||||
switch (opinfo.am) {
|
||||
case MOS65XX_AM_ZP:
|
||||
case MOS65XX_AM_ZP_X:
|
||||
case MOS65XX_AM_ZP_Y:
|
||||
case MOS65XX_AM_ZP_IND:
|
||||
case MOS65XX_AM_ZP_X_IND:
|
||||
case MOS65XX_AM_ZP_IND_Y:
|
||||
case MOS65XX_AM_ZP_IND_LONG:
|
||||
case MOS65XX_AM_ZP_IND_LONG_Y:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_DP;
|
||||
break;
|
||||
case MOS65XX_AM_BLOCK:
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_ACC;
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_X;
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_Y;
|
||||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_ACC;
|
||||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_X;
|
||||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_Y;
|
||||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_B;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case MOS65XX_AM_ZP:
|
||||
case MOS65XX_AM_ZP_X:
|
||||
case MOS65XX_AM_ZP_Y:
|
||||
case MOS65XX_AM_ZP_IND:
|
||||
case MOS65XX_AM_ZP_X_IND:
|
||||
case MOS65XX_AM_ZP_IND_Y:
|
||||
case MOS65XX_AM_ZP_IND_LONG:
|
||||
case MOS65XX_AM_ZP_IND_LONG_Y:
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_DP;
|
||||
break;
|
||||
case MOS65XX_AM_BLOCK:
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_ACC;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_X;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_Y;
|
||||
detail->regs_write[detail->regs_write_count++] =
|
||||
MOS65XX_REG_ACC;
|
||||
detail->regs_write[detail->regs_write_count++] =
|
||||
MOS65XX_REG_X;
|
||||
detail->regs_write[detail->regs_write_count++] =
|
||||
MOS65XX_REG_Y;
|
||||
detail->regs_write[detail->regs_write_count++] =
|
||||
MOS65XX_REG_B;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (opinfo.am) {
|
||||
case MOS65XX_AM_ZP_IND:
|
||||
case MOS65XX_AM_ZP_X_IND:
|
||||
case MOS65XX_AM_ZP_IND_Y:
|
||||
case MOS65XX_AM_ABS:
|
||||
case MOS65XX_AM_ABS_X:
|
||||
case MOS65XX_AM_ABS_Y:
|
||||
case MOS65XX_AM_ABS_X_IND:
|
||||
/* these depend on the databank to generate a 24-bit address */
|
||||
/* exceptions: PEA, PEI, and JMP (abs) */
|
||||
if (opinfo.ins == MOS65XX_INS_PEI || opinfo.ins == MOS65XX_INS_PEA) break;
|
||||
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_B;
|
||||
break;
|
||||
default:
|
||||
case MOS65XX_AM_ZP_IND:
|
||||
case MOS65XX_AM_ZP_X_IND:
|
||||
case MOS65XX_AM_ZP_IND_Y:
|
||||
case MOS65XX_AM_ABS:
|
||||
case MOS65XX_AM_ABS_X:
|
||||
case MOS65XX_AM_ABS_Y:
|
||||
case MOS65XX_AM_ABS_X_IND:
|
||||
/* these depend on the databank to generate a 24-bit address */
|
||||
/* exceptions: PEA, PEI, and JMP (abs) */
|
||||
if (opinfo.ins == MOS65XX_INS_PEI ||
|
||||
opinfo.ins == MOS65XX_INS_PEA)
|
||||
break;
|
||||
detail->regs_read[detail->regs_read_count++] =
|
||||
MOS65XX_REG_B;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,47 +210,59 @@ static void fillDetails(MCInst *MI, struct OpInfo opinfo, int cpu_type)
|
|||
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_P;
|
||||
}
|
||||
|
||||
switch(opinfo.am) {
|
||||
case MOS65XX_AM_IMP:
|
||||
break;
|
||||
case MOS65XX_AM_IMM:
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_IMM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].imm = MI->Operands[0].ImmVal;
|
||||
switch (opinfo.am) {
|
||||
case MOS65XX_AM_IMP:
|
||||
break;
|
||||
case MOS65XX_AM_IMM:
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type =
|
||||
MOS65XX_OP_IMM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].imm =
|
||||
MI->Operands[0].ImmVal;
|
||||
detail->mos65xx.op_count++;
|
||||
break;
|
||||
case MOS65XX_AM_ACC:
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type =
|
||||
MOS65XX_OP_REG;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].reg =
|
||||
MOS65XX_REG_ACC;
|
||||
detail->mos65xx.op_count++;
|
||||
break;
|
||||
case MOS65XX_AM_REL: {
|
||||
int value = MI->Operands[0].ImmVal;
|
||||
if (MI->op1_size == 1)
|
||||
value = 2 + (signed char)value;
|
||||
else
|
||||
value = 3 + (signed short)value;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type =
|
||||
MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].mem =
|
||||
(MI->address + value) & 0xffff;
|
||||
detail->mos65xx.op_count++;
|
||||
break;
|
||||
}
|
||||
case MOS65XX_AM_ZP_REL: {
|
||||
int value = 3 + (signed char)MI->Operands[1].ImmVal;
|
||||
/* BBR0, zp, rel and BBS0, zp, rel */
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type =
|
||||
MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].mem =
|
||||
MI->Operands[0].ImmVal;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count + 1].type =
|
||||
MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count + 1].mem =
|
||||
(MI->address + value) & 0xffff;
|
||||
detail->mos65xx.op_count += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
for (i = 0; i < MI->size; ++i) {
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type =
|
||||
MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].mem =
|
||||
MI->Operands[i].ImmVal;
|
||||
detail->mos65xx.op_count++;
|
||||
break;
|
||||
case MOS65XX_AM_ACC:
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_REG;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].reg = MOS65XX_REG_ACC;
|
||||
detail->mos65xx.op_count++;
|
||||
break;
|
||||
case MOS65XX_AM_REL: {
|
||||
int value = MI->Operands[0].ImmVal;
|
||||
if (MI->op1_size == 1)
|
||||
value = 2 + (signed char)value;
|
||||
else
|
||||
value = 3 + (signed short)value;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].mem = (MI->address + value) & 0xffff;
|
||||
detail->mos65xx.op_count++;
|
||||
break;
|
||||
}
|
||||
case MOS65XX_AM_ZP_REL: {
|
||||
int value = 3 + (signed char)MI->Operands[1].ImmVal;
|
||||
/* BBR0, zp, rel and BBS0, zp, rel */
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].mem = MI->Operands[0].ImmVal;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count+1].type = MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count+1].mem = (MI->address + value) & 0xffff;
|
||||
detail->mos65xx.op_count+=2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
for (i = 0; i < MI->size; ++i) {
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_MEM;
|
||||
detail->mos65xx.operands[detail->mos65xx.op_count].mem = MI->Operands[i].ImmVal;
|
||||
detail->mos65xx.op_count++;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -256,150 +280,150 @@ void MOS65XX_printInst(MCInst *MI, struct SStream *O, void *PrinterInfo)
|
|||
|
||||
SStream_concat0(O, InstructionInfoTable[opinfo.ins].name);
|
||||
switch (opinfo.ins) {
|
||||
/* special case - bit included as part of the instruction name */
|
||||
case MOS65XX_INS_BBR:
|
||||
case MOS65XX_INS_BBS:
|
||||
case MOS65XX_INS_RMB:
|
||||
case MOS65XX_INS_SMB:
|
||||
SStream_concat(O, "%d", (opcode >> 4) & 0x07);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
/* special case - bit included as part of the instruction name */
|
||||
case MOS65XX_INS_BBR:
|
||||
case MOS65XX_INS_BBS:
|
||||
case MOS65XX_INS_RMB:
|
||||
case MOS65XX_INS_SMB:
|
||||
SStream_concat(O, "%d", (opcode >> 4) & 0x07);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
value = MI->Operands[0].ImmVal;
|
||||
|
||||
switch (opinfo.am) {
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_IMP:
|
||||
break;
|
||||
case MOS65XX_AM_IMP:
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ACC:
|
||||
SStream_concat0(O, " a");
|
||||
break;
|
||||
case MOS65XX_AM_ACC:
|
||||
SStream_concat0(O, " a");
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_IMM:
|
||||
if (MI->imm_size == 1)
|
||||
SStream_concat(O, " #%s%02x", prefix, value);
|
||||
else
|
||||
SStream_concat(O, " #%s%04x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_IMM:
|
||||
if (MI->imm_size == 1)
|
||||
SStream_concat(O, " #%s%02x", prefix, value);
|
||||
else
|
||||
SStream_concat(O, " #%s%04x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP:
|
||||
SStream_concat(O, " %s%02x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP:
|
||||
SStream_concat(O, " %s%02x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS:
|
||||
SStream_concat(O, " %s%04x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS:
|
||||
SStream_concat(O, " %s%04x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS_LONG_X:
|
||||
SStream_concat(O, " %s%06x, x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS_LONG_X:
|
||||
SStream_concat(O, " %s%06x, x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_INT:
|
||||
SStream_concat(O, " %s%02x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_INT:
|
||||
SStream_concat(O, " %s%02x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS_X:
|
||||
SStream_concat(O, " %s%04x, x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS_X:
|
||||
SStream_concat(O, " %s%04x, x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS_Y:
|
||||
SStream_concat(O, " %s%04x, y", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS_Y:
|
||||
SStream_concat(O, " %s%04x, y", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS_LONG:
|
||||
SStream_concat(O, " %s%06x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS_LONG:
|
||||
SStream_concat(O, " %s%06x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_X:
|
||||
SStream_concat(O, " %s%02x, x", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP_X:
|
||||
SStream_concat(O, " %s%02x, x", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_Y:
|
||||
SStream_concat(O, " %s%02x, y", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP_Y:
|
||||
SStream_concat(O, " %s%02x, y", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_REL:
|
||||
if (MI->op1_size == 1)
|
||||
value = 2 + (signed char)value;
|
||||
else
|
||||
value = 3 + (signed short)value;
|
||||
case MOS65XX_AM_REL:
|
||||
if (MI->op1_size == 1)
|
||||
value = 2 + (signed char)value;
|
||||
else
|
||||
value = 3 + (signed short)value;
|
||||
|
||||
SStream_concat(O, " %s%04x", prefix,
|
||||
(MI->address + value) & 0xffff);
|
||||
break;
|
||||
SStream_concat(O, " %s%04x", prefix,
|
||||
(MI->address + value) & 0xffff);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS_IND:
|
||||
SStream_concat(O, " (%s%04x)", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS_IND:
|
||||
SStream_concat(O, " (%s%04x)", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS_X_IND:
|
||||
SStream_concat(O, " (%s%04x, x)", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS_X_IND:
|
||||
SStream_concat(O, " (%s%04x, x)", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ABS_IND_LONG:
|
||||
SStream_concat(O, " [%s%04x]", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ABS_IND_LONG:
|
||||
SStream_concat(O, " [%s%04x]", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_IND:
|
||||
SStream_concat(O, " (%s%02x)", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP_IND:
|
||||
SStream_concat(O, " (%s%02x)", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_X_IND:
|
||||
SStream_concat(O, " (%s%02x, x)", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP_X_IND:
|
||||
SStream_concat(O, " (%s%02x, x)", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_IND_Y:
|
||||
SStream_concat(O, " (%s%02x), y", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP_IND_Y:
|
||||
SStream_concat(O, " (%s%02x), y", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_IND_LONG:
|
||||
SStream_concat(O, " [%s%02x]", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP_IND_LONG:
|
||||
SStream_concat(O, " [%s%02x]", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_IND_LONG_Y:
|
||||
SStream_concat(O, " [%s%02x], y", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_ZP_IND_LONG_Y:
|
||||
SStream_concat(O, " [%s%02x], y", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_SR:
|
||||
SStream_concat(O, " %s%02x, s", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_SR:
|
||||
SStream_concat(O, " %s%02x, s", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_SR_IND_Y:
|
||||
SStream_concat(O, " (%s%02x, s), y", prefix, value);
|
||||
break;
|
||||
case MOS65XX_AM_SR_IND_Y:
|
||||
SStream_concat(O, " (%s%02x, s), y", prefix, value);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_BLOCK:
|
||||
SStream_concat(O, " %s%02x, %s%02x",
|
||||
prefix, MI->Operands[0].ImmVal,
|
||||
prefix, MI->Operands[1].ImmVal);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_REL:
|
||||
value = 3 + (signed char)MI->Operands[1].ImmVal;
|
||||
/* BBR0, zp, rel and BBS0, zp, rel */
|
||||
SStream_concat(O, " %s%02x, %s%04x",
|
||||
prefix, MI->Operands[0].ImmVal,
|
||||
prefix, (MI->address + value) & 0xffff);
|
||||
break;
|
||||
case MOS65XX_AM_BLOCK:
|
||||
SStream_concat(O, " %s%02x, %s%02x", prefix,
|
||||
MI->Operands[0].ImmVal, prefix,
|
||||
MI->Operands[1].ImmVal);
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_ZP_REL:
|
||||
value = 3 + (signed char)MI->Operands[1].ImmVal;
|
||||
/* BBR0, zp, rel and BBS0, zp, rel */
|
||||
SStream_concat(O, " %s%02x, %s%04x", prefix,
|
||||
MI->Operands[0].ImmVal, prefix,
|
||||
(MI->address + value) & 0xffff);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MOS65XX_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
|
||||
MCInst *MI, uint16_t *size, uint64_t address,
|
||||
void *inst_info)
|
||||
{
|
||||
int i;
|
||||
unsigned char opcode;
|
||||
unsigned char len;
|
||||
unsigned cpu_offset = 0;
|
||||
int cpu_type = MOS65XX_CPU_TYPE_6502;
|
||||
cs_struct* handle = MI->csh;
|
||||
cs_struct *handle = MI->csh;
|
||||
mos65xx_info *info = (mos65xx_info *)handle->printer_info;
|
||||
OpInfo opinfo;
|
||||
|
||||
|
|
@ -421,25 +445,27 @@ bool MOS65XX_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||
len = opinfo.operand_bytes + 1;
|
||||
|
||||
if (cpu_type == MOS65XX_CPU_TYPE_65816 && opinfo.am == MOS65XX_AM_IMM) {
|
||||
switch(opinfo.ins) {
|
||||
case MOS65XX_INS_CPX:
|
||||
case MOS65XX_INS_CPY:
|
||||
case MOS65XX_INS_LDX:
|
||||
case MOS65XX_INS_LDY:
|
||||
if (info->long_x) ++len;
|
||||
break;
|
||||
case MOS65XX_INS_ADC:
|
||||
case MOS65XX_INS_AND:
|
||||
case MOS65XX_INS_BIT:
|
||||
case MOS65XX_INS_CMP:
|
||||
case MOS65XX_INS_EOR:
|
||||
case MOS65XX_INS_LDA:
|
||||
case MOS65XX_INS_ORA:
|
||||
case MOS65XX_INS_SBC:
|
||||
if (info->long_m) ++len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (opinfo.ins) {
|
||||
case MOS65XX_INS_CPX:
|
||||
case MOS65XX_INS_CPY:
|
||||
case MOS65XX_INS_LDX:
|
||||
case MOS65XX_INS_LDY:
|
||||
if (info->long_x)
|
||||
++len;
|
||||
break;
|
||||
case MOS65XX_INS_ADC:
|
||||
case MOS65XX_INS_AND:
|
||||
case MOS65XX_INS_BIT:
|
||||
case MOS65XX_INS_CMP:
|
||||
case MOS65XX_INS_EOR:
|
||||
case MOS65XX_INS_LDA:
|
||||
case MOS65XX_INS_ORA:
|
||||
case MOS65XX_INS_SBC:
|
||||
if (info->long_m)
|
||||
++len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -463,31 +489,32 @@ bool MOS65XX_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||
}
|
||||
|
||||
switch (opinfo.am) {
|
||||
case MOS65XX_AM_ZP_REL:
|
||||
MCOperand_CreateImm0(MI, code[1]);
|
||||
MCOperand_CreateImm0(MI, code[2]);
|
||||
break;
|
||||
case MOS65XX_AM_BLOCK:
|
||||
MCOperand_CreateImm0(MI, code[2]);
|
||||
MCOperand_CreateImm0(MI, code[1]);
|
||||
break;
|
||||
case MOS65XX_AM_IMP:
|
||||
case MOS65XX_AM_ACC:
|
||||
break;
|
||||
case MOS65XX_AM_ZP_REL:
|
||||
MCOperand_CreateImm0(MI, code[1]);
|
||||
MCOperand_CreateImm0(MI, code[2]);
|
||||
break;
|
||||
case MOS65XX_AM_BLOCK:
|
||||
MCOperand_CreateImm0(MI, code[2]);
|
||||
MCOperand_CreateImm0(MI, code[1]);
|
||||
break;
|
||||
case MOS65XX_AM_IMP:
|
||||
case MOS65XX_AM_ACC:
|
||||
break;
|
||||
|
||||
case MOS65XX_AM_IMM:
|
||||
MI->has_imm = 1;
|
||||
MI->imm_size = len - 1;
|
||||
/* 65816 immediate is either 1 or 2 bytes */
|
||||
/* drop through */
|
||||
default:
|
||||
if (len == 2)
|
||||
MCOperand_CreateImm0(MI, code[1]);
|
||||
else if (len == 3)
|
||||
MCOperand_CreateImm0(MI, (code[2]<<8) | code[1]);
|
||||
else if (len == 4)
|
||||
MCOperand_CreateImm0(MI, (code[3]<<16) | (code[2]<<8) | code[1]);
|
||||
break;
|
||||
case MOS65XX_AM_IMM:
|
||||
MI->has_imm = 1;
|
||||
MI->imm_size = len - 1;
|
||||
/* 65816 immediate is either 1 or 2 bytes */
|
||||
/* drop through */
|
||||
default:
|
||||
if (len == 2)
|
||||
MCOperand_CreateImm0(MI, code[1]);
|
||||
else if (len == 3)
|
||||
MCOperand_CreateImm0(MI, (code[2] << 8) | code[1]);
|
||||
else if (len == 4)
|
||||
MCOperand_CreateImm0(
|
||||
MI, (code[3] << 16) | (code[2] << 8) | code[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
|
|
@ -511,7 +538,7 @@ const char *MOS65XX_insn_name(csh handle, unsigned int id)
|
|||
#endif
|
||||
}
|
||||
|
||||
const char* MOS65XX_reg_name(csh handle, unsigned int reg)
|
||||
const char *MOS65XX_reg_name(csh handle, unsigned int reg)
|
||||
{
|
||||
#ifdef CAPSTONE_DIET
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -14,9 +14,10 @@ const char *MOS65XX_insn_name(csh handle, unsigned int id);
|
|||
|
||||
const char *MOS65XX_group_name(csh handle, unsigned int id);
|
||||
|
||||
const char* MOS65XX_reg_name(csh handle, unsigned int reg);
|
||||
const char *MOS65XX_reg_name(csh handle, unsigned int reg);
|
||||
|
||||
bool MOS65XX_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *MI, uint16_t *size, uint64_t address, void *inst_info);
|
||||
MCInst *MI, uint16_t *size, uint64_t address,
|
||||
void *inst_info);
|
||||
|
||||
#endif //CAPSTONE_MOS65XXDISASSEMBLER_H
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct mos65xx_info {
|
||||
|
||||
const char *hex_prefix;
|
||||
unsigned cpu_type;
|
||||
unsigned long_m;
|
||||
|
|
@ -19,5 +18,4 @@ typedef struct mos65xx_info {
|
|||
|
||||
} mos65xx_info;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ cs_err MOS65XX_global_init(cs_struct *ud)
|
|||
info->long_m = 0;
|
||||
info->long_x = 0;
|
||||
|
||||
|
||||
ud->printer = MOS65XX_printInst;
|
||||
ud->printer_info = info;
|
||||
ud->insn_id = MOS65XX_get_insn_id;
|
||||
|
|
@ -38,40 +37,44 @@ cs_err MOS65XX_global_init(cs_struct *ud)
|
|||
cs_err MOS65XX_option(cs_struct *handle, cs_opt_type type, size_t value)
|
||||
{
|
||||
mos65xx_info *info = (mos65xx_info *)handle->printer_info;
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
default:
|
||||
break;
|
||||
case CS_OPT_MODE:
|
||||
|
||||
if (value & CS_MODE_MOS65XX_6502)
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_6502;
|
||||
if (value & CS_MODE_MOS65XX_65C02)
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_65C02;
|
||||
if (value & CS_MODE_MOS65XX_W65C02)
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_W65C02;
|
||||
if (value &
|
||||
(CS_MODE_MOS65XX_65816 | CS_MODE_MOS65XX_65816_LONG_M |
|
||||
CS_MODE_MOS65XX_65816_LONG_X))
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_65816;
|
||||
|
||||
info->long_m = value & CS_MODE_MOS65XX_65816_LONG_M ? 1 : 0;
|
||||
info->long_x = value & CS_MODE_MOS65XX_65816_LONG_X ? 1 : 0;
|
||||
|
||||
// NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
handle->mode = (cs_mode)value;
|
||||
// NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
break;
|
||||
case CS_OPT_SYNTAX:
|
||||
switch (value) {
|
||||
default:
|
||||
// wrong syntax value
|
||||
handle->errnum = CS_ERR_OPTION;
|
||||
return CS_ERR_OPTION;
|
||||
case CS_OPT_SYNTAX_DEFAULT:
|
||||
info->hex_prefix = NULL;
|
||||
break;
|
||||
case CS_OPT_MODE:
|
||||
|
||||
if (value & CS_MODE_MOS65XX_6502)
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_6502;
|
||||
if (value & CS_MODE_MOS65XX_65C02)
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_65C02;
|
||||
if (value & CS_MODE_MOS65XX_W65C02)
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_W65C02;
|
||||
if (value & (CS_MODE_MOS65XX_65816|CS_MODE_MOS65XX_65816_LONG_M|CS_MODE_MOS65XX_65816_LONG_X))
|
||||
info->cpu_type = MOS65XX_CPU_TYPE_65816;
|
||||
|
||||
info->long_m = value & CS_MODE_MOS65XX_65816_LONG_M ? 1 : 0;
|
||||
info->long_x = value & CS_MODE_MOS65XX_65816_LONG_X ? 1 : 0;
|
||||
|
||||
handle->mode = (cs_mode)value; // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
break;
|
||||
case CS_OPT_SYNTAX:
|
||||
switch(value) {
|
||||
default:
|
||||
// wrong syntax value
|
||||
handle->errnum = CS_ERR_OPTION;
|
||||
return CS_ERR_OPTION;
|
||||
case CS_OPT_SYNTAX_DEFAULT:
|
||||
info->hex_prefix = NULL;
|
||||
break;
|
||||
case CS_OPT_SYNTAX_MOTOROLA:
|
||||
info->hex_prefix = "$";
|
||||
break;
|
||||
}
|
||||
handle->syntax = (int)value;
|
||||
case CS_OPT_SYNTAX_MOTOROLA:
|
||||
info->hex_prefix = "$";
|
||||
break;
|
||||
}
|
||||
handle->syntax = (int)value;
|
||||
break;
|
||||
}
|
||||
return CS_ERR_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,186 +5,187 @@
|
|||
#define LLVM_LIB_TARGET_MIPS_NANOMIPSCP0REGMAP_H
|
||||
|
||||
struct CP0SelRegister_t {
|
||||
const char *Name;
|
||||
int RegNum;
|
||||
int Select;
|
||||
int Index;
|
||||
const char *Name;
|
||||
int RegNum;
|
||||
int Select;
|
||||
int Index;
|
||||
};
|
||||
|
||||
static const struct CP0SelRegister_t CP0SelRegs[] = {
|
||||
{"index", 0, 0},
|
||||
{"mvpcontrol", 0, 1},
|
||||
{"mvpconf0", 0, 2},
|
||||
{"mvpconf1", 0, 3},
|
||||
{"vpcontrol", 0, 4},
|
||||
{"random", 1, 0},
|
||||
{"vpecontrol", 1, 1},
|
||||
{"vpeconf0", 1, 2},
|
||||
{"vpeconf1", 1, 3},
|
||||
{"yqmask", 1, 4},
|
||||
{"vpeschedule", 1, 5},
|
||||
{"vpeschefback", 1, 6},
|
||||
{"vpeopt", 1, 7},
|
||||
{"entrylo0", 2, 0},
|
||||
{"tcstatus", 2, 1},
|
||||
{"tcbind", 2, 2},
|
||||
{"tcrestart", 2, 3},
|
||||
{"tchalt", 2, 4},
|
||||
{"tccontext", 2, 5},
|
||||
{"tcschedule", 2, 6},
|
||||
{"tcschefback", 2, 7},
|
||||
{"entrylo1", 3, 0},
|
||||
{"globalnumber", 3, 1},
|
||||
{"tcopt", 3, 7},
|
||||
{"context", 4, 0},
|
||||
{"contextconfig", 4, 1},
|
||||
{"userlocal", 4, 2},
|
||||
{"xcontextconfig", 4, 3},
|
||||
{"debugcontextid", 4, 4},
|
||||
{"memorymapid", 4, 5},
|
||||
{"pagemask", 5, 0},
|
||||
{"pagegrain", 5, 1},
|
||||
{"segctl0", 5, 2},
|
||||
{"segctl1", 5, 3},
|
||||
{"segctl2", 5, 4},
|
||||
{"pwbase", 5, 5},
|
||||
{"pwfield", 5, 6},
|
||||
{"pwsize", 5, 7},
|
||||
{"wired", 6, 0},
|
||||
{"srsconf0", 6, 1},
|
||||
{"srsconf1", 6, 2},
|
||||
{"srsconf2", 6, 3},
|
||||
{"srsconf3", 6, 4},
|
||||
{"srsconf4", 6, 5},
|
||||
{"pwctl", 6, 6},
|
||||
{"hwrena", 7, 0},
|
||||
{"badvaddr", 8, 0},
|
||||
{"badinst", 8, 1},
|
||||
{"badinstrp", 8, 2},
|
||||
{"badinstrx", 8, 3},
|
||||
{"count", 9, 0},
|
||||
{"entryhi", 10, 0},
|
||||
{"guestctl1", 10, 4},
|
||||
{"guestctl2", 10, 5},
|
||||
{"guestctl3", 10, 6},
|
||||
{"compare", 11, 0},
|
||||
{"guestctl0ext", 11, 4},
|
||||
{"status", 12, 0},
|
||||
{"intctl", 12, 1},
|
||||
{"srsctl", 12, 2},
|
||||
{"srsmap", 12, 3},
|
||||
{"view_ipl", 12, 4},
|
||||
{"srsmap2", 12, 5},
|
||||
{"guestctl0", 12, 6},
|
||||
{"gtoffset", 12, 7},
|
||||
{"cause", 13, 0},
|
||||
{"view_ripl", 13, 4},
|
||||
{"nestedexc", 13, 5},
|
||||
{"epc", 14, 0},
|
||||
{"nestedepc", 14, 2},
|
||||
{"prid", 15, 0},
|
||||
{"ebase", 15, 1},
|
||||
{"cdmmbase", 15, 2},
|
||||
{"cmgcrbase", 15, 3},
|
||||
{"bevva", 15, 4},
|
||||
{"config", 16, 0},
|
||||
{"config1", 16, 1},
|
||||
{"config2", 16, 2},
|
||||
{"config3", 16, 3},
|
||||
{"config4", 16, 4},
|
||||
{"config5", 16, 5},
|
||||
{"lladdr", 17, 0},
|
||||
{"maar", 17, 1},
|
||||
{"maari", 17, 2},
|
||||
{"watchlo0", 18, 0},
|
||||
{"watchlo1", 18, 1},
|
||||
{"watchlo2", 18, 2},
|
||||
{"watchlo3", 18, 3},
|
||||
{"watchlo4", 18, 4},
|
||||
{"watchlo5", 18, 5},
|
||||
{"watchlo6", 18, 6},
|
||||
{"watchlo7", 18, 7},
|
||||
{"watchlo8", 18, 8},
|
||||
{"watchlo9", 18, 9},
|
||||
{"watchlo10", 18,10},
|
||||
{"watchlo11", 18,11},
|
||||
{"watchlo12", 18,12},
|
||||
{"watchlo13", 18,13},
|
||||
{"watchlo14", 18,14},
|
||||
{"watchlo15", 18,15},
|
||||
{"watchhi0", 19, 0},
|
||||
{"watchhi1", 19, 1},
|
||||
{"watchhi2", 19, 2},
|
||||
{"watchhi3", 19, 3},
|
||||
{"watchhi4", 19, 4},
|
||||
{"watchhi5", 19, 5},
|
||||
{"watchhi6", 19, 6},
|
||||
{"watchhi7", 19, 7},
|
||||
{"watchhi8", 19, 8},
|
||||
{"watchhi9", 19, 9},
|
||||
{"watchhi10", 19,10},
|
||||
{"watchhi11", 19,11},
|
||||
{"watchhi12", 19,12},
|
||||
{"watchhi13", 19,13},
|
||||
{"watchhi14", 19,14},
|
||||
{"watchhi15", 19,15},
|
||||
{"xcontext", 20, 0},
|
||||
{"debug", 23, 0},
|
||||
{"tracecontrol", 23, 1},
|
||||
{"tracecontrol2", 23, 2},
|
||||
{"usertracedata1", 23, 3},
|
||||
{"traceibpc", 23, 4},
|
||||
{"tracedbpc", 23, 5},
|
||||
{"debug2", 23, 6},
|
||||
{"depc", 24, 0},
|
||||
{"tracecontrol3", 24, 2},
|
||||
{"usertracedata2", 24, 3},
|
||||
{"perfctl0", 25, 0},
|
||||
{"perfcnt0", 25, 1},
|
||||
{"perfctl1", 25, 2},
|
||||
{"perfcnt1", 25, 3},
|
||||
{"perfctl2", 25, 4},
|
||||
{"perfcnt2", 25, 5},
|
||||
{"perfctl3", 25, 6},
|
||||
{"perfcnt3", 25, 7},
|
||||
{"perfctl4", 25, 8},
|
||||
{"perfcnt4", 25, 9},
|
||||
{"perfctl5", 25,10},
|
||||
{"perfcnt5", 25,11},
|
||||
{"perfctl6", 25,12},
|
||||
{"perfcnt6", 25,13},
|
||||
{"perfctl7", 25,14},
|
||||
{"perfcnt7", 25,15},
|
||||
{"errctl", 26, 0},
|
||||
{"cacheerr", 27, 0},
|
||||
{"itaglo", 28, 0},
|
||||
{"idatalo", 28, 1},
|
||||
{"dtaglo", 28, 2},
|
||||
{"ddatalo", 28, 3},
|
||||
{"itaghi", 29, 0},
|
||||
{"idatahi", 29, 1},
|
||||
{"dtaghi", 29, 2},
|
||||
{"ddatahi", 29, 3},
|
||||
{"errorepc", 30, 0},
|
||||
{"desave", 31, 0},
|
||||
{"kscratch1", 31, 2},
|
||||
{"kscratch2", 31, 3},
|
||||
{"kscratch3", 31, 4},
|
||||
{"kscratch4", 31, 5},
|
||||
{"kscratch5", 31, 6},
|
||||
{"kscratch6", 31, 7}
|
||||
{ "index", 0, 0 },
|
||||
{ "mvpcontrol", 0, 1 },
|
||||
{ "mvpconf0", 0, 2 },
|
||||
{ "mvpconf1", 0, 3 },
|
||||
{ "vpcontrol", 0, 4 },
|
||||
{ "random", 1, 0 },
|
||||
{ "vpecontrol", 1, 1 },
|
||||
{ "vpeconf0", 1, 2 },
|
||||
{ "vpeconf1", 1, 3 },
|
||||
{ "yqmask", 1, 4 },
|
||||
{ "vpeschedule", 1, 5 },
|
||||
{ "vpeschefback", 1, 6 },
|
||||
{ "vpeopt", 1, 7 },
|
||||
{ "entrylo0", 2, 0 },
|
||||
{ "tcstatus", 2, 1 },
|
||||
{ "tcbind", 2, 2 },
|
||||
{ "tcrestart", 2, 3 },
|
||||
{ "tchalt", 2, 4 },
|
||||
{ "tccontext", 2, 5 },
|
||||
{ "tcschedule", 2, 6 },
|
||||
{ "tcschefback", 2, 7 },
|
||||
{ "entrylo1", 3, 0 },
|
||||
{ "globalnumber", 3, 1 },
|
||||
{ "tcopt", 3, 7 },
|
||||
{ "context", 4, 0 },
|
||||
{ "contextconfig", 4, 1 },
|
||||
{ "userlocal", 4, 2 },
|
||||
{ "xcontextconfig", 4, 3 },
|
||||
{ "debugcontextid", 4, 4 },
|
||||
{ "memorymapid", 4, 5 },
|
||||
{ "pagemask", 5, 0 },
|
||||
{ "pagegrain", 5, 1 },
|
||||
{ "segctl0", 5, 2 },
|
||||
{ "segctl1", 5, 3 },
|
||||
{ "segctl2", 5, 4 },
|
||||
{ "pwbase", 5, 5 },
|
||||
{ "pwfield", 5, 6 },
|
||||
{ "pwsize", 5, 7 },
|
||||
{ "wired", 6, 0 },
|
||||
{ "srsconf0", 6, 1 },
|
||||
{ "srsconf1", 6, 2 },
|
||||
{ "srsconf2", 6, 3 },
|
||||
{ "srsconf3", 6, 4 },
|
||||
{ "srsconf4", 6, 5 },
|
||||
{ "pwctl", 6, 6 },
|
||||
{ "hwrena", 7, 0 },
|
||||
{ "badvaddr", 8, 0 },
|
||||
{ "badinst", 8, 1 },
|
||||
{ "badinstrp", 8, 2 },
|
||||
{ "badinstrx", 8, 3 },
|
||||
{ "count", 9, 0 },
|
||||
{ "entryhi", 10, 0 },
|
||||
{ "guestctl1", 10, 4 },
|
||||
{ "guestctl2", 10, 5 },
|
||||
{ "guestctl3", 10, 6 },
|
||||
{ "compare", 11, 0 },
|
||||
{ "guestctl0ext", 11, 4 },
|
||||
{ "status", 12, 0 },
|
||||
{ "intctl", 12, 1 },
|
||||
{ "srsctl", 12, 2 },
|
||||
{ "srsmap", 12, 3 },
|
||||
{ "view_ipl", 12, 4 },
|
||||
{ "srsmap2", 12, 5 },
|
||||
{ "guestctl0", 12, 6 },
|
||||
{ "gtoffset", 12, 7 },
|
||||
{ "cause", 13, 0 },
|
||||
{ "view_ripl", 13, 4 },
|
||||
{ "nestedexc", 13, 5 },
|
||||
{ "epc", 14, 0 },
|
||||
{ "nestedepc", 14, 2 },
|
||||
{ "prid", 15, 0 },
|
||||
{ "ebase", 15, 1 },
|
||||
{ "cdmmbase", 15, 2 },
|
||||
{ "cmgcrbase", 15, 3 },
|
||||
{ "bevva", 15, 4 },
|
||||
{ "config", 16, 0 },
|
||||
{ "config1", 16, 1 },
|
||||
{ "config2", 16, 2 },
|
||||
{ "config3", 16, 3 },
|
||||
{ "config4", 16, 4 },
|
||||
{ "config5", 16, 5 },
|
||||
{ "lladdr", 17, 0 },
|
||||
{ "maar", 17, 1 },
|
||||
{ "maari", 17, 2 },
|
||||
{ "watchlo0", 18, 0 },
|
||||
{ "watchlo1", 18, 1 },
|
||||
{ "watchlo2", 18, 2 },
|
||||
{ "watchlo3", 18, 3 },
|
||||
{ "watchlo4", 18, 4 },
|
||||
{ "watchlo5", 18, 5 },
|
||||
{ "watchlo6", 18, 6 },
|
||||
{ "watchlo7", 18, 7 },
|
||||
{ "watchlo8", 18, 8 },
|
||||
{ "watchlo9", 18, 9 },
|
||||
{ "watchlo10", 18, 10 },
|
||||
{ "watchlo11", 18, 11 },
|
||||
{ "watchlo12", 18, 12 },
|
||||
{ "watchlo13", 18, 13 },
|
||||
{ "watchlo14", 18, 14 },
|
||||
{ "watchlo15", 18, 15 },
|
||||
{ "watchhi0", 19, 0 },
|
||||
{ "watchhi1", 19, 1 },
|
||||
{ "watchhi2", 19, 2 },
|
||||
{ "watchhi3", 19, 3 },
|
||||
{ "watchhi4", 19, 4 },
|
||||
{ "watchhi5", 19, 5 },
|
||||
{ "watchhi6", 19, 6 },
|
||||
{ "watchhi7", 19, 7 },
|
||||
{ "watchhi8", 19, 8 },
|
||||
{ "watchhi9", 19, 9 },
|
||||
{ "watchhi10", 19, 10 },
|
||||
{ "watchhi11", 19, 11 },
|
||||
{ "watchhi12", 19, 12 },
|
||||
{ "watchhi13", 19, 13 },
|
||||
{ "watchhi14", 19, 14 },
|
||||
{ "watchhi15", 19, 15 },
|
||||
{ "xcontext", 20, 0 },
|
||||
{ "debug", 23, 0 },
|
||||
{ "tracecontrol", 23, 1 },
|
||||
{ "tracecontrol2", 23, 2 },
|
||||
{ "usertracedata1", 23, 3 },
|
||||
{ "traceibpc", 23, 4 },
|
||||
{ "tracedbpc", 23, 5 },
|
||||
{ "debug2", 23, 6 },
|
||||
{ "depc", 24, 0 },
|
||||
{ "tracecontrol3", 24, 2 },
|
||||
{ "usertracedata2", 24, 3 },
|
||||
{ "perfctl0", 25, 0 },
|
||||
{ "perfcnt0", 25, 1 },
|
||||
{ "perfctl1", 25, 2 },
|
||||
{ "perfcnt1", 25, 3 },
|
||||
{ "perfctl2", 25, 4 },
|
||||
{ "perfcnt2", 25, 5 },
|
||||
{ "perfctl3", 25, 6 },
|
||||
{ "perfcnt3", 25, 7 },
|
||||
{ "perfctl4", 25, 8 },
|
||||
{ "perfcnt4", 25, 9 },
|
||||
{ "perfctl5", 25, 10 },
|
||||
{ "perfcnt5", 25, 11 },
|
||||
{ "perfctl6", 25, 12 },
|
||||
{ "perfcnt6", 25, 13 },
|
||||
{ "perfctl7", 25, 14 },
|
||||
{ "perfcnt7", 25, 15 },
|
||||
{ "errctl", 26, 0 },
|
||||
{ "cacheerr", 27, 0 },
|
||||
{ "itaglo", 28, 0 },
|
||||
{ "idatalo", 28, 1 },
|
||||
{ "dtaglo", 28, 2 },
|
||||
{ "ddatalo", 28, 3 },
|
||||
{ "itaghi", 29, 0 },
|
||||
{ "idatahi", 29, 1 },
|
||||
{ "dtaghi", 29, 2 },
|
||||
{ "ddatahi", 29, 3 },
|
||||
{ "errorepc", 30, 0 },
|
||||
{ "desave", 31, 0 },
|
||||
{ "kscratch1", 31, 2 },
|
||||
{ "kscratch2", 31, 3 },
|
||||
{ "kscratch3", 31, 4 },
|
||||
{ "kscratch4", 31, 5 },
|
||||
{ "kscratch5", 31, 6 },
|
||||
{ "kscratch6", 31, 7 }
|
||||
};
|
||||
|
||||
inline static int COP0Map_getEncIndexMap(int RegNo)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(CP0SelRegs) / sizeof(CP0SelRegs[0])); ++i) {
|
||||
unsigned RegEnc = (CP0SelRegs[i].RegNum << 5) | CP0SelRegs[i].Select;
|
||||
if (RegEnc == RegNo) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(CP0SelRegs) / sizeof(CP0SelRegs[0])); ++i) {
|
||||
unsigned RegEnc = (CP0SelRegs[i].RegNum << 5) |
|
||||
CP0SelRegs[i].Select;
|
||||
if (RegEnc == RegNo) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // LLVM_LIB_TARGET_MIPS_NANOMIPSCP0REGMAP_H
|
||||
|
|
|
|||
|
|
@ -53,135 +53,123 @@
|
|||
|
||||
bool Mips_getFeatureBits(unsigned int mode, unsigned int feature)
|
||||
{
|
||||
switch(feature) {
|
||||
switch (feature) {
|
||||
case Mips_FeatureGP64Bit:
|
||||
return mode & (CS_MODE_MIPS3 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS3 | CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
case Mips_FeatureFP64Bit:
|
||||
return mode & (CS_MODE_MIPS32R6 | CS_MODE_MIPS3 |
|
||||
CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32R6 | CS_MODE_MIPS3 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureNaN2008:
|
||||
return mode & (CS_MODE_MIPS32R6 | CS_MODE_MIPS64R6);
|
||||
case Mips_FeatureAbs2008:
|
||||
return mode & (CS_MODE_MIPS32R6 | CS_MODE_MIPS64R6);
|
||||
case Mips_FeatureMips1:
|
||||
return mode & (CS_MODE_MIPS1 | CS_MODE_MIPS2 |
|
||||
CS_MODE_MIPS32 | CS_MODE_MIPS32R2 |
|
||||
CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS3 |
|
||||
CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS1 | CS_MODE_MIPS2 | CS_MODE_MIPS32 |
|
||||
CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS3 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips2:
|
||||
return mode & (CS_MODE_MIPS2 | CS_MODE_MIPS32 |
|
||||
CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS3 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS2 | CS_MODE_MIPS32 | CS_MODE_MIPS32R2 |
|
||||
CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS3 | CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips3_32:
|
||||
return mode & (CS_MODE_MIPS32 | CS_MODE_MIPS32R2 |
|
||||
CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS3 |
|
||||
CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32 | CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 | CS_MODE_MIPS3 |
|
||||
CS_MODE_MIPS4 | CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips3_32r2:
|
||||
return mode & (CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS3 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS3 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips3:
|
||||
return mode & (CS_MODE_MIPS3 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS3 | CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips4_32:
|
||||
return mode & (CS_MODE_MIPS32 | CS_MODE_MIPS32R2 |
|
||||
CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32 | CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 | CS_MODE_MIPS4 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips4_32r2:
|
||||
return mode & (CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips4:
|
||||
return mode & (CS_MODE_MIPS4 | CS_MODE_MIPS5 |
|
||||
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS4 | CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips5_32r2:
|
||||
return mode & (CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips5:
|
||||
return mode & (CS_MODE_MIPS5 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS5 | CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips32:
|
||||
return mode & (CS_MODE_MIPS32 | CS_MODE_MIPS32R2 |
|
||||
CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32 | CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 | CS_MODE_MIPS64 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips32r2:
|
||||
return mode & (CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
|
||||
CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips32r3:
|
||||
return mode & (CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 |
|
||||
CS_MODE_MIPS32R6 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6);
|
||||
return mode &
|
||||
(CS_MODE_MIPS32R3 | CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6);
|
||||
case Mips_FeatureMips32r5:
|
||||
return mode & (CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6);
|
||||
return mode & (CS_MODE_MIPS32R5 | CS_MODE_MIPS32R6 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6);
|
||||
case Mips_FeatureMips32r6:
|
||||
return mode & (CS_MODE_MIPS32R6 | CS_MODE_MIPS64R6);
|
||||
case Mips_FeatureMips64:
|
||||
return mode & (CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
|
||||
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS64 | CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
|
||||
CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips64r2:
|
||||
return mode & (CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
|
||||
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
|
||||
CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
return mode &
|
||||
(CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6 | CS_MODE_OCTEON | CS_MODE_OCTEONP);
|
||||
case Mips_FeatureMips64r3:
|
||||
return mode & (CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
|
||||
CS_MODE_MIPS64R6);
|
||||
return mode &
|
||||
(CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6);
|
||||
case Mips_FeatureMips64r5:
|
||||
return mode & (CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6);
|
||||
case Mips_FeatureMips64r6:
|
||||
|
|
@ -191,8 +179,7 @@ bool Mips_getFeatureBits(unsigned int mode, unsigned int feature)
|
|||
case Mips_FeatureMicroMips:
|
||||
return mode & CS_MODE_MICRO;
|
||||
case Mips_FeatureNanoMips:
|
||||
return mode & (CS_MODE_NANOMIPS | CS_MODE_NMS1 |
|
||||
CS_MODE_I7200);
|
||||
return mode & (CS_MODE_NANOMIPS | CS_MODE_NMS1 | CS_MODE_I7200);
|
||||
case Mips_FeatureNMS1:
|
||||
return mode & CS_MODE_NMS1;
|
||||
case Mips_FeatureTLB:
|
||||
|
|
@ -241,8 +228,9 @@ bool Mips_getFeatureBits(unsigned int mode, unsigned int feature)
|
|||
}
|
||||
}
|
||||
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address, SStream *CStream);
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size,
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CStream);
|
||||
|
||||
// end anonymous namespace
|
||||
|
||||
|
|
@ -601,14 +589,15 @@ DEFINE_DecodeUImmWithOffset(5, 1);
|
|||
DEFINE_DecodeUImmWithOffset(2, 1);
|
||||
|
||||
#define DECLARE_DecodeSImmWithOffsetAndScale(Bits, Offset, ScaleBy) \
|
||||
static DecodeStatus CONCAT( \
|
||||
DecodeSImmWithOffsetAndScale, \
|
||||
CONCAT(Bits, CONCAT(Offset, ScaleBy)))( \
|
||||
static DecodeStatus CONCAT(DecodeSImmWithOffsetAndScale, \
|
||||
CONCAT(Bits, CONCAT(Offset, ScaleBy)))( \
|
||||
MCInst * Inst, unsigned Value, uint64_t Address, \
|
||||
const void *Decoder);
|
||||
|
||||
#define DECLARE_DecodeSImmWithOffsetAndScale_2(Bits, Offset) DECLARE_DecodeSImmWithOffsetAndScale(Bits, Offset, 1)
|
||||
#define DECLARE_DecodeSImmWithOffsetAndScale_3(Bits) DECLARE_DecodeSImmWithOffsetAndScale(Bits, 0, 1)
|
||||
#define DECLARE_DecodeSImmWithOffsetAndScale_2(Bits, Offset) \
|
||||
DECLARE_DecodeSImmWithOffsetAndScale(Bits, Offset, 1)
|
||||
#define DECLARE_DecodeSImmWithOffsetAndScale_3(Bits) \
|
||||
DECLARE_DecodeSImmWithOffsetAndScale(Bits, 0, 1)
|
||||
|
||||
DECLARE_DecodeSImmWithOffsetAndScale_3(16);
|
||||
DECLARE_DecodeSImmWithOffsetAndScale_3(10);
|
||||
|
|
@ -697,7 +686,7 @@ static DecodeStatus DecodeDAHIDATIMMR6(MCInst *MI, uint32_t insn,
|
|||
*/
|
||||
|
||||
static DecodeStatus DecodeDAHIDATI(MCInst *MI, uint32_t insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeAddiGroupBranch(MCInst *MI, uint32_t insn,
|
||||
uint64_t Address,
|
||||
|
|
@ -777,13 +766,12 @@ static DecodeStatus DecodeFIXMEInstruction(MCInst *Inst, uint32_t Insn,
|
|||
|
||||
static unsigned getReg(const MCInst *Inst, unsigned RC, unsigned RegNo)
|
||||
{
|
||||
const MCRegisterClass* c = MCRegisterInfo_getRegClass(Inst->MRI, RC);
|
||||
const MCRegisterClass *c = MCRegisterInfo_getRegClass(Inst->MRI, RC);
|
||||
return MCRegisterClass_getRegister(c, RegNo);
|
||||
}
|
||||
|
||||
typedef DecodeStatus (*DecodeFN)(MCInst *Inst, uint32_t Insn,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
typedef DecodeStatus (*DecodeFN)(MCInst *Inst, uint32_t Insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeINSVE_DF(MCInst *MI, uint32_t insn, uint64_t Address,
|
||||
const void *Decoder)
|
||||
|
|
@ -793,7 +781,7 @@ static DecodeStatus DecodeINSVE_DF(MCInst *MI, uint32_t insn, uint64_t Address,
|
|||
uint32_t tmp = fieldFromInstruction_4(insn, 17, 5);
|
||||
unsigned NSize = 0;
|
||||
DecodeFN RegDecoder = NULL;
|
||||
if ((tmp & 0x18) == 0x00) { // INSVE_B
|
||||
if ((tmp & 0x18) == 0x00) { // INSVE_B
|
||||
NSize = 4;
|
||||
RegDecoder = DecodeMSA128BRegisterClass;
|
||||
} else if ((tmp & 0x1c) == 0x10) { // INSVE_H
|
||||
|
|
@ -805,8 +793,10 @@ static DecodeStatus DecodeINSVE_DF(MCInst *MI, uint32_t insn, uint64_t Address,
|
|||
} else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
|
||||
NSize = 1;
|
||||
RegDecoder = DecodeMSA128DRegisterClass;
|
||||
} else
|
||||
} else {
|
||||
CS_ASSERT_RET_VAL(0 && "Invalid encoding", MCDisassembler_Fail);
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
// $wd
|
||||
tmp = fieldFromInstruction_4(insn, 6, 5);
|
||||
|
|
@ -843,16 +833,16 @@ static DecodeStatus DecodeDAHIDATIMMR6(MCInst *MI, uint32_t insn,
|
|||
*/
|
||||
|
||||
static DecodeStatus DecodeDAHIDATI(MCInst *MI, uint32_t insn, uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
uint32_t Rs = fieldFromInstruction_4(insn, 21, 5);
|
||||
uint32_t Imm = fieldFromInstruction_4(insn, 0, 16);
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
const void *Decoder)
|
||||
{
|
||||
uint32_t Rs = fieldFromInstruction_4(insn, 21, 5);
|
||||
uint32_t Imm = fieldFromInstruction_4(insn, 0, 16);
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeAddiGroupBranch(MCInst *MI, uint32_t insn,
|
||||
uint64_t Address, const void *Decoder)
|
||||
|
|
@ -883,8 +873,8 @@ static DecodeStatus DecodeAddiGroupBranch(MCInst *MI, uint32_t insn,
|
|||
MCInst_setOpcode(MI, (Mips_BEQZALC));
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
|
@ -902,26 +892,26 @@ static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst *MI, uint32_t insn,
|
|||
|
||||
if (Rs >= Rt) {
|
||||
MCInst_setOpcode(MI, (Mips_BOVC_MMR6));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
Imm = SignExtend64(fieldFromInstruction_4(insn, 0, 16), 16) *
|
||||
2 +
|
||||
4;
|
||||
} else if (Rs != 0 && Rs < Rt) {
|
||||
MCInst_setOpcode(MI, (Mips_BEQC_MMR6));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
Imm = SignExtend64(fieldFromInstruction_4(insn, 0, 16), 16) *
|
||||
4 +
|
||||
4;
|
||||
} else {
|
||||
MCInst_setOpcode(MI, (Mips_BEQZALC_MMR6));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
Imm = SignExtend64(fieldFromInstruction_4(insn, 0, 16), 16) *
|
||||
2 +
|
||||
4;
|
||||
|
|
@ -962,8 +952,8 @@ static DecodeStatus DecodeDaddiGroupBranch(MCInst *MI, uint32_t insn,
|
|||
MCInst_setOpcode(MI, (Mips_BNEZALC));
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
|
@ -981,26 +971,26 @@ static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst *MI, uint32_t insn,
|
|||
|
||||
if (Rs >= Rt) {
|
||||
MCInst_setOpcode(MI, (Mips_BNVC_MMR6));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
Imm = SignExtend64(fieldFromInstruction_4(insn, 0, 16), 16) *
|
||||
2 +
|
||||
4;
|
||||
} else if (Rs != 0 && Rs < Rt) {
|
||||
MCInst_setOpcode(MI, (Mips_BNEC_MMR6));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
Imm = SignExtend64(fieldFromInstruction_4(insn, 0, 16), 16) *
|
||||
4 +
|
||||
4;
|
||||
} else {
|
||||
MCInst_setOpcode(MI, (Mips_BNEZALC_MMR6));
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
Imm = SignExtend64(fieldFromInstruction_4(insn, 0, 16), 16) *
|
||||
2 +
|
||||
4;
|
||||
|
|
@ -1040,8 +1030,8 @@ static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
|
|
@ -1079,8 +1069,8 @@ static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
|
|
@ -1122,8 +1112,8 @@ static DecodeStatus DecodeBlezlGroupBranch(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
|
|
@ -1166,8 +1156,8 @@ static DecodeStatus DecodeBgtzlGroupBranch(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
|
|
@ -1213,12 +1203,12 @@ static DecodeStatus DecodeBgtzGroupBranch(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
if (HasRt)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
||||
|
|
@ -1257,8 +1247,8 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
|
@ -1290,7 +1280,9 @@ static DecodeStatus DecodeDEXT(MCInst *MI, uint32_t Insn, uint64_t Address,
|
|||
Size = Msbd + 1;
|
||||
break;
|
||||
default:
|
||||
CS_ASSERT_RET_VAL(0 && "Unknown DEXT instruction!", MCDisassembler_Fail);
|
||||
CS_ASSERT_RET_VAL(0 && "Unknown DEXT instruction!",
|
||||
MCDisassembler_Fail);
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
MCInst_setOpcode(MI, (Mips_DEXT));
|
||||
|
|
@ -1332,7 +1324,9 @@ static DecodeStatus DecodeDINS(MCInst *MI, uint32_t Insn, uint64_t Address,
|
|||
Size = Msbd + 33 - Pos;
|
||||
break;
|
||||
default:
|
||||
CS_ASSERT_RET_VAL(0 && "Unknown DINS instruction!", MCDisassembler_Fail);
|
||||
CS_ASSERT_RET_VAL(0 && "Unknown DINS instruction!",
|
||||
MCDisassembler_Fail);
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
uint32_t Rs = fieldFromInstruction_4(Insn, 21, 5);
|
||||
|
|
@ -1404,14 +1398,14 @@ static DecodeStatus readInstruction32(const uint8_t *Bytes, size_t BytesLen,
|
|||
if (IsBigEndian) {
|
||||
// Encoded as a big-endian 32-bit word in the stream.
|
||||
*Insn = (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
|
||||
((unsigned)Bytes[0] << 24);
|
||||
((unsigned)Bytes[0] << 24);
|
||||
} else {
|
||||
if (IsMicroMips) {
|
||||
*Insn = (Bytes[2] << 0) | (Bytes[3] << 8) |
|
||||
(Bytes[0] << 16) | ((unsigned)Bytes[1] << 24);
|
||||
(Bytes[0] << 16) | ((unsigned)Bytes[1] << 24);
|
||||
} else {
|
||||
*Insn = (Bytes[0] << 0) | (Bytes[1] << 8) |
|
||||
(Bytes[2] << 16) | ((unsigned)Bytes[3] << 24);
|
||||
(Bytes[2] << 16) | ((unsigned)Bytes[3] << 24);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1440,12 +1434,13 @@ static DecodeStatus readInstruction48(const uint8_t *Bytes, size_t BytesLen,
|
|||
|
||||
*Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
|
||||
*Insn = ((*Insn << 32) | (Bytes[4] << 0) | (Bytes[5] << 8) |
|
||||
(Bytes[2] << 16) | ((unsigned)Bytes[3] << 24));
|
||||
(Bytes[2] << 16) | ((unsigned)Bytes[3] << 24));
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address, SStream *CStream)
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size,
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CStream)
|
||||
{
|
||||
uint64_t Insn;
|
||||
DecodeStatus Result;
|
||||
|
|
@ -1466,16 +1461,17 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
bool IsPTR64 = Mips_getFeatureBits(mode, Mips_FeaturePTR64Bit);
|
||||
// Only present in MIPS-I and MIPS-II
|
||||
bool HasCOP3 = !Mips_getFeatureBits(mode, Mips_FeatureMips32) &&
|
||||
!Mips_getFeatureBits(mode, Mips_FeatureMips3);
|
||||
!Mips_getFeatureBits(mode, Mips_FeatureMips3);
|
||||
|
||||
if (IsNanoMips) {
|
||||
uint64_t Insn2;
|
||||
Result = readInstruction48(Bytes, BytesLen, Address, Size,
|
||||
&Insn2, IsBigEndian, IsNanoMips);
|
||||
&Insn2, IsBigEndian, IsNanoMips);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
// Calling the auto-generated decoder function.
|
||||
Result = decodeInstruction_8(DecoderTableNanoMips48,
|
||||
Instr, Insn2, Address, NULL);
|
||||
Instr, Insn2, Address,
|
||||
NULL);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
*Size = 6;
|
||||
return Result;
|
||||
|
|
@ -1483,7 +1479,7 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
}
|
||||
|
||||
Result = readInstruction32(Bytes, BytesLen, Address, Size,
|
||||
&Insn, IsBigEndian, IsNanoMips);
|
||||
&Insn, IsBigEndian, IsNanoMips);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
// Calling the auto-generated decoder function.
|
||||
Result = decodeInstruction_4(DecoderTableNanoMips32,
|
||||
|
|
@ -1496,7 +1492,7 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
}
|
||||
|
||||
Result = readInstruction16(Bytes, BytesLen, Address, Size,
|
||||
&Insn, IsBigEndian);
|
||||
&Insn, IsBigEndian);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
// Calling the auto-generated decoder function for NanoMips
|
||||
// 16-bit instructions.
|
||||
|
|
@ -1508,9 +1504,9 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
return Result;
|
||||
}
|
||||
|
||||
Result = decodeInstruction_2(DecoderTableNanoMips_Conflict_Space16,
|
||||
Instr, Insn, Address,
|
||||
NULL);
|
||||
Result = decodeInstruction_2(
|
||||
DecoderTableNanoMips_Conflict_Space16, Instr,
|
||||
Insn, Address, NULL);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
*Size = 2;
|
||||
return Result;
|
||||
|
|
@ -1558,9 +1554,9 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
|
||||
if (IsMips32r6) {
|
||||
// Calling the auto-generated decoder function.
|
||||
Result = decodeInstruction_4(DecoderTableMicroMipsR6_Ambiguous32,
|
||||
Instr, Insn, Address,
|
||||
NULL);
|
||||
Result = decodeInstruction_4(
|
||||
DecoderTableMicroMipsR6_Ambiguous32, Instr,
|
||||
Insn, Address, NULL);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
*Size = 4;
|
||||
return Result;
|
||||
|
|
@ -1613,8 +1609,8 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
Result = readInstruction32(Bytes, BytesLen, Address, Size,
|
||||
&Insn, IsBigEndian, IsMicroMips);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
Result = decodeInstruction_4(DecoderTable32, Instr, Insn, Address,
|
||||
NULL);
|
||||
Result = decodeInstruction_4(DecoderTable32, Instr,
|
||||
Insn, Address, NULL);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
*Size = 4;
|
||||
return Result;
|
||||
|
|
@ -1628,14 +1624,15 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
}
|
||||
|
||||
*Size = 2;
|
||||
return decodeInstruction_2(DecoderTable16, Instr, Insn, Address, NULL);
|
||||
return decodeInstruction_2(DecoderTable16, Instr, Insn, Address,
|
||||
NULL);
|
||||
}
|
||||
|
||||
// Attempt to read the instruction so that we can attempt to decode it. If
|
||||
// the buffer is not 4 bytes long, let the higher level logic figure out
|
||||
// what to do with a size of zero and MCDisassembler::Fail.
|
||||
Result = readInstruction32(Bytes, BytesLen, Address, Size, &Insn, IsBigEndian,
|
||||
IsMicroMips);
|
||||
Result = readInstruction32(Bytes, BytesLen, Address, Size, &Insn,
|
||||
IsBigEndian, IsMicroMips);
|
||||
if (Result == MCDisassembler_Fail)
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
|
|
@ -1664,8 +1661,9 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
}
|
||||
|
||||
if (IsMips32r6 || IsMips64r6) {
|
||||
Result = decodeInstruction_4(DecoderTableMips32r6_64r6_BranchZero32, Instr,
|
||||
Insn, Address, NULL);
|
||||
Result = decodeInstruction_4(
|
||||
DecoderTableMips32r6_64r6_BranchZero32, Instr, Insn,
|
||||
Address, NULL);
|
||||
if (Result != MCDisassembler_Fail)
|
||||
return Result;
|
||||
|
||||
|
|
@ -1674,8 +1672,9 @@ static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t
|
|||
if (Result != MCDisassembler_Fail)
|
||||
return Result;
|
||||
|
||||
Result = decodeInstruction_4(DecoderTableMips32r6_64r6_Ambiguous32, Instr,
|
||||
Insn, Address, NULL);
|
||||
Result = decodeInstruction_4(
|
||||
DecoderTableMips32r6_64r6_Ambiguous32, Instr, Insn,
|
||||
Address, NULL);
|
||||
if (Result != MCDisassembler_Fail)
|
||||
return Result;
|
||||
}
|
||||
|
|
@ -2008,7 +2007,7 @@ static DecodeStatus DecodeMem(MCInst *Inst, uint32_t Insn, uint64_t Address,
|
|||
|
||||
#define DEFINE_DecodeMemNM(Offbits, isSigned, rt) \
|
||||
static DecodeStatus CONCAT(DecodeMemNM, \
|
||||
CONCAT(Offbits, CONCAT(isSigned, rt)))( \
|
||||
CONCAT(Offbits, CONCAT(isSigned, rt)))( \
|
||||
MCInst * Inst, uint32_t Insn, uint64_t Address, \
|
||||
const void *Decoder) \
|
||||
{ \
|
||||
|
|
@ -2142,7 +2141,9 @@ static DecodeStatus DecodeCOP0SelRegisterClass(MCInst *Inst, unsigned RegNo,
|
|||
MCInst_setOpcode(Inst, (Mips_MTHC0_NM));
|
||||
break;
|
||||
default:
|
||||
CS_ASSERT_RET_VAL(0 && "Unknown instruction!", MCDisassembler_Fail);
|
||||
CS_ASSERT_RET_VAL(0 && "Unknown instruction!",
|
||||
MCDisassembler_Fail);
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
Reg = getReg(Inst, Mips_COP0RegClassID, RegNo >> 5);
|
||||
MCOperand_CreateReg0(Inst, (Reg));
|
||||
|
|
@ -2959,8 +2960,10 @@ DEFINE_DecodeUImmWithOffsetAndScale(21, 0, 1);
|
|||
return MCDisassembler_Success; \
|
||||
}
|
||||
|
||||
#define DEFINE_DecodeSImmWithOffsetAndScale_2(Bits, Offset) DEFINE_DecodeSImmWithOffsetAndScale(Bits, Offset, 1)
|
||||
#define DEFINE_DecodeSImmWithOffsetAndScale_3(Bits) DEFINE_DecodeSImmWithOffsetAndScale(Bits, 0, 1)
|
||||
#define DEFINE_DecodeSImmWithOffsetAndScale_2(Bits, Offset) \
|
||||
DEFINE_DecodeSImmWithOffsetAndScale(Bits, Offset, 1)
|
||||
#define DEFINE_DecodeSImmWithOffsetAndScale_3(Bits) \
|
||||
DEFINE_DecodeSImmWithOffsetAndScale(Bits, 0, 1)
|
||||
|
||||
DEFINE_DecodeSImmWithOffsetAndScale_3(16);
|
||||
DEFINE_DecodeSImmWithOffsetAndScale_3(10);
|
||||
|
|
@ -3200,12 +3203,12 @@ static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
|
||||
if (HasRt)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
||||
|
|
@ -3249,8 +3252,8 @@ static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst *MI, uint32_t insn,
|
|||
}
|
||||
|
||||
if (HasRs)
|
||||
MCOperand_CreateReg0(
|
||||
MI, (getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI,
|
||||
(getReg(MI, Mips_GPR32RegClassID, Rs)));
|
||||
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR32RegClassID, Rt)));
|
||||
|
||||
MCOperand_CreateImm0(MI, (Imm));
|
||||
|
|
@ -3310,8 +3313,8 @@ static DecodeStatus DecodeNMRegListOperand(MCInst *Inst, uint32_t Insn,
|
|||
unsigned i;
|
||||
unsigned RegNo;
|
||||
|
||||
MCOperand_CreateReg0(
|
||||
Inst, (getReg(Inst, Mips_GPRNM32RegClassID, RegStart)));
|
||||
MCOperand_CreateReg0(Inst,
|
||||
(getReg(Inst, Mips_GPRNM32RegClassID, RegStart)));
|
||||
for (i = RegStart + 1; i < RegStart + RegCount; i++) {
|
||||
if (i == RegStart + RegCount - 1 && GP_bit)
|
||||
RegNo = 28;
|
||||
|
|
@ -3420,8 +3423,9 @@ static DecodeStatus DecodeBranchConflictNM(MCInst *Inst, uint32_t Insn,
|
|||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
DecodeStatus Mips_LLVM_getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address, SStream *CStream)
|
||||
DecodeStatus Mips_LLVM_getInstruction(MCInst *Instr, uint64_t *Size,
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CStream)
|
||||
{
|
||||
return getInstruction(Instr, Size, Bytes, BytesLen, Address, CStream);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,10 +118,12 @@ static void printRegName(MCInst *MI, SStream *OS, MCRegister Reg)
|
|||
if (!(syntax_opt & CS_OPT_SYNTAX_NO_DOLLAR)) {
|
||||
SStream_concat1(OS, '$');
|
||||
}
|
||||
SStream_concat0(OS, Mips_LLVM_getRegisterName(Reg, syntax_opt & CS_OPT_SYNTAX_NOREGNAME));
|
||||
SStream_concat0(OS, Mips_LLVM_getRegisterName(
|
||||
Reg, syntax_opt & CS_OPT_SYNTAX_NOREGNAME));
|
||||
}
|
||||
|
||||
static void patch_cs_printer(MCInst *MI, SStream *O) {
|
||||
static void patch_cs_printer(MCInst *MI, SStream *O)
|
||||
{
|
||||
// replace '# 16 bit inst' to empty.
|
||||
SStream_replc(O, '#', 0);
|
||||
SStream_trimls(O);
|
||||
|
|
@ -137,14 +139,17 @@ static void patch_cs_printer(MCInst *MI, SStream *O) {
|
|||
}
|
||||
}
|
||||
|
||||
static void patch_cs_detail_operand_reg(cs_mips_op *op, unsigned reg, unsigned access) {
|
||||
static void patch_cs_detail_operand_reg(cs_mips_op *op, unsigned reg,
|
||||
unsigned access)
|
||||
{
|
||||
op->type = MIPS_OP_REG;
|
||||
op->reg = reg;
|
||||
op->is_reglist = false;
|
||||
op->access = access;
|
||||
}
|
||||
|
||||
static void patch_cs_details(MCInst *MI) {
|
||||
static void patch_cs_details(MCInst *MI)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
||||
|
|
@ -152,7 +157,7 @@ static void patch_cs_details(MCInst *MI) {
|
|||
unsigned opcode = MCInst_getOpcode(MI);
|
||||
unsigned n_ops = MCInst_getNumOperands(MI);
|
||||
|
||||
switch(opcode) {
|
||||
switch (opcode) {
|
||||
/* mips r2 to r5 only 64bit */
|
||||
case Mips_DSDIV: /// ddiv $$zero, $rs, $rt
|
||||
/* fall-thru */
|
||||
|
|
@ -225,7 +230,8 @@ static void patch_cs_details(MCInst *MI) {
|
|||
}
|
||||
}
|
||||
|
||||
void Mips_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O) {
|
||||
void Mips_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O)
|
||||
{
|
||||
bool useAliasDetails = map_use_alias_details(MI);
|
||||
if (!useAliasDetails) {
|
||||
SStream_Close(O);
|
||||
|
|
@ -234,8 +240,7 @@ void Mips_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O) {
|
|||
map_set_fill_detail_ops(MI, false);
|
||||
}
|
||||
|
||||
if (printAliasInstr(MI, Address, O) ||
|
||||
printAlias4(MI, Address, O)) {
|
||||
if (printAliasInstr(MI, Address, O) || printAlias4(MI, Address, O)) {
|
||||
MCInst_setIsAlias(MI, true);
|
||||
} else {
|
||||
printInstruction(MI, Address, O);
|
||||
|
|
@ -274,7 +279,6 @@ void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
if (MCOperand_isImm(Op)) {
|
||||
switch (MCInst_getOpcode(MI)) {
|
||||
case Mips_LI48_NM:
|
||||
|
|
@ -317,22 +321,24 @@ static void printJumpOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
|||
printInt64(O, Base | Target);
|
||||
}
|
||||
|
||||
static void printBranchOperand(MCInst *MI, uint64_t Address, unsigned OpNo, SStream *O)
|
||||
static void printBranchOperand(MCInst *MI, uint64_t Address, unsigned OpNo,
|
||||
SStream *O)
|
||||
{
|
||||
add_cs_detail(MI, Mips_OP_GROUP_BranchOperand, OpNo);
|
||||
MCOperand *Op = MCInst_getOperand(MI, (OpNo));
|
||||
if (MCOperand_isReg(Op))
|
||||
return printRegName(MI, O, MCOperand_getReg(Op));
|
||||
|
||||
uint64_t Target = Address + MCOperand_getImm(Op);
|
||||
uint64_t Target = Address + MCOperand_getImm(Op);
|
||||
printInt64(O, Target);
|
||||
}
|
||||
|
||||
#define DEFINE_printUImm(Bits) \
|
||||
static void CONCAT(printUImm, CONCAT(Bits, 0))(MCInst * MI, int opNum, \
|
||||
SStream *O) \
|
||||
SStream *O) \
|
||||
{ \
|
||||
add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), opNum); \
|
||||
add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \
|
||||
opNum); \
|
||||
MCOperand *MO = MCInst_getOperand(MI, (opNum)); \
|
||||
if (MCOperand_isImm(MO)) { \
|
||||
uint64_t Imm = MCOperand_getImm(MO); \
|
||||
|
|
@ -345,11 +351,12 @@ static void printBranchOperand(MCInst *MI, uint64_t Address, unsigned OpNo, SStr
|
|||
}
|
||||
|
||||
#define DEFINE_printUImm_2(Bits, Offset) \
|
||||
static void CONCAT(printUImm, CONCAT(Bits, Offset))(MCInst * MI, int opNum, \
|
||||
SStream *O) \
|
||||
static void CONCAT(printUImm, CONCAT(Bits, Offset))( \
|
||||
MCInst * MI, int opNum, SStream *O) \
|
||||
{ \
|
||||
add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, Offset)), \
|
||||
opNum); \
|
||||
add_cs_detail( \
|
||||
MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, Offset)), \
|
||||
opNum); \
|
||||
MCOperand *MO = MCInst_getOperand(MI, (opNum)); \
|
||||
if (MCOperand_isImm(MO)) { \
|
||||
uint64_t Imm = MCOperand_getImm(MO); \
|
||||
|
|
@ -429,9 +436,11 @@ static void printMemOperand(MCInst *MI, int opNum, SStream *O)
|
|||
case Mips_SHX_NM:
|
||||
case Mips_SHXS_NM:
|
||||
if (!MCOperand_isReg(MCInst_getOperand(MI, (opNum + 1)))) {
|
||||
add_cs_detail(MI, Mips_OP_GROUP_MemOperand, (opNum + 1));
|
||||
printRegName(MI, O, MCOperand_getImm(MCInst_getOperand(
|
||||
MI, (opNum + 1))));
|
||||
add_cs_detail(MI, Mips_OP_GROUP_MemOperand,
|
||||
(opNum + 1));
|
||||
printRegName(MI, O,
|
||||
MCOperand_getImm(MCInst_getOperand(
|
||||
MI, (opNum + 1))));
|
||||
break;
|
||||
}
|
||||
// Fall through
|
||||
|
|
@ -462,7 +471,7 @@ static void printFCCOperand(MCInst *MI, int opNum, SStream *O)
|
|||
}
|
||||
|
||||
static bool printAlias(const char *Str, const MCInst *MI, uint64_t Address,
|
||||
unsigned OpNo, SStream *OS, bool IsBranch)
|
||||
unsigned OpNo, SStream *OS, bool IsBranch)
|
||||
{
|
||||
SStream_concat(OS, "%s%s", "\t", Str);
|
||||
SStream_concat0(OS, "\t");
|
||||
|
|
@ -474,7 +483,8 @@ static bool printAlias(const char *Str, const MCInst *MI, uint64_t Address,
|
|||
}
|
||||
|
||||
static bool printAlias2(const char *Str, const MCInst *MI, uint64_t Address,
|
||||
unsigned OpNo0, unsigned OpNo1, SStream *OS, bool IsBranch)
|
||||
unsigned OpNo0, unsigned OpNo1, SStream *OS,
|
||||
bool IsBranch)
|
||||
{
|
||||
printAlias(Str, MI, Address, OpNo0, OS, IsBranch);
|
||||
SStream_concat0(OS, ", ");
|
||||
|
|
@ -486,7 +496,8 @@ static bool printAlias2(const char *Str, const MCInst *MI, uint64_t Address,
|
|||
}
|
||||
|
||||
static bool printAlias3(const char *Str, const MCInst *MI, uint64_t Address,
|
||||
unsigned OpNo0, unsigned OpNo1, unsigned OpNo2, SStream *OS)
|
||||
unsigned OpNo0, unsigned OpNo1, unsigned OpNo2,
|
||||
SStream *OS)
|
||||
{
|
||||
printAlias(Str, MI, Address, OpNo0, OS, false);
|
||||
SStream_concat0(OS, ", ");
|
||||
|
|
@ -503,8 +514,7 @@ static bool printAlias4(const MCInst *MI, uint64_t Address, SStream *OS)
|
|||
case Mips_BEQ_MM:
|
||||
// beq $zero, $zero, $L2 => b $L2
|
||||
// beq $r0, $zero, $L2 => beqz $r0, $L2
|
||||
return (isReg(MI, 0, Mips_ZERO) &&
|
||||
isReg(MI, 1, Mips_ZERO) &&
|
||||
return (isReg(MI, 0, Mips_ZERO) && isReg(MI, 1, Mips_ZERO) &&
|
||||
printAlias("b", MI, Address, 2, OS, true)) ||
|
||||
(isReg(MI, 1, Mips_ZERO) &&
|
||||
printAlias2("beqz", MI, Address, 0, 2, OS, true));
|
||||
|
|
@ -597,7 +607,8 @@ static void printRegisterList(MCInst *MI, int opNum, SStream *O)
|
|||
for (int i = opNum, e = MCInst_getNumOperands(MI) - 2; i != e; ++i) {
|
||||
if (i != opNum)
|
||||
SStream_concat0(O, ", ");
|
||||
printRegName(MI, O, MCOperand_getReg(MCInst_getOperand(MI, (i))));
|
||||
printRegName(MI, O,
|
||||
MCOperand_getReg(MCInst_getOperand(MI, (i))));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -606,7 +617,8 @@ static void printNanoMipsRegisterList(MCInst *MI, int OpNum, SStream *O)
|
|||
add_cs_detail(MI, Mips_OP_GROUP_NanoMipsRegisterList, OpNum);
|
||||
for (unsigned I = OpNum; I < MCInst_getNumOperands(MI); I++) {
|
||||
SStream_concat0(O, ", ");
|
||||
printRegName(MI, O, MCOperand_getReg(MCInst_getOperand(MI, (I))));
|
||||
printRegName(MI, O,
|
||||
MCOperand_getReg(MCInst_getOperand(MI, (I))));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -640,8 +652,7 @@ static void printPCRel(MCInst *MI, uint64_t Address, int OpNum, SStream *O)
|
|||
if (MCOperand_isImm(MO)) {
|
||||
add_cs_detail(MI, Mips_OP_GROUP_PCRel, OpNum);
|
||||
printUInt64(O, MCOperand_getImm(MO) + Address);
|
||||
}
|
||||
else
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +664,7 @@ const char *Mips_LLVM_getRegisterName(unsigned RegNo, bool noRegName)
|
|||
if (noRegName) {
|
||||
return getRegisterName(RegNo);
|
||||
}
|
||||
switch(RegNo) {
|
||||
switch (RegNo) {
|
||||
case MIPS_REG_AT:
|
||||
case MIPS_REG_AT_64:
|
||||
return "at";
|
||||
|
|
|
|||
|
|
@ -103,19 +103,20 @@ static const char *MipsFCCToString(Mips_CondCode CC);
|
|||
static const char *getRegisterName(unsigned RegNo);
|
||||
static void printInstruction(MCInst *MI, uint64_t Address, SStream *O);
|
||||
static bool printAliasInstr(MCInst *MI, uint64_t Address, SStream *OS);
|
||||
static void printCustomAliasOperand(MCInst *MI, uint64_t Address, unsigned OpIdx,
|
||||
unsigned PrintMethodIdx, SStream *O);
|
||||
static void printCustomAliasOperand(MCInst *MI, uint64_t Address,
|
||||
unsigned OpIdx, unsigned PrintMethodIdx,
|
||||
SStream *O);
|
||||
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
|
||||
static void printJumpOperand(MCInst *MI, unsigned OpNo, SStream *O);
|
||||
static void printBranchOperand(MCInst *MI, uint64_t Address, unsigned OpNo,
|
||||
SStream *O);
|
||||
SStream *O);
|
||||
|
||||
#define DECLARE_printUImm_2(Bits, Offset) \
|
||||
static void CONCAT(printUImm, CONCAT(Bits, Offset))( \
|
||||
MCInst *MI, int opNum, SStream *O)
|
||||
MCInst * MI, int opNum, SStream *O)
|
||||
#define DECLARE_printUImm(Bits) \
|
||||
static void CONCAT(printUImm, CONCAT(Bits, 0))( \
|
||||
MCInst *MI, int opNum, SStream *O)
|
||||
static void CONCAT(printUImm, CONCAT(Bits, 0))(MCInst * MI, int opNum, \
|
||||
SStream *O)
|
||||
DECLARE_printUImm(0);
|
||||
DECLARE_printUImm(1);
|
||||
DECLARE_printUImm(10);
|
||||
|
|
@ -142,12 +143,13 @@ static void printMemOperand(MCInst *MI, int opNum, SStream *O);
|
|||
static void printMemOperandEA(MCInst *MI, int opNum, SStream *O);
|
||||
static void printFCCOperand(MCInst *MI, int opNum, SStream *O);
|
||||
static bool printAlias(const char *Str, const MCInst *MI, uint64_t Address,
|
||||
unsigned OpNo, SStream *OS, bool IsBranch);
|
||||
unsigned OpNo, SStream *OS, bool IsBranch);
|
||||
static bool printAlias2(const char *Str, const MCInst *MI, uint64_t Address,
|
||||
unsigned OpNo0, unsigned OpNo1, SStream *OS,
|
||||
bool IsBranch);
|
||||
unsigned OpNo0, unsigned OpNo1, SStream *OS,
|
||||
bool IsBranch);
|
||||
static bool printAlias3(const char *Str, const MCInst *MI, uint64_t Address,
|
||||
unsigned OpNo0, unsigned OpNo1, unsigned OpNo2, SStream *OS);
|
||||
unsigned OpNo0, unsigned OpNo1, unsigned OpNo2,
|
||||
SStream *OS);
|
||||
static bool printAlias4(const MCInst *MI, uint64_t Address, SStream *OS);
|
||||
static void printRegisterList(MCInst *MI, int opNum, SStream *O);
|
||||
static void printNanoMipsRegisterList(MCInst *MI, int opNum, SStream *O);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
const char *Mips_LLVM_getRegisterName(unsigned RegNo, bool noRegName);
|
||||
void Mips_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O);
|
||||
DecodeStatus Mips_LLVM_getInstruction(MCInst *Instr, uint64_t *Size,
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CStream);
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CStream);
|
||||
|
||||
#endif // CS_MIPS_LINKAGE_H
|
||||
|
|
|
|||
|
|
@ -197,9 +197,8 @@ bool Mips_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
|||
instr->MRI = (MCRegisterInfo *)info;
|
||||
map_set_fill_detail_ops(instr, true);
|
||||
|
||||
DecodeStatus Result = Mips_LLVM_getInstruction(instr, &size64, code, code_len,
|
||||
address,
|
||||
info);
|
||||
DecodeStatus Result = Mips_LLVM_getInstruction(instr, &size64, code,
|
||||
code_len, address, info);
|
||||
*size = size64;
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
Mips_set_instr_map_data(instr);
|
||||
|
|
@ -303,7 +302,8 @@ static void Mips_set_detail_op_reg(MCInst *MI, unsigned OpNum, mips_reg Reg,
|
|||
return;
|
||||
}
|
||||
|
||||
CS_ASSERT(is_reglist || (map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_REG);
|
||||
CS_ASSERT(is_reglist ||
|
||||
(map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_REG);
|
||||
Mips_get_detail_op(MI, 0)->type = MIPS_OP_REG;
|
||||
Mips_get_detail_op(MI, 0)->reg = Reg;
|
||||
Mips_get_detail_op(MI, 0)->is_reglist = is_reglist;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ void Mips_init_mri(MCRegisterInfo *MRI);
|
|||
// return name of register in friendly string
|
||||
const char *Mips_reg_name(csh handle, unsigned int reg);
|
||||
|
||||
void Mips_printer(MCInst *MI, SStream *O,
|
||||
void * /* MCRegisterInfo* */ info);
|
||||
void Mips_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info);
|
||||
|
||||
// given internal insn id, return public instruction ID
|
||||
void Mips_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
||||
|
|
@ -28,12 +27,12 @@ const char *Mips_insn_name(csh handle, unsigned int id);
|
|||
const char *Mips_group_name(csh handle, unsigned int id);
|
||||
|
||||
bool Mips_getInstruction(csh handle, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
|
||||
void Mips_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
|
||||
// cs_detail related functions
|
||||
void Mips_init_cs_detail(MCInst *MI);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
|
|||
}
|
||||
|
||||
static DecodeStatus DecodeFpRCRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
if (RegNo > 30 || (RegNo & 1))
|
||||
return MCDisassembler_Fail;
|
||||
|
|
@ -410,8 +411,8 @@ DecodeStatus getInstruction(csh ud, const uint8_t *Bytes, size_t BytesLen,
|
|||
uint32_t Prefix = readBytes32(MI, Bytes);
|
||||
uint32_t BaseInst = readBytes32(MI, Bytes + 4);
|
||||
uint64_t Inst = BaseInst | (uint64_t)Prefix << 32;
|
||||
DecodeStatus result =
|
||||
decodeInstruction_4(DecoderTable64, MI, Inst, Address, NULL);
|
||||
DecodeStatus result = decodeInstruction_4(DecoderTable64, MI,
|
||||
Inst, Address, NULL);
|
||||
if (result != MCDisassembler_Fail) {
|
||||
*Size = 8;
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -119,7 +119,10 @@ static inline void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
|||
unsigned Reg = MCOperand_getReg(Op);
|
||||
if (!MI->csh->ShowVSRNumsAsVR)
|
||||
Reg = PPCInstrInfo_getRegNumForOperand(
|
||||
MCInstrDesc_get(MCInst_getOpcode(MI), PPCDescs.Insts, ARR_SIZE(PPCDescs.Insts)), Reg, OpNo);
|
||||
MCInstrDesc_get(MCInst_getOpcode(MI),
|
||||
PPCDescs.Insts,
|
||||
ARR_SIZE(PPCDescs.Insts)),
|
||||
Reg, OpNo);
|
||||
|
||||
const char *RegName;
|
||||
RegName = getVerboseConditionRegName(
|
||||
|
|
@ -445,7 +448,9 @@ static inline void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
|||
return;
|
||||
}
|
||||
|
||||
printUInt64(O, ((unsigned)MCOperand_getImm(MCInst_getOperand(MI, (OpNo))) << 2));
|
||||
printUInt64(O,
|
||||
((unsigned)MCOperand_getImm(MCInst_getOperand(MI, (OpNo)))
|
||||
<< 2));
|
||||
}
|
||||
|
||||
static inline void printcrbitm(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
|
|
|
|||
|
|
@ -122,49 +122,69 @@ static inline bool isRunOfOnes64(uint64_t Val, unsigned *MB, unsigned *ME)
|
|||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "PPCGenSubtargetInfo.inc"
|
||||
|
||||
#define PPC_REGS0_7(X) { X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 }
|
||||
#define PPC_REGS0_7(X) \
|
||||
{ \
|
||||
X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 \
|
||||
}
|
||||
|
||||
#define PPC_REGS0_31(X) \
|
||||
{ X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, \
|
||||
X##8, X##9, X##10, X##11, X##12, X##13, X##14, X##15, \
|
||||
X##16, X##17, X##18, X##19, X##20, X##21, X##22, X##23, \
|
||||
X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 }
|
||||
{ \
|
||||
X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, \
|
||||
X##10, X##11, X##12, X##13, X##14, X##15, X##16, \
|
||||
X##17, X##18, X##19, X##20, X##21, X##22, X##23, \
|
||||
X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 \
|
||||
}
|
||||
|
||||
#define PPC_REGS_EVEN0_30(X) \
|
||||
{ X##0, X##2, X##4, X##6, X##8, X##10, X##12, X##14, \
|
||||
X##16, X##18, X##20, X##22, X##24, X##26, X##28, X##30 }
|
||||
{ \
|
||||
X##0, X##2, X##4, X##6, X##8, X##10, X##12, X##14, X##16, \
|
||||
X##18, X##20, X##22, X##24, X##26, X##28, X##30 \
|
||||
}
|
||||
|
||||
#define PPC_REGS0_63(X) \
|
||||
{ \
|
||||
X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, \
|
||||
X##8, X##9, X##10, X##11, X##12, X##13, X##14, X##15, \
|
||||
X##16, X##17, X##18, X##19, X##20, X##21, X##22, X##23, \
|
||||
X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31, \
|
||||
X##32, X##33, X##34, X##35, X##36, X##37, X##38, X##39, \
|
||||
X##40, X##41, X##42, X##43, X##44, X##45, X##46, X##47, \
|
||||
X##48, X##49, X##50, X##51, X##52, X##53, X##54, X##55, \
|
||||
X##56, X##57, X##58, X##59, X##60, X##61, X##62, X##63 \
|
||||
X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, \
|
||||
X##10, X##11, X##12, X##13, X##14, X##15, X##16, \
|
||||
X##17, X##18, X##19, X##20, X##21, X##22, X##23, \
|
||||
X##24, X##25, X##26, X##27, X##28, X##29, X##30, \
|
||||
X##31, X##32, X##33, X##34, X##35, X##36, X##37, \
|
||||
X##38, X##39, X##40, X##41, X##42, X##43, X##44, \
|
||||
X##45, X##46, X##47, X##48, X##49, X##50, X##51, \
|
||||
X##52, X##53, X##54, X##55, X##56, X##57, X##58, \
|
||||
X##59, X##60, X##61, X##62, X##63 \
|
||||
}
|
||||
|
||||
#define PPC_REGS_NO0_31(Z, X) \
|
||||
{ Z, X##1, X##2, X##3, X##4, X##5, X##6, X##7, \
|
||||
X##8, X##9, X##10, X##11, X##12, X##13, X##14, X##15, \
|
||||
X##16, X##17, X##18, X##19, X##20, X##21, X##22, X##23, \
|
||||
X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 }
|
||||
{ \
|
||||
Z, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, \
|
||||
X##10, X##11, X##12, X##13, X##14, X##15, X##16, \
|
||||
X##17, X##18, X##19, X##20, X##21, X##22, X##23, \
|
||||
X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 \
|
||||
}
|
||||
|
||||
#define PPC_REGS_LO_HI(LO, HI) \
|
||||
{ LO##0, LO##1, LO##2, LO##3, LO##4, LO##5, LO##6, LO##7, \
|
||||
LO##8, LO##9, LO##10, LO##11, LO##12, LO##13, LO##14, LO##15, \
|
||||
LO##16, LO##17, LO##18, LO##19, LO##20, LO##21, LO##22, LO##23, \
|
||||
LO##24, LO##25, LO##26, LO##27, LO##28, LO##29, LO##30, LO##31, \
|
||||
HI##0, HI##1, HI##2, HI##3, HI##4, HI##5, HI##6, HI##7, \
|
||||
HI##8, HI##9, HI##10, HI##11, HI##12, HI##13, HI##14, HI##15, \
|
||||
HI##16, HI##17, HI##18, HI##19, HI##20, HI##21, HI##22, HI##23, \
|
||||
HI##24, HI##25, HI##26, HI##27, HI##28, HI##29, HI##30, HI##31 }
|
||||
{ \
|
||||
LO##0, LO##1, LO##2, LO##3, LO##4, LO##5, LO##6, LO##7, LO##8, \
|
||||
LO##9, LO##10, LO##11, LO##12, LO##13, LO##14, LO##15, \
|
||||
LO##16, LO##17, LO##18, LO##19, LO##20, LO##21, \
|
||||
LO##22, LO##23, LO##24, LO##25, LO##26, LO##27, \
|
||||
LO##28, LO##29, LO##30, LO##31, HI##0, HI##1, HI##2, \
|
||||
HI##3, HI##4, HI##5, HI##6, HI##7, HI##8, HI##9, \
|
||||
HI##10, HI##11, HI##12, HI##13, HI##14, HI##15, \
|
||||
HI##16, HI##17, HI##18, HI##19, HI##20, HI##21, \
|
||||
HI##22, HI##23, HI##24, HI##25, HI##26, HI##27, \
|
||||
HI##28, HI##29, HI##30, HI##31 \
|
||||
}
|
||||
|
||||
#define PPC_REGS0_7(X) { X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 }
|
||||
#define PPC_REGS0_7(X) \
|
||||
{ \
|
||||
X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 \
|
||||
}
|
||||
|
||||
#define PPC_REGS0_3(X) { X##0, X##1, X##2, X##3 }
|
||||
#define PPC_REGS0_3(X) \
|
||||
{ \
|
||||
X##0, X##1, X##2, X##3 \
|
||||
}
|
||||
|
||||
#define DEFINE_PPC_REGCLASSES \
|
||||
static const MCPhysReg RRegs[32] = PPC_REGS0_31(PPC_R); \
|
||||
|
|
|
|||
|
|
@ -350,23 +350,28 @@ bool PPC_getFeatureBits(unsigned int mode, unsigned int feature)
|
|||
} else if (feature == PPC_FeatureModernAIXAs) {
|
||||
return (mode & CS_MODE_MODERN_AIX_AS) != 0;
|
||||
} else if (feature == PPC_AIXOS) {
|
||||
return (mode & CS_MODE_AIX_OS) != 0 || (mode & CS_MODE_MODERN_AIX_AS) != 0;
|
||||
return (mode & CS_MODE_AIX_OS) != 0 ||
|
||||
(mode & CS_MODE_MODERN_AIX_AS) != 0;
|
||||
} else if (feature == PPC_FeatureMSYNC) {
|
||||
return (mode & CS_MODE_MSYNC) != 0;
|
||||
}
|
||||
if ((mode & (CS_MODE_PWR7 | CS_MODE_PWR8 | CS_MODE_PWR9 | CS_MODE_PWR10 | CS_MODE_PPC_ISA_FUTURE)) == 0) {
|
||||
if ((mode & (CS_MODE_PWR7 | CS_MODE_PWR8 | CS_MODE_PWR9 |
|
||||
CS_MODE_PWR10 | CS_MODE_PPC_ISA_FUTURE)) == 0) {
|
||||
// By default support everything
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_feature_of(feature, P7Features, ARR_SIZE(P7Features))) {
|
||||
return (mode & (CS_MODE_PWR7 | CS_MODE_PWR8 | CS_MODE_PWR9 | CS_MODE_PWR10 | CS_MODE_PPC_ISA_FUTURE));
|
||||
return (mode & (CS_MODE_PWR7 | CS_MODE_PWR8 | CS_MODE_PWR9 |
|
||||
CS_MODE_PWR10 | CS_MODE_PPC_ISA_FUTURE));
|
||||
}
|
||||
if (is_feature_of(feature, P8Features, ARR_SIZE(P8Features))) {
|
||||
return (mode & (CS_MODE_PWR8 | CS_MODE_PWR9 | CS_MODE_PWR10 | CS_MODE_PPC_ISA_FUTURE));
|
||||
return (mode & (CS_MODE_PWR8 | CS_MODE_PWR9 | CS_MODE_PWR10 |
|
||||
CS_MODE_PPC_ISA_FUTURE));
|
||||
}
|
||||
if (is_feature_of(feature, P9Features, ARR_SIZE(P9Features))) {
|
||||
return (mode & (CS_MODE_PWR9 | CS_MODE_PWR10 | CS_MODE_PPC_ISA_FUTURE));
|
||||
return (mode & (CS_MODE_PWR9 | CS_MODE_PWR10 |
|
||||
CS_MODE_PPC_ISA_FUTURE));
|
||||
}
|
||||
if (is_feature_of(feature, P10Features, ARR_SIZE(P10Features))) {
|
||||
return (mode & (CS_MODE_PWR10 | CS_MODE_PPC_ISA_FUTURE));
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ ppc_reg PPC_map_register(unsigned int r);
|
|||
bool PPC_getFeatureBits(unsigned int mode, unsigned int feature);
|
||||
|
||||
void PPC_add_cs_detail_0(MCInst *MI, ppc_op_group op_group, unsigned OpNo);
|
||||
void PPC_add_cs_detail_1(MCInst *MI, ppc_op_group op_group, unsigned OpNo, const char *Modifier);
|
||||
void PPC_add_cs_detail_1(MCInst *MI, ppc_op_group op_group, unsigned OpNo,
|
||||
const char *Modifier);
|
||||
|
||||
void PPC_set_detail_op_reg(MCInst *MI, unsigned OpNum, ppc_reg Reg);
|
||||
void PPC_set_detail_op_imm(MCInst *MI, unsigned OpNum, int64_t Imm);
|
||||
|
|
|
|||
|
|
@ -21,25 +21,25 @@
|
|||
// instruction info tracks. All definitions must match RISCVInstrFormats.td.
|
||||
enum {
|
||||
IRISCVII_InstFormatPseudo = 0,
|
||||
IRISCVII_InstFormatR = 1,
|
||||
IRISCVII_InstFormatR4 = 2,
|
||||
IRISCVII_InstFormatI = 3,
|
||||
IRISCVII_InstFormatS = 4,
|
||||
IRISCVII_InstFormatB = 5,
|
||||
IRISCVII_InstFormatU = 6,
|
||||
IRISCVII_InstFormatJ = 7,
|
||||
IRISCVII_InstFormatCR = 8,
|
||||
IRISCVII_InstFormatCI = 9,
|
||||
IRISCVII_InstFormatCSS = 10,
|
||||
IRISCVII_InstFormatCIW = 11,
|
||||
IRISCVII_InstFormatCL = 12,
|
||||
IRISCVII_InstFormatCS = 13,
|
||||
IRISCVII_InstFormatCA = 14,
|
||||
IRISCVII_InstFormatCB = 15,
|
||||
IRISCVII_InstFormatCJ = 16,
|
||||
IRISCVII_InstFormatOther = 17,
|
||||
IRISCVII_InstFormatR = 1,
|
||||
IRISCVII_InstFormatR4 = 2,
|
||||
IRISCVII_InstFormatI = 3,
|
||||
IRISCVII_InstFormatS = 4,
|
||||
IRISCVII_InstFormatB = 5,
|
||||
IRISCVII_InstFormatU = 6,
|
||||
IRISCVII_InstFormatJ = 7,
|
||||
IRISCVII_InstFormatCR = 8,
|
||||
IRISCVII_InstFormatCI = 9,
|
||||
IRISCVII_InstFormatCSS = 10,
|
||||
IRISCVII_InstFormatCIW = 11,
|
||||
IRISCVII_InstFormatCL = 12,
|
||||
IRISCVII_InstFormatCS = 13,
|
||||
IRISCVII_InstFormatCA = 14,
|
||||
IRISCVII_InstFormatCB = 15,
|
||||
IRISCVII_InstFormatCJ = 16,
|
||||
IRISCVII_InstFormatOther = 17,
|
||||
|
||||
IRISCVII_InstFormatMask = 31
|
||||
IRISCVII_InstFormatMask = 31
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -51,56 +51,56 @@ enum {
|
|||
|
||||
// Describes the predecessor/successor bits used in the FENCE instruction.
|
||||
enum FenceField {
|
||||
RISCVFenceField_I = 8,
|
||||
RISCVFenceField_O = 4,
|
||||
RISCVFenceField_R = 2,
|
||||
RISCVFenceField_W = 1
|
||||
RISCVFenceField_I = 8,
|
||||
RISCVFenceField_O = 4,
|
||||
RISCVFenceField_R = 2,
|
||||
RISCVFenceField_W = 1
|
||||
};
|
||||
|
||||
// Describes the supported floating point rounding mode encodings.
|
||||
enum RoundingMode {
|
||||
RISCVFPRndMode_RNE = 0,
|
||||
RISCVFPRndMode_RTZ = 1,
|
||||
RISCVFPRndMode_RDN = 2,
|
||||
RISCVFPRndMode_RUP = 3,
|
||||
RISCVFPRndMode_RMM = 4,
|
||||
RISCVFPRndMode_DYN = 7,
|
||||
RISCVFPRndMode_Invalid
|
||||
RISCVFPRndMode_RNE = 0,
|
||||
RISCVFPRndMode_RTZ = 1,
|
||||
RISCVFPRndMode_RDN = 2,
|
||||
RISCVFPRndMode_RUP = 3,
|
||||
RISCVFPRndMode_RMM = 4,
|
||||
RISCVFPRndMode_DYN = 7,
|
||||
RISCVFPRndMode_Invalid
|
||||
};
|
||||
|
||||
inline static const char *roundingModeToString(enum RoundingMode RndMode)
|
||||
inline static const char *roundingModeToString(enum RoundingMode RndMode)
|
||||
{
|
||||
switch (RndMode) {
|
||||
default:
|
||||
CS_ASSERT(0 && "Unknown floating point rounding mode");
|
||||
case RISCVFPRndMode_RNE:
|
||||
return "rne";
|
||||
case RISCVFPRndMode_RTZ:
|
||||
return "rtz";
|
||||
case RISCVFPRndMode_RDN:
|
||||
return "rdn";
|
||||
case RISCVFPRndMode_RUP:
|
||||
return "rup";
|
||||
case RISCVFPRndMode_RMM:
|
||||
return "rmm";
|
||||
case RISCVFPRndMode_DYN:
|
||||
return "dyn";
|
||||
}
|
||||
switch (RndMode) {
|
||||
default:
|
||||
CS_ASSERT(0 && "Unknown floating point rounding mode");
|
||||
case RISCVFPRndMode_RNE:
|
||||
return "rne";
|
||||
case RISCVFPRndMode_RTZ:
|
||||
return "rtz";
|
||||
case RISCVFPRndMode_RDN:
|
||||
return "rdn";
|
||||
case RISCVFPRndMode_RUP:
|
||||
return "rup";
|
||||
case RISCVFPRndMode_RMM:
|
||||
return "rmm";
|
||||
case RISCVFPRndMode_DYN:
|
||||
return "dyn";
|
||||
}
|
||||
}
|
||||
|
||||
inline static bool RISCVFPRndMode_isValidRoundingMode(unsigned Mode)
|
||||
inline static bool RISCVFPRndMode_isValidRoundingMode(unsigned Mode)
|
||||
{
|
||||
switch (Mode) {
|
||||
default:
|
||||
return false;
|
||||
case RISCVFPRndMode_RNE:
|
||||
case RISCVFPRndMode_RTZ:
|
||||
case RISCVFPRndMode_RDN:
|
||||
case RISCVFPRndMode_RUP:
|
||||
case RISCVFPRndMode_RMM:
|
||||
case RISCVFPRndMode_DYN:
|
||||
return true;
|
||||
}
|
||||
switch (Mode) {
|
||||
default:
|
||||
return false;
|
||||
case RISCVFPRndMode_RNE:
|
||||
case RISCVFPRndMode_RTZ:
|
||||
case RISCVFPRndMode_RDN:
|
||||
case RISCVFPRndMode_RUP:
|
||||
case RISCVFPRndMode_RMM:
|
||||
case RISCVFPRndMode_DYN:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@
|
|||
/* Capstone Disassembly Engine */
|
||||
/* RISC-V Backend By Rodrigo Cortes Porto <porto703@gmail.com> &
|
||||
Shawn Chang <citypw@gmail.com>, HardenedLinux@2018 */
|
||||
|
||||
|
||||
#ifdef CAPSTONE_HAS_RISCV
|
||||
|
||||
#include <stdio.h> // DEBUG
|
||||
#include <stdio.h> // DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -30,7 +30,6 @@
|
|||
#include "RISCVBaseInfo.h"
|
||||
#include "RISCVDisassembler.h"
|
||||
|
||||
|
||||
/* Need the feature infos define in
|
||||
RISCVGenSubtargetInfo.inc. */
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
|
|
@ -39,10 +38,10 @@
|
|||
/* When we specify the RISCV64 mode, It means It is RV64IMAFD.
|
||||
Similar, RISCV32 means RV32IMAFD.
|
||||
*/
|
||||
static uint64_t getFeatureBits(int mode)
|
||||
static uint64_t getFeatureBits(int mode)
|
||||
{
|
||||
uint64_t ret = RISCV_FeatureStdExtM | RISCV_FeatureStdExtA |
|
||||
RISCV_FeatureStdExtF | RISCV_FeatureStdExtD ;
|
||||
RISCV_FeatureStdExtF | RISCV_FeatureStdExtD;
|
||||
|
||||
if (mode & CS_MODE_RISCV64)
|
||||
ret |= RISCV_Feature64Bit;
|
||||
|
|
@ -59,260 +58,253 @@ static uint64_t getFeatureBits(int mode)
|
|||
#include "RISCVGenInstrInfo.inc"
|
||||
|
||||
static const unsigned GPRDecoderTable[] = {
|
||||
RISCV_X0, RISCV_X1, RISCV_X2, RISCV_X3,
|
||||
RISCV_X4, RISCV_X5, RISCV_X6, RISCV_X7,
|
||||
RISCV_X8, RISCV_X9, RISCV_X10, RISCV_X11,
|
||||
RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15,
|
||||
RISCV_X16, RISCV_X17, RISCV_X18, RISCV_X19,
|
||||
RISCV_X20, RISCV_X21, RISCV_X22, RISCV_X23,
|
||||
RISCV_X24, RISCV_X25, RISCV_X26, RISCV_X27,
|
||||
RISCV_X28, RISCV_X29, RISCV_X30, RISCV_X31
|
||||
RISCV_X0, RISCV_X1, RISCV_X2, RISCV_X3, RISCV_X4, RISCV_X5,
|
||||
RISCV_X6, RISCV_X7, RISCV_X8, RISCV_X9, RISCV_X10, RISCV_X11,
|
||||
RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, RISCV_X16, RISCV_X17,
|
||||
RISCV_X18, RISCV_X19, RISCV_X20, RISCV_X21, RISCV_X22, RISCV_X23,
|
||||
RISCV_X24, RISCV_X25, RISCV_X26, RISCV_X27, RISCV_X28, RISCV_X29,
|
||||
RISCV_X30, RISCV_X31
|
||||
};
|
||||
|
||||
static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
unsigned Reg = 0;
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (RegNo >= ARR_SIZE(GPRDecoderTable))
|
||||
return MCDisassembler_Fail;
|
||||
if (RegNo >= ARR_SIZE(GPRDecoderTable))
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
// We must define our own mapping from RegNo to register identifier.
|
||||
// Accessing index RegNo in the register class will work in the case that
|
||||
// registers were added in ascending order, but not in general.
|
||||
Reg = GPRDecoderTable[RegNo];
|
||||
//Inst.addOperand(MCOperand::createReg(Reg));
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
// We must define our own mapping from RegNo to register identifier.
|
||||
// Accessing index RegNo in the register class will work in the case that
|
||||
// registers were added in ascending order, but not in general.
|
||||
Reg = GPRDecoderTable[RegNo];
|
||||
//Inst.addOperand(MCOperand::createReg(Reg));
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static const unsigned FPR32DecoderTable[] = {
|
||||
RISCV_F0_32, RISCV_F1_32, RISCV_F2_32, RISCV_F3_32,
|
||||
RISCV_F4_32, RISCV_F5_32, RISCV_F6_32, RISCV_F7_32,
|
||||
RISCV_F8_32, RISCV_F9_32, RISCV_F10_32, RISCV_F11_32,
|
||||
RISCV_F12_32, RISCV_F13_32, RISCV_F14_32, RISCV_F15_32,
|
||||
RISCV_F16_32, RISCV_F17_32, RISCV_F18_32, RISCV_F19_32,
|
||||
RISCV_F20_32, RISCV_F21_32, RISCV_F22_32, RISCV_F23_32,
|
||||
RISCV_F24_32, RISCV_F25_32, RISCV_F26_32, RISCV_F27_32,
|
||||
RISCV_F28_32, RISCV_F29_32, RISCV_F30_32, RISCV_F31_32
|
||||
RISCV_F0_32, RISCV_F1_32, RISCV_F2_32, RISCV_F3_32, RISCV_F4_32,
|
||||
RISCV_F5_32, RISCV_F6_32, RISCV_F7_32, RISCV_F8_32, RISCV_F9_32,
|
||||
RISCV_F10_32, RISCV_F11_32, RISCV_F12_32, RISCV_F13_32, RISCV_F14_32,
|
||||
RISCV_F15_32, RISCV_F16_32, RISCV_F17_32, RISCV_F18_32, RISCV_F19_32,
|
||||
RISCV_F20_32, RISCV_F21_32, RISCV_F22_32, RISCV_F23_32, RISCV_F24_32,
|
||||
RISCV_F25_32, RISCV_F26_32, RISCV_F27_32, RISCV_F28_32, RISCV_F29_32,
|
||||
RISCV_F30_32, RISCV_F31_32
|
||||
};
|
||||
|
||||
static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
unsigned Reg = 0;
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (RegNo >= ARR_SIZE(FPR32DecoderTable))
|
||||
return MCDisassembler_Fail;
|
||||
if (RegNo >= ARR_SIZE(FPR32DecoderTable))
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
// We must define our own mapping from RegNo to register identifier.
|
||||
// Accessing index RegNo in the register class will work in the case that
|
||||
// registers were added in ascending order, but not in general.
|
||||
Reg = FPR32DecoderTable[RegNo];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
// We must define our own mapping from RegNo to register identifier.
|
||||
// Accessing index RegNo in the register class will work in the case that
|
||||
// registers were added in ascending order, but not in general.
|
||||
Reg = FPR32DecoderTable[RegNo];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeFPR32CRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
unsigned Reg = 0;
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (RegNo > 8)
|
||||
return MCDisassembler_Fail;
|
||||
Reg = FPR32DecoderTable[RegNo + 8];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
if (RegNo > 8)
|
||||
return MCDisassembler_Fail;
|
||||
Reg = FPR32DecoderTable[RegNo + 8];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static const unsigned FPR64DecoderTable[] = {
|
||||
RISCV_F0_64, RISCV_F1_64, RISCV_F2_64, RISCV_F3_64,
|
||||
RISCV_F4_64, RISCV_F5_64, RISCV_F6_64, RISCV_F7_64,
|
||||
RISCV_F8_64, RISCV_F9_64, RISCV_F10_64, RISCV_F11_64,
|
||||
RISCV_F12_64, RISCV_F13_64, RISCV_F14_64, RISCV_F15_64,
|
||||
RISCV_F16_64, RISCV_F17_64, RISCV_F18_64, RISCV_F19_64,
|
||||
RISCV_F20_64, RISCV_F21_64, RISCV_F22_64, RISCV_F23_64,
|
||||
RISCV_F24_64, RISCV_F25_64, RISCV_F26_64, RISCV_F27_64,
|
||||
RISCV_F28_64, RISCV_F29_64, RISCV_F30_64, RISCV_F31_64
|
||||
RISCV_F0_64, RISCV_F1_64, RISCV_F2_64, RISCV_F3_64, RISCV_F4_64,
|
||||
RISCV_F5_64, RISCV_F6_64, RISCV_F7_64, RISCV_F8_64, RISCV_F9_64,
|
||||
RISCV_F10_64, RISCV_F11_64, RISCV_F12_64, RISCV_F13_64, RISCV_F14_64,
|
||||
RISCV_F15_64, RISCV_F16_64, RISCV_F17_64, RISCV_F18_64, RISCV_F19_64,
|
||||
RISCV_F20_64, RISCV_F21_64, RISCV_F22_64, RISCV_F23_64, RISCV_F24_64,
|
||||
RISCV_F25_64, RISCV_F26_64, RISCV_F27_64, RISCV_F28_64, RISCV_F29_64,
|
||||
RISCV_F30_64, RISCV_F31_64
|
||||
};
|
||||
|
||||
static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
unsigned Reg = 0;
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (RegNo >= ARR_SIZE(FPR64DecoderTable))
|
||||
return MCDisassembler_Fail;
|
||||
if (RegNo >= ARR_SIZE(FPR64DecoderTable))
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
// We must define our own mapping from RegNo to register identifier.
|
||||
// Accessing index RegNo in the register class will work in the case that
|
||||
// registers were added in ascending order, but not in general.
|
||||
Reg = FPR64DecoderTable[RegNo];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
// We must define our own mapping from RegNo to register identifier.
|
||||
// Accessing index RegNo in the register class will work in the case that
|
||||
// registers were added in ascending order, but not in general.
|
||||
Reg = FPR64DecoderTable[RegNo];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeFPR64CRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
unsigned Reg = 0;
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (RegNo > 8)
|
||||
return MCDisassembler_Fail;
|
||||
Reg = FPR64DecoderTable[RegNo + 8];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
if (RegNo > 8)
|
||||
return MCDisassembler_Fail;
|
||||
Reg = FPR64DecoderTable[RegNo + 8];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
if (RegNo == 0)
|
||||
return MCDisassembler_Fail;
|
||||
return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
|
||||
if (RegNo == 0)
|
||||
return MCDisassembler_Fail;
|
||||
return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
if (RegNo == 2)
|
||||
return MCDisassembler_Fail;
|
||||
return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
|
||||
if (RegNo == 2)
|
||||
return MCDisassembler_Fail;
|
||||
return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
unsigned Reg = 0;
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (RegNo > 8)
|
||||
return MCDisassembler_Fail;
|
||||
if (RegNo > 8)
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
Reg = GPRDecoderTable[RegNo + 8];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
Reg = GPRDecoderTable[RegNo + 8];
|
||||
MCOperand_CreateReg0(Inst, Reg);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
// Add implied SP operand for instructions *SP compressed instructions. The SP
|
||||
// operand isn't explicitly encoded in the instruction.
|
||||
static void addImplySP(MCInst *Inst, int64_t Address, const void *Decoder)
|
||||
static void addImplySP(MCInst *Inst, int64_t Address, const void *Decoder)
|
||||
{
|
||||
if (MCInst_getOpcode(Inst) == RISCV_C_LWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_SWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_LDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_SDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FLWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FSWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FLDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FSDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_ADDI4SPN) {
|
||||
if (MCInst_getOpcode(Inst) == RISCV_C_LWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_SWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_LDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_SDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FLWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FSWSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FLDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_FSDSP ||
|
||||
MCInst_getOpcode(Inst) == RISCV_C_ADDI4SPN) {
|
||||
DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
|
||||
}
|
||||
}
|
||||
|
||||
if (MCInst_getOpcode(Inst) == RISCV_C_ADDI16SP) {
|
||||
DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
|
||||
DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
|
||||
}
|
||||
if (MCInst_getOpcode(Inst) == RISCV_C_ADDI16SP) {
|
||||
DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
|
||||
DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
|
||||
}
|
||||
}
|
||||
|
||||
static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder,
|
||||
unsigned N)
|
||||
int64_t Address, const void *Decoder,
|
||||
unsigned N)
|
||||
{
|
||||
//CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
|
||||
addImplySP(Inst, Address, Decoder);
|
||||
//Inst.addOperand(MCOperand::createImm(Imm));
|
||||
MCOperand_CreateImm0(Inst, Imm);
|
||||
return MCDisassembler_Success;
|
||||
//CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
|
||||
addImplySP(Inst, Address, Decoder);
|
||||
//Inst.addOperand(MCOperand::createImm(Imm));
|
||||
MCOperand_CreateImm0(Inst, Imm);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeUImmNonZeroOperand(MCInst *Inst, uint64_t Imm,
|
||||
int64_t Address,
|
||||
const void *Decoder,
|
||||
unsigned N)
|
||||
int64_t Address,
|
||||
const void *Decoder, unsigned N)
|
||||
{
|
||||
if (Imm == 0)
|
||||
return MCDisassembler_Fail;
|
||||
return decodeUImmOperand(Inst, Imm, Address, Decoder, N);
|
||||
if (Imm == 0)
|
||||
return MCDisassembler_Fail;
|
||||
return decodeUImmOperand(Inst, Imm, Address, Decoder, N);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder,
|
||||
unsigned N)
|
||||
int64_t Address, const void *Decoder,
|
||||
unsigned N)
|
||||
{
|
||||
//CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
|
||||
addImplySP(Inst, Address, Decoder);
|
||||
// Sign-extend the number in the bottom N bits of Imm
|
||||
//Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
|
||||
return MCDisassembler_Success;
|
||||
//CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
|
||||
addImplySP(Inst, Address, Decoder);
|
||||
// Sign-extend the number in the bottom N bits of Imm
|
||||
//Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeSImmNonZeroOperand(MCInst *Inst, uint64_t Imm,
|
||||
int64_t Address,
|
||||
const void *Decoder,
|
||||
unsigned N)
|
||||
int64_t Address,
|
||||
const void *Decoder, unsigned N)
|
||||
{
|
||||
if (Imm == 0)
|
||||
return MCDisassembler_Fail;
|
||||
return decodeSImmOperand(Inst, Imm, Address, Decoder, N);
|
||||
if (Imm == 0)
|
||||
return MCDisassembler_Fail;
|
||||
return decodeSImmOperand(Inst, Imm, Address, Decoder, N);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeSImmOperandAndLsl1(MCInst *Inst, uint64_t Imm,
|
||||
int64_t Address,
|
||||
const void *Decoder,
|
||||
unsigned N)
|
||||
int64_t Address,
|
||||
const void *Decoder, unsigned N)
|
||||
{
|
||||
//CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
|
||||
// Sign-extend the number in the bottom N bits of Imm after accounting for
|
||||
// the fact that the N bit immediate is stored in N-1 bits (the LSB is
|
||||
// always zero)
|
||||
//Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Imm << 1, N));
|
||||
return MCDisassembler_Success;
|
||||
//CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
|
||||
// Sign-extend the number in the bottom N bits of Imm after accounting for
|
||||
// the fact that the N bit immediate is stored in N-1 bits (the LSB is
|
||||
// always zero)
|
||||
//Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Imm << 1, N));
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeCLUIImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
int64_t Address,
|
||||
const void *Decoder)
|
||||
int64_t Address, const void *Decoder)
|
||||
{
|
||||
//CS_ASSERT(isUInt<6>(Imm) && "Invalid immediate");
|
||||
if (Imm > 31) {
|
||||
Imm = (SignExtend64(Imm, 6) & 0xfffff);
|
||||
}
|
||||
//Inst.addOperand(MCOperand::createImm(Imm));
|
||||
MCOperand_CreateImm0(Inst, Imm);
|
||||
return MCDisassembler_Success;
|
||||
//CS_ASSERT(isUInt<6>(Imm) && "Invalid immediate");
|
||||
if (Imm > 31) {
|
||||
Imm = (SignExtend64(Imm, 6) & 0xfffff);
|
||||
}
|
||||
//Inst.addOperand(MCOperand::createImm(Imm));
|
||||
MCOperand_CreateImm0(Inst, Imm);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeFRMArg(MCInst *Inst, uint64_t Imm,
|
||||
int64_t Address,
|
||||
const void *Decoder)
|
||||
static DecodeStatus decodeFRMArg(MCInst *Inst, uint64_t Imm, int64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
//CS_ASSERT(isUInt<3>(Imm) && "Invalid immediate");
|
||||
if (!RISCVFPRndMode_isValidRoundingMode(Imm))
|
||||
return MCDisassembler_Fail;
|
||||
//CS_ASSERT(isUInt<3>(Imm) && "Invalid immediate");
|
||||
if (!RISCVFPRndMode_isValidRoundingMode(Imm))
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
//Inst.addOperand(MCOperand::createImm(Imm));
|
||||
MCOperand_CreateImm0(Inst, Imm);
|
||||
return MCDisassembler_Success;
|
||||
//Inst.addOperand(MCOperand::createImm(Imm));
|
||||
MCOperand_CreateImm0(Inst, Imm);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
|
||||
#include "RISCVGenDisassemblerTables.inc"
|
||||
|
||||
static void init_MI_insn_detail(MCInst *MI)
|
||||
static void init_MI_insn_detail(MCInst *MI)
|
||||
{
|
||||
if (MI->flat_insn->detail) {
|
||||
memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
|
||||
}
|
||||
if (MI->flat_insn->detail) {
|
||||
memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the load/store instructions through the opcode.
|
||||
|
|
@ -328,8 +320,8 @@ static void markLSInsn(MCInst *MI, uint32_t in)
|
|||
#define MASK_LS_INSN 0x0000007f
|
||||
uint32_t opcode = in & MASK_LS_INSN;
|
||||
if (0 == (opcode ^ 0x03) || 0 == (opcode ^ 0x07) ||
|
||||
0 == (opcode ^ 0x23) || 0 == (opcode ^ 0x27) ||
|
||||
0 == (opcode ^ 0x2f))
|
||||
0 == (opcode ^ 0x23) || 0 == (opcode ^ 0x27) ||
|
||||
0 == (opcode ^ 0x2f))
|
||||
MI->flat_insn->detail->riscv.need_effective_addr = true;
|
||||
#undef MASK_LS_INSN
|
||||
return;
|
||||
|
|
@ -340,102 +332,101 @@ static void markCLSInsn(MCInst *MI, uint32_t in)
|
|||
// Unfortunately there is no obvious pattern in terms of RISC-V C instructions
|
||||
// Thus, we compare the instruction IDs to see if it is a load/store instruction
|
||||
unsigned id = MCInst_getOpcode(MI);
|
||||
if (id == RISCV_C_FLD || id == RISCV_C_LW ||
|
||||
id == RISCV_C_FLW || id == RISCV_C_LD ||
|
||||
id == RISCV_C_FSD || id == RISCV_C_SW ||
|
||||
id == RISCV_C_FSW || id == RISCV_C_SD ||
|
||||
id == RISCV_C_FLDSP || id == RISCV_C_LWSP ||
|
||||
id == RISCV_C_FLWSP || id == RISCV_C_LDSP ||
|
||||
id == RISCV_C_FSDSP || id == RISCV_C_SWSP ||
|
||||
id == RISCV_C_FSWSP || id == RISCV_C_SDSP) {
|
||||
if (id == RISCV_C_FLD || id == RISCV_C_LW || id == RISCV_C_FLW ||
|
||||
id == RISCV_C_LD || id == RISCV_C_FSD || id == RISCV_C_SW ||
|
||||
id == RISCV_C_FSW || id == RISCV_C_SD || id == RISCV_C_FLDSP ||
|
||||
id == RISCV_C_LWSP || id == RISCV_C_FLWSP || id == RISCV_C_LDSP ||
|
||||
id == RISCV_C_FSDSP || id == RISCV_C_SWSP || id == RISCV_C_FSWSP ||
|
||||
id == RISCV_C_SDSP) {
|
||||
RISCV_get_detail(MI)->need_effective_addr = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static DecodeStatus RISCVDisassembler_getInstruction(int mode, MCInst *MI,
|
||||
const uint8_t *code, size_t code_len,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
MCRegisterInfo *MRI)
|
||||
static DecodeStatus
|
||||
RISCVDisassembler_getInstruction(int mode, MCInst *MI, const uint8_t *code,
|
||||
size_t code_len, uint16_t *Size,
|
||||
uint64_t Address, MCRegisterInfo *MRI)
|
||||
{
|
||||
// TODO: This will need modification when supporting instruction set
|
||||
// extensions with instructions > 32-bits (up to 176 bits wide).
|
||||
uint32_t Inst = 0;
|
||||
DecodeStatus Result;
|
||||
// TODO: This will need modification when supporting instruction set
|
||||
// extensions with instructions > 32-bits (up to 176 bits wide).
|
||||
uint32_t Inst = 0;
|
||||
DecodeStatus Result;
|
||||
|
||||
// It's a 32 bit instruction if bit 0 and 1 are 1.
|
||||
if ((code[0] & 0x3) == 0x3) {
|
||||
if (code_len < 4) {
|
||||
*Size = 0;
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
// It's a 32 bit instruction if bit 0 and 1 are 1.
|
||||
if ((code[0] & 0x3) == 0x3) {
|
||||
if (code_len < 4) {
|
||||
*Size = 0;
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
*Size = 4;
|
||||
// Get the four bytes of the instruction.
|
||||
//Encoded as little endian 32 bits.
|
||||
Inst = code[0] | (code[1] << 8) | (code[2] << 16) | ((uint32_t)code[3] << 24);
|
||||
*Size = 4;
|
||||
// Get the four bytes of the instruction.
|
||||
//Encoded as little endian 32 bits.
|
||||
Inst = code[0] | (code[1] << 8) | (code[2] << 16) |
|
||||
((uint32_t)code[3] << 24);
|
||||
init_MI_insn_detail(MI);
|
||||
// Now we need mark what instruction need fix effective address output.
|
||||
if (MI->csh->detail_opt)
|
||||
markLSInsn(MI, Inst);
|
||||
Result = decodeInstruction(DecoderTable32, MI, Inst, Address, MRI, mode);
|
||||
} else {
|
||||
if (code_len < 2) {
|
||||
*Size = 0;
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
Result = decodeInstruction(DecoderTable32, MI, Inst, Address,
|
||||
MRI, mode);
|
||||
} else {
|
||||
if (code_len < 2) {
|
||||
*Size = 0;
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
// If not b4bit.
|
||||
if (! (getFeatureBits(mode) & ((uint64_t)RISCV_Feature64Bit))) {
|
||||
// Trying RISCV32Only_16 table (16-bit Instruction)
|
||||
Inst = code[0] | (code[1] << 8);
|
||||
init_MI_insn_detail(MI);
|
||||
Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Inst, Address,
|
||||
MRI, mode);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
*Size = 2;
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
// Trying RISCV_C table (16-bit Instruction)
|
||||
Inst = code[0] | (code[1] << 8);
|
||||
init_MI_insn_detail(MI);
|
||||
// Calling the auto-generated decoder function.
|
||||
Result = decodeInstruction(DecoderTable16, MI, Inst, Address, MRI, mode);
|
||||
// Now we need mark what instruction need fix effective address output.
|
||||
// Note that we mark it AFTER the instruction is decoded
|
||||
// This is because there is no obvious pattern in terms of RISC-V C instructions
|
||||
// So we compare the instruction IDs one by one
|
||||
if (detail_is_set(MI))
|
||||
markCLSInsn(MI, Inst);
|
||||
*Size = 2;
|
||||
}
|
||||
if (!(getFeatureBits(mode) & ((uint64_t)RISCV_Feature64Bit))) {
|
||||
// Trying RISCV32Only_16 table (16-bit Instruction)
|
||||
Inst = code[0] | (code[1] << 8);
|
||||
init_MI_insn_detail(MI);
|
||||
Result = decodeInstruction(DecoderTableRISCV32Only_16,
|
||||
MI, Inst, Address, MRI,
|
||||
mode);
|
||||
if (Result != MCDisassembler_Fail) {
|
||||
*Size = 2;
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
// Trying RISCV_C table (16-bit Instruction)
|
||||
Inst = code[0] | (code[1] << 8);
|
||||
init_MI_insn_detail(MI);
|
||||
// Calling the auto-generated decoder function.
|
||||
Result = decodeInstruction(DecoderTable16, MI, Inst, Address,
|
||||
MRI, mode);
|
||||
// Now we need mark what instruction need fix effective address output.
|
||||
// Note that we mark it AFTER the instruction is decoded
|
||||
// This is because there is no obvious pattern in terms of RISC-V C instructions
|
||||
// So we compare the instruction IDs one by one
|
||||
if (detail_is_set(MI))
|
||||
markCLSInsn(MI, Inst);
|
||||
*Size = 2;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool RISCV_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info)
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info)
|
||||
{
|
||||
cs_struct *handle = (cs_struct *)(uintptr_t)ud;
|
||||
cs_struct *handle = (cs_struct *)(uintptr_t)ud;
|
||||
|
||||
DecodeStatus Result =
|
||||
RISCVDisassembler_getInstruction(handle->mode, instr,
|
||||
code, code_len,
|
||||
size, address,
|
||||
(MCRegisterInfo *)info);
|
||||
DecodeStatus Result = RISCVDisassembler_getInstruction(
|
||||
handle->mode, instr, code, code_len, size, address,
|
||||
(MCRegisterInfo *)info);
|
||||
if (Result == MCDisassembler_SoftFail) {
|
||||
MCInst_setSoftFail(instr);
|
||||
}
|
||||
return Result != MCDisassembler_Fail;
|
||||
|
||||
}
|
||||
|
||||
void RISCV_init(MCRegisterInfo * MRI)
|
||||
void RISCV_init(MCRegisterInfo *MRI)
|
||||
{
|
||||
/*
|
||||
/*
|
||||
InitMCRegisterInfo(RISCVRegDesc, 97, RA, PC,
|
||||
RISCVMCRegisterClasses, 11,
|
||||
RISCVRegUnitRoots,
|
||||
|
|
@ -450,15 +441,10 @@ void RISCV_init(MCRegisterInfo * MRI)
|
|||
RISCVRegEncodingTable);
|
||||
*/
|
||||
|
||||
MCRegisterInfo_InitMCRegisterInfo(MRI, RISCVRegDesc, 97, 0, 0,
|
||||
RISCVMCRegisterClasses, 11,
|
||||
0,
|
||||
0,
|
||||
RISCVRegDiffLists,
|
||||
0,
|
||||
RISCVSubRegIdxLists,
|
||||
2,
|
||||
0);
|
||||
MCRegisterInfo_InitMCRegisterInfo(MRI, RISCVRegDesc, 97, 0, 0,
|
||||
RISCVMCRegisterClasses, 11, 0, 0,
|
||||
RISCVRegDiffLists, 0,
|
||||
RISCVSubRegIdxLists, 2, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Capstone Disassembly Engine */
|
||||
/* RISC-V Backend By Rodrigo Cortes Porto <porto703@gmail.com> &
|
||||
Shawn Chang <citypw@gmail.com>, HardenedLinux@2018 */
|
||||
|
||||
|
||||
#ifndef CS_RISCVDISASSEMBLER_H
|
||||
#define CS_RISCVDISASSEMBLER_H
|
||||
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
void RISCV_init(MCRegisterInfo *MRI);
|
||||
|
||||
bool RISCV_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,8 +17,8 @@
|
|||
#include "../../MCInst.h"
|
||||
#include "../../SStream.h"
|
||||
|
||||
void RISCV_printInst(MCInst * MI, SStream * O, void *info);
|
||||
void RISCV_printInst(MCInst *MI, SStream *O, void *info);
|
||||
|
||||
void RISCV_post_printer(csh ud, cs_insn * insn, char *insn_asm, MCInst * mci);
|
||||
void RISCV_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#ifdef CAPSTONE_HAS_RISCV
|
||||
|
||||
#include <stdio.h> // debug
|
||||
#include <stdio.h> // debug
|
||||
#include <string.h>
|
||||
|
||||
#include "../../Mapping.h"
|
||||
|
|
@ -18,103 +18,55 @@
|
|||
static const name_map reg_name_maps[] = {
|
||||
{ RISCV_REG_INVALID, NULL },
|
||||
|
||||
{ RISCV_REG_X0, "zero" },
|
||||
{ RISCV_REG_X1, "ra" },
|
||||
{ RISCV_REG_X2, "sp" },
|
||||
{ RISCV_REG_X3, "gp" },
|
||||
{ RISCV_REG_X4, "tp" },
|
||||
{ RISCV_REG_X5, "t0" },
|
||||
{ RISCV_REG_X6, "t1" },
|
||||
{ RISCV_REG_X7, "t2" },
|
||||
{ RISCV_REG_X8, "s0" },
|
||||
{ RISCV_REG_X9, "s1" },
|
||||
{ RISCV_REG_X10, "a0" },
|
||||
{ RISCV_REG_X11, "a1" },
|
||||
{ RISCV_REG_X12, "a2" },
|
||||
{ RISCV_REG_X13, "a3" },
|
||||
{ RISCV_REG_X14, "a4" },
|
||||
{ RISCV_REG_X15, "a5" },
|
||||
{ RISCV_REG_X16, "a6" },
|
||||
{ RISCV_REG_X17, "a7" },
|
||||
{ RISCV_REG_X18, "s2" },
|
||||
{ RISCV_REG_X19, "s3" },
|
||||
{ RISCV_REG_X20, "s4" },
|
||||
{ RISCV_REG_X21, "s5" },
|
||||
{ RISCV_REG_X22, "s6" },
|
||||
{ RISCV_REG_X23, "s7" },
|
||||
{ RISCV_REG_X24, "s8" },
|
||||
{ RISCV_REG_X25, "s9" },
|
||||
{ RISCV_REG_X26, "s10" },
|
||||
{ RISCV_REG_X27, "s11" },
|
||||
{ RISCV_REG_X28, "t3" },
|
||||
{ RISCV_REG_X29, "t4" },
|
||||
{ RISCV_REG_X30, "t5" },
|
||||
{ RISCV_REG_X31, "t6" },
|
||||
{ RISCV_REG_X0, "zero" }, { RISCV_REG_X1, "ra" },
|
||||
{ RISCV_REG_X2, "sp" }, { RISCV_REG_X3, "gp" },
|
||||
{ RISCV_REG_X4, "tp" }, { RISCV_REG_X5, "t0" },
|
||||
{ RISCV_REG_X6, "t1" }, { RISCV_REG_X7, "t2" },
|
||||
{ RISCV_REG_X8, "s0" }, { RISCV_REG_X9, "s1" },
|
||||
{ RISCV_REG_X10, "a0" }, { RISCV_REG_X11, "a1" },
|
||||
{ RISCV_REG_X12, "a2" }, { RISCV_REG_X13, "a3" },
|
||||
{ RISCV_REG_X14, "a4" }, { RISCV_REG_X15, "a5" },
|
||||
{ RISCV_REG_X16, "a6" }, { RISCV_REG_X17, "a7" },
|
||||
{ RISCV_REG_X18, "s2" }, { RISCV_REG_X19, "s3" },
|
||||
{ RISCV_REG_X20, "s4" }, { RISCV_REG_X21, "s5" },
|
||||
{ RISCV_REG_X22, "s6" }, { RISCV_REG_X23, "s7" },
|
||||
{ RISCV_REG_X24, "s8" }, { RISCV_REG_X25, "s9" },
|
||||
{ RISCV_REG_X26, "s10" }, { RISCV_REG_X27, "s11" },
|
||||
{ RISCV_REG_X28, "t3" }, { RISCV_REG_X29, "t4" },
|
||||
{ RISCV_REG_X30, "t5" }, { RISCV_REG_X31, "t6" },
|
||||
|
||||
{ RISCV_REG_F0_32, "ft0" },
|
||||
{ RISCV_REG_F0_64, "ft0" },
|
||||
{ RISCV_REG_F1_32, "ft1" },
|
||||
{ RISCV_REG_F1_64, "ft1" },
|
||||
{ RISCV_REG_F2_32, "ft2" },
|
||||
{ RISCV_REG_F2_64, "ft2" },
|
||||
{ RISCV_REG_F3_32, "ft3" },
|
||||
{ RISCV_REG_F3_64, "ft3" },
|
||||
{ RISCV_REG_F4_32, "ft4" },
|
||||
{ RISCV_REG_F4_64, "ft4" },
|
||||
{ RISCV_REG_F5_32, "ft5" },
|
||||
{ RISCV_REG_F5_64, "ft5" },
|
||||
{ RISCV_REG_F6_32, "ft6" },
|
||||
{ RISCV_REG_F6_64, "ft6" },
|
||||
{ RISCV_REG_F7_32, "ft7" },
|
||||
{ RISCV_REG_F7_64, "ft7" },
|
||||
{ RISCV_REG_F8_32, "fs0" },
|
||||
{ RISCV_REG_F8_64, "fs0" },
|
||||
{ RISCV_REG_F9_32, "fs1" },
|
||||
{ RISCV_REG_F9_64, "fs1" },
|
||||
{ RISCV_REG_F10_32, "fa0" },
|
||||
{ RISCV_REG_F10_64, "fa0" },
|
||||
{ RISCV_REG_F11_32, "fa1" },
|
||||
{ RISCV_REG_F11_64, "fa1" },
|
||||
{ RISCV_REG_F12_32, "fa2" },
|
||||
{ RISCV_REG_F12_64, "fa2" },
|
||||
{ RISCV_REG_F13_32, "fa3" },
|
||||
{ RISCV_REG_F13_64, "fa3" },
|
||||
{ RISCV_REG_F14_32, "fa4" },
|
||||
{ RISCV_REG_F14_64, "fa4" },
|
||||
{ RISCV_REG_F15_32, "fa5" },
|
||||
{ RISCV_REG_F15_64, "fa5" },
|
||||
{ RISCV_REG_F16_32, "fa6" },
|
||||
{ RISCV_REG_F16_64, "fa6" },
|
||||
{ RISCV_REG_F17_32, "fa7" },
|
||||
{ RISCV_REG_F17_64, "fa7" },
|
||||
{ RISCV_REG_F18_32, "fs2" },
|
||||
{ RISCV_REG_F18_64, "fs2" },
|
||||
{ RISCV_REG_F19_32, "fs3" },
|
||||
{ RISCV_REG_F19_64, "fs3" },
|
||||
{ RISCV_REG_F20_32, "fs4" },
|
||||
{ RISCV_REG_F20_64, "fs4" },
|
||||
{ RISCV_REG_F21_32, "fs5" },
|
||||
{ RISCV_REG_F21_64, "fs5" },
|
||||
{ RISCV_REG_F22_32, "fs6" },
|
||||
{ RISCV_REG_F22_64, "fs6" },
|
||||
{ RISCV_REG_F23_32, "fs7" },
|
||||
{ RISCV_REG_F23_64, "fs7" },
|
||||
{ RISCV_REG_F24_32, "fs8" },
|
||||
{ RISCV_REG_F24_64, "fs8" },
|
||||
{ RISCV_REG_F25_32, "fs9" },
|
||||
{ RISCV_REG_F25_64, "fs9" },
|
||||
{ RISCV_REG_F26_32, "fs10" },
|
||||
{ RISCV_REG_F26_64, "fs10" },
|
||||
{ RISCV_REG_F27_32, "fs11" },
|
||||
{ RISCV_REG_F27_64, "fs11" },
|
||||
{ RISCV_REG_F28_32, "ft8" },
|
||||
{ RISCV_REG_F28_64, "ft8" },
|
||||
{ RISCV_REG_F29_32, "ft9" },
|
||||
{ RISCV_REG_F29_64, "ft9" },
|
||||
{ RISCV_REG_F30_32, "ft10" },
|
||||
{ RISCV_REG_F30_64, "ft10" },
|
||||
{ RISCV_REG_F31_32, "ft11" },
|
||||
{ RISCV_REG_F31_64, "ft11" },
|
||||
{ RISCV_REG_F0_32, "ft0" }, { RISCV_REG_F0_64, "ft0" },
|
||||
{ RISCV_REG_F1_32, "ft1" }, { RISCV_REG_F1_64, "ft1" },
|
||||
{ RISCV_REG_F2_32, "ft2" }, { RISCV_REG_F2_64, "ft2" },
|
||||
{ RISCV_REG_F3_32, "ft3" }, { RISCV_REG_F3_64, "ft3" },
|
||||
{ RISCV_REG_F4_32, "ft4" }, { RISCV_REG_F4_64, "ft4" },
|
||||
{ RISCV_REG_F5_32, "ft5" }, { RISCV_REG_F5_64, "ft5" },
|
||||
{ RISCV_REG_F6_32, "ft6" }, { RISCV_REG_F6_64, "ft6" },
|
||||
{ RISCV_REG_F7_32, "ft7" }, { RISCV_REG_F7_64, "ft7" },
|
||||
{ RISCV_REG_F8_32, "fs0" }, { RISCV_REG_F8_64, "fs0" },
|
||||
{ RISCV_REG_F9_32, "fs1" }, { RISCV_REG_F9_64, "fs1" },
|
||||
{ RISCV_REG_F10_32, "fa0" }, { RISCV_REG_F10_64, "fa0" },
|
||||
{ RISCV_REG_F11_32, "fa1" }, { RISCV_REG_F11_64, "fa1" },
|
||||
{ RISCV_REG_F12_32, "fa2" }, { RISCV_REG_F12_64, "fa2" },
|
||||
{ RISCV_REG_F13_32, "fa3" }, { RISCV_REG_F13_64, "fa3" },
|
||||
{ RISCV_REG_F14_32, "fa4" }, { RISCV_REG_F14_64, "fa4" },
|
||||
{ RISCV_REG_F15_32, "fa5" }, { RISCV_REG_F15_64, "fa5" },
|
||||
{ RISCV_REG_F16_32, "fa6" }, { RISCV_REG_F16_64, "fa6" },
|
||||
{ RISCV_REG_F17_32, "fa7" }, { RISCV_REG_F17_64, "fa7" },
|
||||
{ RISCV_REG_F18_32, "fs2" }, { RISCV_REG_F18_64, "fs2" },
|
||||
{ RISCV_REG_F19_32, "fs3" }, { RISCV_REG_F19_64, "fs3" },
|
||||
{ RISCV_REG_F20_32, "fs4" }, { RISCV_REG_F20_64, "fs4" },
|
||||
{ RISCV_REG_F21_32, "fs5" }, { RISCV_REG_F21_64, "fs5" },
|
||||
{ RISCV_REG_F22_32, "fs6" }, { RISCV_REG_F22_64, "fs6" },
|
||||
{ RISCV_REG_F23_32, "fs7" }, { RISCV_REG_F23_64, "fs7" },
|
||||
{ RISCV_REG_F24_32, "fs8" }, { RISCV_REG_F24_64, "fs8" },
|
||||
{ RISCV_REG_F25_32, "fs9" }, { RISCV_REG_F25_64, "fs9" },
|
||||
{ RISCV_REG_F26_32, "fs10" }, { RISCV_REG_F26_64, "fs10" },
|
||||
{ RISCV_REG_F27_32, "fs11" }, { RISCV_REG_F27_64, "fs11" },
|
||||
{ RISCV_REG_F28_32, "ft8" }, { RISCV_REG_F28_64, "ft8" },
|
||||
{ RISCV_REG_F29_32, "ft9" }, { RISCV_REG_F29_64, "ft9" },
|
||||
{ RISCV_REG_F30_32, "ft10" }, { RISCV_REG_F30_64, "ft10" },
|
||||
{ RISCV_REG_F31_32, "ft11" }, { RISCV_REG_F31_64, "ft11" },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -131,12 +83,16 @@ const char *RISCV_reg_name(csh handle, unsigned int reg)
|
|||
|
||||
static const insn_map insns[] = {
|
||||
// dummy item
|
||||
{
|
||||
0, 0,
|
||||
{ 0,
|
||||
0,
|
||||
#ifndef CAPSTONE_DIET
|
||||
{0}, {0}, {0}, 0, 0
|
||||
{ 0 },
|
||||
{ 0 },
|
||||
{ 0 },
|
||||
0,
|
||||
0
|
||||
#endif
|
||||
},
|
||||
},
|
||||
|
||||
#include "RISCVMappingInsn.inc"
|
||||
};
|
||||
|
|
@ -149,7 +105,8 @@ static const map_insn_ops insn_operands[] = {
|
|||
|
||||
#endif
|
||||
|
||||
void RISCV_add_cs_detail(MCInst *MI, unsigned OpNum) {
|
||||
void RISCV_add_cs_detail(MCInst *MI, unsigned OpNum)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
||||
|
|
@ -158,91 +115,98 @@ void RISCV_add_cs_detail(MCInst *MI, unsigned OpNum) {
|
|||
if (op_type == CS_OP_IMM) {
|
||||
RISCV_get_detail_op(MI, 0)->type = RISCV_OP_IMM;
|
||||
RISCV_get_detail_op(MI, 0)->imm = MCInst_getOpVal(MI, OpNum);
|
||||
RISCV_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
|
||||
RISCV_get_detail_op(MI, 0)->access =
|
||||
map_get_op_access(MI, OpNum);
|
||||
RISCV_inc_op_count(MI);
|
||||
}
|
||||
else if (op_type == CS_OP_REG) {
|
||||
} else if (op_type == CS_OP_REG) {
|
||||
RISCV_get_detail_op(MI, 0)->type = RISCV_OP_REG;
|
||||
RISCV_get_detail_op(MI, 0)->reg = MCInst_getOpVal(MI, OpNum);
|
||||
RISCV_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
|
||||
RISCV_get_detail_op(MI, 0)->access =
|
||||
map_get_op_access(MI, OpNum);
|
||||
RISCV_inc_op_count(MI);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
CS_ASSERT(0 && "Op type not handled.");
|
||||
}
|
||||
}
|
||||
|
||||
// given internal insn id, return public instruction info
|
||||
void RISCV_get_insn_id(cs_struct * h, cs_insn * insn, unsigned int id)
|
||||
void RISCV_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
|
||||
i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
|
||||
if (i != 0) {
|
||||
insn->id = insns[i].mapid;
|
||||
i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
|
||||
if (i != 0) {
|
||||
insn->id = insns[i].mapid;
|
||||
|
||||
if (h->detail_opt) {
|
||||
if (h->detail_opt) {
|
||||
#ifndef CAPSTONE_DIET
|
||||
memcpy(insn->detail->regs_read,
|
||||
insns[i].regs_use, sizeof(insns[i].regs_use));
|
||||
insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use);
|
||||
memcpy(insn->detail->regs_read, insns[i].regs_use,
|
||||
sizeof(insns[i].regs_use));
|
||||
insn->detail->regs_read_count =
|
||||
(uint8_t)count_positive(insns[i].regs_use);
|
||||
|
||||
memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
|
||||
insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod);
|
||||
memcpy(insn->detail->regs_write, insns[i].regs_mod,
|
||||
sizeof(insns[i].regs_mod));
|
||||
insn->detail->regs_write_count =
|
||||
(uint8_t)count_positive(insns[i].regs_mod);
|
||||
|
||||
memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups));
|
||||
insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups);
|
||||
memcpy(insn->detail->groups, insns[i].groups,
|
||||
sizeof(insns[i].groups));
|
||||
insn->detail->groups_count =
|
||||
(uint8_t)count_positive8(insns[i].groups);
|
||||
|
||||
if (insns[i].branch || insns[i].indirect_branch) {
|
||||
// this insn also belongs to JUMP group. add JUMP group
|
||||
insn->detail->groups[insn->detail->groups_count] = RISCV_GRP_JUMP;
|
||||
insn->detail->groups_count++;
|
||||
}
|
||||
if (insns[i].branch || insns[i].indirect_branch) {
|
||||
// this insn also belongs to JUMP group. add JUMP group
|
||||
insn->detail
|
||||
->groups[insn->detail->groups_count] =
|
||||
RISCV_GRP_JUMP;
|
||||
insn->detail->groups_count++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const name_map insn_name_maps[] = {
|
||||
{RISCV_INS_INVALID, NULL},
|
||||
{ RISCV_INS_INVALID, NULL },
|
||||
|
||||
#include "RISCVGenInsnNameMaps.inc"
|
||||
};
|
||||
|
||||
const char *RISCV_insn_name(csh handle, unsigned int id)
|
||||
const char *RISCV_insn_name(csh handle, unsigned int id)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
if (id >= RISCV_INS_ENDING)
|
||||
return NULL;
|
||||
if (id >= RISCV_INS_ENDING)
|
||||
return NULL;
|
||||
|
||||
return insn_name_maps[id].name;
|
||||
return insn_name_maps[id].name;
|
||||
#else
|
||||
return NULL;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map group_name_maps[] = {
|
||||
// generic groups
|
||||
{ RISCV_GRP_INVALID, NULL },
|
||||
{ RISCV_GRP_JUMP, "jump" },
|
||||
{ RISCV_GRP_CALL, "call" },
|
||||
{ RISCV_GRP_RET, "ret" },
|
||||
{ RISCV_GRP_INT, "int" },
|
||||
{ RISCV_GRP_IRET, "iret" },
|
||||
{ RISCV_GRP_PRIVILEGE, "privileged" },
|
||||
{ RISCV_GRP_BRANCH_RELATIVE, "branch_relative" },
|
||||
|
||||
// architecture specific
|
||||
{ RISCV_GRP_ISRV32, "isrv32" },
|
||||
{ RISCV_GRP_ISRV64, "isrv64" },
|
||||
{ RISCV_GRP_HASSTDEXTA, "hasStdExtA" },
|
||||
{ RISCV_GRP_HASSTDEXTC, "hasStdExtC" },
|
||||
{ RISCV_GRP_HASSTDEXTD, "hasStdExtD" },
|
||||
{ RISCV_GRP_HASSTDEXTF, "hasStdExtF" },
|
||||
{ RISCV_GRP_HASSTDEXTM, "hasStdExtM" },
|
||||
|
||||
/*
|
||||
// generic groups
|
||||
{ RISCV_GRP_INVALID, NULL },
|
||||
{ RISCV_GRP_JUMP, "jump" },
|
||||
{ RISCV_GRP_CALL, "call" },
|
||||
{ RISCV_GRP_RET, "ret" },
|
||||
{ RISCV_GRP_INT, "int" },
|
||||
{ RISCV_GRP_IRET, "iret" },
|
||||
{ RISCV_GRP_PRIVILEGE, "privileged" },
|
||||
{ RISCV_GRP_BRANCH_RELATIVE, "branch_relative" },
|
||||
|
||||
// architecture specific
|
||||
{ RISCV_GRP_ISRV32, "isrv32" },
|
||||
{ RISCV_GRP_ISRV64, "isrv64" },
|
||||
{ RISCV_GRP_HASSTDEXTA, "hasStdExtA" },
|
||||
{ RISCV_GRP_HASSTDEXTC, "hasStdExtC" },
|
||||
{ RISCV_GRP_HASSTDEXTD, "hasStdExtD" },
|
||||
{ RISCV_GRP_HASSTDEXTF, "hasStdExtF" },
|
||||
{ RISCV_GRP_HASSTDEXTM, "hasStdExtM" },
|
||||
|
||||
/*
|
||||
{ RISCV_GRP_ISRVA, "isrva" },
|
||||
{ RISCV_GRP_ISRVC, "isrvc" },
|
||||
{ RISCV_GRP_ISRVD, "isrvd" },
|
||||
|
|
@ -257,7 +221,7 @@ static const name_map group_name_maps[] = {
|
|||
{ RISCV_GRP_ISRV64F, "isrv64f" },
|
||||
{ RISCV_GRP_ISRV64M, "isrv64m" }
|
||||
*/
|
||||
{ RISCV_GRP_ENDING, NULL }
|
||||
{ RISCV_GRP_ENDING, NULL }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -265,8 +229,8 @@ const char *RISCV_group_name(csh handle, unsigned int id)
|
|||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
// verify group id
|
||||
if (id >= RISCV_GRP_ENDING ||
|
||||
(id > RISCV_GRP_BRANCH_RELATIVE && id < RISCV_GRP_ISRV32))
|
||||
if (id >= RISCV_GRP_ENDING ||
|
||||
(id > RISCV_GRP_BRANCH_RELATIVE && id < RISCV_GRP_ISRV32))
|
||||
return NULL;
|
||||
return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
|
||||
#else
|
||||
|
|
@ -289,7 +253,8 @@ riscv_reg RISCV_map_insn(const char *name)
|
|||
// map internal raw register to 'public' register
|
||||
riscv_reg RISCV_map_register(unsigned int r)
|
||||
{
|
||||
static const unsigned int map[] = { 0,
|
||||
static const unsigned int map[] = {
|
||||
0,
|
||||
RISCV_REG_X0,
|
||||
RISCV_REG_X1,
|
||||
RISCV_REG_X2,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "../../include/capstone/capstone.h"
|
||||
|
||||
// given internal insn id, return public instruction info
|
||||
void RISCV_get_insn_id(cs_struct * h, cs_insn * insn, unsigned int id);
|
||||
void RISCV_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
||||
|
||||
const char *RISCV_insn_name(csh handle, unsigned int id);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "RISCVMapping.h"
|
||||
#include "RISCVModule.h"
|
||||
|
||||
cs_err RISCV_global_init(cs_struct * ud)
|
||||
cs_err RISCV_global_init(cs_struct *ud)
|
||||
{
|
||||
MCRegisterInfo *mri;
|
||||
mri = cs_mem_malloc(sizeof(*mri));
|
||||
|
|
@ -31,7 +31,7 @@ cs_err RISCV_global_init(cs_struct * ud)
|
|||
return CS_ERR_OK;
|
||||
}
|
||||
|
||||
cs_err RISCV_option(cs_struct * handle, cs_opt_type type, size_t value)
|
||||
cs_err RISCV_option(cs_struct *handle, cs_opt_type type, size_t value)
|
||||
{
|
||||
if (type == CS_OPT_SYNTAX) {
|
||||
handle->syntax = (int)value;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "../../utils.h"
|
||||
|
||||
cs_err RISCV_global_init(cs_struct * ud);
|
||||
cs_err RISCV_option(cs_struct * handle, cs_opt_type type, size_t value);
|
||||
cs_err RISCV_global_init(cs_struct *ud);
|
||||
cs_err RISCV_option(cs_struct *handle, cs_opt_type type, size_t value);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -11,9 +11,10 @@ typedef struct sh_info {
|
|||
} sh_info;
|
||||
|
||||
bool SH_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address, void *info);
|
||||
MCInst *instr, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
|
||||
void SH_reg_access(const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
void SH_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,34 +6,33 @@
|
|||
#include "../../Mapping.h"
|
||||
#include "SHInstPrinter.h"
|
||||
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const char* const s_reg_names[] = {
|
||||
"invalid",
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"r0_bank", "r1_bank", "r2_bank", "r3_bank",
|
||||
"r4_bank", "r5_bank", "r6_bank", "r7_bank",
|
||||
"fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
|
||||
"fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
|
||||
"dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
|
||||
"xd0", "xd2", "xd4", "xd6", "xd8", "xd10", "xd12", "xd14",
|
||||
"xf0", "xf1", "xf2", "xf3", "xf4", "xf5", "xf6", "xf7",
|
||||
"xf8", "xf9", "xf10", "xf11", "xf12", "xf13", "xf14", "xf15",
|
||||
"fv0", "fv4", "fv8", "fv12",
|
||||
"xmtrx",
|
||||
"pc", "pr", "mach", "macl",
|
||||
"sr", "gbr", "ssr", "spc", "sgr", "dbr", "vbr", "tbr",
|
||||
"rs", "re", "mod",
|
||||
"fpul", "fpscr",
|
||||
"x0", "x1", "y0", "y1", "a0", "a1", "a0g", "a1g", "m0", "m1",
|
||||
"dsr",
|
||||
"0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7",
|
||||
"0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf",
|
||||
static const char *const s_reg_names[] = {
|
||||
"invalid", "r0", "r1", "r2", "r3", "r4",
|
||||
"r5", "r6", "r7", "r8", "r9", "r10",
|
||||
"r11", "r12", "r13", "r14", "r15", "r0_bank",
|
||||
"r1_bank", "r2_bank", "r3_bank", "r4_bank", "r5_bank", "r6_bank",
|
||||
"r7_bank", "fr0", "fr1", "fr2", "fr3", "fr4",
|
||||
"fr5", "fr6", "fr7", "fr8", "fr9", "fr10",
|
||||
"fr11", "fr12", "fr13", "fr14", "fr15", "dr0",
|
||||
"dr2", "dr4", "dr6", "dr8", "dr10", "dr12",
|
||||
"dr14", "xd0", "xd2", "xd4", "xd6", "xd8",
|
||||
"xd10", "xd12", "xd14", "xf0", "xf1", "xf2",
|
||||
"xf3", "xf4", "xf5", "xf6", "xf7", "xf8",
|
||||
"xf9", "xf10", "xf11", "xf12", "xf13", "xf14",
|
||||
"xf15", "fv0", "fv4", "fv8", "fv12", "xmtrx",
|
||||
"pc", "pr", "mach", "macl", "sr", "gbr",
|
||||
"ssr", "spc", "sgr", "dbr", "vbr", "tbr",
|
||||
"rs", "re", "mod", "fpul", "fpscr", "x0",
|
||||
"x1", "y0", "y1", "a0", "a1", "a0g",
|
||||
"a1g", "m0", "m1", "dsr", "0x0", "0x1",
|
||||
"0x2", "0x3", "0x4", "0x5", "0x6", "0x7",
|
||||
"0x8", "0x9", "0xa", "0xb", "0xc", "0xd",
|
||||
"0xe", "0xf",
|
||||
};
|
||||
#endif
|
||||
|
||||
const char* SH_reg_name(csh handle, unsigned int reg)
|
||||
const char *SH_reg_name(csh handle, unsigned int reg)
|
||||
{
|
||||
#ifdef CAPSTONE_DIET
|
||||
return NULL;
|
||||
|
|
@ -45,73 +44,44 @@ const char* SH_reg_name(csh handle, unsigned int reg)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
void SH_get_insn_id(cs_struct* h, cs_insn* insn, unsigned int id)
|
||||
void SH_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
||||
{
|
||||
insn->id = id; // These id's matches for sh
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const char* const s_insn_names[] = {
|
||||
"unknown",
|
||||
"add", "add", "addc", "addv", "and",
|
||||
"band", "bandnot", "bclr",
|
||||
"bf", "bf/s", "bld", "bldnot", "bor", "bornot", "bra", "braf",
|
||||
"bset", "bsr", "bsrf", "bst", "bt", "bt/s", "bxor",
|
||||
"clips", "clipu",
|
||||
"clrdmxy",
|
||||
"clrmac", "clrs", "clrt",
|
||||
"cmp/eq", "cmp/ge", "cmp/gt", "cmp/hi", "cmp/hs", "cmp/pl",
|
||||
"cmp/pz", "cmp/str",
|
||||
"div0s", "div0u", "div1",
|
||||
"divs", "divu",
|
||||
"dmuls.l", "dmulu.l",
|
||||
"dt",
|
||||
"exts", "exts", "extu", "extu",
|
||||
"fabs", "fadd", "fcmp/eq", "fcmp/gt",
|
||||
"fcnvds", "fcnvsd", "fdiv",
|
||||
"fipr", "fldi0", "fldi1", "flds", "float",
|
||||
"fmac", "fmov", "fmul", "fneg", "fpchg",
|
||||
"frchg", "fsca", "fschg", "fsqrt", "fsrra",
|
||||
"fsts", "fsub", "ftrc", "ftrv",
|
||||
"icbi",
|
||||
"jmp", "jsr", "jsr/n",
|
||||
"ldbank",
|
||||
"ldc", "ldrc", "ldre", "ldrs", "lds",
|
||||
"ldtlb",
|
||||
"mac.l", "mac.w",
|
||||
"mov", "mova", "movca", "movco", "movi20", "movi20s",
|
||||
"movli", "movml", "movmu", "movrt", "movt", "movu", "movua",
|
||||
"mul.l", "mulr", "muls", "mulu",
|
||||
"neg", "negc",
|
||||
"nop",
|
||||
"not", "nott",
|
||||
"ocbi", "ocbp", "ocbwb",
|
||||
"or",
|
||||
"pref", "prefi",
|
||||
"resbank",
|
||||
"rotcl", "rotcr", "rotl", "rotr",
|
||||
"rte", "rts", "rts/n", "rtv/n",
|
||||
"setdmx", "setdmy", "setrc",
|
||||
"sets", "sett",
|
||||
"shad", "shal", "shar", "shld", "shll",
|
||||
"shll16", "shll2", "shll8",
|
||||
"shlr", "shlr16", "shlr2", "shlr8",
|
||||
"sleep",
|
||||
"stbank",
|
||||
"stc", "sts",
|
||||
"sub", "subc", "subv",
|
||||
"swap", "swap",
|
||||
"synco",
|
||||
"tas",
|
||||
"trapa",
|
||||
"tst",
|
||||
"xor",
|
||||
"xtrct",
|
||||
static const char *const s_insn_names[] = {
|
||||
"unknown", "add", "add", "addc", "addv", "and",
|
||||
"band", "bandnot", "bclr", "bf", "bf/s", "bld",
|
||||
"bldnot", "bor", "bornot", "bra", "braf", "bset",
|
||||
"bsr", "bsrf", "bst", "bt", "bt/s", "bxor",
|
||||
"clips", "clipu", "clrdmxy", "clrmac", "clrs", "clrt",
|
||||
"cmp/eq", "cmp/ge", "cmp/gt", "cmp/hi", "cmp/hs", "cmp/pl",
|
||||
"cmp/pz", "cmp/str", "div0s", "div0u", "div1", "divs",
|
||||
"divu", "dmuls.l", "dmulu.l", "dt", "exts", "exts",
|
||||
"extu", "extu", "fabs", "fadd", "fcmp/eq", "fcmp/gt",
|
||||
"fcnvds", "fcnvsd", "fdiv", "fipr", "fldi0", "fldi1",
|
||||
"flds", "float", "fmac", "fmov", "fmul", "fneg",
|
||||
"fpchg", "frchg", "fsca", "fschg", "fsqrt", "fsrra",
|
||||
"fsts", "fsub", "ftrc", "ftrv", "icbi", "jmp",
|
||||
"jsr", "jsr/n", "ldbank", "ldc", "ldrc", "ldre",
|
||||
"ldrs", "lds", "ldtlb", "mac.l", "mac.w", "mov",
|
||||
"mova", "movca", "movco", "movi20", "movi20s", "movli",
|
||||
"movml", "movmu", "movrt", "movt", "movu", "movua",
|
||||
"mul.l", "mulr", "muls", "mulu", "neg", "negc",
|
||||
"nop", "not", "nott", "ocbi", "ocbp", "ocbwb",
|
||||
"or", "pref", "prefi", "resbank", "rotcl", "rotcr",
|
||||
"rotl", "rotr", "rte", "rts", "rts/n", "rtv/n",
|
||||
"setdmx", "setdmy", "setrc", "sets", "sett", "shad",
|
||||
"shal", "shar", "shld", "shll", "shll16", "shll2",
|
||||
"shll8", "shlr", "shlr16", "shlr2", "shlr8", "sleep",
|
||||
"stbank", "stc", "sts", "sub", "subc", "subv",
|
||||
"swap", "swap", "synco", "tas", "trapa", "tst",
|
||||
"xor", "xtrct",
|
||||
};
|
||||
#endif
|
||||
|
||||
const char* SH_insn_name(csh handle, unsigned int id)
|
||||
const char *SH_insn_name(csh handle, unsigned int id)
|
||||
{
|
||||
#ifdef CAPSTONE_DIET
|
||||
return NULL;
|
||||
|
|
@ -138,7 +108,7 @@ static void print_dsp_double(SStream *O, sh_info *info, int xy)
|
|||
}
|
||||
} else {
|
||||
SStream_concat(O, "mov%c", suffix_xy);
|
||||
switch(info->op.operands[xy].dsp.size) {
|
||||
switch (info->op.operands[xy].dsp.size) {
|
||||
case 16:
|
||||
SStream_concat0(O, ".w ");
|
||||
break;
|
||||
|
|
@ -146,22 +116,31 @@ static void print_dsp_double(SStream *O, sh_info *info, int xy)
|
|||
SStream_concat0(O, ".l ");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
switch(info->op.operands[xy].dsp.operand[i]) {
|
||||
switch (info->op.operands[xy].dsp.operand[i]) {
|
||||
default:
|
||||
break;
|
||||
case SH_OP_DSP_REG_IND:
|
||||
SStream_concat(O, "@%s", s_reg_names[info->op.operands[xy].dsp.r[i]]);
|
||||
SStream_concat(O, "@%s",
|
||||
s_reg_names[info->op.operands[xy]
|
||||
.dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_POST:
|
||||
SStream_concat(O, "@%s+", s_reg_names[info->op.operands[xy].dsp.r[i]]);
|
||||
SStream_concat(O, "@%s+",
|
||||
s_reg_names[info->op.operands[xy]
|
||||
.dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_INDEX:
|
||||
SStream_concat(O, "@%s+%s", s_reg_names[info->op.operands[xy].dsp.r[i]], s_reg_names[SH_REG_R8 + xy]);
|
||||
SStream_concat(O, "@%s+%s",
|
||||
s_reg_names[info->op.operands[xy]
|
||||
.dsp.r[i]],
|
||||
s_reg_names[SH_REG_R8 + xy]);
|
||||
break;
|
||||
case SH_OP_DSP_REG:
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[xy].dsp.r[i]]);
|
||||
SStream_concat(O, "%s",
|
||||
s_reg_names[info->op.operands[xy]
|
||||
.dsp.r[i]]);
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
|
|
@ -173,47 +152,22 @@ static void print_dsp_double(SStream *O, sh_info *info, int xy)
|
|||
}
|
||||
|
||||
static const char *s_dsp_insns[] = {
|
||||
"invalid",
|
||||
"nop",
|
||||
"mov",
|
||||
"pshl",
|
||||
"psha",
|
||||
"pmuls",
|
||||
"pclr_pmuls",
|
||||
"psub_pmuls",
|
||||
"padd_pmuls",
|
||||
"psubc",
|
||||
"paddc",
|
||||
"pcmp",
|
||||
"pabs",
|
||||
"prnd",
|
||||
"psub",
|
||||
"psub",
|
||||
"padd",
|
||||
"pand",
|
||||
"pxor",
|
||||
"por",
|
||||
"pdec",
|
||||
"pinc",
|
||||
"pclr",
|
||||
"pdmsb",
|
||||
"pneg",
|
||||
"pcopy",
|
||||
"psts",
|
||||
"plds",
|
||||
"pswap",
|
||||
"pwad",
|
||||
"invalid", "nop", "mov", "pshl", "psha", "pmuls",
|
||||
"pclr_pmuls", "psub_pmuls", "padd_pmuls", "psubc", "paddc", "pcmp",
|
||||
"pabs", "prnd", "psub", "psub", "padd", "pand",
|
||||
"pxor", "por", "pdec", "pinc", "pclr", "pdmsb",
|
||||
"pneg", "pcopy", "psts", "plds", "pswap", "pwad",
|
||||
"pwsb",
|
||||
};
|
||||
|
||||
static void print_dsp(SStream *O, sh_info *info)
|
||||
{
|
||||
int i;
|
||||
switch(info->op.op_count) {
|
||||
switch (info->op.op_count) {
|
||||
case 1:
|
||||
// single transfer
|
||||
SStream_concat0(O, "movs");
|
||||
switch(info->op.operands[0].dsp.size) {
|
||||
switch (info->op.operands[0].dsp.size) {
|
||||
case 16:
|
||||
SStream_concat0(O, ".w ");
|
||||
break;
|
||||
|
|
@ -222,23 +176,34 @@ static void print_dsp(SStream *O, sh_info *info)
|
|||
break;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
switch(info->op.operands[0].dsp.operand[i]) {
|
||||
switch (info->op.operands[0].dsp.operand[i]) {
|
||||
default:
|
||||
break;
|
||||
case SH_OP_DSP_REG_PRE:
|
||||
SStream_concat(O, "@-%s", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
SStream_concat(O, "@-%s",
|
||||
s_reg_names[info->op.operands[0]
|
||||
.dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_IND:
|
||||
SStream_concat(O, "@%s", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
SStream_concat(O, "@%s",
|
||||
s_reg_names[info->op.operands[0]
|
||||
.dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_POST:
|
||||
SStream_concat(O, "@%s+", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
SStream_concat(O, "@%s+",
|
||||
s_reg_names[info->op.operands[0]
|
||||
.dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_INDEX:
|
||||
SStream_concat(O, "@%s+%s", s_reg_names[info->op.operands[0].dsp.r[i]],s_reg_names[SH_REG_R8]);
|
||||
SStream_concat(O, "@%s+%s",
|
||||
s_reg_names[info->op.operands[0]
|
||||
.dsp.r[i]],
|
||||
s_reg_names[SH_REG_R8]);
|
||||
break;
|
||||
case SH_OP_DSP_REG:
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
SStream_concat(O, "%s",
|
||||
s_reg_names[info->op.operands[0]
|
||||
.dsp.r[i]]);
|
||||
}
|
||||
if (i == 0)
|
||||
SStream_concat0(O, ",");
|
||||
|
|
@ -249,20 +214,20 @@ static void print_dsp(SStream *O, sh_info *info)
|
|||
print_dsp_double(O, info, 1);
|
||||
break;
|
||||
case 3: // Parallel
|
||||
switch(info->op.operands[2].dsp.cc) {
|
||||
switch (info->op.operands[2].dsp.cc) {
|
||||
default:
|
||||
break;
|
||||
case SH_DSP_CC_DCT:
|
||||
SStream_concat0(O,"dct ");
|
||||
SStream_concat0(O, "dct ");
|
||||
break;
|
||||
case SH_DSP_CC_DCF:
|
||||
SStream_concat0(O,"dcf ");
|
||||
SStream_concat0(O, "dcf ");
|
||||
break;
|
||||
}
|
||||
switch(info->op.operands[2].dsp.insn) {
|
||||
switch (info->op.operands[2].dsp.insn) {
|
||||
case SH_INS_DSP_PSUB_PMULS:
|
||||
case SH_INS_DSP_PADD_PMULS:
|
||||
switch(info->op.operands[2].dsp.insn) {
|
||||
switch (info->op.operands[2].dsp.insn) {
|
||||
default:
|
||||
break;
|
||||
case SH_INS_DSP_PSUB_PMULS:
|
||||
|
|
@ -273,39 +238,57 @@ static void print_dsp(SStream *O, sh_info *info)
|
|||
break;
|
||||
}
|
||||
for (i = 0; i < 6; i++) {
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[2].dsp.r[i]]);
|
||||
SStream_concat(O, "%s",
|
||||
s_reg_names[info->op.operands[2]
|
||||
.dsp.r[i]]);
|
||||
if ((i % 3) < 2)
|
||||
SStream_concat0(O, ",");
|
||||
if (i == 2)
|
||||
SStream_concat(O, " %s ", s_dsp_insns[SH_INS_DSP_PMULS]);
|
||||
SStream_concat(
|
||||
O, " %s ",
|
||||
s_dsp_insns[SH_INS_DSP_PMULS]);
|
||||
}
|
||||
break;
|
||||
case SH_INS_DSP_PCLR_PMULS:
|
||||
SStream_concat0(O, s_dsp_insns[SH_INS_DSP_PCLR]);
|
||||
SStream_concat(O, " %s ", s_reg_names[info->op.operands[2].dsp.r[3]]);
|
||||
SStream_concat(
|
||||
O, " %s ",
|
||||
s_reg_names[info->op.operands[2].dsp.r[3]]);
|
||||
SStream_concat(O, "%s ", s_dsp_insns[SH_INS_DSP_PMULS]);
|
||||
for (i = 0; i < 3; i++) {
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[2].dsp.r[i]]);
|
||||
SStream_concat(O, "%s",
|
||||
s_reg_names[info->op.operands[2]
|
||||
.dsp.r[i]]);
|
||||
if (i < 2)
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
SStream_concat0(O, s_dsp_insns[info->op.operands[2].dsp.insn]);
|
||||
SStream_concat0(
|
||||
O, s_dsp_insns[info->op.operands[2].dsp.insn]);
|
||||
SStream_concat0(O, " ");
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (info->op.operands[2].dsp.r[i] == SH_REG_INVALID) {
|
||||
if (info->op.operands[2].dsp.r[i] ==
|
||||
SH_REG_INVALID) {
|
||||
if (i == 0) {
|
||||
SStream_concat(O, "#%d", info->op.operands[2].dsp.imm);
|
||||
SStream_concat(
|
||||
O, "#%d",
|
||||
info->op.operands[2]
|
||||
.dsp.imm);
|
||||
}
|
||||
} else
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[2].dsp.r[i]]);
|
||||
if (i < 2 && info->op.operands[2].dsp.r[i + 1] != SH_REG_INVALID)
|
||||
SStream_concat(
|
||||
O, "%s",
|
||||
s_reg_names[info->op.operands[2]
|
||||
.dsp.r[i]]);
|
||||
if (i < 2 &&
|
||||
info->op.operands[2].dsp.r[i + 1] !=
|
||||
SH_REG_INVALID)
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (info->op.operands[0].dsp.insn != SH_INS_DSP_NOP) {
|
||||
SStream_concat0(O, " ");
|
||||
print_dsp_double(O, info, 0);
|
||||
|
|
@ -318,8 +301,9 @@ static void print_dsp(SStream *O, sh_info *info)
|
|||
}
|
||||
}
|
||||
|
||||
static void PrintMemop(SStream *O, sh_op_mem *op) {
|
||||
switch(op->address) {
|
||||
static void PrintMemop(SStream *O, sh_op_mem *op)
|
||||
{
|
||||
switch (op->address) {
|
||||
case SH_OP_MEM_INVALID:
|
||||
break;
|
||||
case SH_OP_MEM_REG_IND:
|
||||
|
|
@ -334,43 +318,43 @@ static void PrintMemop(SStream *O, sh_op_mem *op) {
|
|||
case SH_OP_MEM_REG_DISP:
|
||||
SStream_concat(O, "@(%d,%s)", op->disp, s_reg_names[op->reg]);
|
||||
break;
|
||||
case SH_OP_MEM_REG_R0: /// <= R0 indexed
|
||||
SStream_concat(O, "@(%s,%s)",
|
||||
s_reg_names[SH_REG_R0], s_reg_names[op->reg]);
|
||||
case SH_OP_MEM_REG_R0: /// <= R0 indexed
|
||||
SStream_concat(O, "@(%s,%s)", s_reg_names[SH_REG_R0],
|
||||
s_reg_names[op->reg]);
|
||||
break;
|
||||
case SH_OP_MEM_GBR_DISP: /// <= GBR based displaysment
|
||||
SStream_concat(O, "@(%d,%s)",
|
||||
op->disp, s_reg_names[SH_REG_GBR]);
|
||||
case SH_OP_MEM_GBR_DISP: /// <= GBR based displaysment
|
||||
SStream_concat(O, "@(%d,%s)", op->disp,
|
||||
s_reg_names[SH_REG_GBR]);
|
||||
break;
|
||||
case SH_OP_MEM_GBR_R0: /// <= GBR based R0 indexed
|
||||
SStream_concat(O, "@(%s,%s)",
|
||||
s_reg_names[SH_REG_R0], s_reg_names[SH_REG_GBR]);
|
||||
case SH_OP_MEM_GBR_R0: /// <= GBR based R0 indexed
|
||||
SStream_concat(O, "@(%s,%s)", s_reg_names[SH_REG_R0],
|
||||
s_reg_names[SH_REG_GBR]);
|
||||
break;
|
||||
case SH_OP_MEM_PCR: /// <= PC relative
|
||||
case SH_OP_MEM_PCR: /// <= PC relative
|
||||
SStream_concat(O, "0x%x", op->disp);
|
||||
break;
|
||||
case SH_OP_MEM_TBR_DISP: /// <= GBR based displaysment
|
||||
SStream_concat(O, "@@(%d,%s)",
|
||||
op->disp, s_reg_names[SH_REG_TBR]);
|
||||
case SH_OP_MEM_TBR_DISP: /// <= GBR based displaysment
|
||||
SStream_concat(O, "@@(%d,%s)", op->disp,
|
||||
s_reg_names[SH_REG_TBR]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void SH_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
||||
void SH_printInst(MCInst *MI, SStream *O, void *PrinterInfo)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
sh_info *info = (sh_info *)PrinterInfo;
|
||||
int i;
|
||||
int imm;
|
||||
|
||||
if (MI->Opcode == SH_INS_DSP) {
|
||||
if (MI->Opcode == SH_INS_DSP) {
|
||||
print_dsp(O, info);
|
||||
return;
|
||||
}
|
||||
|
||||
SStream_concat0(O, (char*)s_insn_names[MI->Opcode]);
|
||||
switch(info->op.size) {
|
||||
|
||||
SStream_concat0(O, (char *)s_insn_names[MI->Opcode]);
|
||||
switch (info->op.size) {
|
||||
case 8:
|
||||
SStream_concat0(O, ".b");
|
||||
break;
|
||||
|
|
@ -386,11 +370,12 @@ void SH_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
}
|
||||
SStream_concat0(O, " ");
|
||||
for (i = 0; i < info->op.op_count; i++) {
|
||||
switch(info->op.operands[i].type) {
|
||||
switch (info->op.operands[i].type) {
|
||||
case SH_OP_INVALID:
|
||||
break;
|
||||
case SH_OP_REG:
|
||||
SStream_concat0(O, s_reg_names[info->op.operands[i].reg]);
|
||||
SStream_concat0(O,
|
||||
s_reg_names[info->op.operands[i].reg]);
|
||||
break;
|
||||
case SH_OP_IMM:
|
||||
imm = info->op.operands[i].imm;
|
||||
|
|
@ -409,13 +394,13 @@ void SH_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map group_name_maps[] = {
|
||||
{ SH_GRP_INVALID , NULL },
|
||||
{ SH_GRP_INVALID, NULL },
|
||||
{ SH_GRP_JUMP, "jump" },
|
||||
{ SH_GRP_CALL, "call" },
|
||||
{ SH_GRP_INT, "int" },
|
||||
{ SH_GRP_RET , "ret" },
|
||||
{ SH_GRP_INT, "int" },
|
||||
{ SH_GRP_RET, "ret" },
|
||||
{ SH_GRP_IRET, "iret" },
|
||||
{ SH_GRP_PRIVILEGE, "privilege" },
|
||||
{ SH_GRP_PRIVILEGE, "privilege" },
|
||||
{ SH_GRP_BRANCH_RELATIVE, "branch_relative" },
|
||||
{ SH_GRP_SH2, "SH2" },
|
||||
{ SH_GRP_SH2E, "SH2E" },
|
||||
|
|
@ -437,4 +422,3 @@ const char *SH_group_name(csh handle, unsigned int id)
|
|||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#ifndef CS_SHINSTPRINTER_H
|
||||
#define CS_SHINSTPRINTER_H
|
||||
|
||||
|
||||
#include "capstone/capstone.h"
|
||||
#include "../../utils.h"
|
||||
#include "../../MCInst.h"
|
||||
|
|
@ -15,9 +14,9 @@
|
|||
struct SStream;
|
||||
|
||||
void SH_printInst(MCInst *MI, struct SStream *O, void *Info);
|
||||
const char* SH_reg_name(csh handle, unsigned int reg);
|
||||
void SH_get_insn_id(cs_struct* h, cs_insn* insn, unsigned int id);
|
||||
const char* SH_insn_name(csh handle, unsigned int id);
|
||||
const char *SH_reg_name(csh handle, unsigned int reg);
|
||||
void SH_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
||||
const char *SH_insn_name(csh handle, unsigned int id);
|
||||
const char *SH_group_name(csh handle, unsigned int id);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ cs_err SH_global_init(cs_struct *ud)
|
|||
ud->group_name = SH_group_name;
|
||||
ud->disasm = SH_getInstruction;
|
||||
#ifndef CAPSTONE_DIET
|
||||
ud->reg_access = SH_reg_access;
|
||||
ud->reg_access = SH_reg_access;
|
||||
#endif
|
||||
|
||||
return CS_ERR_OK;
|
||||
|
|
|
|||
|
|
@ -41,72 +41,83 @@
|
|||
#define DEBUG_TYPE "sparc-disassembler"
|
||||
|
||||
static const unsigned IntRegDecoderTable[] = {
|
||||
Sparc_G0, Sparc_G1, Sparc_G2, Sparc_G3, Sparc_G4, Sparc_G5, Sparc_G6, Sparc_G7,
|
||||
Sparc_O0, Sparc_O1, Sparc_O2, Sparc_O3, Sparc_O4, Sparc_O5, Sparc_O6, Sparc_O7,
|
||||
Sparc_L0, Sparc_L1, Sparc_L2, Sparc_L3, Sparc_L4, Sparc_L5, Sparc_L6, Sparc_L7,
|
||||
Sparc_I0, Sparc_I1, Sparc_I2, Sparc_I3, Sparc_I4, Sparc_I5, Sparc_I6, Sparc_I7
|
||||
Sparc_G0, Sparc_G1, Sparc_G2, Sparc_G3, Sparc_G4, Sparc_G5, Sparc_G6,
|
||||
Sparc_G7, Sparc_O0, Sparc_O1, Sparc_O2, Sparc_O3, Sparc_O4, Sparc_O5,
|
||||
Sparc_O6, Sparc_O7, Sparc_L0, Sparc_L1, Sparc_L2, Sparc_L3, Sparc_L4,
|
||||
Sparc_L5, Sparc_L6, Sparc_L7, Sparc_I0, Sparc_I1, Sparc_I2, Sparc_I3,
|
||||
Sparc_I4, Sparc_I5, Sparc_I6, Sparc_I7
|
||||
};
|
||||
|
||||
static const unsigned FPRegDecoderTable[] = {
|
||||
Sparc_F0, Sparc_F1, Sparc_F2, Sparc_F3, Sparc_F4, Sparc_F5, Sparc_F6, Sparc_F7,
|
||||
Sparc_F8, Sparc_F9, Sparc_F10, Sparc_F11, Sparc_F12, Sparc_F13, Sparc_F14, Sparc_F15,
|
||||
Sparc_F16, Sparc_F17, Sparc_F18, Sparc_F19, Sparc_F20, Sparc_F21, Sparc_F22, Sparc_F23,
|
||||
Sparc_F24, Sparc_F25, Sparc_F26, Sparc_F27, Sparc_F28, Sparc_F29, Sparc_F30, Sparc_F31
|
||||
Sparc_F0, Sparc_F1, Sparc_F2, Sparc_F3, Sparc_F4, Sparc_F5,
|
||||
Sparc_F6, Sparc_F7, Sparc_F8, Sparc_F9, Sparc_F10, Sparc_F11,
|
||||
Sparc_F12, Sparc_F13, Sparc_F14, Sparc_F15, Sparc_F16, Sparc_F17,
|
||||
Sparc_F18, Sparc_F19, Sparc_F20, Sparc_F21, Sparc_F22, Sparc_F23,
|
||||
Sparc_F24, Sparc_F25, Sparc_F26, Sparc_F27, Sparc_F28, Sparc_F29,
|
||||
Sparc_F30, Sparc_F31
|
||||
};
|
||||
|
||||
static const unsigned DFPRegDecoderTable[] = {
|
||||
Sparc_D0, Sparc_D16, Sparc_D1, Sparc_D17, Sparc_D2, Sparc_D18, Sparc_D3, Sparc_D19,
|
||||
Sparc_D4, Sparc_D20, Sparc_D5, Sparc_D21, Sparc_D6, Sparc_D22, Sparc_D7, Sparc_D23,
|
||||
Sparc_D8, Sparc_D24, Sparc_D9, Sparc_D25, Sparc_D10, Sparc_D26, Sparc_D11, Sparc_D27,
|
||||
Sparc_D12, Sparc_D28, Sparc_D13, Sparc_D29, Sparc_D14, Sparc_D30, Sparc_D15, Sparc_D31
|
||||
Sparc_D0, Sparc_D16, Sparc_D1, Sparc_D17, Sparc_D2, Sparc_D18,
|
||||
Sparc_D3, Sparc_D19, Sparc_D4, Sparc_D20, Sparc_D5, Sparc_D21,
|
||||
Sparc_D6, Sparc_D22, Sparc_D7, Sparc_D23, Sparc_D8, Sparc_D24,
|
||||
Sparc_D9, Sparc_D25, Sparc_D10, Sparc_D26, Sparc_D11, Sparc_D27,
|
||||
Sparc_D12, Sparc_D28, Sparc_D13, Sparc_D29, Sparc_D14, Sparc_D30,
|
||||
Sparc_D15, Sparc_D31
|
||||
};
|
||||
|
||||
static const unsigned QFPRegDecoderTable[] = {
|
||||
Sparc_Q0, Sparc_Q8, ~0U, ~0U, Sparc_Q1, Sparc_Q9, ~0U, ~0U,
|
||||
Sparc_Q0, Sparc_Q8, ~0U, ~0U, Sparc_Q1, Sparc_Q9, ~0U, ~0U,
|
||||
Sparc_Q2, Sparc_Q10, ~0U, ~0U, Sparc_Q3, Sparc_Q11, ~0U, ~0U,
|
||||
Sparc_Q4, Sparc_Q12, ~0U, ~0U, Sparc_Q5, Sparc_Q13, ~0U, ~0U,
|
||||
Sparc_Q6, Sparc_Q14, ~0U, ~0U, Sparc_Q7, Sparc_Q15, ~0U, ~0U
|
||||
};
|
||||
|
||||
static const unsigned FCCRegDecoderTable[] = { Sparc_FCC0, Sparc_FCC1, Sparc_FCC2,
|
||||
Sparc_FCC3 };
|
||||
static const unsigned FCCRegDecoderTable[] = { Sparc_FCC0, Sparc_FCC1,
|
||||
Sparc_FCC2, Sparc_FCC3 };
|
||||
|
||||
static const unsigned ASRRegDecoderTable[] = {
|
||||
Sparc_Y, Sparc_ASR1, Sparc_ASR2, Sparc_ASR3, Sparc_ASR4, Sparc_ASR5, Sparc_ASR6,
|
||||
Sparc_ASR7, Sparc_ASR8, Sparc_ASR9, Sparc_ASR10, Sparc_ASR11, Sparc_ASR12, Sparc_ASR13,
|
||||
Sparc_ASR14, Sparc_ASR15, Sparc_ASR16, Sparc_ASR17, Sparc_ASR18, Sparc_ASR19, Sparc_ASR20,
|
||||
Sparc_ASR21, Sparc_ASR22, Sparc_ASR23, Sparc_ASR24, Sparc_ASR25, Sparc_ASR26, Sparc_ASR27,
|
||||
Sparc_ASR28, Sparc_ASR29, Sparc_ASR30, Sparc_ASR31
|
||||
Sparc_Y, Sparc_ASR1, Sparc_ASR2, Sparc_ASR3, Sparc_ASR4,
|
||||
Sparc_ASR5, Sparc_ASR6, Sparc_ASR7, Sparc_ASR8, Sparc_ASR9,
|
||||
Sparc_ASR10, Sparc_ASR11, Sparc_ASR12, Sparc_ASR13, Sparc_ASR14,
|
||||
Sparc_ASR15, Sparc_ASR16, Sparc_ASR17, Sparc_ASR18, Sparc_ASR19,
|
||||
Sparc_ASR20, Sparc_ASR21, Sparc_ASR22, Sparc_ASR23, Sparc_ASR24,
|
||||
Sparc_ASR25, Sparc_ASR26, Sparc_ASR27, Sparc_ASR28, Sparc_ASR29,
|
||||
Sparc_ASR30, Sparc_ASR31
|
||||
};
|
||||
|
||||
static const unsigned PRRegDecoderTable[] = {
|
||||
Sparc_TPC, Sparc_TNPC, Sparc_TSTATE, Sparc_TT, Sparc_TICK,
|
||||
Sparc_TBA, Sparc_PSTATE, Sparc_TL, Sparc_PIL, Sparc_CWP,
|
||||
Sparc_CANSAVE, Sparc_CANRESTORE, Sparc_CLEANWIN, Sparc_OTHERWIN, Sparc_WSTATE
|
||||
Sparc_TPC, Sparc_TNPC, Sparc_TSTATE, Sparc_TT,
|
||||
Sparc_TICK, Sparc_TBA, Sparc_PSTATE, Sparc_TL,
|
||||
Sparc_PIL, Sparc_CWP, Sparc_CANSAVE, Sparc_CANRESTORE,
|
||||
Sparc_CLEANWIN, Sparc_OTHERWIN, Sparc_WSTATE
|
||||
};
|
||||
|
||||
static const uint16_t IntPairDecoderTable[] = {
|
||||
Sparc_G0_G1, Sparc_G2_G3, Sparc_G4_G5, Sparc_G6_G7, Sparc_O0_O1, Sparc_O2_O3,
|
||||
Sparc_O4_O5, Sparc_O6_O7, Sparc_L0_L1, Sparc_L2_L3, Sparc_L4_L5, Sparc_L6_L7,
|
||||
Sparc_G0_G1, Sparc_G2_G3, Sparc_G4_G5, Sparc_G6_G7,
|
||||
Sparc_O0_O1, Sparc_O2_O3, Sparc_O4_O5, Sparc_O6_O7,
|
||||
Sparc_L0_L1, Sparc_L2_L3, Sparc_L4_L5, Sparc_L6_L7,
|
||||
Sparc_I0_I1, Sparc_I2_I3, Sparc_I4_I5, Sparc_I6_I7,
|
||||
};
|
||||
|
||||
static const unsigned CPRegDecoderTable[] = {
|
||||
Sparc_C0, Sparc_C1, Sparc_C2, Sparc_C3, Sparc_C4, Sparc_C5, Sparc_C6, Sparc_C7,
|
||||
Sparc_C8, Sparc_C9, Sparc_C10, Sparc_C11, Sparc_C12, Sparc_C13, Sparc_C14, Sparc_C15,
|
||||
Sparc_C16, Sparc_C17, Sparc_C18, Sparc_C19, Sparc_C20, Sparc_C21, Sparc_C22, Sparc_C23,
|
||||
Sparc_C24, Sparc_C25, Sparc_C26, Sparc_C27, Sparc_C28, Sparc_C29, Sparc_C30, Sparc_C31
|
||||
Sparc_C0, Sparc_C1, Sparc_C2, Sparc_C3, Sparc_C4, Sparc_C5,
|
||||
Sparc_C6, Sparc_C7, Sparc_C8, Sparc_C9, Sparc_C10, Sparc_C11,
|
||||
Sparc_C12, Sparc_C13, Sparc_C14, Sparc_C15, Sparc_C16, Sparc_C17,
|
||||
Sparc_C18, Sparc_C19, Sparc_C20, Sparc_C21, Sparc_C22, Sparc_C23,
|
||||
Sparc_C24, Sparc_C25, Sparc_C26, Sparc_C27, Sparc_C28, Sparc_C29,
|
||||
Sparc_C30, Sparc_C31
|
||||
};
|
||||
|
||||
static const uint16_t CPPairDecoderTable[] = {
|
||||
Sparc_C0_C1, Sparc_C2_C3, Sparc_C4_C5, Sparc_C6_C7, Sparc_C8_C9, Sparc_C10_C11,
|
||||
Sparc_C12_C13, Sparc_C14_C15, Sparc_C16_C17, Sparc_C18_C19, Sparc_C20_C21, Sparc_C22_C23,
|
||||
Sparc_C0_C1, Sparc_C2_C3, Sparc_C4_C5, Sparc_C6_C7,
|
||||
Sparc_C8_C9, Sparc_C10_C11, Sparc_C12_C13, Sparc_C14_C15,
|
||||
Sparc_C16_C17, Sparc_C18_C19, Sparc_C20_C21, Sparc_C22_C23,
|
||||
Sparc_C24_C25, Sparc_C26_C27, Sparc_C28_C29, Sparc_C30_C31
|
||||
};
|
||||
|
||||
static DecodeStatus DecodeDisp19(MCInst *Inst, uint32_t ImmVal,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
int64_t BranchTarget = Address + (SignExtend64(ImmVal, 19) * 4);
|
||||
MCOperand_CreateImm0(Inst, BranchTarget);
|
||||
|
|
@ -114,8 +125,7 @@ static DecodeStatus DecodeDisp19(MCInst *Inst, uint32_t ImmVal,
|
|||
}
|
||||
|
||||
static DecodeStatus DecodeDisp16(MCInst *Inst, uint32_t ImmVal,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
int64_t BranchTarget = Address + (SignExtend64(ImmVal, 16) * 4);
|
||||
MCOperand_CreateImm0(Inst, BranchTarget);
|
||||
|
|
@ -123,8 +133,7 @@ static DecodeStatus DecodeDisp16(MCInst *Inst, uint32_t ImmVal,
|
|||
}
|
||||
|
||||
static DecodeStatus DecodeDisp22(MCInst *Inst, uint32_t ImmVal,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
int64_t BranchTarget = Address + (SignExtend64(ImmVal, 22) * 4);
|
||||
MCOperand_CreateImm0(Inst, BranchTarget);
|
||||
|
|
@ -271,8 +280,9 @@ static DecodeStatus DecodeSIMM13(MCInst *Inst, unsigned insn, uint64_t Address,
|
|||
|
||||
#include "SparcGenDisassemblerTables.inc"
|
||||
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address, SStream *CStream)
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size,
|
||||
const uint8_t *Bytes, size_t BytesLen,
|
||||
uint64_t Address, SStream *CStream)
|
||||
{
|
||||
if (BytesLen < 4) {
|
||||
return MCDisassembler_Fail;
|
||||
|
|
@ -333,10 +343,13 @@ static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn, uint64_t Address,
|
|||
}
|
||||
|
||||
DecodeStatus Sparc_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||
size_t ByteLen, MCInst *MI, uint16_t *Size,
|
||||
uint64_t Address, void *Info) {
|
||||
size_t ByteLen, MCInst *MI,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
void *Info)
|
||||
{
|
||||
uint64_t s = 0;
|
||||
DecodeStatus status = getInstruction(MI, &s, Bytes, ByteLen, Address, NULL);
|
||||
*Size = (uint16_t) s;
|
||||
DecodeStatus status =
|
||||
getInstruction(MI, &s, Bytes, ByteLen, Address, NULL);
|
||||
*Size = (uint16_t)s;
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,10 +42,9 @@
|
|||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
|
||||
static void printCustomAliasOperand(
|
||||
MCInst *MI, uint64_t Address, unsigned OpIdx,
|
||||
unsigned PrintMethodIdx,
|
||||
SStream *OS);
|
||||
static void printCustomAliasOperand(MCInst *MI, uint64_t Address,
|
||||
unsigned OpIdx, unsigned PrintMethodIdx,
|
||||
SStream *OS);
|
||||
static void printOperand(MCInst *MI, int opNum, SStream *O);
|
||||
|
||||
#define GET_INSTRUCTION_NAME
|
||||
|
|
@ -70,8 +69,7 @@ static void printInst(MCInst *MI, uint64_t Address, SStream *O)
|
|||
bool useAliasDetails = map_use_alias_details(MI);
|
||||
map_set_fill_detail_ops(MI, useAliasDetails);
|
||||
|
||||
if (!printAliasInstr(MI, Address, O) &&
|
||||
!printSparcAliasInstr(MI, O)) {
|
||||
if (!printAliasInstr(MI, Address, O) && !printSparcAliasInstr(MI, O)) {
|
||||
MCInst_setIsAlias(MI, false);
|
||||
} else {
|
||||
isAlias = true;
|
||||
|
|
@ -135,9 +133,11 @@ bool printSparcAliasInstr(MCInst *MI, SStream *O)
|
|||
case Sparc_V9FCMPES:
|
||||
case Sparc_V9FCMPED:
|
||||
case Sparc_V9FCMPEQ: {
|
||||
if (Sparc_getFeatureBits(MI->csh->mode, Sparc_FeatureV9) || (MCInst_getNumOperands(MI) != 3) ||
|
||||
if (Sparc_getFeatureBits(MI->csh->mode, Sparc_FeatureV9) ||
|
||||
(MCInst_getNumOperands(MI) != 3) ||
|
||||
(!MCOperand_isReg(MCInst_getOperand(MI, (0)))) ||
|
||||
(MCOperand_getReg(MCInst_getOperand(MI, (0))) != Sparc_FCC0))
|
||||
(MCOperand_getReg(MCInst_getOperand(MI, (0))) !=
|
||||
Sparc_FCC0))
|
||||
return false;
|
||||
// if V8, skip printing %fcc0.
|
||||
switch (MCInst_getOpcode(MI)) {
|
||||
|
|
@ -263,7 +263,8 @@ void printCCOperand(MCInst *MI, int opNum, SStream *O)
|
|||
case Sparc_CBCOND:
|
||||
case Sparc_CBCONDA:
|
||||
// Make sure CC is a cp conditional flag.
|
||||
CC = (CC < SPARC_CC_CPCC_BEGIN) ? (CC + SPARC_CC_CPCC_BEGIN) : CC;
|
||||
CC = (CC < SPARC_CC_CPCC_BEGIN) ? (CC + SPARC_CC_CPCC_BEGIN) :
|
||||
CC;
|
||||
break;
|
||||
case Sparc_BPR:
|
||||
case Sparc_BPRA:
|
||||
|
|
@ -319,7 +320,8 @@ void printASITag(MCInst *MI, int opNum, SStream *O)
|
|||
{
|
||||
Sparc_add_cs_detail_0(MI, Sparc_OP_GROUP_ASITag, opNum);
|
||||
unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (opNum)));
|
||||
const Sparc_ASITag_ASITag *ASITag = Sparc_ASITag_lookupASITagByEncoding(Imm);
|
||||
const Sparc_ASITag_ASITag *ASITag =
|
||||
Sparc_ASITag_lookupASITagByEncoding(Imm);
|
||||
if (Sparc_getFeatureBits(MI->csh->mode, Sparc_FeatureV9) && ASITag) {
|
||||
SStream_concat1(O, '#');
|
||||
SStream_concat0(O, ASITag->Name);
|
||||
|
|
@ -327,9 +329,8 @@ void printASITag(MCInst *MI, int opNum, SStream *O)
|
|||
printUInt32(O, Imm);
|
||||
}
|
||||
|
||||
|
||||
void Sparc_LLVM_printInst(MCInst *MI, uint64_t Address, const char *Annot,
|
||||
SStream *O)
|
||||
SStream *O)
|
||||
{
|
||||
printInst(MI, Address, O);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,13 @@
|
|||
#include "../../SStream.h"
|
||||
|
||||
DecodeStatus Sparc_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||
size_t ByteLen, MCInst *MI, uint16_t *Size,
|
||||
uint64_t Address, void *Info);
|
||||
size_t ByteLen, MCInst *MI,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
void *Info);
|
||||
const char *Sparc_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx);
|
||||
void Sparc_LLVM_printInstruction(MCInst *MI, SStream *O,
|
||||
void * /* MCRegisterInfo* */ info);
|
||||
void * /* MCRegisterInfo* */ info);
|
||||
void Sparc_LLVM_printInst(MCInst *MI, uint64_t Address, const char *Annot,
|
||||
SStream *O);
|
||||
SStream *O);
|
||||
|
||||
#endif // CS_SPARC_LINKAGE_H
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ void Sparc_init_cs_detail(MCInst *MI)
|
|||
if (!detail_is_set(MI)) {
|
||||
return;
|
||||
}
|
||||
memset(get_detail(MI), 0, offsetof(cs_detail, sparc) + sizeof(cs_sparc));
|
||||
memset(get_detail(MI), 0,
|
||||
offsetof(cs_detail, sparc) + sizeof(cs_sparc));
|
||||
Sparc_get_detail(MI)->cc = SPARC_CC_UNDEF;
|
||||
Sparc_get_detail(MI)->cc_field = SPARC_CC_FIELD_NONE;
|
||||
}
|
||||
|
|
@ -62,7 +63,8 @@ static void Sparc_add_bit_details(MCInst *MI, const uint8_t *Bytes,
|
|||
//
|
||||
// See: Opcode Maps - Table 39 - Sparc V9 ISA
|
||||
size_t op2 = get_insn_field_r(insn, 22, 24);
|
||||
detail->cc_field = op2 == 6 ? SPARC_CC_FIELD_FCC0 : SPARC_CC_FIELD_ICC;
|
||||
detail->cc_field = op2 == 6 ? SPARC_CC_FIELD_FCC0 :
|
||||
SPARC_CC_FIELD_ICC;
|
||||
break;
|
||||
}
|
||||
case SPARC_INSN_FORM_F2_3:
|
||||
|
|
@ -150,9 +152,9 @@ static void Sparc_add_bit_details(MCInst *MI, const uint8_t *Bytes,
|
|||
case SPARC_INSN_FORM_F2_3:
|
||||
case SPARC_INSN_FORM_F2_4:
|
||||
detail->hint = get_insn_field_r(insn, 29, 29);
|
||||
detail->hint |=
|
||||
get_insn_field_r(insn, 19, 19) == 0 ? SPARC_HINT_PN :
|
||||
SPARC_HINT_PT;
|
||||
detail->hint |= get_insn_field_r(insn, 19, 19) == 0 ?
|
||||
SPARC_HINT_PN :
|
||||
SPARC_HINT_PT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -231,8 +233,8 @@ static void insert_op(MCInst *MI, unsigned index, cs_sparc_op op)
|
|||
/// Inserts a register to the detail operands at @index.
|
||||
/// Already present operands are moved.
|
||||
/// If @index is -1 the operand is appended.
|
||||
static void Sparc_insert_detail_op_reg_at(MCInst *MI, unsigned index, sparc_reg Reg,
|
||||
cs_ac_type access)
|
||||
static void Sparc_insert_detail_op_reg_at(MCInst *MI, unsigned index,
|
||||
sparc_reg Reg, cs_ac_type access)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
|
|
@ -268,21 +270,24 @@ static void Sparc_correct_details(MCInst *MI)
|
|||
case Sparc_PWRPSRrr:
|
||||
case Sparc_WRPSRri:
|
||||
case Sparc_WRPSRrr:
|
||||
Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_PSR, CS_AC_WRITE);
|
||||
Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_PSR,
|
||||
CS_AC_WRITE);
|
||||
break;
|
||||
case Sparc_RDWIM:
|
||||
Sparc_insert_detail_op_reg_at(MI, 0, SPARC_REG_WIM, CS_AC_READ);
|
||||
break;
|
||||
case Sparc_WRWIMri:
|
||||
case Sparc_WRWIMrr:
|
||||
Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_WIM, CS_AC_WRITE);
|
||||
Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_WIM,
|
||||
CS_AC_WRITE);
|
||||
break;
|
||||
case Sparc_RDTBR:
|
||||
Sparc_insert_detail_op_reg_at(MI, 0, SPARC_REG_TBR, CS_AC_READ);
|
||||
break;
|
||||
case Sparc_WRTBRri:
|
||||
case Sparc_WRTBRrr:
|
||||
Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_TBR, CS_AC_WRITE);
|
||||
Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_TBR,
|
||||
CS_AC_WRITE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -376,7 +381,8 @@ void Sparc_set_detail_op_reg(MCInst *MI, unsigned OpNum, sparc_reg Reg)
|
|||
default:
|
||||
Sparc_get_detail_op(MI, 0)->type = SPARC_OP_REG;
|
||||
Sparc_get_detail_op(MI, 0)->reg = Reg;
|
||||
Sparc_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
|
||||
Sparc_get_detail_op(MI, 0)->access =
|
||||
map_get_op_access(MI, OpNum);
|
||||
Sparc_inc_op_count(MI);
|
||||
return;
|
||||
// The LLVM definition is inconsistent with the cc fields.
|
||||
|
|
@ -411,7 +417,8 @@ static inline bool is_single_reg_mem_case(MCInst *MI, unsigned OpNo)
|
|||
}
|
||||
if (MI->size == 1) {
|
||||
return true;
|
||||
} else if (MI->size > OpNo + 1 && Sparc_get_detail(MI)->operands[0].type != SPARC_OP_MEM) {
|
||||
} else if (MI->size > OpNo + 1 &&
|
||||
Sparc_get_detail(MI)->operands[0].type != SPARC_OP_MEM) {
|
||||
// Next operand is not a memory operand (disponent or index reg).
|
||||
return !(map_get_op_type(MI, OpNo + 1) & SPARC_OP_MEM);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue