core: add Sparc arch

This commit is contained in:
Nguyen Anh Quynh 2014-03-10 11:58:57 +08:00
parent f3b7bcfea1
commit 05e27138ae
24 changed files with 8572 additions and 11 deletions

View File

@ -7,12 +7,14 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
(0) Tailor Capstone to your need. (0) Tailor Capstone to your need.
Out of 5 archtitectures supported by Capstone (Arm, Arm64, Mips, PPC & X86), Out of 6 archtitectures supported by Capstone (Arm, Arm64, Mips, PPC, Sparc &
if you just need several selected archs, you can choose which ones you want X86), if you just need several selected archs, you can choose which ones you
to compile in by modifying config.mk before going to next steps. want to compile in by modifying "config.mk" before going to next steps.
By default, all 5 architectures are compiled. By default, all 6 architectures are compiled.
Capstone also supports "diet" engine to minimize the binaries for embedding
purpose. See docs/README for further instructions.
(1) Compile from source (1) Compile from source
@ -54,6 +56,8 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
/usr/include/capstone/arm64.h /usr/include/capstone/arm64.h
/usr/include/capstone/mips.h /usr/include/capstone/mips.h
/usr/include/capstone/ppc.h /usr/include/capstone/ppc.h
/usr/include/capstone/sparc.h
/usr/include/capstone/diet.h
/usr/lib/libcapstone.so (for Linux/*nix), or /usr/lib/libcapstone.dylib (OSX) /usr/lib/libcapstone.so (for Linux/*nix), or /usr/lib/libcapstone.dylib (OSX)
/usr/lib/libcapstone.a /usr/lib/libcapstone.a

View File

@ -128,6 +128,7 @@ typedef struct cs_insn_flat {
cs_arm arm; // ARM architecture (including Thumb/Thumb2) cs_arm arm; // ARM architecture (including Thumb/Thumb2)
cs_mips mips; // MIPS architecture cs_mips mips; // MIPS architecture
cs_ppc ppc; // PowerPC architecture cs_ppc ppc; // PowerPC architecture
cs_sparc sparc; // PowerPC architecture
}; };
} cs_insn_flat; } cs_insn_flat;

View File

@ -114,6 +114,23 @@ ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS)))
endif endif
DEP_SPARC =
DEP_SPARC += arch/Sparc/SparcGenAsmWriter.inc
DEP_SPARC += arch/Sparc/SparcGenInstrInfo.inc
DEP_SPARC += arch/Sparc/SparcGenSubtargetInfo.inc
DEP_SPARC += arch/Sparc/SparcGenDisassemblerTables.inc
DEP_SPARC += arch/Sparc/SparcGenRegisterInfo.inc
LIBOBJ_SPARC =
ifneq (,$(findstring sparc,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_SPARC
LIBOBJ_SPARC += arch/Sparc/SparcDisassembler.o
LIBOBJ_SPARC += arch/Sparc/SparcInstPrinter.o
LIBOBJ_SPARC += arch/Sparc/SparcMapping.o
LIBOBJ_SPARC += arch/Sparc/SparcModule.o
endif
DEP_X86 = DEP_X86 =
DEP_X86 += arch/X86/X86GenAsmWriter.inc DEP_X86 += arch/X86/X86GenAsmWriter.inc
DEP_X86 += arch/X86/X86GenAsmWriter1.inc DEP_X86 += arch/X86/X86GenAsmWriter1.inc
@ -134,7 +151,7 @@ endif
LIBOBJ = LIBOBJ =
LIBOBJ += cs.o utils.o SStream.o MCInstrDesc.o MCRegisterInfo.o LIBOBJ += cs.o utils.o SStream.o MCInstrDesc.o MCRegisterInfo.o
LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_X86) LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_SPARC) $(LIBOBJ_X86)
LIBOBJ += MCInst.o LIBOBJ += MCInst.o
@ -202,6 +219,7 @@ $(LIBOBJ_ARM): $(DEP_ARM)
$(LIBOBJ_ARM64): $(DEP_ARM64) $(LIBOBJ_ARM64): $(DEP_ARM64)
$(LIBOBJ_MIPS): $(DEP_MIPS) $(LIBOBJ_MIPS): $(DEP_MIPS)
$(LIBOBJ_PPC): $(DEP_PPC) $(LIBOBJ_PPC): $(DEP_PPC)
$(LIBOBJ_SPARC): $(DEP_SPARC)
$(LIBOBJ_X86): $(DEP_X86) $(LIBOBJ_X86): $(DEP_X86)
# auto-generate include/diet.h # auto-generate include/diet.h

3
README
View File

@ -4,7 +4,8 @@ disasm engine for binary analysis and reversing in the security community.
Created by Nguyen Anh Quynh, then developed and maintained by a small community, Created by Nguyen Anh Quynh, then developed and maintained by a small community,
Capstone offers some unparalleled features: Capstone offers some unparalleled features:
- Support multiple hardware architectures: ARM, ARM64 (ARMv8), Mips, PPC & X86. - Support multiple hardware architectures: ARM, ARM64 (ARMv8), Mips, PPC, Sparc
and X86.
- Having clean/simple/lightweight/intuitive architecture-neutral API. - Having clean/simple/lightweight/intuitive architecture-neutral API.

63
arch/Sparc/Sparc.h Normal file
View File

@ -0,0 +1,63 @@
//===-- Sparc.h - Top-level interface for Sparc representation --*- 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 entry points for global functions defined in the LLVM
// Sparc back-end.
//
//===----------------------------------------------------------------------===//
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#ifndef CS_SPARC_TARGET_SPARC_H
#define CS_SPARC_TARGET_SPARC_H
#include "../../include/sparc.h"
inline static const char *SPARCCondCodeToString(sparc_cc CC)
{
switch (CC) {
default: return NULL; // unreachable
case SPARC_CC_ICC_A: return "a";
case SPARC_CC_ICC_N: return "n";
case SPARC_CC_ICC_NE: return "ne";
case SPARC_CC_ICC_E: return "e";
case SPARC_CC_ICC_G: return "g";
case SPARC_CC_ICC_LE: return "le";
case SPARC_CC_ICC_GE: return "ge";
case SPARC_CC_ICC_L: return "l";
case SPARC_CC_ICC_GU: return "gu";
case SPARC_CC_ICC_LEU: return "leu";
case SPARC_CC_ICC_CC: return "cc";
case SPARC_CC_ICC_CS: return "cs";
case SPARC_CC_ICC_POS: return "pos";
case SPARC_CC_ICC_NEG: return "neg";
case SPARC_CC_ICC_VC: return "vc";
case SPARC_CC_ICC_VS: return "vs";
case SPARC_CC_FCC_A: return "a";
case SPARC_CC_FCC_N: return "n";
case SPARC_CC_FCC_U: return "u";
case SPARC_CC_FCC_G: return "g";
case SPARC_CC_FCC_UG: return "ug";
case SPARC_CC_FCC_L: return "l";
case SPARC_CC_FCC_UL: return "ul";
case SPARC_CC_FCC_LG: return "lg";
case SPARC_CC_FCC_NE: return "ne";
case SPARC_CC_FCC_E: return "e";
case SPARC_CC_FCC_UE: return "ue";
case SPARC_CC_FCC_GE: return "ge";
case SPARC_CC_FCC_UGE: return "uge";
case SPARC_CC_FCC_LE: return "le";
case SPARC_CC_FCC_ULE: return "ule";
case SPARC_CC_FCC_O: return "o";
}
}
#endif

View File

@ -0,0 +1,471 @@
//===------ SparcDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h> // DEBUG
#include <stdlib.h>
#include <string.h>
#include "../../cs_priv.h"
#include "../../SubtargetFeature.h"
#include "../../MCInst.h"
#include "../../MCInstrDesc.h"
#include "../../MCFixedLenDisassembler.h"
#include "../../MCRegisterInfo.h"
#include "../../MCDisassembler.h"
#include "../../MathExtras.h"
#define GET_REGINFO_MC_DESC
#define GET_REGINFO_ENUM
#include "SparcGenRegisterInfo.inc"
static const unsigned IntRegDecoderTable[] = {
SP_G0, SP_G1, SP_G2, SP_G3,
SP_G4, SP_G5, SP_G6, SP_G7,
SP_O0, SP_O1, SP_O2, SP_O3,
SP_O4, SP_O5, SP_O6, SP_O7,
SP_L0, SP_L1, SP_L2, SP_L3,
SP_L4, SP_L5, SP_L6, SP_L7,
SP_I0, SP_I1, SP_I2, SP_I3,
SP_I4, SP_I5, SP_I6, SP_I7
};
static const unsigned FPRegDecoderTable[] = {
SP_F0, SP_F1, SP_F2, SP_F3,
SP_F4, SP_F5, SP_F6, SP_F7,
SP_F8, SP_F9, SP_F10, SP_F11,
SP_F12, SP_F13, SP_F14, SP_F15,
SP_F16, SP_F17, SP_F18, SP_F19,
SP_F20, SP_F21, SP_F22, SP_F23,
SP_F24, SP_F25, SP_F26, SP_F27,
SP_F28, SP_F29, SP_F30, SP_F31
};
static const unsigned DFPRegDecoderTable[] = {
SP_D0, SP_D16, SP_D1, SP_D17,
SP_D2, SP_D18, SP_D3, SP_D19,
SP_D4, SP_D20, SP_D5, SP_D21,
SP_D6, SP_D22, SP_D7, SP_D23,
SP_D8, SP_D24, SP_D9, SP_D25,
SP_D10, SP_D26, SP_D11, SP_D27,
SP_D12, SP_D28, SP_D13, SP_D29,
SP_D14, SP_D30, SP_D15, SP_D31
};
static const unsigned QFPRegDecoderTable[] = {
SP_Q0, SP_Q8, ~0U, ~0U,
SP_Q1, SP_Q9, ~0U, ~0U,
SP_Q2, SP_Q10, ~0U, ~0U,
SP_Q3, SP_Q11, ~0U, ~0U,
SP_Q4, SP_Q12, ~0U, ~0U,
SP_Q5, SP_Q13, ~0U, ~0U,
SP_Q6, SP_Q14, ~0U, ~0U,
SP_Q7, SP_Q15, ~0U, ~0U
};
static const unsigned FCCRegDecoderTable[] = {
SP_FCC0, SP_FCC1, SP_FCC2, SP_FCC3
};
static uint64_t getFeatureBits(int mode)
{
// support everything
return (uint64_t)-1;
}
static DecodeStatus DecodeIntRegsRegisterClass(MCInst *Inst, unsigned RegNo,
uint64_t Address, const void *Decoder)
{
unsigned Reg;
if (RegNo > 31)
return MCDisassembler_Fail;
Reg = IntRegDecoderTable[RegNo];
MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeI64RegsRegisterClass(MCInst *Inst, unsigned RegNo,
uint64_t Address, const void *Decoder)
{
unsigned Reg;
if (RegNo > 31)
return MCDisassembler_Fail;
Reg = IntRegDecoderTable[RegNo];
MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
uint64_t Address, const void *Decoder)
{
unsigned Reg;
if (RegNo > 31)
return MCDisassembler_Fail;
Reg = FPRegDecoderTable[RegNo];
MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeDFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
uint64_t Address, const void *Decoder)
{
unsigned Reg;
if (RegNo > 31)
return MCDisassembler_Fail;
Reg = DFPRegDecoderTable[RegNo];
MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeQFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
uint64_t Address, const void *Decoder)
{
unsigned Reg;
if (RegNo > 31)
return MCDisassembler_Fail;
Reg = QFPRegDecoderTable[RegNo];
if (Reg == ~0U)
return MCDisassembler_Fail;
MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeFCCRegsRegisterClass(MCInst *Inst, unsigned RegNo,
uint64_t Address, const void *Decoder)
{
if (RegNo > 3)
return MCDisassembler_Fail;
MCInst_addOperand(Inst, MCOperand_CreateReg(FCCRegDecoderTable[RegNo]));
return MCDisassembler_Success;
}
static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCall(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSIMM13(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeJMPL(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address,
const void *Decoder);
#define GET_SUBTARGETINFO_ENUM
#include "SparcGenSubtargetInfo.inc"
#include "SparcGenDisassemblerTables.inc"
/// readInstruction - read four bytes and return 32 bit word.
static DecodeStatus readInstruction32(unsigned char *code, size_t len, uint32_t *Insn)
{
uint8_t Bytes[4];
if (len < 4)
// not enough data
return MCDisassembler_Fail;
memcpy(Bytes, code, 4);
// Encoded as a big-endian 32-bit word in the stream.
*Insn = (Bytes[3] << 0) |
(Bytes[2] << 8) |
(Bytes[1] << 16) |
(Bytes[0] << 24);
return MCDisassembler_Success;
}
bool Sparc_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *MI,
uint16_t *size, uint64_t address, void *info)
{
uint32_t Insn;
DecodeStatus Result;
Result = readInstruction32(code, code_len, &Insn);
if (Result == MCDisassembler_Fail)
return MCDisassembler_Fail;
Result = decodeInstruction_4(DecoderTableSparc32, MI, Insn, address,
(MCRegisterInfo *)info, 0);
if (Result != MCDisassembler_Fail) {
*size = 4;
return Result;
}
return MCDisassembler_Fail;
}
typedef DecodeStatus (*DecodeFunc)(MCInst *MI, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeMem(MCInst *MI, unsigned insn, uint64_t Address,
const void *Decoder,
bool isLoad, DecodeFunc DecodeRD)
{
DecodeStatus status;
unsigned rd = fieldFromInstruction_4(insn, 25, 5);
unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
bool isImm = fieldFromInstruction_4(insn, 13, 1);
unsigned rs2 = 0;
unsigned simm13 = 0;
if (isImm)
simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
else
rs2 = fieldFromInstruction_4(insn, 0, 5);
if (isLoad) {
status = DecodeRD(MI, rd, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
}
// Decode rs1.
status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
// Decode imm|rs2.
if (isImm)
MCInst_addOperand(MI, MCOperand_CreateImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
}
if (!isLoad) {
status = DecodeRD(MI, rd, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
}
return MCDisassembler_Success;
}
static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeIntRegsRegisterClass);
}
static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeFPRegsRegisterClass);
}
static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeDFPRegsRegisterClass);
}
static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeQFPRegsRegisterClass);
}
static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeIntRegsRegisterClass);
}
static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn, uint64_t Address,
const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeFPRegsRegisterClass);
}
static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeDFPRegsRegisterClass);
}
static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn,
uint64_t Address, const void *Decoder)
{
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeQFPRegsRegisterClass);
}
/*
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
uint64_t Address, uint64_t Offset,
uint64_t Width, MCInst *MI,
const void *Decoder)
{
const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
Offset, Width);
}
*/
static DecodeStatus DecodeCall(MCInst *MI, unsigned insn,
uint64_t Address, const void *Decoder)
{
unsigned tgt = fieldFromInstruction_4(insn, 0, 30);
tgt <<= 2;
/*
if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 0, 30, MI, Decoder))
*/
MCInst_addOperand(MI, MCOperand_CreateImm(tgt));
return MCDisassembler_Success;
}
static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn,
uint64_t Address, const void *Decoder)
{
unsigned tgt = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
MCInst_addOperand(MI, MCOperand_CreateImm(tgt));
return MCDisassembler_Success;
}
static DecodeStatus DecodeJMPL(MCInst *MI, unsigned insn, uint64_t Address,
const void *Decoder)
{
DecodeStatus status;
unsigned rd = fieldFromInstruction_4(insn, 25, 5);
unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
unsigned rs2 = 0;
unsigned simm13 = 0;
if (isImm)
simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
else
rs2 = fieldFromInstruction_4(insn, 0, 5);
// Decode RD.
status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
// Decode RS1.
status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
// Decode RS1 | SIMM13.
if (isImm)
MCInst_addOperand(MI, MCOperand_CreateImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
}
return MCDisassembler_Success;
}
static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address,
const void *Decoder)
{
DecodeStatus status;
unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
unsigned rs2 = 0;
unsigned simm13 = 0;
if (isImm)
simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
else
rs2 = fieldFromInstruction_4(insn, 0, 5);
// Decode RS1.
status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
// Decode RS2 | SIMM13.
if (isImm)
MCInst_addOperand(MI, MCOperand_CreateImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler_Success)
return status;
}
return MCDisassembler_Success;
}
void Sparc_init(MCRegisterInfo *MRI)
{
/*
InitMCRegisterInfo(SparcRegDesc, 119, RA, PC,
SparcMCRegisterClasses, 8,
SparcRegUnitRoots,
86,
SparcRegDiffLists,
SparcRegStrings,
SparcSubRegIdxLists,
7,
SparcSubRegIdxRanges,
SparcRegEncodingTable);
*/
MCRegisterInfo_InitMCRegisterInfo(MRI, SparcRegDesc, 119,
0, 0,
SparcMCRegisterClasses, 8,
0, 0,
SparcRegDiffLists,
0,
SparcSubRegIdxLists, 7,
0);
}

