forked from capstone-engine/capstone
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
arm64: update core. this added a lot more details to cs_arm64_op struct
- Loading branch information
Showing
24 changed files
with
33,732 additions
and
34,271 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,14 @@ | |
/* By Nguyen Anh Quynh <[email protected]>, 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() | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <[email protected]>, 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 |
Oops, something went wrong.