arm64: update core. this added a lot more details to cs_arm64_op struct

This commit is contained in:
Nguyen Anh Quynh 2014-08-25 16:47:12 +08:00
parent ffb6b23c7d
commit 46a74e53b7
24 changed files with 39630 additions and 40169 deletions

View File

@ -414,4 +414,26 @@ static inline int64_t SignExtend64(uint64_t X, unsigned B) {
return (int64_t)(X << (64 - B)) >> (64 - B);
}
/// \brief Count number of 0's from the most significant bit to the least
/// stopping at the first 1.
///
/// Only unsigned integral types are allowed.
///
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments.
static inline unsigned int countLeadingZeros(int x)
{
unsigned count = 0;
int i;
const unsigned bits = sizeof(x) * 8;
for (i = bits; --i; ) {
if (x < 0) break;
count++;
x <<= 1;
}
return count;
}
#endif

View File

@ -2,12 +2,14 @@
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdint.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "SStream.h"
#include "cs_priv.h"
#include "utils.h"
#ifdef _MSC_VER
#pragma warning(disable: 4996) // disable MSVC's warning on strcpy()
@ -40,6 +42,84 @@ void SStream_concat(SStream *ss, const char *fmt, ...)
#endif
}
// print number with prefix #
void printInt64Bang(SStream *O, int64_t val)
{
if (val >= 0) {
if (val > HEX_THRESHOLD)
SStream_concat(O, "#0x%"PRIx64, val);
else
SStream_concat(O, "#%"PRIu64, val);
} else {
if (val <- HEX_THRESHOLD)
SStream_concat(O, "#-0x%"PRIx64, -val);
else
SStream_concat(O, "#-%"PRIu64, -val);
}
}
// print number
void printInt64(SStream *O, int64_t val)
{
if (val >= 0) {
if (val > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, val);
else
SStream_concat(O, "%"PRIu64, val);
} else {
if (val <- HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -val);
else
SStream_concat(O, "-%"PRIu64, -val);
}
}
void printInt32Bang(SStream *O, int32_t val)
{
if (val >= 0) {
if (val > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", val);
else
SStream_concat(O, "#%u", val);
} else {
if (val <- HEX_THRESHOLD)
SStream_concat(O, "#-0x%x", -val);
else
SStream_concat(O, "#-%u", -val);
}
}
void printInt32(SStream *O, int32_t val)
{
if (val >= 0) {
if (val > HEX_THRESHOLD)
SStream_concat(O, "0x%x", val);
else
SStream_concat(O, "%u", val);
} else {
if (val <- HEX_THRESHOLD)
SStream_concat(O, "-0x%x", -val);
else
SStream_concat(O, "-%u", -val);
}
}
void printUInt32Bang(SStream *O, uint32_t val)
{
if (val > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", val);
else
SStream_concat(O, "#%u", val);
}
void printUInt32(SStream *O, uint32_t val)
{
if (val > HEX_THRESHOLD)
SStream_concat(O, "0x%x", val);
else
SStream_concat(O, "%u", val);
}
/*
int main()
{

View File

@ -15,4 +15,16 @@ void SStream_concat(SStream *ss, const char *fmt, ...);
void SStream_concat0(SStream *ss, char *s);
void printInt64Bang(SStream *O, int64_t val);
void printInt64(SStream *O, int64_t val);
void printInt32Bang(SStream *O, int32_t val);
void printInt32(SStream *O, int32_t val);
void printUInt32Bang(SStream *O, uint32_t val);
void printUInt32(SStream *O, uint32_t val);
#endif

View File

@ -0,0 +1,224 @@
//===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the AArch64 addressing mode implementation stuff.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64ADDRESSINGMODES_H
#define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64ADDRESSINGMODES_H
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014 */
#include "../../MathExtras.h"
/// AArch64_AM - AArch64 Addressing Mode Stuff
//===----------------------------------------------------------------------===//
// Shifts
//
typedef enum AArch64_AM_ShiftExtendType {
AArch64_AM_InvalidShiftExtend = -1,
AArch64_AM_LSL = 0,
AArch64_AM_LSR,
AArch64_AM_ASR,
AArch64_AM_ROR,
AArch64_AM_MSL,
AArch64_AM_UXTB,
AArch64_AM_UXTH,
AArch64_AM_UXTW,
AArch64_AM_UXTX,
AArch64_AM_SXTB,
AArch64_AM_SXTH,
AArch64_AM_SXTW,
AArch64_AM_SXTX,
} AArch64_AM_ShiftExtendType;
/// getShiftName - Get the string encoding for the shift type.
static inline const char *AArch64_AM_getShiftExtendName(AArch64_AM_ShiftExtendType ST)
{
switch (ST) {
default: return NULL; // never reach
case AArch64_AM_LSL: return "lsl";
case AArch64_AM_LSR: return "lsr";
case AArch64_AM_ASR: return "asr";
case AArch64_AM_ROR: return "ror";
case AArch64_AM_MSL: return "msl";
case AArch64_AM_UXTB: return "uxtb";
case AArch64_AM_UXTH: return "uxth";
case AArch64_AM_UXTW: return "uxtw";
case AArch64_AM_UXTX: return "uxtx";
case AArch64_AM_SXTB: return "sxtb";
case AArch64_AM_SXTH: return "sxth";
case AArch64_AM_SXTW: return "sxtw";
case AArch64_AM_SXTX: return "sxtx";
}
}
/// getShiftType - Extract the shift type.
static inline AArch64_AM_ShiftExtendType AArch64_AM_getShiftType(unsigned Imm)
{
switch ((Imm >> 6) & 0x7) {
default: return AArch64_AM_InvalidShiftExtend;
case 0: return AArch64_AM_LSL;
case 1: return AArch64_AM_LSR;
case 2: return AArch64_AM_ASR;
case 3: return AArch64_AM_ROR;
case 4: return AArch64_AM_MSL;
}
}
/// getShiftValue - Extract the shift value.
static inline unsigned AArch64_AM_getShiftValue(unsigned Imm)
{
return Imm & 0x3f;
}
//===----------------------------------------------------------------------===//
// Extends
//
/// getArithShiftValue - get the arithmetic shift value.
static inline unsigned AArch64_AM_getArithShiftValue(unsigned Imm)
{
return Imm & 0x7;
}
/// getExtendType - Extract the extend type for operands of arithmetic ops.
static inline AArch64_AM_ShiftExtendType AArch64_AM_getExtendType(unsigned Imm)
{
// assert((Imm & 0x7) == Imm && "invalid immediate!");
switch (Imm) {
default: // llvm_unreachable("Compiler bug!");
case 0: return AArch64_AM_UXTB;
case 1: return AArch64_AM_UXTH;
case 2: return AArch64_AM_UXTW;
case 3: return AArch64_AM_UXTX;
case 4: return AArch64_AM_SXTB;
case 5: return AArch64_AM_SXTH;
case 6: return AArch64_AM_SXTW;
case 7: return AArch64_AM_SXTX;
}
}
static inline AArch64_AM_ShiftExtendType AArch64_AM_getArithExtendType(unsigned Imm)
{
return AArch64_AM_getExtendType((Imm >> 3) & 0x7);
}
static inline uint64_t ror(uint64_t elt, unsigned size)
{
return ((elt & 1) << (size-1)) | (elt >> 1);
}
/// decodeLogicalImmediate - Decode a logical immediate value in the form
/// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the
/// integer value it represents with regSize bits.
static inline uint64_t AArch64_AM_decodeLogicalImmediate(uint64_t val, unsigned regSize)
{
// Extract the N, imms, and immr fields.
unsigned N = (val >> 12) & 1;
unsigned immr = (val >> 6) & 0x3f;
unsigned imms = val & 0x3f;
// assert((regSize == 64 || N == 0) && "undefined logical immediate encoding");
int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
// assert(len >= 0 && "undefined logical immediate encoding");
unsigned size = (1 << len);
unsigned R = immr & (size - 1);
unsigned S = imms & (size - 1);
// assert(S != size - 1 && "undefined logical immediate encoding");
uint64_t pattern = (1ULL << (S + 1)) - 1;
for (unsigned i = 0; i < R; ++i)
pattern = ror(pattern, size);
// Replicate the pattern to fill the regSize.
while (size != regSize) {
pattern |= (pattern << size);
size *= 2;
}
return pattern;
}
/// isValidDecodeLogicalImmediate - Check to see if the logical immediate value
/// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits)
/// is a valid encoding for an integer value with regSize bits.
static inline bool AArch64_AM_isValidDecodeLogicalImmediate(uint64_t val, unsigned regSize)
{
// Extract the N and imms fields needed for checking.
unsigned N = (val >> 12) & 1;
unsigned imms = val & 0x3f;
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
return false;
unsigned size = (1 << len);
unsigned S = imms & (size - 1);
if (S == size - 1) // undefined logical immediate encoding
return false;
return true;
}
//===----------------------------------------------------------------------===//
// Floating-point Immediates
//
static inline float AArch64_AM_getFPImmFloat(unsigned Imm)
{
// We expect an 8-bit binary encoding of a floating-point number here.
union {
uint32_t I;
float F;
} FPUnion;
uint8_t Sign = (Imm >> 7) & 0x1;
uint8_t Exp = (Imm >> 4) & 0x7;
uint8_t Mantissa = Imm & 0xf;
// 8-bit FP iEEEE Float Encoding
// abcd efgh aBbbbbbc defgh000 00000000 00000000
//
// where B = NOT(b);
FPUnion.I = 0;
FPUnion.I |= Sign << 31;
FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
FPUnion.I |= (Exp & 0x3) << 23;
FPUnion.I |= Mantissa << 19;
return FPUnion.F;
}
//===--------------------------------------------------------------------===//
// AdvSIMD Modified Immediates
//===--------------------------------------------------------------------===//
static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType10(uint8_t Imm)
{
uint64_t EncVal = 0;
if (Imm & 0x80) EncVal |= 0xff00000000000000ULL;
if (Imm & 0x40) EncVal |= 0x00ff000000000000ULL;
if (Imm & 0x20) EncVal |= 0x0000ff0000000000ULL;
if (Imm & 0x10) EncVal |= 0x000000ff00000000ULL;
if (Imm & 0x08) EncVal |= 0x00000000ff000000ULL;
if (Imm & 0x04) EncVal |= 0x0000000000ff0000ULL;
if (Imm & 0x02) EncVal |= 0x000000000000ff00ULL;
if (Imm & 0x01) EncVal |= 0x00000000000000ffULL;
return EncVal;
}
#endif

View File

@ -27,7 +27,7 @@
#include "AArch64BaseInfo.h"
char *NamedImmMapper_toString(NamedImmMapper *N, uint32_t Value, bool *Valid)
char *A64NamedImmMapper_toString(A64NamedImmMapper *N, uint32_t Value, bool *Valid)
{
unsigned i;
for (i = 0; i < N->NumPairs; ++i) {
@ -56,7 +56,7 @@ static bool compare_lower_str(char *s1, char *s2)
return res;
}
uint32_t NamedImmMapper_fromString(NamedImmMapper *N, char *Name, bool *Valid)
uint32_t A64NamedImmMapper_fromString(A64NamedImmMapper *N, char *Name, bool *Valid)
{
unsigned i;
for (i = 0; i < N->NumPairs; ++i) {
@ -70,7 +70,7 @@ uint32_t NamedImmMapper_fromString(NamedImmMapper *N, char *Name, bool *Valid)
return (uint32_t)-1;
}
bool NamedImmMapper_validImm(NamedImmMapper *N, uint32_t Value)
bool A64NamedImmMapper_validImm(A64NamedImmMapper *N, uint32_t Value)
{
return Value < N->TooBigImm;
}
@ -97,7 +97,7 @@ static char *utostr(uint64_t X, bool isNeg)
return result;
}
static NamedImmMapper_Mapping SysRegPairs[] = {
static A64NamedImmMapper_Mapping SysRegPairs[] = {
{"osdtrrx_el1", A64SysReg_OSDTRRX_EL1},
{"osdtrtx_el1", A64SysReg_OSDTRTX_EL1},
{"teecr32_el1", A64SysReg_TEECR32_EL1},
@ -576,14 +576,19 @@ static NamedImmMapper_Mapping SysRegPairs[] = {
{"ich_lr15_el2", A64SysReg_ICH_LR15_EL2}
};
static A64NamedImmMapper_Mapping CycloneSysRegPairs[] = {
{"cpm_ioacc_ctl_el3", A64SysReg_CPM_IOACC_CTL_EL3}
};
// result must be a big enough buffer: 128 bytes is more than enough
void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *result)
void A64SysRegMapper_toString(A64SysRegMapper *S, uint32_t Bits, bool *Valid, char *result)
{
int dummy;
uint32_t Op0, Op1, CRn, CRm, Op2;
char *Op1S, *CRnS, *CRmS, *Op2S;
unsigned i;
// First search the registers shared by all
for (i = 0; i < ARR_SIZE(SysRegPairs); ++i) {
if (SysRegPairs[i].Value == Bits) {
*Valid = true;
@ -592,6 +597,20 @@ void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *re
}
}
// Next search for target specific registers
// if (FeatureBits & AArch64_ProcCyclone) {
if (true) {
for (i = 0; i < ARR_SIZE(CycloneSysRegPairs); ++i) {
if (CycloneSysRegPairs[i].Value == Bits) {
*Valid = true;
strcpy(result, CycloneSysRegPairs[i].Name);
return;
}
}
}
// Now try the instruction-specific registers (either read-only or
// write-only).
for (i = 0; i < S->NumInstPairs; ++i) {
if (S->InstPairs[i].Value == Bits) {
*Valid = true;
@ -632,7 +651,7 @@ void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *re
cs_mem_free(Op2S);
}
static NamedImmMapper_Mapping TLBIPairs[] = {
static A64NamedImmMapper_Mapping TLBIPairs[] = {
{"ipas2e1is", A64TLBI_IPAS2E1IS},
{"ipas2le1is", A64TLBI_IPAS2LE1IS},
{"vmalle1is", A64TLBI_VMALLE1IS},
@ -667,13 +686,13 @@ static NamedImmMapper_Mapping TLBIPairs[] = {
{"vaale1", A64TLBI_VAALE1}
};
NamedImmMapper A64TLBI_TLBIMapper = {
A64NamedImmMapper A64TLBI_TLBIMapper = {
TLBIPairs,
ARR_SIZE(TLBIPairs),
0,
};
static NamedImmMapper_Mapping ATPairs[] = {
static A64NamedImmMapper_Mapping ATPairs[] = {
{"s1e1r", A64AT_S1E1R},
{"s1e2r", A64AT_S1E2R},
{"s1e3r", A64AT_S1E3R},
@ -688,13 +707,13 @@ static NamedImmMapper_Mapping ATPairs[] = {
{"s12e0w", A64AT_S12E0W},
};
NamedImmMapper A64AT_ATMapper = {
A64NamedImmMapper A64AT_ATMapper = {
ATPairs,
ARR_SIZE(ATPairs),
0,
};
static NamedImmMapper_Mapping DBarrierPairs[] = {
static A64NamedImmMapper_Mapping DBarrierPairs[] = {
{"oshld", A64DB_OSHLD},
{"oshst", A64DB_OSHST},
{"osh", A64DB_OSH},
@ -709,13 +728,13 @@ static NamedImmMapper_Mapping DBarrierPairs[] = {
{"sy", A64DB_SY}
};
NamedImmMapper A64DB_DBarrierMapper = {
A64NamedImmMapper A64DB_DBarrierMapper = {
DBarrierPairs,
ARR_SIZE(DBarrierPairs),
16,
};
static NamedImmMapper_Mapping DCPairs[] = {
static A64NamedImmMapper_Mapping DCPairs[] = {
{"zva", A64DC_ZVA},
{"ivac", A64DC_IVAC},
{"isw", A64DC_ISW},
@ -726,35 +745,35 @@ static NamedImmMapper_Mapping DCPairs[] = {
{"cisw", A64DC_CISW}
};
NamedImmMapper A64DC_DCMapper = {
A64NamedImmMapper A64DC_DCMapper = {
DCPairs,
ARR_SIZE(DCPairs),
0,
};
static NamedImmMapper_Mapping ICPairs[] = {
static A64NamedImmMapper_Mapping ICPairs[] = {
{"ialluis", A64IC_IALLUIS},
{"iallu", A64IC_IALLU},
{"ivau", A64IC_IVAU}
};
NamedImmMapper A64IC_ICMapper = {
A64NamedImmMapper A64IC_ICMapper = {
ICPairs,
ARR_SIZE(ICPairs),
0,
};
static NamedImmMapper_Mapping ISBPairs[] = {
static A64NamedImmMapper_Mapping ISBPairs[] = {
{"sy", A64DB_SY},
};
NamedImmMapper A64ISB_ISBMapper = {
A64NamedImmMapper A64ISB_ISBMapper = {
ISBPairs,
ARR_SIZE(ISBPairs),
16,
};
static NamedImmMapper_Mapping PRFMPairs[] = {
static A64NamedImmMapper_Mapping PRFMPairs[] = {
{"pldl1keep", A64PRFM_PLDL1KEEP},
{"pldl1strm", A64PRFM_PLDL1STRM},
{"pldl2keep", A64PRFM_PLDL2KEEP},
@ -775,25 +794,25 @@ static NamedImmMapper_Mapping PRFMPairs[] = {
{"pstl3strm", A64PRFM_PSTL3STRM}
};
NamedImmMapper A64PRFM_PRFMMapper = {
A64NamedImmMapper A64PRFM_PRFMMapper = {
PRFMPairs,
ARR_SIZE(PRFMPairs),
32,
};
static NamedImmMapper_Mapping PStatePairs[] = {
static A64NamedImmMapper_Mapping PStatePairs[] = {
{"spsel", A64PState_SPSel},
{"daifset", A64PState_DAIFSet},
{"daifclr", A64PState_DAIFClr}
};
NamedImmMapper A64PState_PStateMapper = {
A64NamedImmMapper A64PState_PStateMapper = {
PStatePairs,
ARR_SIZE(PStatePairs),
0,
};
static NamedImmMapper_Mapping MRSPairs[] = {
static A64NamedImmMapper_Mapping MRSPairs[] = {
{"mdccsr_el0", A64SysReg_MDCCSR_EL0},
{"dbgdtrrx_el0", A64SysReg_DBGDTRRX_EL0},
{"mdrar_el1", A64SysReg_MDRAR_EL1},
@ -823,16 +842,16 @@ static NamedImmMapper_Mapping MRSPairs[] = {
{"id_isar3_el1", A64SysReg_ID_ISAR3_EL1},
{"id_isar4_el1", A64SysReg_ID_ISAR4_EL1},
{"id_isar5_el1", A64SysReg_ID_ISAR5_EL1},
{"id_aa64pfr0_el1", A64SysReg_ID_AA64PFR0_EL1},
{"id_aa64pfr1_el1", A64SysReg_ID_AA64PFR1_EL1},
{"id_aa64dfr0_el1", A64SysReg_ID_AA64DFR0_EL1},
{"id_aa64dfr1_el1", A64SysReg_ID_AA64DFR1_EL1},
{"id_aa64afr0_el1", A64SysReg_ID_AA64AFR0_EL1},
{"id_aa64afr1_el1", A64SysReg_ID_AA64AFR1_EL1},
{"id_aa64isar0_el1", A64SysReg_ID_AA64ISAR0_EL1},
{"id_aa64isar1_el1", A64SysReg_ID_AA64ISAR1_EL1},
{"id_aa64mmfr0_el1", A64SysReg_ID_AA64MMFR0_EL1},
{"id_aa64mmfr1_el1", A64SysReg_ID_AA64MMFR1_EL1},
{"id_aa64pfr0_el1", A64SysReg_ID_A64PFR0_EL1},
{"id_aa64pfr1_el1", A64SysReg_ID_A64PFR1_EL1},
{"id_aa64dfr0_el1", A64SysReg_ID_A64DFR0_EL1},
{"id_aa64dfr1_el1", A64SysReg_ID_A64DFR1_EL1},
{"id_aa64afr0_el1", A64SysReg_ID_A64AFR0_EL1},
{"id_aa64afr1_el1", A64SysReg_ID_A64AFR1_EL1},
{"id_aa64isar0_el1", A64SysReg_ID_A64ISAR0_EL1},
{"id_aa64isar1_el1", A64SysReg_ID_A64ISAR1_EL1},
{"id_aa64mmfr0_el1", A64SysReg_ID_A64MMFR0_EL1},
{"id_aa64mmfr1_el1", A64SysReg_ID_A64MMFR1_EL1},
{"mvfr0_el1", A64SysReg_MVFR0_EL1},
{"mvfr1_el1", A64SysReg_MVFR1_EL1},
{"mvfr2_el1", A64SysReg_MVFR2_EL1},
@ -892,13 +911,13 @@ static NamedImmMapper_Mapping MRSPairs[] = {
{"ich_elsr_el2", A64SysReg_ICH_ELSR_EL2}
};
SysRegMapper AArch64_MRSMapper = {
A64SysRegMapper AArch64_MRSMapper = {
NULL,
MRSPairs,
ARR_SIZE(MRSPairs),
};
static NamedImmMapper_Mapping MSRPairs[] = {
static A64NamedImmMapper_Mapping MSRPairs[] = {
{"dbgdtrtx_el0", A64SysReg_DBGDTRTX_EL0},
{"oslar_el1", A64SysReg_OSLAR_EL1},
{"pmswinc_el0", A64SysReg_PMSWINC_EL0},
@ -916,83 +935,10 @@ static NamedImmMapper_Mapping MSRPairs[] = {
{"icc_sgi0r_el1", A64SysReg_ICC_SGI0R_EL1}
};
SysRegMapper AArch64_MSRMapper = {
A64SysRegMapper AArch64_MSRMapper = {
NULL,
MSRPairs,
ARR_SIZE(MSRPairs),
};
// Encoding of the immediate for logical (immediate) instructions:
//
// | N | imms | immr | size | R | S |
// |---+--------+--------+------+--------------+--------------|
// | 1 | ssssss | rrrrrr | 64 | UInt(rrrrrr) | UInt(ssssss) |
// | 0 | 0sssss | xrrrrr | 32 | UInt(rrrrr) | UInt(sssss) |
// | 0 | 10ssss | xxrrrr | 16 | UInt(rrrr) | UInt(ssss) |
// | 0 | 110sss | xxxrrr | 8 | UInt(rrr) | UInt(sss) |
// | 0 | 1110ss | xxxxrr | 4 | UInt(rr) | UInt(ss) |
// | 0 | 11110s | xxxxxr | 2 | UInt(r) | UInt(s) |
// | 0 | 11111x | - | | UNALLOCATED | |
//
// Columns 'R', 'S' and 'size' specify a "bitmask immediate" of size bits in
// which the lower S+1 bits are ones and the remaining bits are zero, then
// rotated right by R bits, which is then replicated across the datapath.
//
// + Values of 'N', 'imms' and 'immr' which do not match the above table are
// RESERVED.
// + If all 's' bits in the imms field are set then the instruction is
// RESERVED.
// + The 'x' bits in the 'immr' field are IGNORED.
bool A64Imms_isLogicalImmBits(unsigned RegWidth, uint32_t Bits, uint64_t *Imm)
{
uint32_t N = Bits >> 12;
uint32_t ImmR = (Bits >> 6) & 0x3f;
uint32_t ImmS = Bits & 0x3f;
uint64_t Mask, WidthMask;
unsigned i;
int Width = 0, Num1s, Rotation;
// N=1 encodes a 64-bit replication and is invalid for the 32-bit
// instructions.
if (RegWidth == 32 && N != 0) return false;
if (N == 1)
Width = 64;
else if ((ImmS & 0x20) == 0)
Width = 32;
else if ((ImmS & 0x10) == 0)
Width = 16;
else if ((ImmS & 0x08) == 0)
Width = 8;
else if ((ImmS & 0x04) == 0)
Width = 4;
else if ((ImmS & 0x02) == 0)
Width = 2;
else {
// ImmS is 0b11111x: UNALLOCATED
return false;
}
Num1s = (ImmS & (Width - 1)) + 1;
// All encodings which would map to -1 (signed) are RESERVED.
if (Num1s == Width)
return false;
Rotation = (ImmR & (Width - 1));
Mask = (1ULL << Num1s) - 1;
WidthMask = Width == 64 ? -1 : (1ULL << Width) - 1;
if (Rotation != 0 && Rotation != 64)
Mask = (Mask >> Rotation)
| ((Mask << (Width - Rotation)) & WidthMask);
*Imm = Mask;
for (i = 1; i < RegWidth / Width; ++i) {
Mask <<= Width;
*Imm |= Mask;
}
return true;
}
#endif

View File

@ -24,50 +24,58 @@
#include <stdint.h>
#include <string.h>
/// Instances of this class can perform bidirectional mapping from random
/// identifier strings to operand encodings. For example "MSR" takes a named
/// system-register which must be encoded somehow and decoded for printing. This
/// central location means that the information for those transformations is not
/// duplicated and remains in sync.
///
/// FIXME: currently the algorithm is a completely unoptimised linear
/// search. Obviously this could be improved, but we would probably want to work
/// out just how often these instructions are emitted before working on it. It
/// might even be optimal to just reorder the tables for the common instructions
/// rather than changing the algorithm.
typedef struct NamedImmMapper_Mapping {
char *Name;
uint32_t Value;
} NamedImmMapper_Mapping;
#ifndef __cplusplus
#if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
#define inline /* inline */
#endif
#endif
typedef struct NamedImmMapper {
NamedImmMapper_Mapping *Pairs;
size_t NumPairs;
uint32_t TooBigImm;
} NamedImmMapper;
inline static unsigned getWRegFromXReg(unsigned Reg)
{
switch (Reg) {
case ARM64_REG_X0: return ARM64_REG_W0;
case ARM64_REG_X1: return ARM64_REG_W1;
case ARM64_REG_X2: return ARM64_REG_W2;
case ARM64_REG_X3: return ARM64_REG_W3;
case ARM64_REG_X4: return ARM64_REG_W4;
case ARM64_REG_X5: return ARM64_REG_W5;
case ARM64_REG_X6: return ARM64_REG_W6;
case ARM64_REG_X7: return ARM64_REG_W7;
case ARM64_REG_X8: return ARM64_REG_W8;
case ARM64_REG_X9: return ARM64_REG_W9;
case ARM64_REG_X10: return ARM64_REG_W10;
case ARM64_REG_X11: return ARM64_REG_W11;
case ARM64_REG_X12: return ARM64_REG_W12;
case ARM64_REG_X13: return ARM64_REG_W13;
case ARM64_REG_X14: return ARM64_REG_W14;
case ARM64_REG_X15: return ARM64_REG_W15;
case ARM64_REG_X16: return ARM64_REG_W16;
case ARM64_REG_X17: return ARM64_REG_W17;
case ARM64_REG_X18: return ARM64_REG_W18;
case ARM64_REG_X19: return ARM64_REG_W19;
case ARM64_REG_X20: return ARM64_REG_W20;
case ARM64_REG_X21: return ARM64_REG_W21;
case ARM64_REG_X22: return ARM64_REG_W22;
case ARM64_REG_X23: return ARM64_REG_W23;
case ARM64_REG_X24: return ARM64_REG_W24;
case ARM64_REG_X25: return ARM64_REG_W25;
case ARM64_REG_X26: return ARM64_REG_W26;
case ARM64_REG_X27: return ARM64_REG_W27;
case ARM64_REG_X28: return ARM64_REG_W28;
case ARM64_REG_FP: return ARM64_REG_W29;
case ARM64_REG_LR: return ARM64_REG_W30;
case ARM64_REG_SP: return ARM64_REG_WSP;
case ARM64_REG_XZR: return ARM64_REG_WZR;
}
typedef struct SysRegMapper {
NamedImmMapper_Mapping *SysRegPairs;
NamedImmMapper_Mapping *InstPairs;
size_t NumInstPairs;
} SysRegMapper;
extern SysRegMapper AArch64_MSRMapper;
extern SysRegMapper AArch64_MRSMapper;
extern NamedImmMapper A64DB_DBarrierMapper;
extern NamedImmMapper A64AT_ATMapper;
extern NamedImmMapper A64DC_DCMapper;
extern NamedImmMapper A64IC_ICMapper;
extern NamedImmMapper A64ISB_ISBMapper;
extern NamedImmMapper A64PRFM_PRFMMapper;
extern NamedImmMapper A64PState_PStateMapper;
extern NamedImmMapper A64TLBI_TLBIMapper;
// For anything else, return it unchanged.
return Reg;
}
// // Enums corresponding to AArch64 condition codes
// The CondCodes constants map directly to the 4-bit encoding of the
// condition field for predicated instructions.
typedef enum A64CC_CondCodes { // Meaning (integer) Meaning (floating-point)
typedef enum A64CC_CondCode { // Meaning (integer) Meaning (floating-point)
A64CC_EQ = 0, // Equal Equal
A64CC_NE, // Not equal Not equal, or unordered
A64CC_HS, // Unsigned higher or same >, ==, or unordered
@ -84,17 +92,11 @@ typedef enum A64CC_CondCodes { // Meaning (integer) Meaning (floating
A64CC_LE, // Signed less than or equal <, ==, or unordered
A64CC_AL, // Always (unconditional) Always (unconditional)
A64CC_NV, // Always (unconditional) Always (unconditional)
// Note the NV exists purely to disassemble 0b1111. Execution
// is "always".
// Note the NV exists purely to disassemble 0b1111. Execution is "always".
A64CC_Invalid
} A64CC_CondCodes;
} A64CC_CondCode;
#ifndef __cplusplus
#if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
#define inline /* inline */
#endif
#endif
inline static char *A64CondCodeToString(A64CC_CondCodes CC)
inline static char *getCondCodeName(A64CC_CondCode CC)
{
switch (CC) {
default: return NULL; // never reach
@ -117,6 +119,52 @@ inline static char *A64CondCodeToString(A64CC_CondCodes CC)
}
}
inline static A64CC_CondCode getInvertedCondCode(A64CC_CondCode Code)
{
// To reverse a condition it's necessary to only invert the low bit:
return (A64CC_CondCode)((unsigned)Code ^ 0x1);
}
/// Instances of this class can perform bidirectional mapping from random
/// identifier strings to operand encodings. For example "MSR" takes a named
/// system-register which must be encoded somehow and decoded for printing. This
/// central location means that the information for those transformations is not
/// duplicated and remains in sync.
///
/// FIXME: currently the algorithm is a completely unoptimised linear
/// search. Obviously this could be improved, but we would probably want to work
/// out just how often these instructions are emitted before working on it. It
/// might even be optimal to just reorder the tables for the common instructions
/// rather than changing the algorithm.
typedef struct A64NamedImmMapper_Mapping {
char *Name;
uint32_t Value;
} A64NamedImmMapper_Mapping;
typedef struct A64NamedImmMapper {
A64NamedImmMapper_Mapping *Pairs;
size_t NumPairs;
uint32_t TooBigImm;
} A64NamedImmMapper;
typedef struct A64SysRegMapper {
A64NamedImmMapper_Mapping *SysRegPairs;
A64NamedImmMapper_Mapping *InstPairs;
size_t NumInstPairs;
} A64SysRegMapper;
extern A64SysRegMapper AArch64_MSRMapper;
extern A64SysRegMapper AArch64_MRSMapper;
extern A64NamedImmMapper A64DB_DBarrierMapper;
extern A64NamedImmMapper A64AT_ATMapper;
extern A64NamedImmMapper A64DC_DCMapper;
extern A64NamedImmMapper A64IC_ICMapper;
extern A64NamedImmMapper A64ISB_ISBMapper;
extern A64NamedImmMapper A64PRFM_PRFMMapper;
extern A64NamedImmMapper A64PState_PStateMapper;
extern A64NamedImmMapper A64TLBI_TLBIMapper;
enum {
A64AT_Invalid = -1, // Op0 Op1 CRn CRm Op2
A64AT_S1E1R = 0x43c0, // 01 000 0111 1000 000
@ -133,7 +181,7 @@ enum {
A64AT_S12E0W = 0x63c7 // 01 100 0111 1000 111
};
enum DBValues {
enum A64DBValues {
A64DB_Invalid = -1,
A64DB_OSHLD = 0x1,
A64DB_OSHST = 0x2,
@ -149,7 +197,7 @@ enum DBValues {
A64DB_SY = 0xf
};
enum DCValues {
enum A64DCValues {
A64DC_Invalid = -1, // Op1 CRn CRm Op2
A64DC_ZVA = 0x5ba1, // 01 011 0111 0100 001
A64DC_IVAC = 0x43b1, // 01 000 0111 0110 001
@ -161,19 +209,19 @@ enum DCValues {
A64DC_CISW = 0x43f2 // 01 000 0111 1110 010
};
enum ICValues {
enum A64ICValues {
A64IC_Invalid = -1, // Op1 CRn CRm Op2
A64IC_IALLUIS = 0x0388, // 000 0111 0001 000
A64IC_IALLU = 0x03a8, // 000 0111 0101 000
A64IC_IVAU = 0x1ba9 // 011 0111 0101 001
};
enum ISBValues {
enum A64ISBValues {
A64ISB_Invalid = -1,
A64ISB_SY = 0xf
};
enum PRFMValues {
enum A64PRFMValues {
A64PRFM_Invalid = -1,
A64PRFM_PLDL1KEEP = 0x00,
A64PRFM_PLDL1STRM = 0x01,
@ -195,7 +243,7 @@ enum PRFMValues {
A64PRFM_PSTL3STRM = 0x15
};
enum PStateValues {
enum A64PStateValues {
A64PState_Invalid = -1,
A64PState_SPSel = 0x05,
A64PState_DAIFSet = 0x1e,
@ -241,8 +289,7 @@ typedef enum A64Layout_VectorLayout {
A64Layout_VL_D
} A64Layout_VectorLayout;
inline static const char *
A64VectorLayoutToString(A64Layout_VectorLayout Layout)
inline static char *A64VectorLayoutToString(A64Layout_VectorLayout Layout)
{
switch (Layout) {
case A64Layout_VL_8B: return ".8b";
@ -261,7 +308,7 @@ A64VectorLayoutToString(A64Layout_VectorLayout Layout)
}
}
enum SysRegROValues {
enum A64SysRegROValues {
A64SysReg_MDCCSR_EL0 = 0x9808, // 10 011 0000 0001 000
A64SysReg_DBGDTRRX_EL0 = 0x9828, // 10 011 0000 0101 000
A64SysReg_MDRAR_EL1 = 0x8080, // 10 000 0001 0000 000
@ -291,16 +338,16 @@ enum SysRegROValues {
A64SysReg_ID_ISAR3_EL1 = 0xc013, // 11 000 0000 0010 011
A64SysReg_ID_ISAR4_EL1 = 0xc014, // 11 000 0000 0010 100
A64SysReg_ID_ISAR5_EL1 = 0xc015, // 11 000 0000 0010 101
A64SysReg_ID_AA64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000
A64SysReg_ID_AA64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001
A64SysReg_ID_AA64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000
A64SysReg_ID_AA64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001
A64SysReg_ID_AA64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100
A64SysReg_ID_AA64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101
A64SysReg_ID_AA64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000
A64SysReg_ID_AA64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001
A64SysReg_ID_AA64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000
A64SysReg_ID_AA64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001
A64SysReg_ID_A64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000
A64SysReg_ID_A64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001
A64SysReg_ID_A64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000
A64SysReg_ID_A64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001
A64SysReg_ID_A64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100
A64SysReg_ID_A64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101
A64SysReg_ID_A64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000
A64SysReg_ID_A64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001
A64SysReg_ID_A64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000
A64SysReg_ID_A64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001
A64SysReg_MVFR0_EL1 = 0xc018, // 11 000 0000 0011 000
A64SysReg_MVFR1_EL1 = 0xc019, // 11 000 0000 0011 001
A64SysReg_MVFR2_EL1 = 0xc01a, // 11 000 0000 0011 010
@ -360,7 +407,7 @@ enum SysRegROValues {
A64SysReg_ICH_ELSR_EL2 = 0xe65d // 11 100 1100 1011 101
};
enum SysRegWOValues {
enum A64SysRegWOValues {
A64SysReg_DBGDTRTX_EL0 = 0x9828, // 10 011 0000 0101 000
A64SysReg_OSLAR_EL1 = 0x8084, // 10 000 0001 0000 100
A64SysReg_PMSWINC_EL0 = 0xdce4, // 11 011 1001 1100 100
@ -378,7 +425,7 @@ enum SysRegWOValues {
A64SysReg_ICC_SGI0R_EL1 = 0xc65f // 11 000 1100 1011 111
};
enum SysRegValues {
enum A64SysRegValues {
A64SysReg_Invalid = -1, // Op0 Op1 CRn CRm Op2
A64SysReg_OSDTRRX_EL1 = 0x8002, // 10 000 0000 0000 010
A64SysReg_OSDTRTX_EL1 = 0x801a, // 10 000 0000 0011 010
@ -858,7 +905,12 @@ enum SysRegValues {
A64SysReg_ICH_LR15_EL2 = 0xe66f // 11 100 1100 1101 111
};
enum TLBIValues {
// Cyclone specific system registers
enum A64CycloneSysRegValues {
A64SysReg_CPM_IOACC_CTL_EL3 = 0xff90
};
enum A64TLBIValues {
A64TLBI_Invalid = -1, // Op0 Op1 CRn CRm Op2
A64TLBI_IPAS2E1IS = 0x6401, // 01 100 1000 0000 001
A64TLBI_IPAS2LE1IS = 0x6405, // 01 100 1000 0000 101
@ -896,12 +948,12 @@ enum TLBIValues {
bool A64Imms_isLogicalImmBits(unsigned RegWidth, uint32_t Bits, uint64_t *Imm);
char *NamedImmMapper_toString(NamedImmMapper *N, uint32_t Value, bool *Valid);
char *A64NamedImmMapper_toString(A64NamedImmMapper *N, uint32_t Value, bool *Valid);
uint32_t NamedImmMapper_fromString(NamedImmMapper *N, char *Name, bool *Valid);
uint32_t A64NamedImmMapper_fromString(A64NamedImmMapper *N, char *Name, bool *Valid);
bool NamedImmMapper_validImm(NamedImmMapper *N, uint32_t Value);
bool A64NamedImmMapper_validImm(A64NamedImmMapper *N, uint32_t Value);
void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *result);
void A64SysRegMapper_toString(A64SysRegMapper *S, uint32_t Bits, bool *Valid, char *result);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,9 +14,15 @@
#undef GET_SUBTARGETINFO_ENUM
enum {
AArch64_FeatureCrypto = 1ULL << 0,
AArch64_FeatureFPARMv8 = 1ULL << 1,
AArch64_FeatureNEON = 1ULL << 2
AArch64_FeatureCRC = 1ULL << 0,
AArch64_FeatureCrypto = 1ULL << 1,
AArch64_FeatureFPARMv8 = 1ULL << 2,
AArch64_FeatureNEON = 1ULL << 3,
AArch64_FeatureZCRegMove = 1ULL << 4,
AArch64_FeatureZCZeroing = 1ULL << 5,
AArch64_ProcA53 = 1ULL << 6,
AArch64_ProcA57 = 1ULL << 7,
AArch64_ProcCyclone = 1ULL << 8
};
#endif // GET_SUBTARGETINFO_ENUM

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,4 +19,17 @@ const char *AArch64_group_name(csh handle, unsigned int id);
// map instruction name to public instruction ID
arm64_reg AArch64_map_insn(const char *name);
// map internal vregister to public register
arm64_reg AArch64_map_vregister(unsigned int r);
void arm64_op_addReg(MCInst *MI, int reg);
void arm64_op_addVectorArrSpecifier(MCInst * MI, int sp);
void arm64_op_addVectorElementSizeSpecifier(MCInst * MI, int sp);
void arm64_op_addFP(MCInst *MI, float fp);
void arm64_op_addImm(MCInst *MI, int64_t imm);
#endif

View File

@ -9723,6 +9723,7 @@ const char *Mips_group_name(csh handle, unsigned int id)
#endif
}
// map instruction name to public instruction ID
mips_reg Mips_map_insn(const char *name)
{
// handle special alias first

File diff suppressed because it is too large Load Diff

View File

@ -1668,11 +1668,12 @@ public class X86_const {
public static final int X86_GRP_BWI = 36;
public static final int X86_GRP_PFI = 37;
public static final int X86_GRP_VLX = 38;
public static final int X86_GRP_JUMP = 39;
public static final int X86_GRP_VM = 40;
public static final int X86_GRP_INT = 41;
public static final int X86_GRP_IRET = 42;
public static final int X86_GRP_CALL = 43;
public static final int X86_GRP_RET = 44;
public static final int X86_GRP_MAX = 45;
public static final int X86_GRP_SMAP = 39;
public static final int X86_GRP_JUMP = 40;
public static final int X86_GRP_VM = 41;
public static final int X86_GRP_INT = 42;
public static final int X86_GRP_IRET = 43;
public static final int X86_GRP_CALL = 44;
public static final int X86_GRP_RET = 45;
public static final int X86_GRP_MAX = 46;
}

File diff suppressed because it is too large Load Diff

View File

@ -1665,10 +1665,11 @@ X86_GRP_DQI = 35
X86_GRP_BWI = 36
X86_GRP_PFI = 37
X86_GRP_VLX = 38
X86_GRP_JUMP = 39
X86_GRP_VM = 40
X86_GRP_INT = 41
X86_GRP_IRET = 42
X86_GRP_CALL = 43
X86_GRP_RET = 44
X86_GRP_MAX = 45
X86_GRP_SMAP = 39
X86_GRP_JUMP = 40
X86_GRP_VM = 41
X86_GRP_INT = 42
X86_GRP_IRET = 43
X86_GRP_CALL = 44
X86_GRP_RET = 45
X86_GRP_MAX = 46

View File

@ -61,6 +61,175 @@ typedef enum arm64_cc {
// is "always".
} arm64_cc;
//> System registers
typedef enum arm64_mrs_reg {
//> System registers for MRS
ARM64_SYSREG_INVALID = 0,
ARM64_SYSREG_MDCCSR_EL0 = 0x9808, // 10 011 0000 0001 000
ARM64_SYSREG_DBGDTRRX_EL0 = 0x9828, // 10 011 0000 0101 000
ARM64_SYSREG_MDRAR_EL1 = 0x8080, // 10 000 0001 0000 000
ARM64_SYSREG_OSLSR_EL1 = 0x808c, // 10 000 0001 0001 100
ARM64_SYSREG_DBGAUTHSTATUS_EL1 = 0x83f6, // 10 000 0111 1110 110
ARM64_SYSREG_PMCEID0_EL0 = 0xdce6, // 11 011 1001 1100 110
ARM64_SYSREG_PMCEID1_EL0 = 0xdce7, // 11 011 1001 1100 111
ARM64_SYSREG_MIDR_EL1 = 0xc000, // 11 000 0000 0000 000
ARM64_SYSREG_CCSIDR_EL1 = 0xc800, // 11 001 0000 0000 000
ARM64_SYSREG_CLIDR_EL1 = 0xc801, // 11 001 0000 0000 001
ARM64_SYSREG_CTR_EL0 = 0xd801, // 11 011 0000 0000 001
ARM64_SYSREG_MPIDR_EL1 = 0xc005, // 11 000 0000 0000 101
ARM64_SYSREG_REVIDR_EL1 = 0xc006, // 11 000 0000 0000 110
ARM64_SYSREG_AIDR_EL1 = 0xc807, // 11 001 0000 0000 111
ARM64_SYSREG_DCZID_EL0 = 0xd807, // 11 011 0000 0000 111
ARM64_SYSREG_ID_PFR0_EL1 = 0xc008, // 11 000 0000 0001 000
ARM64_SYSREG_ID_PFR1_EL1 = 0xc009, // 11 000 0000 0001 001
ARM64_SYSREG_ID_DFR0_EL1 = 0xc00a, // 11 000 0000 0001 010
ARM64_SYSREG_ID_AFR0_EL1 = 0xc00b, // 11 000 0000 0001 011
ARM64_SYSREG_ID_MMFR0_EL1 = 0xc00c, // 11 000 0000 0001 100
ARM64_SYSREG_ID_MMFR1_EL1 = 0xc00d, // 11 000 0000 0001 101
ARM64_SYSREG_ID_MMFR2_EL1 = 0xc00e, // 11 000 0000 0001 110
ARM64_SYSREG_ID_MMFR3_EL1 = 0xc00f, // 11 000 0000 0001 111
ARM64_SYSREG_ID_ISAR0_EL1 = 0xc010, // 11 000 0000 0010 000
ARM64_SYSREG_ID_ISAR1_EL1 = 0xc011, // 11 000 0000 0010 001
ARM64_SYSREG_ID_ISAR2_EL1 = 0xc012, // 11 000 0000 0010 010
ARM64_SYSREG_ID_ISAR3_EL1 = 0xc013, // 11 000 0000 0010 011
ARM64_SYSREG_ID_ISAR4_EL1 = 0xc014, // 11 000 0000 0010 100
ARM64_SYSREG_ID_ISAR5_EL1 = 0xc015, // 11 000 0000 0010 101
ARM64_SYSREG_ID_A64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000
ARM64_SYSREG_ID_A64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001
ARM64_SYSREG_ID_A64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000
ARM64_SYSREG_ID_A64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001
ARM64_SYSREG_ID_A64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100
ARM64_SYSREG_ID_A64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101
ARM64_SYSREG_ID_A64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000
ARM64_SYSREG_ID_A64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001
ARM64_SYSREG_ID_A64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000
ARM64_SYSREG_ID_A64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001
ARM64_SYSREG_MVFR0_EL1 = 0xc018, // 11 000 0000 0011 000
ARM64_SYSREG_MVFR1_EL1 = 0xc019, // 11 000 0000 0011 001
ARM64_SYSREG_MVFR2_EL1 = 0xc01a, // 11 000 0000 0011 010
ARM64_SYSREG_RVBAR_EL1 = 0xc601, // 11 000 1100 0000 001
ARM64_SYSREG_RVBAR_EL2 = 0xe601, // 11 100 1100 0000 001
ARM64_SYSREG_RVBAR_EL3 = 0xf601, // 11 110 1100 0000 001
ARM64_SYSREG_ISR_EL1 = 0xc608, // 11 000 1100 0001 000
ARM64_SYSREG_CNTPCT_EL0 = 0xdf01, // 11 011 1110 0000 001
ARM64_SYSREG_CNTVCT_EL0 = 0xdf02, // 11 011 1110 0000 010
// Trace registers
ARM64_SYSREG_TRCSTATR = 0x8818, // 10 001 0000 0011 000
ARM64_SYSREG_TRCIDR8 = 0x8806, // 10 001 0000 0000 110
ARM64_SYSREG_TRCIDR9 = 0x880e, // 10 001 0000 0001 110
ARM64_SYSREG_TRCIDR10 = 0x8816, // 10 001 0000 0010 110
ARM64_SYSREG_TRCIDR11 = 0x881e, // 10 001 0000 0011 110
ARM64_SYSREG_TRCIDR12 = 0x8826, // 10 001 0000 0100 110
ARM64_SYSREG_TRCIDR13 = 0x882e, // 10 001 0000 0101 110
ARM64_SYSREG_TRCIDR0 = 0x8847, // 10 001 0000 1000 111
ARM64_SYSREG_TRCIDR1 = 0x884f, // 10 001 0000 1001 111
ARM64_SYSREG_TRCIDR2 = 0x8857, // 10 001 0000 1010 111
ARM64_SYSREG_TRCIDR3 = 0x885f, // 10 001 0000 1011 111
ARM64_SYSREG_TRCIDR4 = 0x8867, // 10 001 0000 1100 111
ARM64_SYSREG_TRCIDR5 = 0x886f, // 10 001 0000 1101 111
ARM64_SYSREG_TRCIDR6 = 0x8877, // 10 001 0000 1110 111
ARM64_SYSREG_TRCIDR7 = 0x887f, // 10 001 0000 1111 111
ARM64_SYSREG_TRCOSLSR = 0x888c, // 10 001 0001 0001 100
ARM64_SYSREG_TRCPDSR = 0x88ac, // 10 001 0001 0101 100
ARM64_SYSREG_TRCDEVAFF0 = 0x8bd6, // 10 001 0111 1010 110
ARM64_SYSREG_TRCDEVAFF1 = 0x8bde, // 10 001 0111 1011 110
ARM64_SYSREG_TRCLSR = 0x8bee, // 10 001 0111 1101 110
ARM64_SYSREG_TRCAUTHSTATUS = 0x8bf6, // 10 001 0111 1110 110
ARM64_SYSREG_TRCDEVARCH = 0x8bfe, // 10 001 0111 1111 110
ARM64_SYSREG_TRCDEVID = 0x8b97, // 10 001 0111 0010 111
ARM64_SYSREG_TRCDEVTYPE = 0x8b9f, // 10 001 0111 0011 111
ARM64_SYSREG_TRCPIDR4 = 0x8ba7, // 10 001 0111 0100 111
ARM64_SYSREG_TRCPIDR5 = 0x8baf, // 10 001 0111 0101 111
ARM64_SYSREG_TRCPIDR6 = 0x8bb7, // 10 001 0111 0110 111
ARM64_SYSREG_TRCPIDR7 = 0x8bbf, // 10 001 0111 0111 111
ARM64_SYSREG_TRCPIDR0 = 0x8bc7, // 10 001 0111 1000 111
ARM64_SYSREG_TRCPIDR1 = 0x8bcf, // 10 001 0111 1001 111
ARM64_SYSREG_TRCPIDR2 = 0x8bd7, // 10 001 0111 1010 111
ARM64_SYSREG_TRCPIDR3 = 0x8bdf, // 10 001 0111 1011 111
ARM64_SYSREG_TRCCIDR0 = 0x8be7, // 10 001 0111 1100 111
ARM64_SYSREG_TRCCIDR1 = 0x8bef, // 10 001 0111 1101 111
ARM64_SYSREG_TRCCIDR2 = 0x8bf7, // 10 001 0111 1110 111
ARM64_SYSREG_TRCCIDR3 = 0x8bff, // 10 001 0111 1111 111
// GICv3 registers
ARM64_SYSREG_ICC_IAR1_EL1 = 0xc660, // 11 000 1100 1100 000
ARM64_SYSREG_ICC_IAR0_EL1 = 0xc640, // 11 000 1100 1000 000
ARM64_SYSREG_ICC_HPPIR1_EL1 = 0xc662, // 11 000 1100 1100 010
ARM64_SYSREG_ICC_HPPIR0_EL1 = 0xc642, // 11 000 1100 1000 010
ARM64_SYSREG_ICC_RPR_EL1 = 0xc65b, // 11 000 1100 1011 011
ARM64_SYSREG_ICH_VTR_EL2 = 0xe659, // 11 100 1100 1011 001
ARM64_SYSREG_ICH_EISR_EL2 = 0xe65b, // 11 100 1100 1011 011
ARM64_SYSREG_ICH_ELSR_EL2 = 0xe65d // 11 100 1100 1011 101
} arm64_sysreg;
typedef enum arm64_msr_reg {
//> System registers for MSR
ARM64_SYSREG_DBGDTRTX_EL0 = 0x9828, // 10 011 0000 0101 000
ARM64_SYSREG_OSLAR_EL1 = 0x8084, // 10 000 0001 0000 100
ARM64_SYSREG_PMSWINC_EL0 = 0xdce4, // 11 011 1001 1100 100
// Trace Registers
ARM64_SYSREG_TRCOSLAR = 0x8884, // 10 001 0001 0000 100
ARM64_SYSREG_TRCLAR = 0x8be6, // 10 001 0111 1100 110
// GICv3 registers
ARM64_SYSREG_ICC_EOIR1_EL1 = 0xc661, // 11 000 1100 1100 001
ARM64_SYSREG_ICC_EOIR0_EL1 = 0xc641, // 11 000 1100 1000 001
ARM64_SYSREG_ICC_DIR_EL1 = 0xc659, // 11 000 1100 1011 001
ARM64_SYSREG_ICC_SGI1R_EL1 = 0xc65d, // 11 000 1100 1011 101
ARM64_SYSREG_ICC_ASGI1R_EL1 = 0xc65e, // 11 000 1100 1011 110
ARM64_SYSREG_ICC_SGI0R_EL1 = 0xc65f // 11 000 1100 1011 111
} arm64_msr_reg;
//> System PState Field (MSR instruction)
typedef enum arm64_pstate {
ARM64_PSTATE_INVALID = 0,
ARM64_PSTATE_SPSEL = 0x05,
ARM64_PSTATE_DAIFSET = 0x1e,
ARM64_PSTATE_DAIFCLR = 0x1f
} arm64_pstate;
//> Vector arrangement specifier (for FloatingPoint/Advanced SIMD insn)
typedef enum arm64_vas {
ARM64_VAS_INVALID = 0,
ARM64_VAS_8B,
ARM64_VAS_16B,
ARM64_VAS_4H,
ARM64_VAS_8H,
ARM64_VAS_2S,
ARM64_VAS_4S,
ARM64_VAS_1D,
ARM64_VAS_2D,
ARM64_VAS_1Q,
} arm64_vas;
//> Vector element size specifier
typedef enum arm64_vess {
ARM64_VESS_INVALID = 0,
ARM64_VESS_B,
ARM64_VESS_H,
ARM64_VESS_S,
ARM64_VESS_D,
} arm64_vess;
//> Memory barrier operands
typedef enum arm64_barrier_op {
ARM64_BARRIER_INVALID = 0,
ARM64_BARRIER_OSHLD = 0x1,
ARM64_BARRIER_OSHST = 0x2,
ARM64_BARRIER_OSH = 0x3,
ARM64_BARRIER_NSHLD = 0x5,
ARM64_BARRIER_NSHST = 0x6,
ARM64_BARRIER_NSH = 0x7,
ARM64_BARRIER_ISHLD = 0x9,
ARM64_BARRIER_ISHST = 0xa,
ARM64_BARRIER_ISH = 0xb,
ARM64_BARRIER_LD = 0xd,
ARM64_BARRIER_ST = 0xe,
ARM64_BARRIER_SY = 0xf
} arm64_barrier_op;
//> Operand type for instruction's operands
typedef enum arm64_op_type {
ARM64_OP_INVALID = 0, // Uninitialized.
@ -69,8 +238,111 @@ typedef enum arm64_op_type {
ARM64_OP_IMM, // Immediate operand.
ARM64_OP_FP, // Floating-Point immediate operand.
ARM64_OP_MEM, // Memory operand
ARM64_OP_REG_MRS, // MRS register operand.
ARM64_OP_REG_MSR, // MSR register operand.
ARM64_OP_PSTATE, // PState operand.
ARM64_OP_SYS, // SYS operand for IC/DC/AT/TLBI instructions.
ARM64_OP_PREFETCH, // Prefetch operand (PRFM).
ARM64_OP_BARRIER, // Memory barrier operand (ISB/DMB/DSB instructions).
} arm64_op_type;
//> TLBI operations
typedef enum arm64_tlbi_op {
ARM64_TLBI_INVALID = 0,
ARM64_TLBI_VMALLE1IS,
ARM64_TLBI_VAE1IS,
ARM64_TLBI_ASIDE1IS,
ARM64_TLBI_VAAE1IS,
ARM64_TLBI_VALE1IS,
ARM64_TLBI_VAALE1IS,
ARM64_TLBI_ALLE2IS,
ARM64_TLBI_VAE2IS,
ARM64_TLBI_ALLE1IS,
ARM64_TLBI_VALE2IS,
ARM64_TLBI_VMALLS12E1IS,
ARM64_TLBI_ALLE3IS,
ARM64_TLBI_VAE3IS,
ARM64_TLBI_VALE3IS,
ARM64_TLBI_IPAS2E1IS,
ARM64_TLBI_IPAS2LE1IS,
ARM64_TLBI_IPAS2E1,
ARM64_TLBI_IPAS2LE1,
ARM64_TLBI_VMALLE1,
ARM64_TLBI_VAE1,
ARM64_TLBI_ASIDE1,
ARM64_TLBI_VAAE1,
ARM64_TLBI_VALE1,
ARM64_TLBI_VAALE1,
ARM64_TLBI_ALLE2,
ARM64_TLBI_VAE2,
ARM64_TLBI_ALLE1,
ARM64_TLBI_VALE2,
ARM64_TLBI_VMALLS12E1,
ARM64_TLBI_ALLE3,
ARM64_TLBI_VAE3,
ARM64_TLBI_VALE3,
} arm64_tlbi_op;
//> AT operations
typedef enum arm64_at_op {
ARM64_AT_S1E1R,
ARM64_AT_S1E1W,
ARM64_AT_S1E0R,
ARM64_AT_S1E0W,
ARM64_AT_S1E2R,
ARM64_AT_S1E2W,
ARM64_AT_S12E1R,
ARM64_AT_S12E1W,
ARM64_AT_S12E0R,
ARM64_AT_S12E0W,
ARM64_AT_S1E3R,
ARM64_AT_S1E3W,
} arm64_at_op;
//> DC operations
typedef enum arm64_dc_op {
ARM64_DC_INVALID = 0,
ARM64_DC_ZVA,
ARM64_DC_IVAC,
ARM64_DC_ISW,
ARM64_DC_CVAC,
ARM64_DC_CSW,
ARM64_DC_CVAU,
ARM64_DC_CIVAC,
ARM64_DC_CISW,
} arm64_dc_op;
//> IC operations
typedef enum arm64_ic_op {
ARM64_IC_INVALID = 0,
ARM64_IC_IALLUIS,
ARM64_IC_IALLU,
ARM64_IC_IVAU,
} arm64_ic_op;
//> Prefetch operations (PRFM)
typedef enum arm64_prefetch_op {
ARM64_PRFM_INVALID = 0,
ARM64_PRFM_PLDL1KEEP = 0x00 + 1,
ARM64_PRFM_PLDL1STRM = 0x01 + 1,
ARM64_PRFM_PLDL2KEEP = 0x02 + 1,
ARM64_PRFM_PLDL2STRM = 0x03 + 1,
ARM64_PRFM_PLDL3KEEP = 0x04 + 1,
ARM64_PRFM_PLDL3STRM = 0x05 + 1,
ARM64_PRFM_PLIL1KEEP = 0x08 + 1,
ARM64_PRFM_PLIL1STRM = 0x09 + 1,
ARM64_PRFM_PLIL2KEEP = 0x0a + 1,
ARM64_PRFM_PLIL2STRM = 0x0b + 1,
ARM64_PRFM_PLIL3KEEP = 0x0c + 1,
ARM64_PRFM_PLIL3STRM = 0x0d + 1,
ARM64_PRFM_PSTL1KEEP = 0x10 + 1,
ARM64_PRFM_PSTL1STRM = 0x11 + 1,
ARM64_PRFM_PSTL2KEEP = 0x12 + 1,
ARM64_PRFM_PSTL2STRM = 0x13 + 1,
ARM64_PRFM_PSTL3KEEP = 0x14 + 1,
ARM64_PRFM_PSTL3STRM = 0x15 + 1,
} arm64_prefetch_op;
// Instruction's operand referring to memory
// This is associated with ARM64_OP_MEM operand type above
typedef struct arm64_op_mem {
@ -81,6 +353,9 @@ typedef struct arm64_op_mem {
// Instruction operand
typedef struct cs_arm64_op {
int vector_index; // Vector Index for some vector operands (or 0 if irrelevant)
arm64_vas vas; // Vector Arrangement Specifier
arm64_vess vess; // Vector Element Size Specifier
struct {
arm64_shifter type; // shifter type of this operand
unsigned int value; // shifter value of this operand
@ -92,6 +367,10 @@ typedef struct cs_arm64_op {
int32_t imm; // immediate value, or index for C-IMM or IMM operand
double fp; // floating point value for FP operand
arm64_op_mem mem; // base/index/scale/disp value for MEM operand
arm64_pstate pstate; // PState field of MSR instruction.
unsigned int sys; // IC/DC/AT/TLBI operation (see arm64_ic_op, arm64_dc_op, arm64_at_op, arm64_tlbi_op)
arm64_prefetch_op prefetch; // PRFM operation.
arm64_barrier_op barrier; // Memory barrier operation (ISB/DMB/DSB instructions).
};
} cs_arm64_op;
@ -112,10 +391,12 @@ typedef struct cs_arm64 {
typedef enum arm64_reg {
ARM64_REG_INVALID = 0,
ARM64_REG_X29,
ARM64_REG_X30,
ARM64_REG_NZCV,
ARM64_REG_SP,
ARM64_REG_WSP,
ARM64_REG_WZR,
ARM64_REG_SP,
ARM64_REG_XZR,
ARM64_REG_B0,
ARM64_REG_B1,
@ -337,8 +618,39 @@ typedef enum arm64_reg {
ARM64_REG_X26,
ARM64_REG_X27,
ARM64_REG_X28,
ARM64_REG_X29,
ARM64_REG_X30,
ARM64_REG_V0,
ARM64_REG_V1,
ARM64_REG_V2,
ARM64_REG_V3,
ARM64_REG_V4,
ARM64_REG_V5,
ARM64_REG_V6,
ARM64_REG_V7,
ARM64_REG_V8,
ARM64_REG_V9,
ARM64_REG_V10,
ARM64_REG_V11,
ARM64_REG_V12,
ARM64_REG_V13,
ARM64_REG_V14,
ARM64_REG_V15,
ARM64_REG_V16,
ARM64_REG_V17,
ARM64_REG_V18,
ARM64_REG_V19,
ARM64_REG_V20,
ARM64_REG_V21,
ARM64_REG_V22,
ARM64_REG_V23,
ARM64_REG_V24,
ARM64_REG_V25,
ARM64_REG_V26,
ARM64_REG_V27,
ARM64_REG_V28,
ARM64_REG_V29,
ARM64_REG_V30,
ARM64_REG_V31,
ARM64_REG_MAX, // <-- mark the end of the list of registers
@ -356,33 +668,29 @@ typedef enum arm64_insn {
ARM64_INS_ABS,
ARM64_INS_ADC,
ARM64_INS_ADDHN2,
ARM64_INS_ADDHN,
ARM64_INS_ADDHN2,
ARM64_INS_ADDP,
ARM64_INS_ADDV,
ARM64_INS_ADD,
ARM64_INS_CMN,
ARM64_INS_ADRP,
ARM64_INS_ADDV,
ARM64_INS_ADR,
ARM64_INS_ADRP,
ARM64_INS_AESD,
ARM64_INS_AESE,
ARM64_INS_AESIMC,
ARM64_INS_AESMC,
ARM64_INS_AND,
ARM64_INS_ASR,
ARM64_INS_AT,
ARM64_INS_BFI,
ARM64_INS_B,
ARM64_INS_BFM,
ARM64_INS_BFXIL,
ARM64_INS_BIC,
ARM64_INS_BIF,
ARM64_INS_BIT,
ARM64_INS_BLR,
ARM64_INS_BL,
ARM64_INS_BRK,
ARM64_INS_BLR,
ARM64_INS_BR,
ARM64_INS_BRK,
ARM64_INS_BSL,
ARM64_INS_B,
ARM64_INS_CBNZ,
ARM64_INS_CBZ,
ARM64_INS_CCMN,
@ -397,9 +705,9 @@ typedef enum arm64_insn {
ARM64_INS_CMHS,
ARM64_INS_CMLE,
ARM64_INS_CMLT,
ARM64_INS_CMP,
ARM64_INS_CMTST,
ARM64_INS_CNT,
ARM64_INS_MOV,
ARM64_INS_CRC32B,
ARM64_INS_CRC32CB,
ARM64_INS_CRC32CH,
@ -415,7 +723,6 @@ typedef enum arm64_insn {
ARM64_INS_DCPS1,
ARM64_INS_DCPS2,
ARM64_INS_DCPS3,
ARM64_INS_DC,
ARM64_INS_DMB,
ARM64_INS_DRPS,
ARM64_INS_DSB,
@ -429,10 +736,10 @@ typedef enum arm64_insn {
ARM64_INS_FABS,
ARM64_INS_FACGE,
ARM64_INS_FACGT,
ARM64_INS_FADDP,
ARM64_INS_FADD,
ARM64_INS_FCCMPE,
ARM64_INS_FADDP,
ARM64_INS_FCCMP,
ARM64_INS_FCCMPE,
ARM64_INS_FCMEQ,
ARM64_INS_FCMGE,
ARM64_INS_FCMGT,
@ -443,41 +750,41 @@ typedef enum arm64_insn {
ARM64_INS_FCSEL,
ARM64_INS_FCVTAS,
ARM64_INS_FCVTAU,
ARM64_INS_FCVT,
ARM64_INS_FCVTL,
ARM64_INS_FCVTL2,
ARM64_INS_FCVTMS,
ARM64_INS_FCVTMU,
ARM64_INS_FCVTN,
ARM64_INS_FCVTN2,
ARM64_INS_FCVTNS,
ARM64_INS_FCVTNU,
ARM64_INS_FCVTN,
ARM64_INS_FCVTN2,
ARM64_INS_FCVTPS,
ARM64_INS_FCVTPU,
ARM64_INS_FCVTXN,
ARM64_INS_FCVTXN2,
ARM64_INS_FCVTZS,
ARM64_INS_FCVTZU,
ARM64_INS_FCVT,
ARM64_INS_FDIV,
ARM64_INS_FMADD,
ARM64_INS_FMAX,
ARM64_INS_FMAXNM,
ARM64_INS_FMAXNMP,
ARM64_INS_FMAXNMV,
ARM64_INS_FMAXNM,
ARM64_INS_FMAXP,
ARM64_INS_FMAXV,
ARM64_INS_FMAX,
ARM64_INS_FMIN,
ARM64_INS_FMINNM,
ARM64_INS_FMINNMP,
ARM64_INS_FMINNMV,
ARM64_INS_FMINNM,
ARM64_INS_FMINP,
ARM64_INS_FMINV,
ARM64_INS_FMIN,
ARM64_INS_FMLA,
ARM64_INS_FMLS,
ARM64_INS_FMOV,
ARM64_INS_FMSUB,
ARM64_INS_FMULX,
ARM64_INS_FMUL,
ARM64_INS_FMULX,
ARM64_INS_FNEG,
ARM64_INS_FNMADD,
ARM64_INS_FNMSUB,
@ -499,60 +806,51 @@ typedef enum arm64_insn {
ARM64_INS_HINT,
ARM64_INS_HLT,
ARM64_INS_HVC,
ARM64_INS_IC,
ARM64_INS_INS,
ARM64_INS_ISB,
ARM64_INS_LD1,
ARM64_INS_LD1R,
ARM64_INS_LD2,
ARM64_INS_LD2R,
ARM64_INS_LD3,
ARM64_INS_LD2,
ARM64_INS_LD3R,
ARM64_INS_LD3,
ARM64_INS_LD4,
ARM64_INS_LD4R,
ARM64_INS_LDARB,
ARM64_INS_LDAR,
ARM64_INS_LDARH,
ARM64_INS_LDAR,
ARM64_INS_LDAXP,
ARM64_INS_LDAXRB,
ARM64_INS_LDAXR,
ARM64_INS_LDAXRH,
ARM64_INS_LDAXR,
ARM64_INS_LDNP,
ARM64_INS_LDP,
ARM64_INS_LDPSW,
ARM64_INS_LDRSB,
ARM64_INS_LDURSB,
ARM64_INS_LDRSH,
ARM64_INS_LDURSH,
ARM64_INS_LDRSW,
ARM64_INS_LDRB,
ARM64_INS_LDR,
ARM64_INS_LDRH,
ARM64_INS_LDRSB,
ARM64_INS_LDRSH,
ARM64_INS_LDRSW,
ARM64_INS_LDTRB,
ARM64_INS_LDTRH,
ARM64_INS_LDTRSB,
ARM64_INS_LDTRSH,
ARM64_INS_LDTRSW,
ARM64_INS_LDTR,
ARM64_INS_LDURB,
ARM64_INS_LDUR,
ARM64_INS_LDURH,
ARM64_INS_LDURSB,
ARM64_INS_LDURSH,
ARM64_INS_LDURSW,
ARM64_INS_LDXP,
ARM64_INS_LDXRB,
ARM64_INS_LDXR,
ARM64_INS_LDXRH,
ARM64_INS_LDRH,
ARM64_INS_LDURH,
ARM64_INS_STRH,
ARM64_INS_STURH,
ARM64_INS_LDTRH,
ARM64_INS_STTRH,
ARM64_INS_LDUR,
ARM64_INS_STR,
ARM64_INS_STUR,
ARM64_INS_LDTR,
ARM64_INS_STTR,
ARM64_INS_LDRB,
ARM64_INS_LDURB,
ARM64_INS_STRB,
ARM64_INS_STURB,
ARM64_INS_LDTRB,
ARM64_INS_STTRB,
ARM64_INS_LDP,
ARM64_INS_LDNP,
ARM64_INS_STNP,
ARM64_INS_STP,
ARM64_INS_LDXR,
ARM64_INS_LSL,
ARM64_INS_LSR,
ARM64_INS_MADD,
@ -567,7 +865,6 @@ typedef enum arm64_insn {
ARM64_INS_MSUB,
ARM64_INS_MUL,
ARM64_INS_MVNI,
ARM64_INS_MVN,
ARM64_INS_NEG,
ARM64_INS_NOT,
ARM64_INS_ORN,
@ -577,12 +874,8 @@ typedef enum arm64_insn {
ARM64_INS_PMUL,
ARM64_INS_PRFM,
ARM64_INS_PRFUM,
ARM64_INS_SQRSHRUN2,
ARM64_INS_SQRSHRUN,
ARM64_INS_SQSHRUN2,
ARM64_INS_SQSHRUN,
ARM64_INS_RADDHN2,
ARM64_INS_RADDHN,
ARM64_INS_RADDHN2,
ARM64_INS_RBIT,
ARM64_INS_RET,
ARM64_INS_REV16,
@ -592,25 +885,24 @@ typedef enum arm64_insn {
ARM64_INS_ROR,
ARM64_INS_RSHRN2,
ARM64_INS_RSHRN,
ARM64_INS_RSUBHN2,
ARM64_INS_RSUBHN,
ARM64_INS_RSUBHN2,
ARM64_INS_SABAL2,
ARM64_INS_SABAL,
ARM64_INS_SABA,
ARM64_INS_SABDL2,
ARM64_INS_SABDL,
ARM64_INS_SABD,
ARM64_INS_SADALP,
ARM64_INS_SADDL2,
ARM64_INS_SADDLP,
ARM64_INS_SADDLV,
ARM64_INS_SADDL2,
ARM64_INS_SADDL,
ARM64_INS_SADDW2,
ARM64_INS_SADDW,
ARM64_INS_SBC,
ARM64_INS_SBFIZ,
ARM64_INS_SBFM,
ARM64_INS_SBFX,
ARM64_INS_SCVTF,
ARM64_INS_SDIV,
ARM64_INS_SHA1C,
@ -619,8 +911,8 @@ typedef enum arm64_insn {
ARM64_INS_SHA1P,
ARM64_INS_SHA1SU0,
ARM64_INS_SHA1SU1,
ARM64_INS_SHA256H,
ARM64_INS_SHA256H2,
ARM64_INS_SHA256H,
ARM64_INS_SHA256SU0,
ARM64_INS_SHA256SU1,
ARM64_INS_SHADD,
@ -650,27 +942,31 @@ typedef enum arm64_insn {
ARM64_INS_SMULL,
ARM64_INS_SQABS,
ARM64_INS_SQADD,
ARM64_INS_SQDMLAL2,
ARM64_INS_SQDMLAL,
ARM64_INS_SQDMLSL2,
ARM64_INS_SQDMLAL2,
ARM64_INS_SQDMLSL,
ARM64_INS_SQDMLSL2,
ARM64_INS_SQDMULH,
ARM64_INS_SQDMULL2,
ARM64_INS_SQDMULL,
ARM64_INS_SQDMULL2,
ARM64_INS_SQNEG,
ARM64_INS_SQRDMULH,
ARM64_INS_SQRSHL,
ARM64_INS_SQRSHRN,
ARM64_INS_SQRSHRN2,
ARM64_INS_SQRSHRUN,
ARM64_INS_SQRSHRUN2,
ARM64_INS_SQSHLU,
ARM64_INS_SQSHL,
ARM64_INS_SQSHRN,
ARM64_INS_SQSHRN2,
ARM64_INS_SQSHRUN,
ARM64_INS_SQSHRUN2,
ARM64_INS_SQSUB,
ARM64_INS_SQXTN,
ARM64_INS_SQXTN2,
ARM64_INS_SQXTUN,
ARM64_INS_SQXTN,
ARM64_INS_SQXTUN2,
ARM64_INS_SQXTUN,
ARM64_INS_SRHADD,
ARM64_INS_SRI,
ARM64_INS_SRSHL,
@ -690,34 +986,40 @@ typedef enum arm64_insn {
ARM64_INS_ST3,
ARM64_INS_ST4,
ARM64_INS_STLRB,
ARM64_INS_STLR,
ARM64_INS_STLRH,
ARM64_INS_STLR,
ARM64_INS_STLXP,
ARM64_INS_STLXRB,
ARM64_INS_STLXR,
ARM64_INS_STLXRH,
ARM64_INS_STLXR,
ARM64_INS_STNP,
ARM64_INS_STP,
ARM64_INS_STRB,
ARM64_INS_STR,
ARM64_INS_STRH,
ARM64_INS_STTRB,
ARM64_INS_STTRH,
ARM64_INS_STTR,
ARM64_INS_STURB,
ARM64_INS_STUR,
ARM64_INS_STURH,
ARM64_INS_STXP,
ARM64_INS_STXRB,
ARM64_INS_STXR,
ARM64_INS_STXRH,
ARM64_INS_SUBHN2,
ARM64_INS_STXR,
ARM64_INS_SUBHN,
ARM64_INS_SUBHN2,
ARM64_INS_SUB,
ARM64_INS_SUQADD,
ARM64_INS_SVC,
ARM64_INS_SXTB,
ARM64_INS_SXTH,
ARM64_INS_SXTW,
ARM64_INS_SYSL,
ARM64_INS_SYS,
ARM64_INS_TBL,
ARM64_INS_TBNZ,
ARM64_INS_TBX,
ARM64_INS_TBZ,
ARM64_INS_TLBI,
ARM64_INS_TRN1,
ARM64_INS_TRN2,
ARM64_INS_TST,
ARM64_INS_UABAL2,
ARM64_INS_UABAL,
ARM64_INS_UABA,
@ -725,15 +1027,13 @@ typedef enum arm64_insn {
ARM64_INS_UABDL,
ARM64_INS_UABD,
ARM64_INS_UADALP,
ARM64_INS_UADDL2,
ARM64_INS_UADDLP,
ARM64_INS_UADDLV,
ARM64_INS_UADDL2,
ARM64_INS_UADDL,
ARM64_INS_UADDW2,
ARM64_INS_UADDW,
ARM64_INS_UBFIZ,
ARM64_INS_UBFM,
ARM64_INS_UBFX,
ARM64_INS_UCVTF,
ARM64_INS_UDIV,
ARM64_INS_UHADD,
@ -762,8 +1062,8 @@ typedef enum arm64_insn {
ARM64_INS_UQSHRN,
ARM64_INS_UQSHRN2,
ARM64_INS_UQSUB,
ARM64_INS_UQXTN,
ARM64_INS_UQXTN2,
ARM64_INS_UQXTN,
ARM64_INS_URECPE,
ARM64_INS_URHADD,
ARM64_INS_URSHL,
@ -780,12 +1080,10 @@ typedef enum arm64_insn {
ARM64_INS_USUBL,
ARM64_INS_USUBW2,
ARM64_INS_USUBW,
ARM64_INS_UXTB,
ARM64_INS_UXTH,
ARM64_INS_UZP1,
ARM64_INS_UZP2,
ARM64_INS_XTN,
ARM64_INS_XTN2,
ARM64_INS_XTN,
ARM64_INS_ZIP1,
ARM64_INS_ZIP2,
@ -793,7 +1091,6 @@ typedef enum arm64_insn {
ARM64_INS_MNEG,
ARM64_INS_UMNEGL,
ARM64_INS_SMNEGL,
ARM64_INS_MOV,
ARM64_INS_NOP,
ARM64_INS_YIELD,
ARM64_INS_WFE,
@ -801,6 +1098,31 @@ typedef enum arm64_insn {
ARM64_INS_SEV,
ARM64_INS_SEVL,
ARM64_INS_NGC,
ARM64_INS_SBFIZ,
ARM64_INS_UBFIZ,
ARM64_INS_SBFX,
ARM64_INS_UBFX,
ARM64_INS_BFI,
ARM64_INS_BFXIL,
ARM64_INS_CMN,
ARM64_INS_MVN,
ARM64_INS_TST,
ARM64_INS_CSET,
ARM64_INS_CINC,
ARM64_INS_CSETM,
ARM64_INS_CINV,
ARM64_INS_CNEG,
ARM64_INS_SXTB,
ARM64_INS_SXTH,
ARM64_INS_SXTW,
ARM64_INS_CMP,
ARM64_INS_UXTB,
ARM64_INS_UXTH,
ARM64_INS_UXTW,
ARM64_INS_IC,
ARM64_INS_DC,
ARM64_INS_AT,
ARM64_INS_TLBI,
ARM64_INS_MAX, // <-- mark the end of the list of insn
} arm64_insn;
@ -812,6 +1134,7 @@ typedef enum arm64_insn_group {
ARM64_GRP_CRYPTO,
ARM64_GRP_FPARMV8,
ARM64_GRP_NEON,
ARM64_GRP_CRC,
ARM64_GRP_JUMP, // all jump instructions (conditional+direct+indirect jumps)

View File

@ -1591,6 +1591,7 @@ typedef enum x86_insn_group {
X86_GRP_BWI,
X86_GRP_PFI,
X86_GRP_VLX,
X86_GRP_SMAP,
X86_GRP_JUMP, // all jump instructions (conditional+direct+indirect jumps)
X86_GRP_VM, // all virtualization instructions (VT-x + AMD-V)

View File

@ -69,6 +69,24 @@ static void print_insn_detail(cs_insn *ins)
case ARM64_OP_CIMM:
printf("\t\toperands[%u].type: C-IMM = %u\n", i, op->imm);
break;
case ARM64_OP_REG_MRS:
printf("\t\toperands[%u].type: REG_MRS = 0x%x\n", i, op->reg);
break;
case ARM64_OP_REG_MSR:
printf("\t\toperands[%u].type: REG_MSR = 0x%x\n", i, op->reg);
break;
case ARM64_OP_PSTATE:
printf("\t\toperands[%u].type: PSTATE = 0x%x\n", i, op->pstate);
break;
case ARM64_OP_SYS:
printf("\t\toperands[%u].type: SYS = 0x%x\n", i, op->sys);
break;
case ARM64_OP_PREFETCH:
printf("\t\toperands[%u].type: PREFETCH = 0x%x\n", i, op->prefetch);
break;
case ARM64_OP_BARRIER:
printf("\t\toperands[%u].type: BARRIER = 0x%x\n", i, op->barrier);
break;
}
if (op->shift.type != ARM64_SFT_INVALID &&
@ -78,10 +96,16 @@ static void print_insn_detail(cs_insn *ins)
if (op->ext != ARM64_EXT_INVALID)
printf("\t\t\tExt: %u\n", op->ext);
}
if (arm64->cc != ARM64_CC_INVALID)
printf("\tCode condition: %u\n", arm64->cc);
if (op->vas != ARM64_VAS_INVALID)
printf("\t\t\tVector Arrangement Specifier: 0x%x\n", op->vas);
if (op->vess != ARM64_VESS_INVALID)
printf("\t\t\tVector Element Size: %u\n", op->vess);
if (op->vector_index != 0)
printf("\t\t\tVector Index: %u\n", op->vector_index);
}
if (arm64->update_flags)
printf("\tUpdate-flags: True\n");
@ -89,6 +113,9 @@ static void print_insn_detail(cs_insn *ins)
if (arm64->writeback)
printf("\tWrite-back: True\n");
if (arm64->cc)
printf("\tCode-condition: %u\n", arm64->cc);
printf("\n");
}
@ -139,7 +166,16 @@ static void test()
//#define ARM64_CODE "\x20\xf4\x18\x9e" // fcvtzs x0, s1, #3
//#define ARM64_CODE "\x20\xfc\x02\x9b" // mneg x0, x1, x2
//#define ARM64_CODE "\xd0\xb6\x1e\xd5" // msr s3_6_c11_c6_6, x16
#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b"
//#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b"
//#define ARM64_CODE "\x09\x00\x38\xd5" // DBarrier
//#define ARM64_CODE "\x20\xe4\x3d\x0f\xa2\x00\xae\x9e"
//#define ARM64_CODE "\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5" // DBarrier
//#define ARM64_CODE "\x10\x5b\xe8\x3c"
//#define ARM64_CODE "\x00\x18\xa0\x5f\xa2\x00\xae\x9e"
#define ARM64_CODE "\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c"
struct platform platforms[] = {
{
@ -171,7 +207,7 @@ static void test()
printf("****************\n");
printf("Platform: %s\n", platforms[i].comment);
print_string_hex("Code:", platforms[i].code, platforms[i].size);
print_string_hex("Code: ", platforms[i].code, platforms[i].size);
printf("Disasm:\n");
for (j = 0; j < count; j++) {
@ -185,7 +221,7 @@ static void test()
} else {
printf("****************\n");
printf("Platform: %s\n", platforms[i].comment);
print_string_hex("Code:", platforms[i].code, platforms[i].size);
print_string_hex("Code: ", platforms[i].code, platforms[i].size);
printf("ERROR: Failed to disasm given code!\n");
}

View File

@ -49,7 +49,9 @@ static void test()
//#define ARM64_CODE "\x21\x7c\x02\x9b" // mul x1, x1, x2
//#define ARM64_CODE "\x20\x74\x0b\xd5" // dc zva, x0
//#define ARM64_CODE "\x20\xfc\x02\x9b" // mneg x0, x1, x2
#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x10\x20\x21\x1e"
//#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x10\x20\x21\x1e"
//#define ARM64_CODE "\x21\x7c\x00\x53"
#define ARM64_CODE "\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c"
//#define THUMB_CODE "\x0a\xbf" // itet eq
//#define X86_CODE32 "\x77\x04" // ja +6
#define PPC_CODE "\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21"