Skip to content

Commit

Permalink
arm64: update core. this added a lot more details to cs_arm64_op struct
Browse files Browse the repository at this point in the history
  • Loading branch information
aquynh committed Aug 25, 2014
1 parent ffb6b23 commit 46a74e5
Show file tree
Hide file tree
Showing 24 changed files with 33,732 additions and 34,271 deletions.
22 changes: 22 additions & 0 deletions MathExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
80 changes: 80 additions & 0 deletions SStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
{
Expand Down
12 changes: 12 additions & 0 deletions SStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
224 changes: 224 additions & 0 deletions arch/AArch64/AArch64AddressingModes.h
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
Loading

0 comments on commit 46a74e5

Please sign in to comment.