View File

@ -0,0 +1,19 @@
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#ifndef CS_SPARCDISASSEMBLER_H
#define CS_SPARCDISASSEMBLER_H
#include <stdint.h>
#include "../../include/capstone.h"
#include "../../MCRegisterInfo.h"
#include "../../MCInst.h"
void Sparc_init(MCRegisterInfo *MRI);
bool Sparc_getInstruction(csh ud, const uint8_t *code, size_t code_len,
MCInst *instr, uint16_t *size, uint64_t address, void *info);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,511 @@
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|* *|
|*Target Instruction Enum Values *|
|* *|
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#ifdef GET_INSTRINFO_ENUM
#undef GET_INSTRINFO_ENUM
enum {
SP_PHI = 0,
SP_INLINEASM = 1,
SP_CFI_INSTRUCTION = 2,
SP_EH_LABEL = 3,
SP_GC_LABEL = 4,
SP_KILL = 5,
SP_EXTRACT_SUBREG = 6,
SP_INSERT_SUBREG = 7,
SP_IMPLICIT_DEF = 8,
SP_SUBREG_TO_REG = 9,
SP_COPY_TO_REGCLASS = 10,
SP_DBG_VALUE = 11,
SP_REG_SEQUENCE = 12,
SP_COPY = 13,
SP_BUNDLE = 14,
SP_LIFETIME_START = 15,
SP_LIFETIME_END = 16,
SP_STACKMAP = 17,
SP_PATCHPOINT = 18,
SP_ADDCCri = 19,
SP_ADDCCrr = 20,
SP_ADDCri = 21,
SP_ADDCrr = 22,
SP_ADDEri = 23,
SP_ADDErr = 24,
SP_ADDXC = 25,
SP_ADDXCCC = 26,
SP_ADDXri = 27,
SP_ADDXrr = 28,
SP_ADDri = 29,
SP_ADDrr = 30,
SP_ADJCALLSTACKDOWN = 31,
SP_ADJCALLSTACKUP = 32,
SP_ALIGNADDR = 33,
SP_ALIGNADDRL = 34,
SP_ANDCCri = 35,
SP_ANDCCrr = 36,
SP_ANDNCCri = 37,
SP_ANDNCCrr = 38,
SP_ANDNri = 39,
SP_ANDNrr = 40,
SP_ANDXNrr = 41,
SP_ANDXri = 42,
SP_ANDXrr = 43,
SP_ANDri = 44,
SP_ANDrr = 45,
SP_ARRAY16 = 46,
SP_ARRAY32 = 47,
SP_ARRAY8 = 48,
SP_ATOMIC_LOAD_ADD_32 = 49,
SP_ATOMIC_LOAD_ADD_64 = 50,
SP_ATOMIC_LOAD_AND_32 = 51,
SP_ATOMIC_LOAD_AND_64 = 52,
SP_ATOMIC_LOAD_MAX_32 = 53,
SP_ATOMIC_LOAD_MAX_64 = 54,
SP_ATOMIC_LOAD_MIN_32 = 55,
SP_ATOMIC_LOAD_MIN_64 = 56,
SP_ATOMIC_LOAD_NAND_32 = 57,
SP_ATOMIC_LOAD_NAND_64 = 58,
SP_ATOMIC_LOAD_OR_32 = 59,
SP_ATOMIC_LOAD_OR_64 = 60,
SP_ATOMIC_LOAD_SUB_32 = 61,
SP_ATOMIC_LOAD_SUB_64 = 62,
SP_ATOMIC_LOAD_UMAX_32 = 63,
SP_ATOMIC_LOAD_UMAX_64 = 64,
SP_ATOMIC_LOAD_UMIN_32 = 65,
SP_ATOMIC_LOAD_UMIN_64 = 66,
SP_ATOMIC_LOAD_XOR_32 = 67,
SP_ATOMIC_LOAD_XOR_64 = 68,
SP_ATOMIC_SWAP_64 = 69,
SP_BA = 70,
SP_BCOND = 71,
SP_BCONDA = 72,
SP_BINDri = 73,
SP_BINDrr = 74,
SP_BMASK = 75,
SP_BPFCC = 76,
SP_BPFCCA = 77,
SP_BPFCCANT = 78,
SP_BPFCCNT = 79,
SP_BPGEZapn = 80,
SP_BPGEZapt = 81,
SP_BPGEZnapn = 82,
SP_BPGEZnapt = 83,
SP_BPGZapn = 84,
SP_BPGZapt = 85,
SP_BPGZnapn = 86,
SP_BPGZnapt = 87,
SP_BPICC = 88,
SP_BPICCA = 89,
SP_BPICCANT = 90,
SP_BPICCNT = 91,
SP_BPLEZapn = 92,
SP_BPLEZapt = 93,
SP_BPLEZnapn = 94,
SP_BPLEZnapt = 95,
SP_BPLZapn = 96,
SP_BPLZapt = 97,
SP_BPLZnapn = 98,
SP_BPLZnapt = 99,
SP_BPNZapn = 100,
SP_BPNZapt = 101,
SP_BPNZnapn = 102,
SP_BPNZnapt = 103,
SP_BPXCC = 104,
SP_BPXCCA = 105,
SP_BPXCCANT = 106,
SP_BPXCCNT = 107,
SP_BPZapn = 108,
SP_BPZapt = 109,
SP_BPZnapn = 110,
SP_BPZnapt = 111,
SP_BSHUFFLE = 112,
SP_CALL = 113,
SP_CALLri = 114,
SP_CALLrr = 115,
SP_CASXrr = 116,
SP_CASrr = 117,
SP_CMASK16 = 118,
SP_CMASK32 = 119,
SP_CMASK8 = 120,
SP_CMPri = 121,
SP_CMPrr = 122,
SP_EDGE16 = 123,
SP_EDGE16L = 124,
SP_EDGE16LN = 125,
SP_EDGE16N = 126,
SP_EDGE32 = 127,
SP_EDGE32L = 128,
SP_EDGE32LN = 129,
SP_EDGE32N = 130,
SP_EDGE8 = 131,
SP_EDGE8L = 132,
SP_EDGE8LN = 133,
SP_EDGE8N = 134,
SP_FABSD = 135,
SP_FABSQ = 136,
SP_FABSS = 137,
SP_FADDD = 138,
SP_FADDQ = 139,
SP_FADDS = 140,
SP_FALIGNADATA = 141,
SP_FAND = 142,
SP_FANDNOT1 = 143,
SP_FANDNOT1S = 144,
SP_FANDNOT2 = 145,
SP_FANDNOT2S = 146,
SP_FANDS = 147,
SP_FBCOND = 148,
SP_FBCONDA = 149,
SP_FCHKSM16 = 150,
SP_FCMPD = 151,
SP_FCMPEQ16 = 152,
SP_FCMPEQ32 = 153,
SP_FCMPGT16 = 154,
SP_FCMPGT32 = 155,
SP_FCMPLE16 = 156,
SP_FCMPLE32 = 157,
SP_FCMPNE16 = 158,
SP_FCMPNE32 = 159,
SP_FCMPQ = 160,
SP_FCMPS = 161,
SP_FDIVD = 162,
SP_FDIVQ = 163,
SP_FDIVS = 164,
SP_FDMULQ = 165,
SP_FDTOI = 166,
SP_FDTOQ = 167,
SP_FDTOS = 168,
SP_FDTOX = 169,
SP_FEXPAND = 170,
SP_FHADDD = 171,
SP_FHADDS = 172,
SP_FHSUBD = 173,
SP_FHSUBS = 174,
SP_FITOD = 175,
SP_FITOQ = 176,
SP_FITOS = 177,
SP_FLCMPD = 178,
SP_FLCMPS = 179,
SP_FLUSHW = 180,
SP_FMEAN16 = 181,
SP_FMOVD = 182,
SP_FMOVD_FCC = 183,
SP_FMOVD_ICC = 184,
SP_FMOVD_XCC = 185,
SP_FMOVQ = 186,
SP_FMOVQ_FCC = 187,
SP_FMOVQ_ICC = 188,
SP_FMOVQ_XCC = 189,
SP_FMOVRGEZD = 190,
SP_FMOVRGEZQ = 191,
SP_FMOVRGEZS = 192,
SP_FMOVRGZD = 193,
SP_FMOVRGZQ = 194,
SP_FMOVRGZS = 195,
SP_FMOVRLEZD = 196,
SP_FMOVRLEZQ = 197,
SP_FMOVRLEZS = 198,
SP_FMOVRLZD = 199,
SP_FMOVRLZQ = 200,
SP_FMOVRLZS = 201,
SP_FMOVRNZD = 202,
SP_FMOVRNZQ = 203,
SP_FMOVRNZS = 204,
SP_FMOVRZD = 205,
SP_FMOVRZQ = 206,
SP_FMOVRZS = 207,
SP_FMOVS = 208,
SP_FMOVS_FCC = 209,
SP_FMOVS_ICC = 210,
SP_FMOVS_XCC = 211,
SP_FMUL8SUX16 = 212,
SP_FMUL8ULX16 = 213,
SP_FMUL8X16 = 214,
SP_FMUL8X16AL = 215,
SP_FMUL8X16AU = 216,
SP_FMULD = 217,
SP_FMULD8SUX16 = 218,
SP_FMULD8ULX16 = 219,
SP_FMULQ = 220,
SP_FMULS = 221,
SP_FNADDD = 222,
SP_FNADDS = 223,
SP_FNAND = 224,
SP_FNANDS = 225,
SP_FNEGD = 226,
SP_FNEGQ = 227,
SP_FNEGS = 228,
SP_FNHADDD = 229,
SP_FNHADDS = 230,
SP_FNMULD = 231,
SP_FNMULS = 232,
SP_FNOR = 233,
SP_FNORS = 234,
SP_FNOT1 = 235,
SP_FNOT1S = 236,
SP_FNOT2 = 237,
SP_FNOT2S = 238,
SP_FNSMULD = 239,
SP_FONE = 240,
SP_FONES = 241,
SP_FOR = 242,
SP_FORNOT1 = 243,
SP_FORNOT1S = 244,
SP_FORNOT2 = 245,
SP_FORNOT2S = 246,
SP_FORS = 247,
SP_FPACK16 = 248,
SP_FPACK32 = 249,
SP_FPACKFIX = 250,
SP_FPADD16 = 251,
SP_FPADD16S = 252,
SP_FPADD32 = 253,
SP_FPADD32S = 254,
SP_FPADD64 = 255,
SP_FPMERGE = 256,
SP_FPSUB16 = 257,
SP_FPSUB16S = 258,
SP_FPSUB32 = 259,
SP_FPSUB32S = 260,
SP_FQTOD = 261,
SP_FQTOI = 262,
SP_FQTOS = 263,
SP_FQTOX = 264,
SP_FSLAS16 = 265,
SP_FSLAS32 = 266,
SP_FSLL16 = 267,
SP_FSLL32 = 268,
SP_FSMULD = 269,
SP_FSQRTD = 270,
SP_FSQRTQ = 271,
SP_FSQRTS = 272,
SP_FSRA16 = 273,
SP_FSRA32 = 274,
SP_FSRC1 = 275,
SP_FSRC1S = 276,
SP_FSRC2 = 277,
SP_FSRC2S = 278,
SP_FSRL16 = 279,
SP_FSRL32 = 280,
SP_FSTOD = 281,
SP_FSTOI = 282,
SP_FSTOQ = 283,
SP_FSTOX = 284,
SP_FSUBD = 285,
SP_FSUBQ = 286,
SP_FSUBS = 287,
SP_FXNOR = 288,
SP_FXNORS = 289,
SP_FXOR = 290,
SP_FXORS = 291,
SP_FXTOD = 292,
SP_FXTOQ = 293,
SP_FXTOS = 294,
SP_FZERO = 295,
SP_FZEROS = 296,
SP_GETPCX = 297,
SP_JMPLri = 298,
SP_JMPLrr = 299,
SP_LDDFri = 300,
SP_LDDFrr = 301,
SP_LDFri = 302,
SP_LDFrr = 303,
SP_LDQFri = 304,
SP_LDQFrr = 305,
SP_LDSBri = 306,
SP_LDSBrr = 307,
SP_LDSHri = 308,
SP_LDSHrr = 309,
SP_LDSWri = 310,
SP_LDSWrr = 311,
SP_LDUBri = 312,
SP_LDUBrr = 313,
SP_LDUHri = 314,
SP_LDUHrr = 315,
SP_LDXri = 316,
SP_LDXrr = 317,
SP_LDri = 318,
SP_LDrr = 319,
SP_LEAX_ADDri = 320,
SP_LEA_ADDri = 321,
SP_LZCNT = 322,
SP_MEMBARi = 323,
SP_MOVDTOX = 324,
SP_MOVFCCri = 325,
SP_MOVFCCrr = 326,
SP_MOVICCri = 327,
SP_MOVICCrr = 328,
SP_MOVRGEZri = 329,
SP_MOVRGEZrr = 330,
SP_MOVRGZri = 331,
SP_MOVRGZrr = 332,
SP_MOVRLEZri = 333,
SP_MOVRLEZrr = 334,
SP_MOVRLZri = 335,
SP_MOVRLZrr = 336,
SP_MOVRNZri = 337,
SP_MOVRNZrr = 338,
SP_MOVRRZri = 339,
SP_MOVRRZrr = 340,
SP_MOVSTOSW = 341,
SP_MOVSTOUW = 342,
SP_MOVWTOS = 343,
SP_MOVXCCri = 344,
SP_MOVXCCrr = 345,
SP_MOVXTOD = 346,
SP_MULXri = 347,
SP_MULXrr = 348,
SP_NOP = 349,
SP_ORCCri = 350,
SP_ORCCrr = 351,
SP_ORNCCri = 352,
SP_ORNCCrr = 353,
SP_ORNri = 354,
SP_ORNrr = 355,
SP_ORXNrr = 356,
SP_ORXri = 357,
SP_ORXrr = 358,
SP_ORri = 359,
SP_ORrr = 360,
SP_PDIST = 361,
SP_PDISTN = 362,
SP_POPCrr = 363,
SP_RDY = 364,
SP_RESTOREri = 365,
SP_RESTORErr = 366,
SP_RET = 367,
SP_RETL = 368,
SP_RETTri = 369,
SP_RETTrr = 370,
SP_SAVEri = 371,
SP_SAVErr = 372,
SP_SDIVCCri = 373,
SP_SDIVCCrr = 374,
SP_SDIVXri = 375,
SP_SDIVXrr = 376,
SP_SDIVri = 377,
SP_SDIVrr = 378,
SP_SELECT_CC_DFP_FCC = 379,
SP_SELECT_CC_DFP_ICC = 380,
SP_SELECT_CC_FP_FCC = 381,
SP_SELECT_CC_FP_ICC = 382,
SP_SELECT_CC_Int_FCC = 383,
SP_SELECT_CC_Int_ICC = 384,
SP_SELECT_CC_QFP_FCC = 385,
SP_SELECT_CC_QFP_ICC = 386,
SP_SETHIXi = 387,
SP_SETHIi = 388,
SP_SHUTDOWN = 389,
SP_SIAM = 390,
SP_SLLXri = 391,
SP_SLLXrr = 392,
SP_SLLri = 393,
SP_SLLrr = 394,
SP_SMULCCri = 395,
SP_SMULCCrr = 396,
SP_SMULri = 397,
SP_SMULrr = 398,
SP_SRAXri = 399,
SP_SRAXrr = 400,
SP_SRAri = 401,
SP_SRArr = 402,
SP_SRLXri = 403,
SP_SRLXrr = 404,
SP_SRLri = 405,
SP_SRLrr = 406,
SP_STBAR = 407,
SP_STBri = 408,
SP_STBrr = 409,
SP_STDFri = 410,
SP_STDFrr = 411,
SP_STFri = 412,
SP_STFrr = 413,
SP_STHri = 414,
SP_STHrr = 415,
SP_STQFri = 416,
SP_STQFrr = 417,
SP_STXri = 418,
SP_STXrr = 419,
SP_STri = 420,
SP_STrr = 421,
SP_SUBCCri = 422,
SP_SUBCCrr = 423,
SP_SUBCri = 424,
SP_SUBCrr = 425,
SP_SUBEri = 426,
SP_SUBErr = 427,
SP_SUBXri = 428,
SP_SUBXrr = 429,
SP_SUBri = 430,
SP_SUBrr = 431,
SP_SWAPri = 432,
SP_SWAPrr = 433,
SP_TA3 = 434,
SP_TA5 = 435,
SP_TADDCCTVri = 436,
SP_TADDCCTVrr = 437,
SP_TADDCCri = 438,
SP_TADDCCrr = 439,
SP_TICCri = 440,
SP_TICCrr = 441,
SP_TLS_ADDXrr = 442,
SP_TLS_ADDrr = 443,
SP_TLS_CALL = 444,
SP_TLS_LDXrr = 445,
SP_TLS_LDrr = 446,
SP_TSUBCCTVri = 447,
SP_TSUBCCTVrr = 448,
SP_TSUBCCri = 449,
SP_TSUBCCrr = 450,
SP_TXCCri = 451,
SP_TXCCrr = 452,
SP_UDIVCCri = 453,
SP_UDIVCCrr = 454,
SP_UDIVXri = 455,
SP_UDIVXrr = 456,
SP_UDIVri = 457,
SP_UDIVrr = 458,
SP_UMULCCri = 459,
SP_UMULCCrr = 460,
SP_UMULXHI = 461,
SP_UMULri = 462,
SP_UMULrr = 463,
SP_UNIMP = 464,
SP_V9FCMPD = 465,
SP_V9FCMPED = 466,
SP_V9FCMPEQ = 467,
SP_V9FCMPES = 468,
SP_V9FCMPQ = 469,
SP_V9FCMPS = 470,
SP_V9FMOVD_FCC = 471,
SP_V9FMOVQ_FCC = 472,
SP_V9FMOVS_FCC = 473,
SP_V9MOVFCCri = 474,
SP_V9MOVFCCrr = 475,
SP_WRYri = 476,
SP_WRYrr = 477,
SP_XMULX = 478,
SP_XMULXHI = 479,
SP_XNORCCri = 480,
SP_XNORCCrr = 481,
SP_XNORXrr = 482,
SP_XNORri = 483,
SP_XNORrr = 484,
SP_XORCCri = 485,
SP_XORCCrr = 486,
SP_XORXri = 487,
SP_XORXrr = 488,
SP_XORri = 489,
SP_XORrr = 490,
SP_INSTRUCTION_LIST_END = 491
};
#endif // GET_INSTRINFO_ENUM

