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:
Rot127 2025-08-27 08:50:50 +00:00 committed by GitHub
parent f557fa229e
commit 40f54ce821
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
241 changed files with 23565 additions and 18800 deletions

View file

@ -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

View file

@ -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
View 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

View file

@ -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() }}

View file

@ -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

View file

@ -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

View file

@ -11,4 +11,3 @@ typedef enum DecodeStatus {
} DecodeStatus;
#endif

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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];
}

View file

@ -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

View file

@ -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];
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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,

View file

@ -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

View file

@ -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) {

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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

View file

@ -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 = \

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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

View file

@ -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));

View file

@ -4,7 +4,6 @@
#ifndef CS_EVMINSTPRINTER_H
#define CS_EVMINSTPRINTER_H
#include "capstone/capstone.h"
#include "../../MCInst.h"
#include "../../SStream.h"

View file

@ -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" },

View file

@ -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

View file

@ -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:

View file

@ -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') {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -42,4 +42,3 @@ cs_err M68K_option(cs_struct *handle, cs_opt_type type, size_t value)
}
#endif

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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";

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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); \

View file

@ -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));

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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