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.
Out of 5 archtitectures supported by Capstone (Arm, Arm64, Mips, PPC & X86),
if you just need several selected archs, you can choose which ones you want
to compile in by modifying config.mk before going to next steps.
Out of 6 archtitectures supported by Capstone (Arm, Arm64, Mips, PPC, Sparc &
X86), if you just need several selected archs, you can choose which ones you
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
@ -54,6 +56,8 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
/usr/include/capstone/arm64.h
/usr/include/capstone/mips.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.a

View File

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

View File

@ -114,6 +114,23 @@ ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS)))
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 += arch/X86/X86GenAsmWriter.inc
DEP_X86 += arch/X86/X86GenAsmWriter1.inc
@ -134,7 +151,7 @@ endif
LIBOBJ =
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
@ -202,6 +219,7 @@ $(LIBOBJ_ARM): $(DEP_ARM)
$(LIBOBJ_ARM64): $(DEP_ARM64)
$(LIBOBJ_MIPS): $(DEP_MIPS)
$(LIBOBJ_PPC): $(DEP_PPC)
$(LIBOBJ_SPARC): $(DEP_SPARC)
$(LIBOBJ_X86): $(DEP_X86)
# 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,
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.

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
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)
CAPSTONE_ARCHS += x86

25
cs.c
View File

@ -26,6 +26,7 @@ extern void AArch64_enable(void);
extern void Mips_enable(void);
extern void X86_enable(void);
extern void PPC_enable(void);
extern void Sparc_enable(void);
static void archs_enable(void)
{
@ -43,12 +44,15 @@ static void archs_enable(void)
#ifdef CAPSTONE_HAS_MIPS
Mips_enable();
#endif
#ifdef CAPSTONE_HAS_X86
X86_enable();
#endif
#ifdef CAPSTONE_HAS_POWERPC
PPC_enable();
#endif
#ifdef CAPSTONE_HAS_SPARC
Sparc_enable();
#endif
#ifdef CAPSTONE_HAS_X86
X86_enable();
#endif
initialized = true;
}
@ -88,7 +92,7 @@ bool cs_support(int query)
if (query == CS_ARCH_ALL)
return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) |
(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)
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)
count++;
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;
@ -641,6 +650,14 @@ int cs_op_index(csh ud, cs_insn *insn, unsigned int op_type,
return i;
}
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;

View File

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

View File

@ -1,5 +1,5 @@
# Capstone Disassembler Engine
# By Nguyen Anh Quynh <aquynh@gmail.com>, 2013>
# By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014
include ../config.mk
@ -51,6 +51,9 @@ endif
ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS)))
SOURCES += test_ppc.c
endif
ifneq (,$(findstring sparc,$(CAPSTONE_ARCHS)))
SOURCES += test_sparc.c
endif
ifneq (,$(findstring x86,$(CAPSTONE_ARCHS)))
SOURCES += test_x86.c
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 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[] = {
{
.arch = CS_ARCH_X86,
@ -144,6 +146,13 @@ static void test()
.opt_value = CS_OPT_SYNTAX_NOREGNAME,
.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;

View File

@ -53,6 +53,8 @@ static void test()
//#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"
#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[] = {
{
@ -141,6 +143,13 @@ static void test()
.size = sizeof(PPC_CODE) - 1,
.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;

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