View File

@ -0,0 +1,462 @@
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|* *|
|*Target Register Enum Values *|
|* *|
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#ifdef GET_REGINFO_ENUM
#undef GET_REGINFO_ENUM
enum {
SP_NoRegister,
SP_ICC = 1,
SP_Y = 2,
SP_D0 = 3,
SP_D1 = 4,
SP_D2 = 5,
SP_D3 = 6,
SP_D4 = 7,
SP_D5 = 8,
SP_D6 = 9,
SP_D7 = 10,
SP_D8 = 11,
SP_D9 = 12,
SP_D10 = 13,
SP_D11 = 14,
SP_D12 = 15,
SP_D13 = 16,
SP_D14 = 17,
SP_D15 = 18,
SP_D16 = 19,
SP_D17 = 20,
SP_D18 = 21,
SP_D19 = 22,
SP_D20 = 23,
SP_D21 = 24,
SP_D22 = 25,
SP_D23 = 26,
SP_D24 = 27,
SP_D25 = 28,
SP_D26 = 29,
SP_D27 = 30,
SP_D28 = 31,
SP_D29 = 32,
SP_D30 = 33,
SP_D31 = 34,
SP_F0 = 35,
SP_F1 = 36,
SP_F2 = 37,
SP_F3 = 38,
SP_F4 = 39,
SP_F5 = 40,
SP_F6 = 41,
SP_F7 = 42,
SP_F8 = 43,
SP_F9 = 44,
SP_F10 = 45,
SP_F11 = 46,
SP_F12 = 47,
SP_F13 = 48,
SP_F14 = 49,
SP_F15 = 50,
SP_F16 = 51,
SP_F17 = 52,
SP_F18 = 53,
SP_F19 = 54,
SP_F20 = 55,
SP_F21 = 56,
SP_F22 = 57,
SP_F23 = 58,
SP_F24 = 59,
SP_F25 = 60,
SP_F26 = 61,
SP_F27 = 62,
SP_F28 = 63,
SP_F29 = 64,
SP_F30 = 65,
SP_F31 = 66,
SP_FCC0 = 67,
SP_FCC1 = 68,
SP_FCC2 = 69,
SP_FCC3 = 70,
SP_G0 = 71,
SP_G1 = 72,
SP_G2 = 73,
SP_G3 = 74,
SP_G4 = 75,
SP_G5 = 76,
SP_G6 = 77,
SP_G7 = 78,
SP_I0 = 79,
SP_I1 = 80,
SP_I2 = 81,
SP_I3 = 82,
SP_I4 = 83,
SP_I5 = 84,
SP_I6 = 85,
SP_I7 = 86,
SP_L0 = 87,
SP_L1 = 88,
SP_L2 = 89,
SP_L3 = 90,
SP_L4 = 91,
SP_L5 = 92,
SP_L6 = 93,
SP_L7 = 94,
SP_O0 = 95,
SP_O1 = 96,
SP_O2 = 97,
SP_O3 = 98,
SP_O4 = 99,
SP_O5 = 100,
SP_O6 = 101,
SP_O7 = 102,
SP_Q0 = 103,
SP_Q1 = 104,
SP_Q2 = 105,
SP_Q3 = 106,
SP_Q4 = 107,
SP_Q5 = 108,
SP_Q6 = 109,
SP_Q7 = 110,
SP_Q8 = 111,
SP_Q9 = 112,
SP_Q10 = 113,
SP_Q11 = 114,
SP_Q12 = 115,
SP_Q13 = 116,
SP_Q14 = 117,
SP_Q15 = 118,
SP_NUM_TARGET_REGS // 119
};
// Register classes
enum {
SP_FCCRegsRegClassID = 0,
SP_FPRegsRegClassID = 1,
SP_IntRegsRegClassID = 2,
SP_DFPRegsRegClassID = 3,
SP_I64RegsRegClassID = 4,
SP_DFPRegs_with_sub_evenRegClassID = 5,
SP_QFPRegsRegClassID = 6,
SP_QFPRegs_with_sub_evenRegClassID = 7
};
// Subregister indices
enum {
SP_NoSubRegister,
SP_sub_even, // 1
SP_sub_even64, // 2
SP_sub_odd, // 3
SP_sub_odd64, // 4
SP_sub_odd64_then_sub_even, // 5
SP_sub_odd64_then_sub_odd, // 6
SP_NUM_TARGET_SUBREGS
};
#endif // GET_REGINFO_ENUM
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|* *|
|*MC Register Information *|
|* *|
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifdef GET_REGINFO_MC_DESC
#undef GET_REGINFO_MC_DESC
static MCPhysReg SparcRegDiffLists[] = {
/* 0 */ 65126, 1, 1, 1, 0,
/* 5 */ 32, 1, 0,
/* 8 */ 65436, 32, 1, 65504, 33, 1, 0,
/* 15 */ 34, 1, 0,
/* 18 */ 65437, 34, 1, 65502, 35, 1, 0,
/* 25 */ 36, 1, 0,
/* 28 */ 65438, 36, 1, 65500, 37, 1, 0,
/* 35 */ 38, 1, 0,
/* 38 */ 65439, 38, 1, 65498, 39, 1, 0,
/* 45 */ 40, 1, 0,
/* 48 */ 65440, 40, 1, 65496, 41, 1, 0,
/* 55 */ 42, 1, 0,
/* 58 */ 65441, 42, 1, 65494, 43, 1, 0,
/* 65 */ 44, 1, 0,
/* 68 */ 65442, 44, 1, 65492, 45, 1, 0,
/* 75 */ 46, 1, 0,
/* 78 */ 65443, 46, 1, 65490, 47, 1, 0,
/* 85 */ 65348, 1, 0,
/* 88 */ 65444, 1, 0,
/* 91 */ 65445, 1, 0,
/* 94 */ 65446, 1, 0,
/* 97 */ 65447, 1, 0,
/* 100 */ 65448, 1, 0,
/* 103 */ 65449, 1, 0,
/* 106 */ 65450, 1, 0,
/* 109 */ 65451, 1, 0,
/* 112 */ 65532, 1, 0,
/* 115 */ 15, 0,
/* 117 */ 84, 0,
/* 119 */ 85, 0,
/* 121 */ 86, 0,
/* 123 */ 87, 0,
/* 125 */ 88, 0,
/* 127 */ 89, 0,
/* 129 */ 90, 0,
/* 131 */ 91, 0,
/* 133 */ 65488, 92, 0,
/* 136 */ 65489, 92, 0,
/* 139 */ 65489, 93, 0,
/* 142 */ 65490, 93, 0,
/* 145 */ 65491, 93, 0,
/* 148 */ 65491, 94, 0,
/* 151 */ 65492, 94, 0,
/* 154 */ 65493, 94, 0,
/* 157 */ 65493, 95, 0,
/* 160 */ 65494, 95, 0,
/* 163 */ 65495, 95, 0,
/* 166 */ 65495, 96, 0,
/* 169 */ 65496, 96, 0,
/* 172 */ 65497, 96, 0,
/* 175 */ 65497, 97, 0,
/* 178 */ 65498, 97, 0,
/* 181 */ 65499, 97, 0,
/* 184 */ 65499, 98, 0,
/* 187 */ 65500, 98, 0,
/* 190 */ 65501, 98, 0,
/* 193 */ 65501, 99, 0,
/* 196 */ 65502, 99, 0,
/* 199 */ 65503, 99, 0,
/* 202 */ 65503, 100, 0,
/* 205 */ 65504, 100, 0,
/* 208 */ 65503, 0,
/* 210 */ 65519, 0,
/* 212 */ 65535, 0,
};
static uint16_t SparcSubRegIdxLists[] = {
/* 0 */ 1, 3, 0,
/* 3 */ 2, 4, 0,
/* 6 */ 2, 1, 3, 4, 5, 6, 0,
};
static MCRegisterDesc SparcRegDesc[] = { // Descriptors
{ 3, 0, 0, 0, 0 },
{ 406, 4, 4, 2, 3393 },
{ 410, 4, 4, 2, 3393 },
{ 33, 5, 203, 0, 1794 },
{ 87, 12, 194, 0, 1794 },
{ 133, 15, 194, 0, 1794 },
{ 179, 22, 185, 0, 1794 },
{ 220, 25, 185, 0, 1794 },
{ 261, 32, 176, 0, 1794 },
{ 298, 35, 176, 0, 1794 },
{ 335, 42, 167, 0, 1794 },
{ 372, 45, 167, 0, 1794 },
{ 397, 52, 158, 0, 1794 },
{ 0, 55, 158, 0, 1794 },
{ 54, 62, 149, 0, 1794 },
{ 108, 65, 149, 0, 1794 },
{ 154, 72, 140, 0, 1794 },
{ 200, 75, 140, 0, 1794 },
{ 241, 82, 134, 0, 1794 },
{ 282, 4, 134, 2, 1841 },
{ 319, 4, 131, 2, 1841 },
{ 356, 4, 131, 2, 1841 },
{ 381, 4, 129, 2, 1841 },
{ 12, 4, 129, 2, 1841 },
{ 66, 4, 127, 2, 1841 },
{ 120, 4, 127, 2, 1841 },
{ 166, 4, 125, 2, 1841 },
{ 212, 4, 125, 2, 1841 },
{ 253, 4, 123, 2, 1841 },
{ 290, 4, 123, 2, 1841 },
{ 327, 4, 121, 2, 1841 },
{ 364, 4, 121, 2, 1841 },
{ 389, 4, 119, 2, 1841 },
{ 20, 4, 119, 2, 1841 },
{ 74, 4, 117, 2, 1841 },
{ 36, 4, 205, 2, 3329 },
{ 90, 4, 202, 2, 3329 },
{ 136, 4, 199, 2, 3329 },
{ 182, 4, 196, 2, 3329 },
{ 223, 4, 196, 2, 3329 },
{ 264, 4, 193, 2, 3329 },
{ 301, 4, 190, 2, 3329 },
{ 338, 4, 187, 2, 3329 },
{ 375, 4, 187, 2, 3329 },
{ 400, 4, 184, 2, 3329 },
{ 4, 4, 181, 2, 3329 },
{ 58, 4, 178, 2, 3329 },
{ 112, 4, 178, 2, 3329 },
{ 158, 4, 175, 2, 3329 },
{ 204, 4, 172, 2, 3329 },
{ 245, 4, 169, 2, 3329 },
{ 286, 4, 169, 2, 3329 },
{ 323, 4, 166, 2, 3329 },
{ 360, 4, 163, 2, 3329 },
{ 385, 4, 160, 2, 3329 },
{ 16, 4, 160, 2, 3329 },
{ 70, 4, 157, 2, 3329 },
{ 124, 4, 154, 2, 3329 },
{ 170, 4, 151, 2, 3329 },
{ 216, 4, 151, 2, 3329 },
{ 257, 4, 148, 2, 3329 },
{ 294, 4, 145, 2, 3329 },
{ 331, 4, 142, 2, 3329 },
{ 368, 4, 142, 2, 3329 },
{ 393, 4, 139, 2, 3329 },
{ 24, 4, 136, 2, 3329 },
{ 78, 4, 133, 2, 3329 },
{ 28, 4, 4, 2, 3361 },
{ 82, 4, 4, 2, 3361 },
{ 128, 4, 4, 2, 3361 },
{ 174, 4, 4, 2, 3361 },
{ 39, 4, 4, 2, 3361 },
{ 93, 4, 4, 2, 3361 },
{ 139, 4, 4, 2, 3361 },
{ 185, 4, 4, 2, 3361 },
{ 226, 4, 4, 2, 3361 },
{ 267, 4, 4, 2, 3361 },
{ 304, 4, 4, 2, 3361 },
{ 341, 4, 4, 2, 3361 },
{ 42, 4, 4, 2, 3361 },
{ 96, 4, 4, 2, 3361 },
{ 142, 4, 4, 2, 3361 },
{ 188, 4, 4, 2, 3361 },
{ 229, 4, 4, 2, 3361 },
{ 270, 4, 4, 2, 3361 },
{ 307, 4, 4, 2, 3361 },
{ 344, 4, 4, 2, 3361 },
{ 45, 4, 4, 2, 3361 },
{ 99, 4, 4, 2, 3361 },
{ 145, 4, 4, 2, 3361 },
{ 191, 4, 4, 2, 3361 },
{ 232, 4, 4, 2, 3361 },
{ 273, 4, 4, 2, 3361 },
{ 310, 4, 4, 2, 3361 },
{ 347, 4, 4, 2, 3361 },
{ 48, 4, 4, 2, 3361 },
{ 102, 4, 4, 2, 3361 },
{ 148, 4, 4, 2, 3361 },
{ 194, 4, 4, 2, 3361 },
{ 235, 4, 4, 2, 3361 },
{ 276, 4, 4, 2, 3361 },
{ 313, 4, 4, 2, 3361 },
{ 350, 4, 4, 2, 3361 },
{ 51, 8, 4, 6, 4 },
{ 105, 18, 4, 6, 4 },
{ 151, 28, 4, 6, 4 },
{ 197, 38, 4, 6, 4 },
{ 238, 48, 4, 6, 4 },
{ 279, 58, 4, 6, 4 },
{ 316, 68, 4, 6, 4 },
{ 353, 78, 4, 6, 4 },
{ 378, 88, 4, 3, 1362 },
{ 403, 91, 4, 3, 1362 },
{ 8, 94, 4, 3, 1362 },
{ 62, 97, 4, 3, 1362 },
{ 116, 100, 4, 3, 1362 },
{ 162, 103, 4, 3, 1362 },
{ 208, 106, 4, 3, 1362 },
{ 249, 109, 4, 3, 1362 },
};
// FCCRegs Register Class...
static uint16_t FCCRegs[] = {
SP_FCC0, SP_FCC1, SP_FCC2, SP_FCC3,
};
// FCCRegs Bit set.
static uint8_t FCCRegsBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
};
// FPRegs Register Class...
static uint16_t FPRegs[] = {
SP_F0, SP_F1, SP_F2, SP_F3, SP_F4, SP_F5, SP_F6, SP_F7, SP_F8, SP_F9, SP_F10, SP_F11, SP_F12, SP_F13, SP_F14, SP_F15, SP_F16, SP_F17, SP_F18, SP_F19, SP_F20, SP_F21, SP_F22, SP_F23, SP_F24, SP_F25, SP_F26, SP_F27, SP_F28, SP_F29, SP_F30, SP_F31,
};
// FPRegs Bit set.
static uint8_t FPRegsBits[] = {
0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x07,
};
// IntRegs Register Class...
static uint16_t IntRegs[] = {
SP_I0, SP_I1, SP_I2, SP_I3, SP_I4, SP_I5, SP_I6, SP_I7, SP_G0, SP_G1, SP_G2, SP_G3, SP_G4, SP_G5, SP_G6, SP_G7, SP_L0, SP_L1, SP_L2, SP_L3, SP_L4, SP_L5, SP_L6, SP_L7, SP_O0, SP_O1, SP_O2, SP_O3, SP_O4, SP_O5, SP_O6, SP_O7,
};
// IntRegs Bit set.
static uint8_t IntRegsBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f,
};
// DFPRegs Register Class...
static uint16_t DFPRegs[] = {
SP_D0, SP_D1, SP_D2, SP_D3, SP_D4, SP_D5, SP_D6, SP_D7, SP_D8, SP_D9, SP_D10, SP_D11, SP_D12, SP_D13, SP_D14, SP_D15, SP_D16, SP_D17, SP_D18, SP_D19, SP_D20, SP_D21, SP_D22, SP_D23, SP_D24, SP_D25, SP_D26, SP_D27, SP_D28, SP_D29, SP_D30, SP_D31,
};
// DFPRegs Bit set.
static uint8_t DFPRegsBits[] = {
0xf8, 0xff, 0xff, 0xff, 0x07,
};
// I64Regs Register Class...
static uint16_t I64Regs[] = {
SP_I0, SP_I1, SP_I2, SP_I3, SP_I4, SP_I5, SP_I6, SP_I7, SP_G0, SP_G1, SP_G2, SP_G3, SP_G4, SP_G5, SP_G6, SP_G7, SP_L0, SP_L1, SP_L2, SP_L3, SP_L4, SP_L5, SP_L6, SP_L7, SP_O0, SP_O1, SP_O2, SP_O3, SP_O4, SP_O5, SP_O6, SP_O7,
};
// I64Regs Bit set.
static uint8_t I64RegsBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f,
};
// DFPRegs_with_sub_even Register Class...
static uint16_t DFPRegs_with_sub_even[] = {
SP_D0, SP_D1, SP_D2, SP_D3, SP_D4, SP_D5, SP_D6, SP_D7, SP_D8, SP_D9, SP_D10, SP_D11, SP_D12, SP_D13, SP_D14, SP_D15,
};
// DFPRegs_with_sub_even Bit set.
static uint8_t DFPRegs_with_sub_evenBits[] = {
0xf8, 0xff, 0x07,
};
// QFPRegs Register Class...
static uint16_t QFPRegs[] = {
SP_Q0, SP_Q1, SP_Q2, SP_Q3, SP_Q4, SP_Q5, SP_Q6, SP_Q7, SP_Q8, SP_Q9, SP_Q10, SP_Q11, SP_Q12, SP_Q13, SP_Q14, SP_Q15,
};
// QFPRegs Bit set.
static uint8_t QFPRegsBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f,
};
// QFPRegs_with_sub_even Register Class...
static uint16_t QFPRegs_with_sub_even[] = {
SP_Q0, SP_Q1, SP_Q2, SP_Q3, SP_Q4, SP_Q5, SP_Q6, SP_Q7,
};
// QFPRegs_with_sub_even Bit set.
static uint8_t QFPRegs_with_sub_evenBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f,
};
static MCRegisterClass SparcMCRegisterClasses[] = {
{ "FCCRegs", FCCRegs, FCCRegsBits, 4, sizeof(FCCRegsBits), SP_FCCRegsRegClassID, 0, 0, 1, 1 },
{ "FPRegs", FPRegs, FPRegsBits, 32, sizeof(FPRegsBits), SP_FPRegsRegClassID, 4, 4, 1, 1 },
{ "IntRegs", IntRegs, IntRegsBits, 32, sizeof(IntRegsBits), SP_IntRegsRegClassID, 4, 4, 1, 1 },
{ "DFPRegs", DFPRegs, DFPRegsBits, 32, sizeof(DFPRegsBits), SP_DFPRegsRegClassID, 8, 8, 1, 1 },
{ "I64Regs", I64Regs, I64RegsBits, 32, sizeof(I64RegsBits), SP_I64RegsRegClassID, 8, 8, 1, 1 },
{ "DFPRegs_with_sub_even", DFPRegs_with_sub_even, DFPRegs_with_sub_evenBits, 16, sizeof(DFPRegs_with_sub_evenBits), SP_DFPRegs_with_sub_evenRegClassID, 8, 8, 1, 1 },
{ "QFPRegs", QFPRegs, QFPRegsBits, 16, sizeof(QFPRegsBits), SP_QFPRegsRegClassID, 16, 16, 1, 1 },
{ "QFPRegs_with_sub_even", QFPRegs_with_sub_even, QFPRegs_with_sub_evenBits, 8, sizeof(QFPRegs_with_sub_evenBits), SP_QFPRegs_with_sub_evenRegClassID, 16, 16, 1, 1 },
};
#endif // GET_REGINFO_MC_DESC

View File

@ -0,0 +1,27 @@
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|* *|
|*Subtarget Enumeration Source Fragment *|
|* *|
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#ifdef GET_SUBTARGETINFO_ENUM
#undef GET_SUBTARGETINFO_ENUM
enum {
Sparc_FeatureHardQuad = 1ULL << 0,
Sparc_FeatureV8Deprecated = 1ULL << 1,
Sparc_FeatureV9 = 1ULL << 2,
Sparc_FeatureVIS = 1ULL << 3,
Sparc_FeatureVIS2 = 1ULL << 4,
Sparc_FeatureVIS3 = 1ULL << 5,
Sparc_UsePopc = 1ULL << 6
};
#endif // GET_SUBTARGETINFO_ENUM

View File

@ -0,0 +1,266 @@
//===-- SparcInstPrinter.cpp - Convert Sparc MCInst to assembly syntax --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints an Sparc MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SparcInstPrinter.h"
#include "../../MCInst.h"
#include "../../utils.h"
#include "../../SStream.h"
#include "../../MCRegisterInfo.h"
#include "../../MathExtras.h"
#include "SparcMapping.h"
#include "Sparc.h"
static const char *getRegisterName(unsigned RegNo);
static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
static void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier);
static void printOperand(MCInst *MI, int opNum, SStream *O);
static void set_mem_access(MCInst *MI, bool status)
{
if (MI->csh->detail != CS_OPT_ON)
return;
MI->csh->doing_mem = status;
if (status) {
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].type = SPARC_OP_MEM;
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].mem.base = SPARC_REG_INVALID;
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].mem.disp = 0;
} else {
// done, create the next operand slot
MI->flat_insn.sparc.op_count++;
}
}
void Sparc_post_printer(csh ud, cs_insn *insn, char *insn_asm)
{
if (((cs_struct *)ud)->detail != CS_OPT_ON)
return;
// fix up some instructions
if (insn->id == SPARC_INS_CASX) {
// first op is actually a memop, not regop
insn->detail->sparc.operands[0].type = SPARC_OP_MEM;
insn->detail->sparc.operands[0].mem.base = insn->detail->sparc.operands[0].reg;
insn->detail->sparc.operands[0].mem.disp = 0;
}
}
static void printRegName(SStream *OS, unsigned RegNo)
{
SStream_concat(OS, "%%%s", getRegisterName(RegNo));
}
#define GET_INSTRINFO_ENUM
#include "SparcGenInstrInfo.inc"
#define GET_REGINFO_ENUM
#include "SparcGenRegisterInfo.inc"
static bool printSparcAliasInstr(MCInst *MI, SStream *O)
{
switch (MCInst_getOpcode(MI)) {
default: return false;
case SP_JMPLrr:
case SP_JMPLri:
if (MCInst_getNumOperands(MI) != 3)
return false;
if (!MCOperand_isReg(MCInst_getOperand(MI, 0)))
return false;
switch (MCOperand_getReg(MCInst_getOperand(MI, 0))) {
default: return false;
case SP_G0: // jmp $addr | ret | retl
if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&
MCOperand_getImm(MCInst_getOperand(MI, 2)) == 8) {
switch(MCOperand_getReg(MCInst_getOperand(MI, 1))) {
default: break;
case SP_I7: SStream_concat(O, "\tret"); return true;
case SP_O7: SStream_concat(O, "\tretl"); return true;
}
}
SStream_concat(O, "\tjmp ");
printMemOperand(MI, 1, O, NULL);
return true;
case SP_O7: // call $addr
SStream_concat(O, "\tcall ");
printMemOperand(MI, 1, O, NULL);
return true;
}
case SP_V9FCMPS:
case SP_V9FCMPD:
case SP_V9FCMPQ:
case SP_V9FCMPES:
case SP_V9FCMPED:
case SP_V9FCMPEQ:
if (MI->csh->mode & CS_MODE_V9 || (MCInst_getNumOperands(MI) != 3) ||
(!MCOperand_isReg(MCInst_getOperand(MI, 0))) ||
(MCOperand_getReg(MCInst_getOperand(MI, 0)) != SP_FCC0))
return false;
// if V8, skip printing %fcc0.
switch(MCInst_getOpcode(MI)) {
default:
case SP_V9FCMPS: SStream_concat(O, "\tfcmps "); break;
case SP_V9FCMPD: SStream_concat(O, "\tfcmpd "); break;
case SP_V9FCMPQ: SStream_concat(O, "\tfcmpq "); break;
case SP_V9FCMPES: SStream_concat(O, "\tfcmpes "); break;
case SP_V9FCMPED: SStream_concat(O, "\tfcmped "); break;
case SP_V9FCMPEQ: SStream_concat(O, "\tfcmpeq "); break;
}
printOperand(MI, 1, O);
SStream_concat(O, ", ");
printOperand(MI, 2, O);
return true;
}
}
static void printOperand(MCInst *MI, int opNum, SStream *O)
{
int Imm;
unsigned reg;
MCOperand *MO = MCInst_getOperand(MI, opNum);
if (MCOperand_isReg(MO)) {
reg = MCOperand_getReg(MO);
printRegName(O, reg);
reg = Sparc_map_register(reg);
if (MI->csh->detail) {
if (MI->csh->doing_mem) {
if (MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].mem.base)
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].mem.index = reg;
else
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].mem.base = reg;
} else {
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].type = SPARC_OP_REG;
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].reg = reg;
MI->flat_insn.sparc.op_count++;
}
}
return;
}
if (MCOperand_isImm(MO)) {
Imm = (int)MCOperand_getImm(MO);
if (Imm > HEX_THRESHOLD)
SStream_concat(O, "0x%x", Imm);
else
SStream_concat(O, "%u", Imm);
if (MI->csh->detail) {
if (MI->csh->doing_mem) {
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].mem.disp = Imm;
} else {
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].type = SPARC_OP_IMM;
MI->flat_insn.sparc.operands[MI->flat_insn.sparc.op_count].imm = Imm;
MI->flat_insn.sparc.op_count++;
}
}
}
return;
}
static void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier)
{
MCOperand *MO;
set_mem_access(MI, true);
printOperand(MI, opNum, O);
// If this is an ADD operand, emit it like normal operands.
if (Modifier && !strcmp(Modifier, "arith")) {
SStream_concat(O, ", ");
printOperand(MI, opNum + 1, O);
set_mem_access(MI, false);
return;
}
MO = MCInst_getOperand(MI, opNum + 1);
if (MCOperand_isReg(MO) && (MCOperand_getReg(MO) == SP_G0)) {
set_mem_access(MI, false);
return; // don't print "+%g0"
}
if (MCOperand_isImm(MO) && (MCOperand_getImm(MO) == 0)) {
set_mem_access(MI, false);
return; // don't print "+0"
}
SStream_concat(O, "+");
printOperand(MI, opNum + 1, O);
set_mem_access(MI, false);
}
static void printCCOperand(MCInst *MI, int opNum, SStream *O)
{
int CC = (int)MCOperand_getImm(MCInst_getOperand(MI, opNum));
switch (MCInst_getOpcode(MI)) {
default: break;
case SP_FBCOND:
case SP_FBCONDA:
case SP_BPFCC:
case SP_BPFCCA:
case SP_BPFCCNT:
case SP_BPFCCANT:
case SP_MOVFCCrr: case SP_V9MOVFCCrr:
case SP_MOVFCCri: case SP_V9MOVFCCri:
case SP_FMOVS_FCC: case SP_V9FMOVS_FCC:
case SP_FMOVD_FCC: case SP_V9FMOVD_FCC:
case SP_FMOVQ_FCC: case SP_V9FMOVQ_FCC:
// Make sure CC is a fp conditional flag.
CC = (CC < 16) ? (CC + 16) : CC;
break;
}
SStream_concat(O, "%s", SPARCCondCodeToString((sparc_cc)CC));
if (MI->csh->detail)
MI->flat_insn.sparc.cc = (sparc_cc)CC;
}
static bool printGetPCX(MCInst *MI, unsigned opNum, SStream *O)
{
return true;
}
#define PRINT_ALIAS_INSTR
#include "SparcGenAsmWriter.inc"
void Sparc_printInst(MCInst *MI, SStream *O, void *Info)
{
char *mnem;
mnem = printAliasInstr(MI, O, Info);
if (mnem)
cs_mem_free(mnem);
else {
if (!printSparcAliasInstr(MI, O))
printInstruction(MI, O, NULL);
}
}

View File

@ -0,0 +1,15 @@
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#ifndef CS_SPARCINSTPRINTER_H
#define CS_SPARCINSTPRINTER_H
#include "../../MCInst.h"
#include "../../MCRegisterInfo.h"
#include "../../SStream.h"
void Sparc_printInst(MCInst *MI, SStream *O, void *Info);
void Sparc_post_printer(csh ud, cs_insn *insn, char *insn_asm);
#endif

3179
arch/Sparc/SparcMapping.c Normal file

File diff suppressed because it is too large Load Diff

22
arch/Sparc/SparcMapping.h Normal file
View File

@ -0,0 +1,22 @@
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#ifndef CS_SPARC_MAP_H
#define CS_SPARC_MAP_H
#include "../../include/capstone.h"
#include "../../include/sparc.h"
// return name of regiser in friendly string
const char *Sparc_reg_name(csh handle, unsigned int reg);
// given internal insn id, return public instruction info
void Sparc_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
const char *Sparc_insn_name(csh handle, unsigned int id);
// map internal raw register to 'public' register
sparc_reg Sparc_map_register(unsigned int r);
#endif

54
arch/Sparc/SparcModule.c Normal file
View File

@ -0,0 +1,54 @@
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include "../../utils.h"
#include "../../MCRegisterInfo.h"
#include "SparcDisassembler.h"
#include "SparcInstPrinter.h"
#include "SparcMapping.h"
static cs_err init(cs_struct *ud)
{
MCRegisterInfo *mri;
// verify if requested mode is valid
if (ud->mode & ~(CS_MODE_BIG_ENDIAN | CS_MODE_V9))
return CS_ERR_MODE;
mri = cs_mem_malloc(sizeof(*mri));
Sparc_init(mri);
ud->printer = Sparc_printInst;
ud->printer_info = mri;
ud->getinsn_info = mri;
ud->disasm = Sparc_getInstruction;
ud->post_printer = Sparc_post_printer;
ud->reg_name = Sparc_reg_name;
ud->insn_id = Sparc_get_insn_id;
ud->insn_name = Sparc_insn_name;
return CS_ERR_OK;
}
static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
{
if (type == CS_OPT_SYNTAX)
handle->syntax = value;
return CS_ERR_OK;
}
static void destroy(cs_struct *handle)
{
}
void Sparc_enable(void)
{
arch_init[CS_ARCH_SPARC] = init;
arch_option[CS_ARCH_SPARC] = option;
arch_destroy[CS_ARCH_SPARC] = destroy;
// support this arch
all_arch |= (1 << CS_ARCH_SPARC);
}

View File

@ -18,6 +18,9 @@ CAPSTONE_ARCHS += mips
# Comment out the line below if you don't want to support PowerPC # Comment out the line below if you don't want to support PowerPC
CAPSTONE_ARCHS += powerpc CAPSTONE_ARCHS += powerpc
# Comment out the line below if you don't want to support Sparc
CAPSTONE_ARCHS += sparc
# Comment out the line below if you don't want to support Intel (16/32/64-bit) # Comment out the line below if you don't want to support Intel (16/32/64-bit)
CAPSTONE_ARCHS += x86 CAPSTONE_ARCHS += x86

25
cs.c
View File

@ -26,6 +26,7 @@ extern void AArch64_enable(void);
extern void Mips_enable(void); extern void Mips_enable(void);
extern void X86_enable(void); extern void X86_enable(void);
extern void PPC_enable(void); extern void PPC_enable(void);
extern void Sparc_enable(void);
static void archs_enable(void) static void archs_enable(void)
{ {
@ -43,12 +44,15 @@ static void archs_enable(void)
#ifdef CAPSTONE_HAS_MIPS #ifdef CAPSTONE_HAS_MIPS
Mips_enable(); Mips_enable();
#endif #endif
#ifdef CAPSTONE_HAS_X86
X86_enable();
#endif
#ifdef CAPSTONE_HAS_POWERPC #ifdef CAPSTONE_HAS_POWERPC
PPC_enable(); PPC_enable();
#endif #endif
#ifdef CAPSTONE_HAS_SPARC
Sparc_enable();
#endif
#ifdef CAPSTONE_HAS_X86
X86_enable();
#endif
initialized = true; initialized = true;
} }
@ -88,7 +92,7 @@ bool cs_support(int query)
if (query == CS_ARCH_ALL) if (query == CS_ARCH_ALL)
return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) | return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) |
(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) | (1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
(1 << CS_ARCH_PPC)); (1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC));
if ((unsigned int)query < CS_ARCH_MAX) if ((unsigned int)query < CS_ARCH_MAX)
return all_arch & (1 << query); return all_arch & (1 << query);
@ -576,6 +580,11 @@ int cs_op_count(csh ud, cs_insn *insn, unsigned int op_type)
if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type) if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type)
count++; count++;
break; break;
case CS_ARCH_SPARC:
for (i = 0; i < insn->detail->sparc.op_count; i++)
if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
count++;
break;
} }
return count; return count;
@ -641,6 +650,14 @@ int cs_op_index(csh ud, cs_insn *insn, unsigned int op_type,
return i; return i;
} }
break; break;
case CS_ARCH_SPARC:
for (i = 0; i < insn->detail->sparc.op_count; i++) {
if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
count++;
if (count == post)
return i;
}
break;
} }
return -1; return -1;

View File

@ -39,6 +39,7 @@ typedef enum cs_arch {
CS_ARCH_MIPS, // Mips architecture CS_ARCH_MIPS, // Mips architecture
CS_ARCH_X86, // X86 architecture (including x86 & x86-64) CS_ARCH_X86, // X86 architecture (including x86 & x86-64)
CS_ARCH_PPC, // PowerPC architecture CS_ARCH_PPC, // PowerPC architecture
CS_ARCH_SPARC, // Sparc architecture
CS_ARCH_MAX, CS_ARCH_MAX,
CS_ARCH_ALL = 0xFFFF, CS_ARCH_ALL = 0xFFFF,
} cs_arch; } cs_arch;
@ -56,6 +57,8 @@ typedef enum cs_mode {
CS_MODE_MICRO = 1 << 4, // MicroMips mode (MIPS architecture) CS_MODE_MICRO = 1 << 4, // MicroMips mode (MIPS architecture)
CS_MODE_N64 = 1 << 5, // Nintendo-64 mode (MIPS architecture) CS_MODE_N64 = 1 << 5, // Nintendo-64 mode (MIPS architecture)
CS_MODE_V9 = 1 << 4, // SparcV9 mode (Sparc architecture)
CS_MODE_BIG_ENDIAN = 1 << 31 // big endian mode CS_MODE_BIG_ENDIAN = 1 << 31 // big endian mode
} cs_mode; } cs_mode;
@ -100,6 +103,7 @@ typedef enum cs_opt_value {
#include "mips.h" #include "mips.h"
#include "x86.h" #include "x86.h"
#include "ppc.h" #include "ppc.h"
#include "sparc.h"
// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON // NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
typedef struct cs_detail { typedef struct cs_detail {
@ -119,6 +123,7 @@ typedef struct cs_detail {
cs_arm arm; // ARM architecture (including Thumb/Thumb2) cs_arm arm; // ARM architecture (including Thumb/Thumb2)
cs_mips mips; // MIPS architecture cs_mips mips; // MIPS architecture
cs_ppc ppc; // PowerPC architecture cs_ppc ppc; // PowerPC architecture
cs_sparc sparc; // Sparc architecture
}; };
} cs_detail; } cs_detail;

View File

@ -1,5 +1,5 @@
# Capstone Disassembler Engine # Capstone Disassembler Engine
# By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> # By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014
include ../config.mk include ../config.mk
@ -51,6 +51,9 @@ endif
ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS))) ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS)))
SOURCES += test_ppc.c SOURCES += test_ppc.c
endif endif
ifneq (,$(findstring sparc,$(CAPSTONE_ARCHS)))
SOURCES += test_sparc.c
endif
ifneq (,$(findstring x86,$(CAPSTONE_ARCHS))) ifneq (,$(findstring x86,$(CAPSTONE_ARCHS)))
SOURCES += test_x86.c SOURCES += test_x86.c
endif endif

View File

@ -48,6 +48,8 @@ static void test()
#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9" #define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9"
#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" #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"
#define SPARC_CODE "\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03"
struct platform platforms[] = { struct platform platforms[] = {
{ {
.arch = CS_ARCH_X86, .arch = CS_ARCH_X86,
@ -144,6 +146,13 @@ static void test()
.opt_value = CS_OPT_SYNTAX_NOREGNAME, .opt_value = CS_OPT_SYNTAX_NOREGNAME,
.comment = "PPC-64, print register with number only" .comment = "PPC-64, print register with number only"
}, },
{
.arch = CS_ARCH_SPARC,
.mode = CS_MODE_BIG_ENDIAN,
.code = (unsigned char*)SPARC_CODE,
.size = sizeof(SPARC_CODE) - 1,
.comment = "Sparc"
},
}; };
csh handle; csh handle;

View File

@ -53,6 +53,8 @@ static void test()
//#define THUMB_CODE "\x0a\xbf" // itet eq //#define THUMB_CODE "\x0a\xbf" // itet eq
//#define X86_CODE32 "\x77\x04" // ja +6 //#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" #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"
#define SPARC_CODE "\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03"
struct platform platforms[] = { struct platform platforms[] = {
{ {
@ -141,6 +143,13 @@ static void test()
.size = sizeof(PPC_CODE) - 1, .size = sizeof(PPC_CODE) - 1,
.comment = "PPC-64" .comment = "PPC-64"
}, },
{
.arch = CS_ARCH_SPARC,
.mode = CS_MODE_BIG_ENDIAN,
.code = (unsigned char*)SPARC_CODE,
.size = sizeof(SPARC_CODE) - 1,
.comment = "Sparc"
},
}; };
csh handle; csh handle;

135
tests/test_sparc.c Normal file
View File

@ -0,0 +1,135 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <inttypes.h>
#include <capstone.h>
struct platform {
cs_arch arch;
cs_mode mode;
unsigned char *code;
size_t size;
char *comment;
};
static csh handle;
static void print_string_hex(char *comment, unsigned char *str, int len)
{
unsigned char *c;
printf("%s", comment);
for (c = str; c < str + len; c++) {
printf("0x%02x ", *c & 0xff);
}
printf("\n");
}
static void print_insn_detail(cs_insn *ins)
{
cs_sparc *sparc = &(ins->detail->sparc);
if (sparc->op_count)
printf("\top_count: %u\n", sparc->op_count);
int i;
for (i = 0; i < sparc->op_count; i++) {
cs_sparc_op *op = &(sparc->operands[i]);
switch((int)op->type) {
default:
break;
case SPARC_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case SPARC_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
break;
case SPARC_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != X86_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != X86_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
break;
}
}
if (sparc->cc != 0)
printf("\tCode condition: %u\n", sparc->cc);
if (sparc->hint != 0)
printf("\tHint code: %u\n", sparc->hint);
printf("\n");
}
static void test()
{
#define SPARC_CODE "\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03"
struct platform platforms[] = {
{
.arch = CS_ARCH_SPARC,
.mode = CS_MODE_BIG_ENDIAN,
.code = (unsigned char*)SPARC_CODE,
.size = sizeof(SPARC_CODE) - 1,
.comment = "Sparc",
}
};
uint64_t address = 0x1000;
cs_insn *insn;
int i;
for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
if (err) {
printf("Failed on cs_open() with error returned: %u\n", err);
continue;
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
size_t count = cs_disasm_ex(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
if (count) {
printf("****************\n");
printf("Platform: %s\n", platforms[i].comment);
print_string_hex("Code:", platforms[i].code, platforms[i].size);
printf("Disasm:\n");
size_t j;
for (j = 0; j < count; j++) {
printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
print_insn_detail(&insn[j]);
}
printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size);
// free memory allocated by cs_disasm_ex()
cs_free(insn, count);
} else {
printf("****************\n");
printf("Platform: %s\n", platforms[i].comment);
print_string_hex("Code:", platforms[i].code, platforms[i].size);
printf("ERROR: Failed to disasm given code!\n");
}
printf("\n");
cs_close(&handle);
}
}
int main()
{
test();
return 0;
}