Imported Upstream version 3.0 upstream upstream/3.0
authorSophie Brun <sophie@freexian.com>
Mon, 24 Nov 2014 09:04:14 +0000 (10:04 +0100)
committerSophie Brun <sophie@freexian.com>
Mon, 24 Nov 2014 09:04:14 +0000 (10:04 +0100)
555 files changed:
.gitignore
CMakeLists.txt [new file with mode: 0644]
COMPILE.TXT
COMPILE_CMAKE.TXT [new file with mode: 0644]
COMPILE_MSVC.TXT [new file with mode: 0644]
CREDITS.TXT
ChangeLog
HACK.TXT
LEB128.h
MCDisassembler.h
MCFixedLenDisassembler.h
MCInst.c
MCInst.h
MCInstrDesc.c
MCInstrDesc.h
MCRegisterInfo.c
MCRegisterInfo.h
Makefile
MathExtras.h
README
RELEASE_NOTES
SStream.c
SStream.h
SubtargetFeature.h [deleted file]
TODO
arch/AArch64/AArch64AddressingModes.h [new file with mode: 0644]
arch/AArch64/AArch64BaseInfo.c
arch/AArch64/AArch64BaseInfo.h
arch/AArch64/AArch64Disassembler.c
arch/AArch64/AArch64Disassembler.h
arch/AArch64/AArch64GenAsmWriter.inc
arch/AArch64/AArch64GenDisassemblerTables.inc
arch/AArch64/AArch64GenInstrInfo.inc
arch/AArch64/AArch64GenRegisterInfo.inc
arch/AArch64/AArch64GenSubtargetInfo.inc
arch/AArch64/AArch64InstPrinter.c
arch/AArch64/AArch64InstPrinter.h
arch/AArch64/AArch64Mapping.c
arch/AArch64/AArch64Mapping.h
arch/AArch64/AArch64Module.c
arch/ARM/ARMAddressingModes.h
arch/ARM/ARMBaseInfo.h
arch/ARM/ARMDisassembler.c
arch/ARM/ARMDisassembler.h
arch/ARM/ARMGenAsmWriter.inc
arch/ARM/ARMGenDisassemblerTables.inc
arch/ARM/ARMGenInstrInfo.inc
arch/ARM/ARMGenRegisterInfo.inc
arch/ARM/ARMGenSubtargetInfo.inc
arch/ARM/ARMInstPrinter.c
arch/ARM/ARMInstPrinter.h
arch/ARM/ARMMapping.c
arch/ARM/ARMMapping.h
arch/ARM/ARMModule.c
arch/Mips/MipsDisassembler.c
arch/Mips/MipsDisassembler.h
arch/Mips/MipsGenAsmWriter.inc
arch/Mips/MipsGenDisassemblerTables.inc
arch/Mips/MipsGenInstrInfo.inc
arch/Mips/MipsGenRegisterInfo.inc
arch/Mips/MipsGenSubtargetInfo.inc
arch/Mips/MipsInstPrinter.c
arch/Mips/MipsInstPrinter.h
arch/Mips/MipsMapping.c
arch/Mips/MipsMapping.h
arch/Mips/MipsModule.c
arch/PowerPC/PPCDisassembler.c
arch/PowerPC/PPCDisassembler.h
arch/PowerPC/PPCGenAsmWriter.inc
arch/PowerPC/PPCGenDisassemblerTables.inc
arch/PowerPC/PPCGenInstrInfo.inc
arch/PowerPC/PPCGenRegisterInfo.inc
arch/PowerPC/PPCGenSubtargetInfo.inc
arch/PowerPC/PPCInstPrinter.c
arch/PowerPC/PPCInstPrinter.h
arch/PowerPC/PPCMapping.c
arch/PowerPC/PPCMapping.h
arch/PowerPC/PPCModule.c
arch/PowerPC/PPCPredicates.h
arch/Sparc/Sparc.h [new file with mode: 0644]
arch/Sparc/SparcDisassembler.c [new file with mode: 0644]
arch/Sparc/SparcDisassembler.h [new file with mode: 0644]
arch/Sparc/SparcGenAsmWriter.inc [new file with mode: 0644]
arch/Sparc/SparcGenDisassemblerTables.inc [new file with mode: 0644]
arch/Sparc/SparcGenInstrInfo.inc [new file with mode: 0644]
arch/Sparc/SparcGenRegisterInfo.inc [new file with mode: 0644]
arch/Sparc/SparcGenSubtargetInfo.inc [new file with mode: 0644]
arch/Sparc/SparcInstPrinter.c [new file with mode: 0644]
arch/Sparc/SparcInstPrinter.h [new file with mode: 0644]
arch/Sparc/SparcMapping.c [new file with mode: 0644]
arch/Sparc/SparcMapping.h [new file with mode: 0644]
arch/Sparc/SparcModule.c [new file with mode: 0644]
arch/SystemZ/SystemZDisassembler.c [new file with mode: 0644]
arch/SystemZ/SystemZDisassembler.h [new file with mode: 0644]
arch/SystemZ/SystemZGenAsmWriter.inc [new file with mode: 0644]
arch/SystemZ/SystemZGenDisassemblerTables.inc [new file with mode: 0644]
arch/SystemZ/SystemZGenInstrInfo.inc [new file with mode: 0644]
arch/SystemZ/SystemZGenRegisterInfo.inc [new file with mode: 0644]
arch/SystemZ/SystemZGenSubtargetInfo.inc [new file with mode: 0644]
arch/SystemZ/SystemZInstPrinter.c [new file with mode: 0644]
arch/SystemZ/SystemZInstPrinter.h [new file with mode: 0644]
arch/SystemZ/SystemZMCTargetDesc.c [new file with mode: 0644]
arch/SystemZ/SystemZMCTargetDesc.h [new file with mode: 0644]
arch/SystemZ/SystemZMapping.c [new file with mode: 0644]
arch/SystemZ/SystemZMapping.h [new file with mode: 0644]
arch/SystemZ/SystemZModule.c [new file with mode: 0644]
arch/X86/X86ATTInstPrinter.c
arch/X86/X86BaseInfo.h [new file with mode: 0644]
arch/X86/X86Disassembler.c
arch/X86/X86Disassembler.h
arch/X86/X86DisassemblerDecoder.c
arch/X86/X86DisassemblerDecoder.h
arch/X86/X86DisassemblerDecoderCommon.h
arch/X86/X86GenAsmWriter.inc
arch/X86/X86GenAsmWriter1.inc
arch/X86/X86GenAsmWriter1_reduce.inc [new file with mode: 0644]
arch/X86/X86GenAsmWriter_reduce.inc [new file with mode: 0644]
arch/X86/X86GenDisassemblerTables.inc
arch/X86/X86GenDisassemblerTables_reduce.inc [new file with mode: 0644]
arch/X86/X86GenInstrInfo.inc
arch/X86/X86GenInstrInfo_reduce.inc [new file with mode: 0644]
arch/X86/X86GenRegisterInfo.inc
arch/X86/X86InstPrinter.h
arch/X86/X86IntelInstPrinter.c
arch/X86/X86Mapping.c
arch/X86/X86Mapping.h
arch/X86/X86Module.c
arch/XCore/XCoreDisassembler.c [new file with mode: 0644]
arch/XCore/XCoreDisassembler.h [new file with mode: 0644]
arch/XCore/XCoreGenAsmWriter.inc [new file with mode: 0644]
arch/XCore/XCoreGenDisassemblerTables.inc [new file with mode: 0644]
arch/XCore/XCoreGenInstrInfo.inc [new file with mode: 0644]
arch/XCore/XCoreGenRegisterInfo.inc [new file with mode: 0644]
arch/XCore/XCoreInstPrinter.c [new file with mode: 0644]
arch/XCore/XCoreInstPrinter.h [new file with mode: 0644]
arch/XCore/XCoreMapping.c [new file with mode: 0644]
arch/XCore/XCoreMapping.h [new file with mode: 0644]
arch/XCore/XCoreModule.c [new file with mode: 0644]
bindings/Makefile
bindings/README [new file with mode: 0644]
bindings/const_generator.py
bindings/java/Makefile
bindings/java/Test.java
bindings/java/TestArm.java
bindings/java/TestArm64.java
bindings/java/TestMips.java
bindings/java/TestPpc.java
bindings/java/TestSparc.java [new file with mode: 0644]
bindings/java/TestSystemz.java [new file with mode: 0644]
bindings/java/TestX86.java
bindings/java/TestXcore.java [new file with mode: 0644]
bindings/java/capstone/Arm.java
bindings/java/capstone/Arm64.java
bindings/java/capstone/Arm64_const.java
bindings/java/capstone/Arm_const.java
bindings/java/capstone/Capstone.java
bindings/java/capstone/Mips_const.java
bindings/java/capstone/Ppc.java
bindings/java/capstone/Ppc_const.java
bindings/java/capstone/Sparc.java [new file with mode: 0644]
bindings/java/capstone/Sparc_const.java [new file with mode: 0644]
bindings/java/capstone/Systemz.java [new file with mode: 0644]
bindings/java/capstone/Sysz_const.java [new file with mode: 0644]
bindings/java/capstone/X86.java
bindings/java/capstone/X86_const.java
bindings/java/capstone/Xcore.java [new file with mode: 0644]
bindings/java/capstone/Xcore_const.java [new file with mode: 0644]
bindings/java/run.sh
bindings/ocaml/Makefile
bindings/ocaml/README
bindings/ocaml/arm.ml
bindings/ocaml/arm64.ml
bindings/ocaml/arm64_const.ml [new file with mode: 0644]
bindings/ocaml/arm_const.ml [new file with mode: 0644]
bindings/ocaml/capstone.ml
bindings/ocaml/mips.ml
bindings/ocaml/mips_const.ml [new file with mode: 0644]
bindings/ocaml/ocaml.c
bindings/ocaml/ppc.ml [new file with mode: 0644]
bindings/ocaml/ppc_const.ml [new file with mode: 0644]
bindings/ocaml/sparc.ml [new file with mode: 0644]
bindings/ocaml/sparc_const.ml [new file with mode: 0644]
bindings/ocaml/systemz.ml [new file with mode: 0644]
bindings/ocaml/sysz_const.ml [new file with mode: 0644]
bindings/ocaml/test.ml
bindings/ocaml/test_arm.ml
bindings/ocaml/test_arm64.ml
bindings/ocaml/test_detail.ml
bindings/ocaml/test_mips.ml
bindings/ocaml/test_ppc.ml [new file with mode: 0644]
bindings/ocaml/test_sparc.ml [new file with mode: 0644]
bindings/ocaml/test_systemz.ml [new file with mode: 0644]
bindings/ocaml/test_x86.ml
bindings/ocaml/test_xcore.ml [new file with mode: 0644]
bindings/ocaml/x86.ml
bindings/ocaml/x86_const.ml [new file with mode: 0644]
bindings/ocaml/xcore.ml [new file with mode: 0644]
bindings/ocaml/xcore_const.ml [new file with mode: 0644]
bindings/python/Makefile
bindings/python/README
bindings/python/capstone/__init__.py
bindings/python/capstone/arm.py
bindings/python/capstone/arm64.py
bindings/python/capstone/arm64_const.py
bindings/python/capstone/arm_const.py
bindings/python/capstone/capstone.py [deleted file]
bindings/python/capstone/mips.py
bindings/python/capstone/mips_const.py
bindings/python/capstone/ppc.py
bindings/python/capstone/ppc_const.py
bindings/python/capstone/sparc.py [new file with mode: 0644]
bindings/python/capstone/sparc_const.py [new file with mode: 0644]
bindings/python/capstone/systemz.py [new file with mode: 0644]
bindings/python/capstone/sysz_const.py [new file with mode: 0644]
bindings/python/capstone/x86.py
bindings/python/capstone/x86_const.py
bindings/python/capstone/xcore.py [new file with mode: 0644]
bindings/python/capstone/xcore_const.py [new file with mode: 0644]
bindings/python/pyx/ccapstone.pxd
bindings/python/pyx/ccapstone.pyx
bindings/python/setup.py
bindings/python/setup_cython.py
bindings/python/test.py
bindings/python/test_all.py [new file with mode: 0755]
bindings/python/test_arm.py
bindings/python/test_arm64.py
bindings/python/test_detail.py
bindings/python/test_lite.py
bindings/python/test_mips.py
bindings/python/test_ppc.py
bindings/python/test_skipdata.py [new file with mode: 0755]
bindings/python/test_sparc.py [new file with mode: 0755]
bindings/python/test_systemz.py [new file with mode: 0755]
bindings/python/test_x86.py
bindings/python/test_xcore.py [new file with mode: 0755]
bindings/python/xprint.py [new file with mode: 0755]
config.mk
contrib/README [new file with mode: 0644]
contrib/windows_kernel/README [new file with mode: 0644]
contrib/windows_kernel/libc.cpp [new file with mode: 0644]
contrib/windows_kernel/libc.h [new file with mode: 0644]
cs.c
cs_priv.h
docs/BHUSA2014-capstone.pdf [new file with mode: 0644]
docs/README
functions.mk [new file with mode: 0644]
include/arm.h
include/arm64.h
include/capstone.h
include/mips.h
include/platform.h [new file with mode: 0644]
include/ppc.h
include/sparc.h [new file with mode: 0644]
include/systemz.h [new file with mode: 0644]
include/x86.h
include/xcore.h [new file with mode: 0644]
inttypes.h [new file with mode: 0644]
make.sh
msvc/README [new file with mode: 0644]
msvc/capstone.sln [new file with mode: 0644]
msvc/capstone_dll/capstone_dll.vcxproj [new file with mode: 0644]
msvc/capstone_static/capstone_static.vcxproj [new file with mode: 0644]
msvc/headers/inttypes.h [new file with mode: 0644]
msvc/test/test.vcxproj [new file with mode: 0644]
msvc/test_arm/test_arm.vcxproj [new file with mode: 0644]
msvc/test_arm64/test_arm64.vcxproj [new file with mode: 0644]
msvc/test_detail/test_detail.vcxproj [new file with mode: 0644]
msvc/test_mips/test_mips.vcxproj [new file with mode: 0644]
msvc/test_ppc/test_ppc.vcxproj [new file with mode: 0644]
msvc/test_skipdata/test_skipdata.vcxproj [new file with mode: 0644]
msvc/test_sparc/test_sparc.vcxproj [new file with mode: 0644]
msvc/test_systemz/test_systemz.vcxproj [new file with mode: 0644]
msvc/test_x86/test_x86.vcxproj [new file with mode: 0644]
msvc/test_xcore/test_xcore.vcxproj [new file with mode: 0644]
packages/freebsd/ports/devel/capstone/Makefile
packages/freebsd/ports/devel/capstone/files/patch-Makefile [deleted file]
packages/freebsd/ports/devel/capstone/files/patch-tests_Makefile [deleted file]
packages/freebsd/ports/devel/capstone/pkg-descr
packages/freebsd/ports/devel/capstone/pkg-plist
packages/homebrew/capstone.rb
packages/macports/devel/capstone/Portfile
packages/macports/devel/capstone/files/patch-Makefile.diff
pkgconfig.mk
suite/MC/AArch64/basic-a64-instructions.s.cs [new file with mode: 0644]
suite/MC/AArch64/gicv3-regs.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-2velem.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-3vdiff.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-aba-abd.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-across.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-add-pairwise.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-add-sub-instructions.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-bitwise-instructions.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-compare-instructions.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-crypto.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-extract.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-facge-facgt.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-frsqrt-frecp.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-halving-add-sub.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-max-min-pairwise.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-max-min.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-mla-mls-instructions.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-mov.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-mul-div-instructions.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-perm.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-rounding-halving-add.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-rounding-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-saturating-add-sub.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-saturating-rounding-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-saturating-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-abs.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-add-sub.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-by-elem-mla.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-by-elem-mul.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-by-elem-saturating-mla.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-by-elem-saturating-mul.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-compare.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-cvt.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-dup.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-extract-narrow.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-fp-compare.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-mul.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-neg.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-recip.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-reduce-pairwise.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-rounding-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-saturating-add-sub.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-saturating-rounding-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-saturating-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-shift-imm.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-scalar-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-shift-left-long.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-simd-copy.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-simd-ldst-multi-elem.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-simd-ldst-one-elem.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-simd-misc.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-simd-post-ldst-multi-elem.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-simd-shift.s.cs [new file with mode: 0644]
suite/MC/AArch64/neon-tbl.s.cs [new file with mode: 0644]
suite/MC/AArch64/trace-regs.s.cs [new file with mode: 0644]
suite/MC/ARM/arm-aliases.s.cs [new file with mode: 0644]
suite/MC/ARM/arm-arithmetic-aliases.s.cs [new file with mode: 0644]
suite/MC/ARM/arm-it-block.s.cs [new file with mode: 0644]
suite/MC/ARM/arm-memory-instructions.s.cs [new file with mode: 0644]
suite/MC/ARM/arm-shift-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/arm-thumb-trustzone.s.cs [new file with mode: 0644]
suite/MC/ARM/arm-trustzone.s.cs [new file with mode: 0644]
suite/MC/ARM/arm_addrmode2.s.cs [new file with mode: 0644]
suite/MC/ARM/arm_addrmode3.s.cs [new file with mode: 0644]
suite/MC/ARM/arm_instructions.s.cs [new file with mode: 0644]
suite/MC/ARM/basic-arm-instructions-v8.s.cs [new file with mode: 0644]
suite/MC/ARM/basic-arm-instructions.s.cs [new file with mode: 0644]
suite/MC/ARM/basic-thumb-instructions.s.cs [new file with mode: 0644]
suite/MC/ARM/basic-thumb2-instructions-v8.s.cs [new file with mode: 0644]
suite/MC/ARM/basic-thumb2-instructions.s.cs [new file with mode: 0644]
suite/MC/ARM/crc32-thumb.s.cs [new file with mode: 0644]
suite/MC/ARM/crc32.s.cs [new file with mode: 0644]
suite/MC/ARM/dot-req.s.cs [new file with mode: 0644]
suite/MC/ARM/fp-armv8.s.cs [new file with mode: 0644]
suite/MC/ARM/idiv-thumb.s.cs [new file with mode: 0644]
suite/MC/ARM/idiv.s.cs [new file with mode: 0644]
suite/MC/ARM/load-store-acquire-release-v8-thumb.s.cs [new file with mode: 0644]
suite/MC/ARM/load-store-acquire-release-v8.s.cs [new file with mode: 0644]
suite/MC/ARM/mode-switch.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-abs-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-absdiff-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-add-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-bitcount-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-bitwise-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-cmp-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-convert-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-crypto.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-dup-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-minmax-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-mov-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-mul-accum-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-mul-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-neg-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-pairwise-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-reciprocal-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-reverse-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-satshift-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-shift-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-shiftaccum-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-shuffle-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-sub-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-table-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-v8.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-vld-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-vst-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neon-vswp.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-abs-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-absdiff-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-add-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-bitcount-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-bitwise-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-cmp-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-convert-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-dup-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-minmax-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-mov-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-mul-accum-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-mul-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-neg-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-pairwise-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-reciprocal-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-reverse-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-satshift-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-shift-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-shiftaccum-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-shuffle-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-sub-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-table-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-vld-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/neont2-vst-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/simple-fp-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb-fp-armv8.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb-hints.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb-neon-crypto.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb-neon-v8.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb-shift-encoding.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb2-b.w-encodingT4.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb2-branches.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb2-mclass.s.cs [new file with mode: 0644]
suite/MC/ARM/thumb2-narrow-dp.ll.cs [new file with mode: 0644]
suite/MC/ARM/thumb2-pldw.s.cs [new file with mode: 0644]
suite/MC/ARM/vfp4-thumb.s.cs [new file with mode: 0644]
suite/MC/ARM/vfp4.s.cs [new file with mode: 0644]
suite/MC/ARM/vpush-vpop-thumb.s.cs [new file with mode: 0644]
suite/MC/ARM/vpush-vpop.s.cs [new file with mode: 0644]
suite/MC/Mips/hilo-addressing.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-alu-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-alu-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-branch-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-branch-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-expansions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-jump-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-jump-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-loadstore-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-loadstore-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-loadstore-unaligned-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-loadstore-unaligned.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-movcond-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-movcond-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-multiply-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-multiply-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-shift-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-shift-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-trap-instructions-EB.s.cs [new file with mode: 0644]
suite/MC/Mips/micromips-trap-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-alu-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-control-instructions-64.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-control-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-coprocessor-encodings.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-dsp-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-expansions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-fpu-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-jump-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-memory-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips-register-names.s.cs [new file with mode: 0644]
suite/MC/Mips/mips64-alu-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips64-instructions.s.cs [new file with mode: 0644]
suite/MC/Mips/mips64-register-names.s.cs [new file with mode: 0644]
suite/MC/Mips/mips_directives.s.cs [new file with mode: 0644]
suite/MC/Mips/nabi-regs.s.cs [new file with mode: 0644]
suite/MC/Mips/set-at-directive.s.cs [new file with mode: 0644]
suite/MC/Mips/test_2r.s.cs [new file with mode: 0644]
suite/MC/Mips/test_2rf.s.cs [new file with mode: 0644]
suite/MC/Mips/test_3r.s.cs [new file with mode: 0644]
suite/MC/Mips/test_3rf.s.cs [new file with mode: 0644]
suite/MC/Mips/test_bit.s.cs [new file with mode: 0644]
suite/MC/Mips/test_cbranch.s.cs [new file with mode: 0644]
suite/MC/Mips/test_ctrlregs.s.cs [new file with mode: 0644]
suite/MC/Mips/test_elm.s.cs [new file with mode: 0644]
suite/MC/Mips/test_elm_insert.s.cs [new file with mode: 0644]
suite/MC/Mips/test_elm_insve.s.cs [new file with mode: 0644]
suite/MC/Mips/test_i10.s.cs [new file with mode: 0644]
suite/MC/Mips/test_i5.s.cs [new file with mode: 0644]
suite/MC/Mips/test_i8.s.cs [new file with mode: 0644]
suite/MC/Mips/test_lsa.s.cs [new file with mode: 0644]
suite/MC/Mips/test_mi10.s.cs [new file with mode: 0644]
suite/MC/Mips/test_vec.s.cs [new file with mode: 0644]
suite/MC/PowerPC/ppc64-encoding-bookII.s.cs [new file with mode: 0644]
suite/MC/PowerPC/ppc64-encoding-bookIII.s.cs [new file with mode: 0644]
suite/MC/PowerPC/ppc64-encoding-ext.s.cs [new file with mode: 0644]
suite/MC/PowerPC/ppc64-encoding-fp.s.cs [new file with mode: 0644]
suite/MC/PowerPC/ppc64-encoding-vmx.s.cs [new file with mode: 0644]
suite/MC/PowerPC/ppc64-encoding.s.cs [new file with mode: 0644]
suite/MC/PowerPC/ppc64-operands.s.cs [new file with mode: 0644]
suite/MC/README [new file with mode: 0644]
suite/MC/Sparc/sparc-alu-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparc-atomic-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparc-ctrl-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparc-fp-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparc-mem-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparc-vis.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparc64-alu-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparc64-ctrl-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparcv8-instructions.s.cs [new file with mode: 0644]
suite/MC/Sparc/sparcv9-instructions.s.cs [new file with mode: 0644]
suite/MC/SystemZ/insn-good-z196.s.cs [new file with mode: 0644]
suite/MC/SystemZ/insn-good.s.cs [new file with mode: 0644]
suite/MC/SystemZ/regs-good.s.cs [new file with mode: 0644]
suite/MC/X86/3DNow.s.cs [new file with mode: 0644]
suite/MC/X86/address-size.s.cs [new file with mode: 0644]
suite/MC/X86/avx512-encodings.s.cs [new file with mode: 0644]
suite/MC/X86/intel-syntax-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86-32-avx.s.cs [new file with mode: 0644]
suite/MC/X86/x86-32-fma3.s.cs [new file with mode: 0644]
suite/MC/X86/x86-32-ms-inline-asm.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-avx-clmul-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-avx-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-bmi-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-fma3-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-fma4-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-hle-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-imm-widths.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-rand-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-rtm-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-sse4a.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-tbm-encoding.s.cs [new file with mode: 0644]
suite/MC/X86/x86_64-xop-encoding.s.cs [new file with mode: 0644]
suite/README
suite/arm/Makefile [new file with mode: 0644]
suite/arm/test_arm_regression.c [new file with mode: 0644]
suite/benchmark.py
suite/fuzz.py
suite/ppcbranch.py [new file with mode: 0755]
suite/test_c.sh
suite/test_mc.py [new file with mode: 0755]
suite/test_mc.sh [new file with mode: 0755]
suite/test_python.sh
suite/x86odd.py [new file with mode: 0755]
tests/Makefile
tests/README
tests/test.c
tests/test_arm.c
tests/test_arm64.c
tests/test_detail.c
tests/test_iter.c [new file with mode: 0644]
tests/test_mips.c
tests/test_ppc.c
tests/test_skipdata.c [new file with mode: 0644]
tests/test_sparc.c [new file with mode: 0644]
tests/test_systemz.c [new file with mode: 0644]
tests/test_x86.c
tests/test_xcore.c [new file with mode: 0644]
utils.c
utils.h
xcode/Capstone.xcodeproj/project.pbxproj [new file with mode: 0644]
xcode/Capstone.xcodeproj/project.xcworkspace/contents.xcworkspacedata [new file with mode: 0644]
xcode/CapstoneFramework/Info.plist [new file with mode: 0644]
xcode/README.md [new file with mode: 0644]

index 86033bc..f5772cf 100644 (file)
@@ -2,6 +2,9 @@
 *.o
 *.ko
 
+# Gcc dependency-tracking files
+*.d
+
 # Libraries
 *.lib
 *.a
 # python
 bindings/python/build/
 *.pyc
-bindings/python/pyx/*.c
-bindings/python/pyx/arm.pyx
-bindings/python/pyx/arm64.pyx
-bindings/python/pyx/arm64_const.pyx
-bindings/python/pyx/arm_const.pyx
-bindings/python/pyx/capstone.pyx
-bindings/python/pyx/mips.pyx
-bindings/python/pyx/mips_const.pyx
-bindings/python/pyx/ppc.pyx
-bindings/python/pyx/ppc_const.pyx
-bindings/python/pyx/x86.pyx
-bindings/python/pyx/x86_const.pyx
-
 
 # java
 bindings/java/capstone.jar
 
+# ocaml
+bindings/ocaml/*.cmi
+bindings/ocaml/*.cmx
+bindings/ocaml/*.cmxa
+bindings/ocaml/*.mli
+bindings/ocaml/test
+bindings/ocaml/test_arm
+bindings/ocaml/test_arm64
+bindings/ocaml/test_mips
+bindings/ocaml/test_x86
+bindings/ocaml/test_detail
+bindings/ocaml/test_ppc
+bindings/ocaml/test_sparc
+bindings/ocaml/test_systemz
+bindings/ocaml/test_xcore
+
+
 # test binaries
 tests/test
 tests/test_detail
+tests/test_iter
 tests/test_arm
 tests/test_arm64
 tests/test_mips
 tests/test_x86
 tests/test_ppc
+tests/test_skipdata
+tests/test_sparc
+tests/test_systemz
+tests/test_xcore
 tests/*.static
 
 # vim tmp file
 *.swp
+*~
 
 capstone.pc
 
@@ -57,3 +70,21 @@ _*
 
 # freebsd ports: generated file with "make makesum" command
 packages/freebsd/ports/devel/capstone/distinfo
+
+# VisualStudio
+Debug/
+Release/
+ipch/
+*.sdf
+*.opensdf
+*.suo
+*.user
+
+# Xcode
+xcode/Capstone.xcodeproj/xcuserdata
+
+# suite/
+test_arm_regression
+test_arm_regression.o
+
+ *.s
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2110feb
--- /dev/null
@@ -0,0 +1,215 @@
+cmake_minimum_required(VERSION 2.6)
+project(capstone)
+
+set(VERSION_MAJOR 2)
+set(VERSION_MINOR 2)
+set(VERSION_PATCH 0)
+
+# to configure the options specify them in in the command line or change them in the cmake UI.
+# Don't edit the makefile!
+option(CAPSTONE_BUILD_STATIC "Build static library" ON)
+option(CAPSTONE_BUILD_SHARED "Build shared library" ON)
+option(CAPSTONE_BUILD_DIET "Build diet library" OFF)
+option(CAPSTONE_BUILD_TESTS "Build tests" ON)
+option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON)
+
+option(CAPSTONE_ARM_SUPPORT "ARM support" ON)
+option(CAPSTONE_ARM64_SUPPORT "ARM64 support" ON)
+option(CAPSTONE_MIPS_SUPPORT "MIPS support" ON)
+option(CAPSTONE_PPC_SUPPORT "PowerPC support" ON)
+option(CAPSTONE_SPARC_SUPPORT "Sparc support" ON)
+option(CAPSTONE_SYSZ_SUPPORT "SystemZ support" ON)
+option(CAPSTONE_XCORE_SUPPORT "XCore support" ON)
+option(CAPSTONE_X86_SUPPORT "x86 support" ON)
+option(CAPSTONE_X86_REDUCE "x86 with reduce instruction sets to minimize library" OFF)
+option(CAPSTONE_X86_ATT_DISABLE "Disable x86 AT&T syntax" OFF)
+
+if (CAPSTONE_BUILD_DIET)
+    add_definitions(-DCAPSTONE_DIET)
+endif ()
+
+if (CAPSTONE_USE_DEFAULT_ALLOC)
+    add_definitions(-DCAPSTONE_USE_SYS_DYN_MEM)
+endif ()
+
+if (CAPSTONE_X86_REDUCE)
+    add_definitions(-DCAPSTONE_X86_REDUCE)
+endif ()
+
+if (CAPSTONE_X86_ATT_DISABLE)
+    add_definitions(-DCAPSTONE_X86_ATT_DISABLE)
+endif ()
+
+## sources
+set(SOURCES
+    cs.c
+    MCInst.c
+    MCInstrDesc.c
+    MCRegisterInfo.c
+    SStream.c
+    utils.c
+    )
+
+set(TEST_SOURCES test.c test_detail.c test_skipdata.c test_iter.c)
+
+## architecture support
+if (CAPSTONE_ARM_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_ARM)
+    set(SOURCES
+        ${SOURCES}
+        arch/ARM/ARMDisassembler.c
+        arch/ARM/ARMInstPrinter.c
+        arch/ARM/ARMMapping.c
+        arch/ARM/ARMModule.c
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_arm.c)
+endif ()
+
+if (CAPSTONE_ARM64_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_ARM64)
+    set(SOURCES
+        ${SOURCES}
+        arch/AArch64/AArch64BaseInfo.c
+        arch/AArch64/AArch64Disassembler.c
+        arch/AArch64/AArch64InstPrinter.c
+        arch/AArch64/AArch64Mapping.c
+        arch/AArch64/AArch64Module.c
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_arm64.c)
+endif ()
+
+if (CAPSTONE_MIPS_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_MIPS)
+    set(SOURCES
+        ${SOURCES}
+        arch/Mips/MipsDisassembler.c
+        arch/Mips/MipsInstPrinter.c
+        arch/Mips/MipsMapping.c
+        arch/Mips/MipsModule.c
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_mips.c)
+endif ()
+
+if (CAPSTONE_PPC_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_POWERPC)
+    set(SOURCES
+        ${SOURCES}
+        arch/PowerPC/PPCDisassembler.c
+        arch/PowerPC/PPCInstPrinter.c
+        arch/PowerPC/PPCMapping.c
+        arch/PowerPC/PPCModule.c
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_ppc.c)
+endif ()
+
+if (CAPSTONE_X86_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_X86)
+    set(SOURCES
+        ${SOURCES}
+        arch/X86/X86Disassembler.c
+        arch/X86/X86DisassemblerDecoder.c
+        arch/X86/X86IntelInstPrinter.c
+        arch/X86/X86Mapping.c
+        arch/X86/X86Module.c
+        )
+    if (NOT CAPSTONE_BUILD_DIET)
+        set(SOURCES ${SOURCES} arch/X86/X86ATTInstPrinter.c)
+    endif ()
+    set(TEST_SOURCES ${TEST_SOURCES} test_x86.c)
+endif ()
+
+if (CAPSTONE_SPARC_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_SPARC)
+    set(SOURCES
+        ${SOURCES}
+       arch/Sparc/SparcDisassembler.c
+       arch/Sparc/SparcInstPrinter.c
+       arch/Sparc/SparcMapping.c
+       arch/Sparc/SparcModule.c
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_sparc.c)
+endif ()
+
+if (CAPSTONE_SYSZ_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_SYSZ)
+    set(SOURCES
+        ${SOURCES}
+       arch/SystemZ/SystemZDisassembler.c
+       arch/SystemZ/SystemZInstPrinter.c
+       arch/SystemZ/SystemZMapping.c
+       arch/SystemZ/SystemZModule.c
+       arch/SystemZ/SystemZMCTargetDesc.c
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_systemz.c)
+endif ()
+
+if (CAPSTONE_XCORE_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_XCORE)
+    set(SOURCES
+        ${SOURCES}
+       arch/XCore/XCoreDisassembler.c
+       arch/XCore/XCoreInstPrinter.c
+       arch/XCore/XCoreMapping.c
+       arch/XCore/XCoreModule.c
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_xcore.c)
+endif ()
+
+include_directories("${PROJECT_SOURCE_DIR}/include")
+
+## properties
+# version info
+set_property(GLOBAL PROPERTY VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+set_property(GLOBAL PROPERTY SOVERSION SOVERSION ${VERSION_MAJOR})
+
+## targets
+if (CAPSTONE_BUILD_STATIC)
+    add_library(capstone-static STATIC ${SOURCES})
+    set_property(TARGET capstone-static PROPERTY OUTPUT_NAME capstone)
+    set(default-target capstone-static)
+endif ()
+
+if (CAPSTONE_BUILD_SHARED)
+    add_library(capstone-shared SHARED ${SOURCES})
+    set_property(TARGET capstone-shared PROPERTY OUTPUT_NAME capstone)
+    set_property(TARGET capstone-shared PROPERTY COMPILE_FLAGS -DCAPSTONE_SHARED)
+
+    if(NOT DEFINED default-target)      # honor `capstone-static` for tests first.
+       set(default-target capstone-shared)
+       add_definitions(-DCAPSTONE_SHARED)
+    endif ()
+endif ()
+
+if (CAPSTONE_BUILD_TESTS)
+    foreach (TSRC ${TEST_SOURCES})
+        STRING(REGEX REPLACE ".c$" "" TBIN ${TSRC})
+        add_executable(${TBIN} "tests/${TSRC}")
+        target_link_libraries(${TBIN} ${default-target})
+    endforeach ()
+    if (CAPSTONE_ARM_SUPPORT)
+        set(ARM_REGRESS_TEST test_arm_regression.c)
+        STRING(REGEX REPLACE ".c$" "" ARM_REGRESS_BIN ${ARM_REGRESS_TEST})
+        add_executable(${ARM_REGRESS_BIN} "suite/arm/${ARM_REGRESS_TEST}")
+        target_link_libraries(${ARM_REGRESS_BIN} ${default-target})
+    endif()
+endif ()
+
+## installation
+set(INCLUDES arm64.h  arm.h  capstone.h  mips.h  ppc.h  x86.h sparc.h systemz.h xcore.h platform.h)
+foreach (INC ${INCLUDES})
+    install(FILES "include/${INC}" DESTINATION include/capstone)
+endforeach ()
+
+if (CAPSTONE_BUILD_STATIC)
+    install(TARGETS capstone-static
+            RUNTIME DESTINATION bin
+            LIBRARY DESTINATION lib
+            ARCHIVE DESTINATION lib)
+endif ()
+
+if (CAPSTONE_BUILD_SHARED)
+    install(TARGETS capstone-shared
+            RUNTIME DESTINATION bin
+            LIBRARY DESTINATION lib
+            ARCHIVE DESTINATION lib)
+endif ()
index c8dd7a6..184f0ef 100644 (file)
@@ -1,4 +1,12 @@
-How To Compile, install & run Capstone for Linux, Mac OSX, *BSD and Windows
+This documentation explains how to compile, install & run Capstone on MacOSX,
+Linux, *BSD & Solaris. We also show steps to cross-compile for Microsoft Windows.
+
+To natively compile for Windows using Microsoft Visual Studio, see COMPILE_MSVC.TXT.
+
+To compile using CMake, see COMPILE_CMAKE.TXT.
+
+To compile using XCode on MacOSX, see xcode/README.md.
+
                         *-*-*-*-*-*
 
 Capstone requires no prerequisite packages, so it is easy to compile & install.
@@ -7,11 +15,35 @@ 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 8 archtitectures supported by Capstone (Arm, Arm64, Mips, PPC, Sparc,
+  SystemZ, XCore & X86), if you just need several selected archs, choose which
+  ones you want to compile in by editing "config.mk" before going to next steps.
+
+  By default, all 8 architectures are compiled.
+
+  The other way of customize Capstone without having to edit config.mk is to
+  pass the desired options on the commandline to ./make.sh. Currently,
+  Capstone supports 5 options, as followings.
+
+  - CAPSTONE_ARCHS: specify list of architectures to compiled in.
+  - CAPSTONE_USE_SYS_DYN_MEM: change this if you have your own dynamic memory management.
+  - CAPSTONE_DIET: use this to make the output binaries more compact.
+  - CAPSTONE_X86_REDUCE: another option to make X86 binary smaller.
+  - CAPSTONE_X86_ATT_DISABLE: disables AT&T syntax on x86.
+  - CAPSTONE_STATIC: build static library.
+  - CAPSTONE_SHARED: build dynamic (shared) library.
 
-  By default, all 5 architectures are compiled.
+  By default, Capstone uses system dynamic memory management, both DIET and X86_REDUCE
+  modes are disable, and builds all the static & shared libraries.
+
+  To avoid editing config.mk for these customization, we can pass their values to
+  make.sh, as followings.
+
+  $ CAPSTONE_ARCHS="arm aarch64 x86" CAPSTONE_USE_SYS_DYN_MEM=no CAPSTONE_DIET=yes CAPSTONE_X86_REDUCE=yes ./make.sh
+
+  NOTE: on commandline, put these values in front of ./make.sh, not after it.
+
+  For each option, refer to docs/README for more details.
 
 
 
@@ -23,9 +55,9 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
 
                $ ./make.sh
 
-  - On 64-bit OS, run command below to cross-compile Capstone for 32-bit binary:
+  - On 64-bit OS, run the command below to cross-compile Capstone for 32-bit binary:
 
-       $ ./make.sh nix32
+               $ ./make.sh nix32
 
 
 
@@ -34,10 +66,10 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
   To install Capstone, run:
 
        $ sudo ./make.sh install
-       
+
        For FreeBSD/OpenBSD, where sudo is unavailable, run:
 
-       $ su; ./make.sh install
+               $ su; ./make.sh install
 
   Users are then required to enter root password to copy Capstone into machine
   system directories.
@@ -54,20 +86,24 @@ 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/systemz.h
        /usr/lib/libcapstone.so (for Linux/*nix), or /usr/lib/libcapstone.dylib (OSX)
        /usr/lib/libcapstone.a
 
 
 
-(3) Cross-compile Windows from *nix
+(3) Cross-compile for Windows from *nix
 
   To cross-compile for Windows, Linux & gcc-mingw-w64-i686 (and also gcc-mingw-w64-x86-64
   for 64-bit binaries) are required.
 
        - To cross-compile Windows 32-bit binary, simply run:
+
                $ ./make.sh cross-win32
 
        - To cross-compile Windows 64-bit binary, run:
+
                $ ./make.sh cross-win64
 
   Resulted files libcapstone.dll, libcapstone.dll.a & tests/test*.exe can then
@@ -75,7 +111,7 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
 
 
 
-(4) Cross-compile iOS from Mac OSX.
+(4) Cross-compile for iOS from Mac OSX.
 
   To cross-compile for iOS (iPhone/iPad/iPod), Mac OSX with XCode installed is required. 
 
@@ -96,23 +132,37 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
 
 
 
-(5) Compile on Windows with Cygwin
+(5) Cross-compile for Android
+
+  To cross-compile for Android (smartphone/tablet), Android NDK is required.
+
+       $ ./make.sh cross-android
+
+  Resulted files libcapstone.so, libcapstone.a & tests/test* can then
+  be used on Android devices.
+
+
+
+(6) Compile on Windows with Cygwin
 
   To compile under Cygwin gcc-mingw-w64-i686 or x86_64-w64-mingw32 run:
 
-        - To compile Windows 32-bit binary under Cygwin, simply run
+        - To compile Windows 32-bit binary under Cygwin, run:
+
                 $ ./make.sh cygwin-mingw32
 
-        - To compile Windows 64-bit binary under Cygwin, run
+        - To compile Windows 64-bit binary under Cygwin, run:
+
                 $ ./make.sh cygwin-mingw64
 
   Resulted files libcapstone.dll, libcapstone.dll.a & tests/test*.exe can then
   be used on Windows machine.
 
 
-(6) By default, "cc" (default C compiler on the system) is used as compiler.
 
-       - To use "clang" compiler instead, run command below:
+(7) By default, "cc" (default C compiler on the system) is used as compiler.
+
+       - To use "clang" compiler instead, run the command below:
 
                $ ./make.sh clang
 
@@ -122,11 +172,17 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
 
 
 
-(7) Language bindings
+(8) To uninstall Capstone, run the command below:
+
+               $ sudo ./make.sh uninstall
+
+
+
+(9) Language bindings
 
   So far, Python, Ocaml & Java are supported by bindings in the main code.
   Look for the bindings under directory bindings/, and refer to README file
   of corresponding languages.
 
-  Community also provide bindings for C#, Go, Ruby & Vala. Links to these can
-  be found at address http://capstone-engine.org/download.html
+  Community also provide bindings for C#, Go, Ruby, NodeJS, C++ & Vala. Links to
+  these can be found at address http://capstone-engine.org/download.html
diff --git a/COMPILE_CMAKE.TXT b/COMPILE_CMAKE.TXT
new file mode 100644 (file)
index 0000000..2226e76
--- /dev/null
@@ -0,0 +1,81 @@
+This documentation explains how to compile Capstone with CMake, focus on
+using Microsoft Visual C as the compiler.
+
+To compile Capstone on *nix, see COMPILE.TXT.
+
+To compile Capstone on Windows using Visual Studio, see COMPILE_MSVC.TXT.
+
+                        *-*-*-*-*-*
+
+This documentation requires CMake & Windows SDK or MS Visual Studio installed on
+your machine.
+
+Get CMake for free from http://www.cmake.org.
+
+
+
+(0) Tailor Capstone to your need.
+
+  Out of 8 archtitectures supported by Capstone (Arm, Arm64, Mips, PPC, Sparc,
+  SystemZ, X86 & XCore), if you just need several selected archs, run "cmake"
+  with the unwanted archs disabled (set to 0) as followings.
+
+  - CAPSTONE_ARM_SUPPORT: support ARM. Run cmake with -DCAPSTONE_ARM_SUPPORT=0 to remove ARM.
+  - CAPSTONE_ARM64_SUPPORT: support ARM64. Run cmake with -DCAPSTONE_ARM64_SUPPORT=0 to remove ARM64.
+  - CAPSTONE_MIPS_SUPPORT: support Mips. Run cmake with -DCAPSTONE_MIPS_SUPPORT=0 to remove Mips.
+  - CAPSTONE_PPC_SUPPORT: support PPC. Run cmake with -DCAPSTONE_PPC_SUPPORT=0 to remove PPC.
+  - CAPSTONE_SPARC_SUPPORT: support Sparc. Run cmake with -DCAPSTONE_SPARC_SUPPORT=0 to remove Sparc.
+  - CAPSTONE_SYSZ_SUPPORT: support SystemZ. Run cmake with -DCAPSTONE_SYSZ_SUPPORT=0 to remove SystemZ.
+  - CAPSTONE_XCORE_SUPPORT: support XCore. Run cmake with -DCAPSTONE_XCORE_SUPPORT=0 to remove XCore.
+  - CAPSTONE_X86_SUPPORT: support X86. Run cmake with -DCAPSTONE_X86_SUPPORT=0 to remove X86.
+
+  By default, all 8 architectures are compiled in.
+
+
+  Besides, Capstone also allows some more customization via following macros.
+
+  - CAPSTONE_USE_SYS_DYN_MEM: change this to OFF to use your own dynamic memory management.
+  - CAPSTONE_BUILD_DIET: change this to ON to make the binaries more compact.
+  - CAPSTONE_X86_REDUCE: change this to ON to make X86 binary smaller.
+  - CAPSTONE_X86_ATT_DISABLE: change this to ON to disable AT&T syntax on x86.
+
+  By default, Capstone use system dynamic memory management, and both DIET and X86_REDUCE
+  modes are disabled. To use your own memory allocations, turn ON both DIET &
+  X86_REDUCE, run "cmake" with: -DCAPSTONE_USE_SYS_DYN_MEM=0 -DCAPSTONE_BUILD_DIET=1 -DCAPSTONE_X86_REDUCE=1
+
+
+  For each option, refer to docs/README for more details.
+
+
+
+(1) CMake allows you to generate different generators to build Capstone. Below is
+    some examples on how to build Capstone on Windows with CMake.
+
+
+  (*) To build Capstone using Nmake of Windows SDK, do:
+
+      mkdir build
+      cd build
+      cmake -G "NMake Makefiles" ..
+      nmake
+
+  After this, find the samples test*.exe, libcapstone_static.lib & libcapstone.dll
+  in the same directory.
+
+
+
+  (*) To build Capstone using Visual Studio, choose the generator accordingly to the
+  version of Visual Studio on your machine. For example, with Visual Studio 2013, do:
+
+      mkdir build
+      cd build
+      cmake -G "Visual Studio 12" ..
+
+  After this, find capstone.sln in the same directory. Open it with Visual Studio
+  and build the solution including libraries & all test as usual.
+
+
+
+(2) You can make sure the prior steps successfully worked by launching one of the
+  testing binary (test*.exe).
+
diff --git a/COMPILE_MSVC.TXT b/COMPILE_MSVC.TXT
new file mode 100644 (file)
index 0000000..c872394
--- /dev/null
@@ -0,0 +1,66 @@
+This documentation explains how to compile Capstone on Windows using
+Microsoft Visual Studio version 2010 or newer.
+
+To compile Capstone on *nix, see COMPILE.TXT
+
+To compile Capstone with CMake, see COMPILE_CMAKE.TXT
+
+                        *-*-*-*-*-*
+
+Capstone requires no prerequisite packages, so it is easy to compile & install.
+Open the Visual Studio solution "msvc/capstone.sln" and follow the instructions
+below.
+
+NOTE: This requires Visual Studio 2010 or newer versions.
+
+
+(0) Tailor Capstone to your need.
+
+  Out of 8 archtitectures supported by Capstone (Arm, Arm64, Mips, PPC, Sparc,
+  SystemZ, X86 & XCore), if you just need several selected archs, choose the ones
+  you want to compile in by opening Visual Studio solution "msvc\capstone.sln",
+  then directly editing the projects "capstone_static" & "capstone_dll" for static
+  and dynamic libraries, respectively. This must be done before going to the
+  next steps.
+
+  In VisualStudio interface, modify the preprocessor definitions via
+  "Project Properties" -> "Configuration Propertis" -> "C/C++" -> "Preprocessor"
+  to customize Capstone library, as followings.
+
+  - CAPSTONE_HAS_ARM: support ARM. Delete this to remove ARM support.
+  - CAPSTONE_HAS_ARM64: support ARM64. Delete this to remove ARM64 support.
+  - CAPSTONE_HAS_MIPS: support Mips. Delete this to remove Mips support.
+  - CAPSTONE_HAS_PPC: support PPC. Delete this to remove PPC support.
+  - CAPSTONE_HAS_SPARC: support Sparc. Delete this to remove Sparc support.
+  - CAPSTONE_HAS_SYSZ: support SystemZ. Delete this to remove SystemZ support.
+  - CAPSTONE_HAS_X86: support X86. Delete this to remove X86 support.
+  - CAPSTONE_HAS_XCORE: support XCore. Delete this to remove XCore support.
+
+  By default, all 8 architectures are compiled in.
+
+
+  Besides, Capstone also allows some more customization via following macros.
+
+  - CAPSTONE_USE_SYS_DYN_MEM: delete this to use your own dynamic memory management.
+  - CAPSTONE_DIET_NO: rename this to "CAPSTONE_DIET" to make the binaries more compact.
+  - CAPSTONE_X86_REDUCE_NO: rename this to "CAPSTONE_X86_REDUCE" to make X86 binary smaller.
+  - CAPSTONE_X86_ATT_DISABLE_NO: rename this to "CAPSTONE_X86_ATT_DISABLE" to disable
+    AT&T syntax on x86.
+
+  By default, Capstone use system dynamic memory management, and both DIET and X86_REDUCE
+  modes are disable.
+
+
+  For each option, refer to docs/README for more details.
+
+
+
+(1) Compile from source on Windows with Visual Studio
+
+  - Choose the configuration and the platform you want: Release/Debug & Win32/Win64.
+  - Build only the libraries, or the libraries along with all the tests.
+
+
+
+(2) You can make sure the prior steps successfully worked by launching one of the
+  testing binary (test*.exe).
index 9c70978..d76e499 100644 (file)
@@ -38,3 +38,19 @@ Hugo Fortier
 Joxean Koret
 Bruce Dang
 Andrew Dunham
+
+
+Contributors (in no particular order)
+=====================================
+(Please let us know if you want to have your name here)
+
+Ole André Vadla Ravnås (author of the 100th Pull-Request in our Github repo, thanks!)
+Axel "0vercl0k" Souchet (@0vercl0k) & Alex Ionescu: port to MSVC.
+Daniel Pistelli: Cmake support.
+Peter Hlavaty: integrate Capstone for Windows kernel drivers.
+Guillaume Jeanne: Ocaml binding.
+Martin Tofall, Obsidium Software: Optimize X86 performance & size.
+David Martínez Moreno: Debian package.
+Félix Cloutier: Xcode project.
+Benoit Lecocq: OpenBSD package.
+Christophe Avoinne (Hlide): Improve memory management for better performance.
index d6999e9..ad4e8a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,83 @@
 This file details the changelog of Capstone.
 
 ---------------------------------
+Version 3.0: November 19th, 2014
+
+[ API ]
+
+- New API: cs_disasm_iter & cs_malloc. See docs/README for tutorials.
+- Renamed cs_disasm_ex to cs_disasm (cs_disasm_ex is still supported, but
+  marked obsolete to be removed in future)
+- Support SKIPDATA mode, so Capstone can jump over unknown data and keep going
+  from the next legitimate instruction. See docs/README for tutorials.
+- More details provided in cs_detail struct for all architectures.
+- API version was bumped to 3.0.
+
+
+[ Bindings ]
+
+- Python binding supports Python3 (besides Python2).
+- Support Ocaml binding.
+- Java: add close() method to be used to deinitialize a Capstone object when
+  no longer use it.
+
+
+[ Architectures ]
+
+- New architectures: Sparc, SystemZ & XCore.
+- Important bugfixes for Arm, Arm64, Mips, PowerPC & X86.
+- Support more instructions for Arm, Arm64, Mips, PowerPC & X86.
+- Always expose absolute addresses rather than relative addresses (Arm, Arm64,
+  Mips, PPC, Sparc, X86).
+- Use common instruction operand types REG, IMM, MEM & FP across all
+  architectures (to enable cross-architecture analysis).
+- Use common instruction group types across all architectures (to enable
+  cross-architecture analysis).
+
+
+[ X86 ]
+
+- X86 engine is mature & handles all the malware tricks (that we are aware of).
+- Added a lot of new instructions (such as AVX512, 3DNow, etc).
+- Add prefix symbols X86_PREFIX_REP/REPNE/LOCK/CS/DS/SS/FS/GS/ES/OPSIZE/ADDRSIZE.
+- Print immediate in positive form & hexadecimal for AND/OR/XOR instructions.
+- More friendly disassembly for JMP16i (in the form segment:offset)
+
+
+[ Mips ]
+
+- Engine added supports for new hardware modes: Mips32R6 (CS_MODE_MIPS32R6) &
+  MipsGP64 (CS_MODE_MIPSGP64).
+- Removed the ABI-only mode CS_MODE_N64.
+- New modes CS_MODE_MIPS32 & CS_MODE_MIPS64 (to use instead of CS_MODE_32 &
+  CS_MODE_64).
+
+
+[ ARM ]
+
+- Support new mode CS_MODE_V8 for Armv8 A32 encodings.
+- Print immediate in positive form & hexadecimal for AND/ORR/EOR/BIC instructions
+
+
+[ ARM64 ]
+
+- Print immediate in hexadecimal for AND/ORR/EOR/TST instructions.
+
+
+[ PowerPC ]
+
+- Do not print a dot in front of absolute address.
+
+
+[ Other features ]
+
+- Support for Microsoft Visual Studio (so enable Windows native compilation).
+- Support CMake compilation.
+- Cross-compile for Android.
+- Build libraries/tests using XCode project
+- Much faster, while consuming less memory for all architectures.
+
+---------------------------------
 Version 2.1.2: April 3rd, 2014
 
 This is a stable release to fix some bugs deep in the core. There is no update
index 2462169..44c8179 100644 (file)
--- a/HACK.TXT
+++ b/HACK.TXT
@@ -7,23 +7,34 @@ Capstone source is organized as followings.
 │   ├── ARM         <- ARM engine
 │   ├── Mips        <- Mips engine
 │   ├── PowerPC     <- PowerPC engine
-│   └── X86         <- X86 engine
+│   ├── Sparc       <- Sparc engine
+│   ├── SystemZ     <- SystemZ engine
+│   ├── X86         <- X86 engine
+│   └── XCore       <- XCore engine
 ├── bindings        <- all bindings are under this dir
 │   ├── java        <- Java bindings + test code
 │   ├── ocaml       <- Ocaml bindings + test code
-│   ├── python      <- Python bindings + test code
+│   └── python      <- Python bindings + test code
+├── contrib         <- Code contributed by community to help Capstone integration
+├── docs            <- Documentation
 ├── include         <- API headers in C language (*.h)
+├── msvc            <- Microsoft Visual Studio support (for Windows compile)
+├── packages        <- Packages for Linux/OSX/BSD.
 ├── suite           <- Development test tools - for Capstone developers only
 ├── tests           <- Test code (in C language)
+└── xcode           <- Xcode support (for MacOSX compile)
 
 
-Follow instructions in COMPILE.TXT to see how to compile and run code.
+Follow instructions in COMPILE.TXT for how to compile and run test code.
 
 Note: if you find some strange bugs, it is recommended to firstly clean
 the code and try to recompile/reinstall again. This can be done with:
 
-       $ make clean
-       $ make
-       $ sudo make install
-
+       $ ./make.sh
+       $ sudo ./make.sh install
 
+At the same time, for Java/Ocaml/Python bindings, be sure to always use
+the bindings coming with the core to avoid potential incompatility issue
+with older versions.
+See bindings/<language>/README for detail instructions on how to compile &
+install the bindings.
index bf555e9..2cb489f 100644 (file)
--- a/LEB128.h
+++ b/LEB128.h
@@ -12,8 +12,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_LLVM_SUPPORT_LEB128_H
 #define CS_LLVM_SUPPORT_LEB128_H
index 6bf0537..bbbd38a 100644 (file)
@@ -1,5 +1,5 @@
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_MCDISASSEMBLER_H
 #define CS_MCDISASSEMBLER_H
index 8078a76..ab8b968 100644 (file)
@@ -9,8 +9,8 @@
 // Fixed length disassembler decoder state machine driver.
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_LLVM_MC_MCFIXEDLENDISASSEMBLER_H
 #define CS_LLVM_MC_MCFIXEDLENDISASSEMBLER_H
index 46bb4e6..ab9ded9 100644 (file)
--- a/MCInst.c
+++ b/MCInst.c
@@ -1,5 +1,5 @@
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -8,9 +8,14 @@
 #include "MCInst.h"
 #include "utils.h"
 
+#define MCINST_CACHE (ARR_SIZE(mcInst->Operands) - 1)
+
 void MCInst_Init(MCInst *inst)
 {
-       memset(inst, 0, sizeof(*inst));
+       inst->OpcodePub = 0;
+       inst->size = 0;
+       inst->has_imm = false;
+       inst->op1_size = 0;
 }
 
 void MCInst_clear(MCInst *inst)
@@ -18,8 +23,8 @@ void MCInst_clear(MCInst *inst)
        inst->size = 0;
 }
 
-// NOTE: this will free @Op argument
-void MCInst_insert(MCInst *inst, int index, MCOperand *Op)
+// do not free @Op
+void MCInst_insert0(MCInst *inst, int index, MCOperand *Op)
 {
        int i;
 
@@ -29,8 +34,6 @@ void MCInst_insert(MCInst *inst, int index, MCOperand *Op)
 
        inst->Operands[index] = *Op;
        inst->size++;
-
-       cs_mem_free(Op);
 }
 
 void MCInst_setOpcode(MCInst *inst, unsigned Op)
@@ -63,33 +66,12 @@ unsigned MCInst_getNumOperands(const MCInst *inst)
        return inst->size;
 }
 
-// NOTE: this will free @Op argument
-int MCInst_addOperand(MCInst *inst, MCOperand *Op)
-{
-       if (inst->size == ARR_SIZE(inst->Operands))
-               // full
-               return -1;
-
-       inst->Operands[inst->size] = *Op;
-       cs_mem_free(Op);
-
-       inst->size++;
-
-       return 0;
-}
-
 // This addOperand2 function doesnt free Op
-int MCInst_addOperand2(MCInst *inst, MCOperand *Op)
+void MCInst_addOperand2(MCInst *inst, MCOperand *Op)
 {
-       if (inst->size == ARR_SIZE(inst->Operands))
-               // full
-               return -1;
-
        inst->Operands[inst->size] = *Op;
 
        inst->size++;
-
-       return 0;
 }
 
 void MCOperand_Init(MCOperand *op)
@@ -150,9 +132,9 @@ void MCOperand_setFPImm(MCOperand *op, double Val)
        op->FPImmVal = Val;
 }
 
-MCOperand *MCOperand_CreateReg(unsigned Reg)
+MCOperand *MCOperand_CreateReg1(MCInst *mcInst, unsigned Reg)
 {
-       MCOperand *op = cs_mem_malloc(sizeof(*op));
+       MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
 
        op->Kind = kRegister;
        op->RegVal = Reg;
@@ -160,9 +142,18 @@ MCOperand *MCOperand_CreateReg(unsigned Reg)
        return op;
 }
 
-MCOperand *MCOperand_CreateImm(int64_t Val)
+void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
+{
+       MCOperand *op = &(mcInst->Operands[mcInst->size]);
+       mcInst->size++;
+
+       op->Kind = kRegister;
+       op->RegVal = Reg;
+}
+
+MCOperand *MCOperand_CreateImm1(MCInst *mcInst, int64_t Val)
 {
-       MCOperand *op = cs_mem_malloc(sizeof(*op));
+       MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
 
        op->Kind = kImmediate;
        op->ImmVal = Val;
@@ -170,12 +161,11 @@ MCOperand *MCOperand_CreateImm(int64_t Val)
        return op;
 }
 
-MCOperand *MCOperand_CreateFPImm(double Val)
+void MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
 {
-       MCOperand *op = cs_mem_malloc(sizeof(*op));
-
-       op->Kind = kFPImmediate;
-       op->FPImmVal = Val;
+       MCOperand *op = &(mcInst->Operands[mcInst->size]);
+       mcInst->size++;
 
-       return op;
+       op->Kind = kImmediate;
+       op->ImmVal = Val;
 }
index b6eef1a..97fe80b 100644 (file)
--- a/MCInst.h
+++ b/MCInst.h
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_MCINST_H
 #define CS_MCINST_H
 
 #include <stdint.h>
-#include <stdbool.h>
 
 #include "include/capstone.h"
 
@@ -76,80 +75,45 @@ const MCInst *MCOperand_getInst(const MCOperand *op);
 
 void MCOperand_setInst(MCOperand *op, const MCInst *Val);
 
-MCOperand *MCOperand_CreateReg(unsigned Reg);
+// create Reg operand in the next slot
+void MCOperand_CreateReg0(MCInst *inst, unsigned Reg);
 
-MCOperand *MCOperand_CreateImm(int64_t Val);
+// create Reg operand use the last-unused slot
+MCOperand *MCOperand_CreateReg1(MCInst *inst, unsigned Reg);
 
-MCOperand *MCOperand_CreateFPImm(double Val);
+// create Imm operand in the next slot
+void MCOperand_CreateImm0(MCInst *inst, int64_t Val);
 
-// NOTE: this structure is a flatten version of cs_insn struct
-// Detail information of disassembled instruction
-typedef struct cs_insn_flat {
-       // Instruction ID
-       // Find the instruction id from header file of corresponding architecture,
-       // such as arm.h for ARM, x86.h for X86, etc...
-       // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
-       unsigned int id;
-
-       // Address (EIP) of this instruction
-       // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
-       uint64_t address;
-
-       // Size of this instruction
-       // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
-       uint16_t size;
-       // Machine bytes of this instruction, with number of bytes indicated by @size above
-       // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
-       uint8_t bytes[16];
-
-       // Ascii text of instruction mnemonic
-       // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
-       char mnemonic[32];
-
-       // Ascii text of instruction operands
-       // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
-       char op_str[160];
-
-       // NOTE: All information below is not available when CS_OPT_DETAIL = CS_OPT_OFF
-
-       uint8_t regs_read[12]; // list of implicit registers read by this insn
-       uint8_t regs_read_count; // number of implicit registers read by this insn
-
-       uint8_t regs_write[20]; // list of implicit registers modified by this insn
-       uint8_t regs_write_count; // number of implicit registers modified by this insn
-
-       uint8_t groups[8]; // list of group this instruction belong to
-       uint8_t groups_count; // number of groups this insn belongs to
-
-       // Architecture-specific instruction info
-       union {
-               cs_x86 x86;     // X86 architecture, including 16-bit, 32-bit & 64-bit mode
-               cs_arm64 arm64; // ARM64 architecture (aka AArch64)
-               cs_arm arm;             // ARM architecture (including Thumb/Thumb2)
-               cs_mips mips;   // MIPS architecture
-               cs_ppc ppc;     // PowerPC architecture
-       };
-} cs_insn_flat;
+// create Imm operand in the last-unused slot
+MCOperand *MCOperand_CreateImm1(MCInst *inst, int64_t Val);
 
 /// MCInst - Instances of this class represent a single low-level machine
 /// instruction.
 struct MCInst {
-       unsigned Opcode;
-       MCOperand Operands[32];
-       unsigned size;  // number of operands
-       cs_insn_flat flat_insn; // insn to be exposed to public
        unsigned OpcodePub;
-       int insn_size;  // instruction size
+       uint8_t size;   // number of operands
+       bool has_imm;   // indicate this instruction has an X86_OP_IMM operand - used for ATT syntax
+       uint8_t op1_size; // size of 1st operand - for X86 Intel syntax
+       unsigned Opcode;
+       MCOperand Operands[48];
+       cs_insn *flat_insn;     // insn to be exposed to public
        uint64_t address;       // address of this insn
        cs_struct *csh; // save the main csh
-       uint8_t x86_imm_size;   // save immediate size to print immediate properly
+       uint8_t x86opsize;      // opsize for [mem] operand
+
+       // (Optional) instruction prefix, which can be up to 4 bytes.
+       // A prefix byte gets value 0 when irrelevant.
+       // This is copied from cs_x86 struct
+       uint8_t x86_prefix[4];
+       uint8_t imm_size;       // immediate size for X86_OP_IMM operand
 };
 
 void MCInst_Init(MCInst *inst);
 
 void MCInst_clear(MCInst *inst);
 
-void MCInst_insert(MCInst *inst, int index, MCOperand *Op);
+// do not free operand after inserting
+void MCInst_insert0(MCInst *inst, int index, MCOperand *Op);
 
 void MCInst_setOpcode(MCInst *inst, unsigned Op);
 
@@ -163,9 +127,7 @@ MCOperand *MCInst_getOperand(MCInst *inst, unsigned i);
 
 unsigned MCInst_getNumOperands(const MCInst *inst);
 
-int MCInst_addOperand(MCInst *inst, MCOperand *Op);
-
 // This addOperand2 function doesnt free Op
-int MCInst_addOperand2(MCInst *inst, MCOperand *Op);
+void MCInst_addOperand2(MCInst *inst, MCOperand *Op);
 
 #endif
index 5993323..7b834d3 100644 (file)
@@ -1,5 +1,5 @@
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #include "MCInstrDesc.h"
 
index 4181eb3..ae94b4f 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_LLVM_MC_MCINSTRDESC_H
 #define CS_LLVM_MC_MCINSTRDESC_H
 
-#include <stdbool.h>
 #include <stdint.h>
+#include "include/platform.h"
 
 //===----------------------------------------------------------------------===//
 // Machine Operand Flags and Description
@@ -109,7 +109,8 @@ enum {
        MCID_Rematerializable,
        MCID_CheapAsAMove,
        MCID_ExtraSrcRegAllocReq,
-       MCID_ExtraDefRegAllocReq
+       MCID_ExtraDefRegAllocReq,
+       MCID_RegSequence,
 };
 
 /// MCInstrDesc - Describe properties that are true of each instruction in the
index e7cb452..df1e836 100644 (file)
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #include "MCRegisterInfo.h"
 
index b83d09d..58c2f2d 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_LLVM_MC_MCREGISTERINFO_H
 #define CS_LLVM_MC_MCREGISTERINFO_H
 
-#include <stdbool.h>
 #include <stdint.h>
+#include "include/platform.h"
 
 /// An unsigned integer type large enough to represent all physical registers,
 /// but not necessarily virtual registers.
index 2e104fb..9eead1e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,16 @@
 
 include config.mk
 include pkgconfig.mk   # package version
+include functions.mk
+
+# Verbose output?
+V ?= 0
+
+ifeq ($(PKG_EXTRA),)
+PKG_VERSION = $(PKG_MAJOR).$(PKG_MINOR)
+else
+PKG_VERSION = $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA)
+endif
 
 ifeq ($(CROSS),)
 CC ?= cc
@@ -16,35 +26,44 @@ RANLIB = $(CROSS)ranlib
 STRIP = $(CROSS)strip
 endif
 
-CFLAGS += -fPIC -O3 -Wall -Iinclude
+ifneq (,$(findstring yes,$(CAPSTONE_DIET)))
+CFLAGS ?= -Os
+CFLAGS += -DCAPSTONE_DIET
+else
+CFLAGS ?= -O3
+endif
 
-ifeq ($(USE_SYS_DYN_MEM),yes)
-CFLAGS += -DUSE_SYS_DYN_MEM
+ifneq (,$(findstring yes,$(CAPSTONE_X86_ATT_DISABLE)))
+CFLAGS += -DCAPSTONE_X86_ATT_DISABLE
 endif
 
-ifneq (,$(findstring yes,$(CAPSTONE_DIET)))
-CFLAGS += -DCAPSTONE_DIET
+CFLAGS += -fPIC -Wall -Iinclude
+
+ifeq ($(CAPSTONE_USE_SYS_DYN_MEM),yes)
+CFLAGS += -DCAPSTONE_USE_SYS_DYN_MEM
 endif
 
+CFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch))
+LDFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch))
+
 PREFIX ?= /usr
 DESTDIR ?=
+ifndef BUILDDIR
+BLDIR = .
+OBJDIR = .
+else
+BLDIR = $(abspath $(BUILDDIR))
+OBJDIR = $(BLDIR)/obj
+endif
 INCDIR = $(DESTDIR)$(PREFIX)/include
 
-LIBDIR = $(DESTDIR)$(PREFIX)/lib
-# on x86_64, we might have /usr/lib64 directory instead of /usr/lib
-UNAME_M := $(shell uname -m)
 UNAME_S := $(shell uname -s)
-ifeq ($(UNAME_M), x86_64)
-ifeq (,$(wildcard $(LIBDIR)))
-ifneq ($(UNAME_S), Darwin)
-LIBDIR = $(DESTDIR)$(PREFIX)/lib64
-endif
-endif
-endif
 
-ifneq ($(UNAME_S),Darwin)
-LDFLAGS += -shared
-endif
+LIBDIRARCH ?= lib
+# Uncomment the below line to installs x86_64 libs to lib64/ directory.
+# Or better, pass 'LIBDIRARCH=lib64' to 'make install/uninstall' via 'make.sh'.
+#LIBDIRARCH ?= lib64
+LIBDIR = $(DESTDIR)$(PREFIX)/$(LIBDIRARCH)
 
 LIBDATADIR = $(LIBDIR)
 ifeq ($(UNAME_S), FreeBSD)
@@ -71,10 +90,10 @@ DEP_ARM += arch/ARM/ARMGenSubtargetInfo.inc
 LIBOBJ_ARM =
 ifneq (,$(findstring arm,$(CAPSTONE_ARCHS)))
        CFLAGS += -DCAPSTONE_HAS_ARM
-       LIBOBJ_ARM += arch/ARM/ARMDisassembler.o
-       LIBOBJ_ARM += arch/ARM/ARMInstPrinter.o
-       LIBOBJ_ARM += arch/ARM/ARMMapping.o
-       LIBOBJ_ARM += arch/ARM/ARMModule.o
+       LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMDisassembler.o
+       LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMInstPrinter.o
+       LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMMapping.o
+       LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMModule.o
 endif
 
 DEP_ARM64 =
@@ -87,11 +106,11 @@ DEP_ARM64 += arch/AArch64/AArch64GenRegisterInfo.inc
 LIBOBJ_ARM64 =
 ifneq (,$(findstring aarch64,$(CAPSTONE_ARCHS)))
        CFLAGS += -DCAPSTONE_HAS_ARM64
-       LIBOBJ_ARM64 += arch/AArch64/AArch64BaseInfo.o
-       LIBOBJ_ARM64 += arch/AArch64/AArch64Disassembler.o
-       LIBOBJ_ARM64 += arch/AArch64/AArch64InstPrinter.o
-       LIBOBJ_ARM64 += arch/AArch64/AArch64Mapping.o
-       LIBOBJ_ARM64 += arch/AArch64/AArch64Module.o
+       LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64BaseInfo.o
+       LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64Disassembler.o
+       LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64InstPrinter.o
+       LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64Mapping.o
+       LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64Module.o
 endif
 
 
@@ -105,10 +124,10 @@ DEP_MIPS += arch/Mips/MipsGenSubtargetInfo.inc
 LIBOBJ_MIPS =
 ifneq (,$(findstring mips,$(CAPSTONE_ARCHS)))
        CFLAGS += -DCAPSTONE_HAS_MIPS
-       LIBOBJ_MIPS += arch/Mips/MipsDisassembler.o
-       LIBOBJ_MIPS += arch/Mips/MipsInstPrinter.o
-       LIBOBJ_MIPS += arch/Mips/MipsMapping.o
-       LIBOBJ_MIPS += arch/Mips/MipsModule.o
+       LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsDisassembler.o
+       LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsInstPrinter.o
+       LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsMapping.o
+       LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsModule.o
 endif
 
 
@@ -122,66 +141,126 @@ DEP_PPC += arch/PowerPC/PPCGenRegisterInfo.inc
 LIBOBJ_PPC =
 ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS)))
        CFLAGS += -DCAPSTONE_HAS_POWERPC
-       LIBOBJ_PPC += arch/PowerPC/PPCDisassembler.o
-       LIBOBJ_PPC += arch/PowerPC/PPCInstPrinter.o
-       LIBOBJ_PPC += arch/PowerPC/PPCMapping.o
-       LIBOBJ_PPC += arch/PowerPC/PPCModule.o
+       LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCDisassembler.o
+       LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCInstPrinter.o
+       LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCMapping.o
+       LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCModule.o
+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 += $(OBJDIR)/arch/Sparc/SparcDisassembler.o
+       LIBOBJ_SPARC += $(OBJDIR)/arch/Sparc/SparcInstPrinter.o
+       LIBOBJ_SPARC += $(OBJDIR)/arch/Sparc/SparcMapping.o
+       LIBOBJ_SPARC += $(OBJDIR)/arch/Sparc/SparcModule.o
 endif
 
 
+DEP_SYSZ =
+DEP_SYSZ += arch/SystemZ/SystemZGenAsmWriter.inc
+DEP_SYSZ += arch/SystemZ/SystemZGenInstrInfo.inc
+DEP_SYSZ += arch/SystemZ/SystemZGenSubtargetInfo.inc
+DEP_SYSZ += arch/SystemZ/SystemZGenDisassemblerTables.inc
+DEP_SYSZ += arch/SystemZ/SystemZGenRegisterInfo.inc
+
+LIBOBJ_SYSZ =
+ifneq (,$(findstring systemz,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_SYSZ
+       LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZDisassembler.o
+       LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZInstPrinter.o
+       LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZMapping.o
+       LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZModule.o
+       LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZMCTargetDesc.o
+endif
+
+
+# by default, we compile full X86 instruction sets
+X86_REDUCE =
+ifneq (,$(findstring yes,$(CAPSTONE_X86_REDUCE)))
+X86_REDUCE = _reduce
+CFLAGS += -DCAPSTONE_X86_REDUCE -Os
+endif
+
 DEP_X86 =
-DEP_X86 += arch/X86/X86GenAsmWriter.inc
-DEP_X86 += arch/X86/X86GenAsmWriter1.inc
-DEP_X86 += arch/X86/X86GenDisassemblerTables.inc
-DEP_X86 += arch/X86/X86GenInstrInfo.inc
+DEP_X86 += arch/X86/X86GenAsmWriter$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86GenAsmWriter1$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86GenDisassemblerTables$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86GenInstrInfo$(X86_REDUCE).inc
 DEP_X86 += arch/X86/X86GenRegisterInfo.inc
 
 LIBOBJ_X86 =
 ifneq (,$(findstring x86,$(CAPSTONE_ARCHS)))
        CFLAGS += -DCAPSTONE_HAS_X86
-       LIBOBJ_X86 += arch/X86/X86DisassemblerDecoder.o
-       LIBOBJ_X86 += arch/X86/X86Disassembler.o
-       LIBOBJ_X86 += arch/X86/X86IntelInstPrinter.o
-       LIBOBJ_X86 += arch/X86/X86ATTInstPrinter.o
-       LIBOBJ_X86 += arch/X86/X86Mapping.o
-       LIBOBJ_X86 += arch/X86/X86Module.o
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86DisassemblerDecoder.o
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Disassembler.o
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86IntelInstPrinter.o
+# assembly syntax is irrelevant in Diet mode, when this info is suppressed
+ifeq (,$(findstring yes,$(CAPSTONE_DIET)))
+ifeq (,$(findstring yes,$(CAPSTONE_X86_ATT_DISABLE)))
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86ATTInstPrinter.o
+endif
+endif
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Mapping.o
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Module.o
+endif
+
+
+DEP_XCORE =
+DEP_XCORE += arch/XCore/XCoreGenAsmWriter.inc
+DEP_XCORE += arch/XCore/XCoreGenInstrInfo.inc
+DEP_XCORE += arch/XCore/XCoreGenDisassemblerTables.inc
+DEP_XCORE += arch/XCore/XCoreGenRegisterInfo.inc
+
+LIBOBJ_XCORE =
+ifneq (,$(findstring xcore,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_XCORE
+       LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreDisassembler.o
+       LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreInstPrinter.o
+       LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreMapping.o
+       LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreModule.o
 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 += MCInst.o
+LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o
+LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_X86) $(LIBOBJ_XCORE)
+LIBOBJ += $(OBJDIR)/MCInst.o
 
 
-PKGCFCGDIR = $(LIBDATADIR)/pkgconfig
+PKGCFGDIR ?= $(LIBDATADIR)/pkgconfig
 API_MAJOR=$(shell echo `grep -e CS_API_MAJOR include/capstone.h | grep -v = | awk '{print $$3}'` | awk '{print $$1}')
 VERSION_EXT =
 
-# OSX?
-ifeq ($(UNAME_S),Darwin)
+IS_APPLE := $(shell $(CC) -dM -E - < /dev/null | grep __apple_build_version__ | wc -l | tr -d " ")
+ifeq ($(IS_APPLE),1)
 EXT = dylib
 VERSION_EXT = $(API_MAJOR).$(EXT)
-LDFLAGS += -dynamiclib -install_name lib$(LIBNAME).$(VERSION_EXT) -current_version $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA) -compatibility_version $(PKG_MAJOR).$(PKG_MINOR)
+$(LIBNAME)_LDFLAGS += -dynamiclib -install_name lib$(LIBNAME).$(VERSION_EXT) -current_version $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA) -compatibility_version $(PKG_MAJOR).$(PKG_MINOR)
 AR_EXT = a
+# Homebrew wants to make sure its formula does not disable FORTIFY_SOURCE
+# However, this is not really necessary because 'CAPSTONE_USE_SYS_DYN_MEM=yes' by default
 ifneq ($(HOMEBREW_CAPSTONE),1)
-ifneq ($(USE_SYS_DYN_MEM),yes)
+ifneq ($(CAPSTONE_USE_SYS_DYN_MEM),yes)
 # remove string check because OSX kernel complains about missing symbols
 CFLAGS += -D_FORTIFY_SOURCE=0
 endif
-# By default, suppose that Brew is installed & use Brew path for pkgconfig file
-PKGCFCGDIR = /usr/local/lib/pkgconfig
-# is Macport installed instead?
-ifneq (,$(wildcard /opt/local/bin/port))
-# then correct the path for pkgconfig file
-PKGCFCGDIR = /opt/local/lib/pkgconfig
-endif
 endif
 else
+$(LIBNAME)_LDFLAGS += -shared
 # Cygwin?
 IS_CYGWIN := $(shell $(CC) -dumpmachine | grep -i cygwin | wc -l)
 ifeq ($(IS_CYGWIN),1)
 EXT = dll
-AR_EXT = dll.a
+AR_EXT = lib
 # Cygwin doesn't like -fPIC
 CFLAGS := $(CFLAGS:-fPIC=)
 # On Windows we need the shared library to be executable
@@ -190,7 +269,7 @@ else
 IS_MINGW := $(shell $(CC) --version | grep -i mingw | wc -l)
 ifeq ($(IS_MINGW),1)
 EXT = dll
-AR_EXT = dll.a
+AR_EXT = lib
 # mingw doesn't like -fPIC either
 CFLAGS := $(CFLAGS:-fPIC=)
 # On Windows we need the shared library to be executable
@@ -199,23 +278,54 @@ else
 EXT = so
 VERSION_EXT = $(EXT).$(API_MAJOR)
 AR_EXT = a
-LDFLAGS += -Wl,-soname,lib$(LIBNAME).$(VERSION_EXT)
+$(LIBNAME)_LDFLAGS += -Wl,-soname,lib$(LIBNAME).$(VERSION_EXT)
+endif
+endif
+endif
+
+ifeq ($(CAPSTONE_SHARED),yes)
+ifeq ($(IS_MINGW),1)
+LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT)
+else ifeq ($(IS_CYGWIN),1)
+LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT)
+else   # *nix
+LIBRARY = $(BLDIR)/lib$(LIBNAME).$(EXT)
+endif
 endif
+
+ifeq ($(CAPSTONE_STATIC),yes)
+ifeq ($(IS_MINGW),1)
+ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT)
+else ifeq ($(IS_CYGWIN),1)
+ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT)
+else
+ARCHIVE = $(BLDIR)/lib$(LIBNAME).$(AR_EXT)
 endif
 endif
 
-LIBRARY = lib$(LIBNAME).$(EXT)
-ARCHIVE = lib$(LIBNAME).$(AR_EXT)
-PKGCFGF = $(LIBNAME).pc
+PKGCFGF = $(BLDIR)/$(LIBNAME).pc
 
 .PHONY: all clean install uninstall dist
 
 all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF)
-       $(MAKE) -C tests
-       $(INSTALL_DATA) lib$(LIBNAME).$(EXT) tests
+ifndef BUILDDIR
+       cd tests && $(MAKE)
+else
+       cd tests && $(MAKE) BUILDDIR=$(BLDIR)
+endif
+ifeq ($(CAPSTONE_SHARED),yes)
+       $(INSTALL_DATA) $(LIBRARY) $(BLDIR)/tests/
+endif
 
+ifeq ($(CAPSTONE_SHARED),yes)
 $(LIBRARY): $(LIBOBJ)
-       $(CC) $(LDFLAGS) $(LIBOBJ) -o $(LIBRARY)
+ifeq ($(V),0)
+       $(call log,LINK,$(@:$(BLDIR)/%=%))
+       @$(create-library)
+else
+       $(create-library)
+endif
+endif
 
 $(LIBOBJ): config.mk
 
@@ -223,55 +333,67 @@ $(LIBOBJ_ARM): $(DEP_ARM)
 $(LIBOBJ_ARM64): $(DEP_ARM64)
 $(LIBOBJ_MIPS): $(DEP_MIPS)
 $(LIBOBJ_PPC): $(DEP_PPC)
+$(LIBOBJ_SPARC): $(DEP_SPARC)
+$(LIBOBJ_SYSZ): $(DEP_SYSZ)
 $(LIBOBJ_X86): $(DEP_X86)
+$(LIBOBJ_XCORE): $(DEP_XCORE)
 
+ifeq ($(CAPSTONE_STATIC),yes)
 $(ARCHIVE): $(LIBOBJ)
-       rm -f $(ARCHIVE)
-       $(AR) q $(ARCHIVE) $(LIBOBJ)
-       $(RANLIB) $(ARCHIVE)
+       @rm -f $(ARCHIVE)
+ifeq ($(V),0)
+       $(call log,AR,$(@:$(BLDIR)/%=%))
+       @$(create-archive)
+else
+       $(create-archive)
+endif
+endif
 
 $(PKGCFGF):
-       echo 'Name: capstone' > $(PKGCFGF)
-       echo 'Description: Capstone disassembly engine' >> $(PKGCFGF)
-ifeq ($(PKG_EXTRA),)
-       echo 'Version: $(PKG_MAJOR).$(PKG_MINOR)' >> $(PKGCFGF)
+ifeq ($(V),0)
+       $(call log,GEN,$(@:$(BLDIR)/%=%))
+       @$(generate-pkgcfg)
 else
-       echo 'Version: $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA)' >> $(PKGCFGF)
+       $(generate-pkgcfg)
 endif
-       echo 'libdir=$(LIBDIR)' >> $(PKGCFGF)
-       echo 'includedir=$(PREFIX)/include/capstone' >> $(PKGCFGF)
-       echo 'archive=$${libdir}/libcapstone.a' >> $(PKGCFGF)
-       echo 'Libs: -L$${libdir} -lcapstone' >> $(PKGCFGF)
-       echo 'Cflags: -I$${includedir}' >> $(PKGCFGF)
 
 install: $(PKGCFGF) $(ARCHIVE) $(LIBRARY)
        mkdir -p $(LIBDIR)
-       # remove potential broken old libs
-       rm -f $(LIBDIR)/lib$(LIBNAME).*
-       $(INSTALL_LIB) lib$(LIBNAME).$(EXT) $(LIBDIR)
+ifeq ($(CAPSTONE_SHARED),yes)
+       $(INSTALL_LIB) $(LIBRARY) $(LIBDIR)
 ifneq ($(VERSION_EXT),)
        cd $(LIBDIR) && \
        mv lib$(LIBNAME).$(EXT) lib$(LIBNAME).$(VERSION_EXT) && \
        ln -s lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT)
 endif
-       $(INSTALL_DATA) lib$(LIBNAME).$(AR_EXT) $(LIBDIR)
+endif
+ifeq ($(CAPSTONE_STATIC),yes)
+       $(INSTALL_DATA) $(ARCHIVE) $(LIBDIR)
+endif
        mkdir -p $(INCDIR)/$(LIBNAME)
        $(INSTALL_DATA) include/*.h $(INCDIR)/$(LIBNAME)
-       mkdir -p $(PKGCFCGDIR)
-       $(INSTALL_DATA) $(PKGCFGF) $(PKGCFCGDIR)/
+       mkdir -p $(PKGCFGDIR)
+       $(INSTALL_DATA) $(PKGCFGF) $(PKGCFGDIR)/
 
 uninstall:
        rm -rf $(INCDIR)/$(LIBNAME)
        rm -f $(LIBDIR)/lib$(LIBNAME).*
-       rm -f $(PKGCFCGDIR)/$(LIBNAME).pc
+       rm -f $(PKGCFGDIR)/$(LIBNAME).pc
 
 clean:
-       rm -f $(LIBOBJ) lib$(LIBNAME).*
+       rm -f $(LIBOBJ)
+       rm -f $(BLDIR)/lib$(LIBNAME).* $(BLDIR)/$(LIBNAME).*
        rm -f $(PKGCFGF)
-       $(MAKE) -C bindings/python clean
-       $(MAKE) -C bindings/java clean
-       $(MAKE) -C bindings/ocaml clean
-       $(MAKE) -C tests clean
+       cd tests && $(MAKE) clean
+       rm -f $(BLDIR)/tests/lib$(LIBNAME).$(EXT)
+
+ifdef BUILDDIR
+       rm -rf $(BUILDDIR)
+endif
+
+       cd bindings/python && $(MAKE) clean
+       cd bindings/java && $(MAKE) clean
+       cd bindings/ocaml && $(MAKE) clean
 
 
 TAG ?= HEAD
@@ -285,5 +407,48 @@ dist:
        git archive --format=tar.gz --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).tgz
        git archive --format=zip --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).zip
 
-.c.o:
-       $(CC) $(CFLAGS) -c $< -o $@
+
+TESTS = test test_detail test_arm test_arm64 test_mips test_ppc test_sparc
+TESTS += test_systemz test_x86 test_xcore test_iter
+TESTS += test.static test_detail.static test_arm.static test_arm64.static
+TESTS += test_mips.static test_ppc.static test_sparc.static
+TESTS += test_systemz.static test_x86.static test_xcore.static
+TESTS += test_skipdata test_skipdata.static test_iter.static
+check:
+       @for t in $(TESTS); do \
+               echo Check $$t ... ; \
+               ./tests/$$t > /dev/null && echo OK || echo FAILED; \
+       done
+
+$(OBJDIR)/%.o: %.c
+       @mkdir -p $(@D)
+ifeq ($(V),0)
+       $(call log,CC,$(@:$(OBJDIR)/%=%))
+       @$(compile)
+else
+       $(compile)
+endif
+
+
+define create-archive
+       $(AR) q $(ARCHIVE) $(LIBOBJ)
+       $(RANLIB) $(ARCHIVE)
+endef
+
+
+define create-library
+       $(CC) $(LDFLAGS) $($(LIBNAME)_LDFLAGS) $(LIBOBJ) -o $(LIBRARY)
+endef
+
+
+define generate-pkgcfg
+       echo 'Name: capstone' > $(PKGCFGF)
+       echo 'Description: Capstone disassembly engine' >> $(PKGCFGF)
+       echo 'Version: $(PKG_VERSION)' >> $(PKGCFGF)
+       echo 'libdir=$(LIBDIR)' >> $(PKGCFGF)
+       echo 'includedir=$(INCDIR)/capstone' >> $(PKGCFGF)
+       echo 'archive=$${libdir}/libcapstone.a' >> $(PKGCFGF)
+       echo 'Libs: -L$${libdir} -lcapstone' >> $(PKGCFGF)
+       echo 'Cflags: -I$${includedir}' >> $(PKGCFGF)
+endef
+
index d330b4a..33bce7b 100644 (file)
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_LLVM_SUPPORT_MATHEXTRAS_H
 #define CS_LLVM_SUPPORT_MATHEXTRAS_H
 # include <intrin.h>
 #endif
 
+#ifndef __cplusplus
+#if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
+#define inline /* inline */
+#endif
+#endif
+
 // NOTE: The following support functions use the _32/_64 extensions instead of
 // type overloading so that signed and unsigned integers can be used without
 // ambiguity.
@@ -408,4 +414,26 @@ static inline int64_t SignExtend64(uint64_t X, unsigned B) {
        return (int64_t)(X << (64 - B)) >> (64 - B);
 }
 
+/// \brief Count number of 0's from the most significant bit to the least
+///   stopping at the first 1.
+///
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
+///   valid arguments.
+static inline unsigned int countLeadingZeros(int x)
+{
+       unsigned count = 0;
+       int i;
+       const unsigned bits = sizeof(x) * 8;
+
+       for (i = bits; --i; ) {
+               if (x < 0) break;
+               count++;
+               x <<= 1;
+       }
+
+       return count;
+}
+
 #endif
diff --git a/README b/README
index 1c40b1a..acf0f49 100644 (file)
--- a/README
+++ b/README
@@ -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,
+  SystemZ, XCore and X86 (including X86_64).
 
 - Having clean/simple/lightweight/intuitive architecture-neutral API.
 
@@ -14,16 +15,19 @@ Capstone offers some unparalleled features:
   registers read & written.
 
 - Implemented in pure C language, with lightweight wrappers for C++, C#, Go,
-  Java, Ocaml, Python, Ruby & Vala ready (either available in main code,
-  or provided externally by community).
+  Java, NodeJS, Ocaml, Python, Ruby & Vala ready (available in main code,
+  or provided externally by the community).
 
-- Native support for Windows & *nix platforms (with OSX, Linux, *BSD & Solaris
-  have been confirmed).
+- Native support for all popular platforms: Windows, Mac OSX, iOS, Android,
+  Linux, *BSD, Solaris, etc.
 
 - Thread-safe by design.
 
 - Special support for embedding into firmware or OS kernel.
 
+- High performance & suitable for malware analysis (capable of handling various
+  X86 malware tricks).
+
 - Distributed under the open source BSD license.
 
 Further information is available at http://www.capstone-engine.org
@@ -31,20 +35,12 @@ Further information is available at http://www.capstone-engine.org
 
 [Compile]
 
-See COMPILE.TXT file for how to compile and install Capstone
-
-
-[Status]
+See COMPILE.TXT file for how to compile and install Capstone.
 
-- Capstone can only compile to Windows via Cygwin, or cross-compile using
-MingW. Visual Studio support will be done in the future.
 
-- X86 engine cannot handle many malware tricks yet. Please report all the raw
-binary code that Capstone cannot disassemble, or does that wrongly, so we can
-fix that in the next version
+[Documentation]
 
-- This package only contains Java & Python bindings. For C#, Go, Ocaml & Ruby,
-refer to the corresponding git repositories.
+See docs/README for how to customize & program your own tools with Capstone.
 
 
 [Hack]
index 4220f77..f10ae50 100644 (file)
@@ -1,7 +1,3 @@
-Version 2.1.2 is a stable release that fixes some bugs deep in the core.
-There is no update to any architectures or bindings, so older bindings
-of release 2.1 can be used with this version 2.1.2 just fine.
-
-For this reason, after upgrading to 2.1.2, users do NOT need to upgrade
-their bindings from release 2.1.
-
+The old bindings from version 2.x are not compatible with version 3.0, so
+must be updated. For Java/Ocaml/Python bindings, see respective README files
+under bindings/ directory in the source on how to reinstall them.
index 380a1f6..4a916c3 100644 (file)
--- a/SStream.c
+++ b/SStream.c
@@ -1,12 +1,19 @@
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #include <stdint.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "SStream.h"
 #include "cs_priv.h"
+#include "inttypes.h"
+#include "utils.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4996) // disable MSVC's warning on strcpy()
+#endif
 
 void SStream_Init(SStream *ss)
 {
@@ -14,18 +21,117 @@ void SStream_Init(SStream *ss)
        ss->buffer[0] = '\0';
 }
 
+void SStream_concat0(SStream *ss, char *s)
+{
+#ifndef CAPSTONE_DIET
+       unsigned int len = (unsigned int) strlen(s);
+
+       memcpy(ss->buffer + ss->index, s, len);
+       ss->index += len;
+       ss->buffer[ss->index] = '\0';
+#endif
+}
+
 void SStream_concat(SStream *ss, const char *fmt, ...)
 {
 #ifndef CAPSTONE_DIET
        va_list ap;
+       int ret;
 
        va_start(ap, fmt);
-       int ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
+       ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
        va_end(ap);
        ss->index += ret;
 #endif
 }
 
+// print number with prefix #
+void printInt64Bang(SStream *O, int64_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "#0x%"PRIx64, val);
+               else
+                       SStream_concat(O, "#%"PRIu64, val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "#-0x%"PRIx64, -val);
+               else
+                       SStream_concat(O, "#-%"PRIu64, -val);
+       }
+}
+
+// print number
+void printInt64(SStream *O, int64_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "0x%"PRIx64, val);
+               else
+                       SStream_concat(O, "%"PRIu64, val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "-0x%"PRIx64, -val);
+               else
+                       SStream_concat(O, "-%"PRIu64, -val);
+       }
+}
+
+// print number in decimal mode
+void printInt32BangDec(SStream *O, int32_t val)
+{
+       if (val >= 0)
+               SStream_concat(O, "#%u", val);
+       else
+               SStream_concat(O, "#-%u", -val);
+}
+
+void printInt32Bang(SStream *O, int32_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "#0x%x", val);
+               else
+                       SStream_concat(O, "#%u", val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "#-0x%x", -val);
+               else
+                       SStream_concat(O, "#-%u", -val);
+       }
+}
+
+void printInt32(SStream *O, int32_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "0x%x", val);
+               else
+                       SStream_concat(O, "%u", val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "-0x%x", -val);
+               else
+                       SStream_concat(O, "-%u", -val);
+       }
+}
+
+void printUInt32Bang(SStream *O, uint32_t val)
+{
+       if (val > HEX_THRESHOLD)
+               SStream_concat(O, "#0x%x", val);
+       else
+               SStream_concat(O, "#%u", val);
+}
+
+void printUInt32(SStream *O, uint32_t val)
+{
+       if (val > HEX_THRESHOLD)
+               SStream_concat(O, "0x%x", val);
+       else
+               SStream_concat(O, "%u", val);
+}
+
 /*
    int main()
    {
index e893453..87e5719 100644 (file)
--- a/SStream.h
+++ b/SStream.h
@@ -1,5 +1,5 @@
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_SSTREAM_H_
 #define CS_SSTREAM_H_
@@ -13,4 +13,21 @@ void SStream_Init(SStream *ss);
 
 void SStream_concat(SStream *ss, const char *fmt, ...);
 
+void SStream_concat0(SStream *ss, char *s);
+
+void printInt64Bang(SStream *O, int64_t val);
+
+void printInt64(SStream *O, int64_t val);
+
+void printInt32Bang(SStream *O, int32_t val);
+
+void printInt32(SStream *O, int32_t val);
+
+void printUInt32Bang(SStream *O, uint32_t val);
+
+void printUInt32(SStream *O, uint32_t val);
+
+// print number in decimal mode
+void printInt32BangDec(SStream *O, int32_t val);
+
 #endif
diff --git a/SubtargetFeature.h b/SubtargetFeature.h
deleted file mode 100644 (file)
index 649fad8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines and manages user or tool specified CPU characteristics.
-// The intent is to be able to package specific features that should or should
-// not be used on a specific target processor.  A tool, such as llc, could, as
-// as example, gather chip info from the command line, a long with features
-// that should be used on that chip.
-//
-//===----------------------------------------------------------------------===//
-
-/* Second-Best Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
-
-#ifndef CS_LLVM_MC_SUBTARGETFEATURE_H
-#define CS_LLVM_MC_SUBTARGETFEATURE_H
-
-//===----------------------------------------------------------------------===//
-///
-/// SubtargetFeatureKV - Used to provide key value pairs for feature and
-/// CPU bit flags.
-//
-typedef struct SubtargetFeatureKV {
-  char *Key;                      // K-V key string
-  char *Desc;                     // Help descriptor
-  const uint64_t Value;                 // K-V integer value
-  const uint64_t Implies;               // K-V bit mask
-} SubtargetFeatureKV;
-
-#endif
diff --git a/TODO b/TODO
index a2e573d..f588bbf 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,24 +3,14 @@ Issues to be solved in next versions
 
 [Core]
 
-- X86 cannot handle many tricks introduced by malware yet. If you find any such
-  instruction sequence that Capstone disassembles wrongly or fails completely,
-  please report. This would be the top priority of our project.
+- X86 can already handle all the malware tricks we are aware of. If you find
+  any such instruction sequence that Capstone disassembles wrongly or fails
+  completely, please report. Fixing this issue is always the top priority of
+  our project.
 
 - More optimization for better performance.
 
-- Support more operand details for Arm, Arm64, Mips & X86, especially focus on
-  non-standard instructions.
-
-- At the moment the only way to get Windows binaries is cross-compiling. We have
-  to port the code over to Visual Studio, so those only have Windows can still
-  compile Capstone without needing to have Linux machine for cross-compiling.
-
-- Reduce the binary size of libraries, so Capstone can be embeded into products.
-
 
 [Bindings]
 
-- OCaml binding are broken due to many API changes. This should be fixed ASAP.
-
-- Python 3 support is needed.
+- OCaml binding is working, but still support the core API better.
diff --git a/arch/AArch64/AArch64AddressingModes.h b/arch/AArch64/AArch64AddressingModes.h
new file mode 100644 (file)
index 0000000..047ee31
--- /dev/null
@@ -0,0 +1,228 @@
+//===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the AArch64 addressing mode implementation stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CS_AARCH64_ADDRESSINGMODES_H
+#define CS_AARCH64_ADDRESSINGMODES_H
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014 */
+
+#include "../../MathExtras.h"
+
+/// AArch64_AM - AArch64 Addressing Mode Stuff
+
+//===----------------------------------------------------------------------===//
+// Shifts
+//
+
+typedef enum AArch64_AM_ShiftExtendType {
+       AArch64_AM_InvalidShiftExtend = -1,
+       AArch64_AM_LSL = 0,
+       AArch64_AM_LSR,
+       AArch64_AM_ASR,
+       AArch64_AM_ROR,
+       AArch64_AM_MSL,
+
+       AArch64_AM_UXTB,
+       AArch64_AM_UXTH,
+       AArch64_AM_UXTW,
+       AArch64_AM_UXTX,
+
+       AArch64_AM_SXTB,
+       AArch64_AM_SXTH,
+       AArch64_AM_SXTW,
+       AArch64_AM_SXTX,
+} AArch64_AM_ShiftExtendType;
+
+/// getShiftName - Get the string encoding for the shift type.
+static inline const char *AArch64_AM_getShiftExtendName(AArch64_AM_ShiftExtendType ST)
+{
+       switch (ST) {
+               default: return NULL; // never reach
+               case AArch64_AM_LSL: return "lsl";
+               case AArch64_AM_LSR: return "lsr";
+               case AArch64_AM_ASR: return "asr";
+               case AArch64_AM_ROR: return "ror";
+               case AArch64_AM_MSL: return "msl";
+               case AArch64_AM_UXTB: return "uxtb";
+               case AArch64_AM_UXTH: return "uxth";
+               case AArch64_AM_UXTW: return "uxtw";
+               case AArch64_AM_UXTX: return "uxtx";
+               case AArch64_AM_SXTB: return "sxtb";
+               case AArch64_AM_SXTH: return "sxth";
+               case AArch64_AM_SXTW: return "sxtw";
+               case AArch64_AM_SXTX: return "sxtx";
+       }
+}
+
+/// getShiftType - Extract the shift type.
+static inline AArch64_AM_ShiftExtendType AArch64_AM_getShiftType(unsigned Imm)
+{
+       switch ((Imm >> 6) & 0x7) {
+               default: return AArch64_AM_InvalidShiftExtend;
+               case 0: return AArch64_AM_LSL;
+               case 1: return AArch64_AM_LSR;
+               case 2: return AArch64_AM_ASR;
+               case 3: return AArch64_AM_ROR;
+               case 4: return AArch64_AM_MSL;
+       }
+}
+
+/// getShiftValue - Extract the shift value.
+static inline unsigned AArch64_AM_getShiftValue(unsigned Imm)
+{
+       return Imm & 0x3f;
+}
+
+//===----------------------------------------------------------------------===//
+// Extends
+//
+
+/// getArithShiftValue - get the arithmetic shift value.
+static inline unsigned AArch64_AM_getArithShiftValue(unsigned Imm)
+{
+       return Imm & 0x7;
+}
+
+/// getExtendType - Extract the extend type for operands of arithmetic ops.
+static inline AArch64_AM_ShiftExtendType AArch64_AM_getExtendType(unsigned Imm)
+{
+       // assert((Imm & 0x7) == Imm && "invalid immediate!");
+       switch (Imm) {
+               default: // llvm_unreachable("Compiler bug!");
+               case 0: return AArch64_AM_UXTB;
+               case 1: return AArch64_AM_UXTH;
+               case 2: return AArch64_AM_UXTW;
+               case 3: return AArch64_AM_UXTX;
+               case 4: return AArch64_AM_SXTB;
+               case 5: return AArch64_AM_SXTH;
+               case 6: return AArch64_AM_SXTW;
+               case 7: return AArch64_AM_SXTX;
+       }
+}
+
+static inline AArch64_AM_ShiftExtendType AArch64_AM_getArithExtendType(unsigned Imm)
+{
+       return AArch64_AM_getExtendType((Imm >> 3) & 0x7);
+}
+
+static inline uint64_t ror(uint64_t elt, unsigned size)
+{
+       return ((elt & 1) << (size-1)) | (elt >> 1);
+}
+
+/// decodeLogicalImmediate - Decode a logical immediate value in the form
+/// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the
+/// integer value it represents with regSize bits.
+static inline uint64_t AArch64_AM_decodeLogicalImmediate(uint64_t val, unsigned regSize)
+{
+       // Extract the N, imms, and immr fields.
+       unsigned N = (val >> 12) & 1;
+       unsigned immr = (val >> 6) & 0x3f;
+       unsigned imms = val & 0x3f;
+       unsigned i;
+
+       // assert((regSize == 64 || N == 0) && "undefined logical immediate encoding");
+       int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
+       // assert(len >= 0 && "undefined logical immediate encoding");
+       unsigned size = (1 << len);
+       unsigned R = immr & (size - 1);
+       unsigned S = imms & (size - 1);
+       // assert(S != size - 1 && "undefined logical immediate encoding");
+       uint64_t pattern = (1ULL << (S + 1)) - 1;
+       for (i = 0; i < R; ++i)
+               pattern = ror(pattern, size);
+
+       // Replicate the pattern to fill the regSize.
+       while (size != regSize) {
+               pattern |= (pattern << size);
+               size *= 2;
+       }
+
+       return pattern;
+}
+
+/// isValidDecodeLogicalImmediate - Check to see if the logical immediate value
+/// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits)
+/// is a valid encoding for an integer value with regSize bits.
+static inline bool AArch64_AM_isValidDecodeLogicalImmediate(uint64_t val, unsigned regSize)
+{
+       unsigned size;
+       unsigned S;
+       int len;
+       // Extract the N and imms fields needed for checking.
+       unsigned N = (val >> 12) & 1;
+       unsigned imms = val & 0x3f;
+
+       if (regSize == 32 && N != 0) // undefined logical immediate encoding
+               return false;
+       len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
+       if (len < 0) // undefined logical immediate encoding
+               return false;
+       size = (1 << len);
+       S = imms & (size - 1);
+       if (S == size - 1) // undefined logical immediate encoding
+               return false;
+
+       return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Floating-point Immediates
+//
+static inline float AArch64_AM_getFPImmFloat(unsigned Imm)
+{
+       // We expect an 8-bit binary encoding of a floating-point number here.
+       union {
+               uint32_t I;
+               float F;
+       } FPUnion;
+
+       uint8_t Sign = (Imm >> 7) & 0x1;
+       uint8_t Exp = (Imm >> 4) & 0x7;
+       uint8_t Mantissa = Imm & 0xf;
+
+       //   8-bit FP    iEEEE Float Encoding
+       //   abcd efgh   aBbbbbbc defgh000 00000000 00000000
+       //
+       // where B = NOT(b);
+
+       FPUnion.I = 0;
+       FPUnion.I |= Sign << 31;
+       FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
+       FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
+       FPUnion.I |= (Exp & 0x3) << 23;
+       FPUnion.I |= Mantissa << 19;
+
+       return FPUnion.F;
+}
+
+//===--------------------------------------------------------------------===//
+// AdvSIMD Modified Immediates
+//===--------------------------------------------------------------------===//
+
+static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType10(uint8_t Imm)
+{
+       uint64_t EncVal = 0;
+       if (Imm & 0x80) EncVal |= 0xff00000000000000ULL;
+       if (Imm & 0x40) EncVal |= 0x00ff000000000000ULL;
+       if (Imm & 0x20) EncVal |= 0x0000ff0000000000ULL;
+       if (Imm & 0x10) EncVal |= 0x000000ff00000000ULL;
+       if (Imm & 0x08) EncVal |= 0x00000000ff000000ULL;
+       if (Imm & 0x04) EncVal |= 0x0000000000ff0000ULL;
+       if (Imm & 0x02) EncVal |= 0x000000000000ff00ULL;
+       if (Imm & 0x01) EncVal |= 0x00000000000000ffULL;
+       return EncVal;
+}
+
+#endif
index e95e0ff..a498c6a 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
+
+#ifdef CAPSTONE_HAS_ARM64
+
+#if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
+#pragma warning(disable:4996)
+#endif
 
 #include "../../utils.h"
 
@@ -21,7 +27,7 @@
 
 #include "AArch64BaseInfo.h"
 
-char *NamedImmMapper_toString(NamedImmMapper *N, uint32_t Value, bool *Valid)
+char *A64NamedImmMapper_toString(A64NamedImmMapper *N, uint32_t Value, bool *Valid)
 {
        unsigned i;
        for (i = 0; i < N->NumPairs; ++i) {
@@ -39,17 +45,18 @@ char *NamedImmMapper_toString(NamedImmMapper *N, uint32_t Value, bool *Valid)
 // return true if s1 == lower(f2), and false otherwise
 static bool compare_lower_str(char *s1, char *s2)
 {
+       bool res;
        char *lower = cs_strdup(s2), *c;
        for (c = lower; *c; c++)
                *c = (char)tolower((int) *c);
 
-       bool res = (strcmp(s1, lower) == 0);
+       res = (strcmp(s1, lower) == 0);
        cs_mem_free(lower);
 
        return res;
 }
 
-uint32_t NamedImmMapper_fromString(NamedImmMapper *N, char *Name, bool *Valid)
+uint32_t A64NamedImmMapper_fromString(A64NamedImmMapper *N, char *Name, bool *Valid)
 {
        unsigned i;
        for (i = 0; i < N->NumPairs; ++i) {
@@ -63,7 +70,7 @@ uint32_t NamedImmMapper_fromString(NamedImmMapper *N, char *Name, bool *Valid)
        return (uint32_t)-1;
 }
 
-bool NamedImmMapper_validImm(NamedImmMapper *N, uint32_t Value)
+bool A64NamedImmMapper_validImm(A64NamedImmMapper *N, uint32_t Value)
 {
        return Value < N->TooBigImm;
 }
@@ -74,6 +81,7 @@ static char *utostr(uint64_t X, bool isNeg)
 {
        char Buffer[22];
        char *BufPtr = Buffer+21;
+       char *result;
 
        Buffer[21] = '\0';
        if (X == 0) *--BufPtr = '0';  // Handle special case...
@@ -85,11 +93,11 @@ static char *utostr(uint64_t X, bool isNeg)
 
        if (isNeg) *--BufPtr = '-';   // Add negative sign...
 
-       char *result = cs_strdup(BufPtr);
+       result = cs_strdup(BufPtr);
        return result;
 }
 
-static NamedImmMapper_Mapping SysRegPairs[] = {
+static A64NamedImmMapper_Mapping SysRegPairs[] = {
        {"osdtrrx_el1", A64SysReg_OSDTRRX_EL1},
        {"osdtrtx_el1",  A64SysReg_OSDTRTX_EL1},
        {"teecr32_el1", A64SysReg_TEECR32_EL1},
@@ -568,10 +576,19 @@ static NamedImmMapper_Mapping SysRegPairs[] = {
        {"ich_lr15_el2", A64SysReg_ICH_LR15_EL2}
 };
 
+static A64NamedImmMapper_Mapping CycloneSysRegPairs[] = {
+       {"cpm_ioacc_ctl_el3", A64SysReg_CPM_IOACC_CTL_EL3}
+};
+
 // result must be a big enough buffer: 128 bytes is more than enough
-void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *result)
+void A64SysRegMapper_toString(A64SysRegMapper *S, uint32_t Bits, bool *Valid, char *result)
 {
+       int dummy;
+       uint32_t Op0, Op1, CRn, CRm, Op2;
+       char *Op1S, *CRnS, *CRmS, *Op2S;
        unsigned i;
+
+       // First search the registers shared by all
        for (i = 0; i < ARR_SIZE(SysRegPairs); ++i) {
                if (SysRegPairs[i].Value == Bits) {
                        *Valid = true;
@@ -580,6 +597,20 @@ void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *re
                }
        }
 
+       // Next search for target specific registers
+       // if (FeatureBits & AArch64_ProcCyclone) {
+       if (true) {
+               for (i = 0; i < ARR_SIZE(CycloneSysRegPairs); ++i) {
+                       if (CycloneSysRegPairs[i].Value == Bits) {
+                               *Valid = true;
+                               strcpy(result, CycloneSysRegPairs[i].Name);
+                               return;
+                       }
+               }
+       }
+
+       // Now try the instruction-specific registers (either read-only or
+       // write-only).
        for (i = 0; i < S->NumInstPairs; ++i) {
                if (S->InstPairs[i].Value == Bits) {
                        *Valid = true;
@@ -588,11 +619,11 @@ void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *re
                }
        }
 
-       uint32_t Op0 = (Bits >> 14) & 0x3;
-       uint32_t Op1 = (Bits >> 11) & 0x7;
-       uint32_t CRn = (Bits >> 7) & 0xf;
-       uint32_t CRm = (Bits >> 3) & 0xf;
-       uint32_t Op2 = Bits & 0x7;
+       Op0 = (Bits >> 14) & 0x3;
+       Op1 = (Bits >> 11) & 0x7;
+       CRn = (Bits >> 7) & 0xf;
+       CRm = (Bits >> 3) & 0xf;
+       Op2 = Bits & 0x7;
 
        // Only combinations matching: 11 xxx 1x11 xxxx xxx are valid for a generic
        // name.
@@ -605,14 +636,13 @@ void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *re
 
        *Valid = true;
 
-       char *Op1S, *CRnS, *CRmS, *Op2S;
        Op1S = utostr(Op1, false);
        CRnS = utostr(CRn, false);
        CRmS = utostr(CRm, false);
        Op2S = utostr(Op2, false);
 
        //printf("Op1S: %s, CRnS: %s, CRmS: %s, Op2S: %s\n", Op1S, CRnS, CRmS, Op2S);
-       int dummy = sprintf(result, "s3_%s_c%s_c%s_%s", Op1S, CRnS, CRmS, Op2S);
+       dummy = sprintf(result, "s3_%s_c%s_c%s_%s", Op1S, CRnS, CRmS, Op2S);
        (void)dummy;
 
        cs_mem_free(Op1S);
@@ -621,7 +651,7 @@ void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *re
        cs_mem_free(Op2S);
 }
 
-static NamedImmMapper_Mapping TLBIPairs[] = {
+static A64NamedImmMapper_Mapping TLBIPairs[] = {
        {"ipas2e1is", A64TLBI_IPAS2E1IS},
        {"ipas2le1is", A64TLBI_IPAS2LE1IS},
        {"vmalle1is", A64TLBI_VMALLE1IS},
@@ -656,13 +686,13 @@ static NamedImmMapper_Mapping TLBIPairs[] = {
        {"vaale1", A64TLBI_VAALE1}
 };
 
-NamedImmMapper A64TLBI_TLBIMapper = {
-       .Pairs = TLBIPairs,
-       .NumPairs = ARR_SIZE(TLBIPairs),
-       .TooBigImm = 0,
+A64NamedImmMapper A64TLBI_TLBIMapper = {
+       TLBIPairs,
+       ARR_SIZE(TLBIPairs),
+       0,
 };
 
-static NamedImmMapper_Mapping ATPairs[] = {
+static A64NamedImmMapper_Mapping ATPairs[] = {
        {"s1e1r", A64AT_S1E1R},
        {"s1e2r", A64AT_S1E2R},
        {"s1e3r", A64AT_S1E3R},
@@ -677,13 +707,13 @@ static NamedImmMapper_Mapping ATPairs[] = {
        {"s12e0w", A64AT_S12E0W},
 };
 
-NamedImmMapper A64AT_ATMapper = {
-       .Pairs = ATPairs,
-       .NumPairs = ARR_SIZE(ATPairs),
-       .TooBigImm = 0,
+A64NamedImmMapper A64AT_ATMapper = {
+       ATPairs,
+       ARR_SIZE(ATPairs),
+       0,
 };
 
-static NamedImmMapper_Mapping DBarrierPairs[] = {
+static A64NamedImmMapper_Mapping DBarrierPairs[] = {
        {"oshld", A64DB_OSHLD},
        {"oshst", A64DB_OSHST},
        {"osh", A64DB_OSH},
@@ -698,13 +728,13 @@ static NamedImmMapper_Mapping DBarrierPairs[] = {
        {"sy", A64DB_SY}
 };
 
-NamedImmMapper A64DB_DBarrierMapper = {
-       .Pairs = DBarrierPairs,
-       .NumPairs = ARR_SIZE(DBarrierPairs),
-       .TooBigImm = 16,
+A64NamedImmMapper A64DB_DBarrierMapper = {
+       DBarrierPairs,
+       ARR_SIZE(DBarrierPairs),
+       16,
 };
 
-static NamedImmMapper_Mapping DCPairs[] = {
+static A64NamedImmMapper_Mapping DCPairs[] = {
        {"zva", A64DC_ZVA},
        {"ivac", A64DC_IVAC},
        {"isw", A64DC_ISW},
@@ -715,35 +745,35 @@ static NamedImmMapper_Mapping DCPairs[] = {
        {"cisw", A64DC_CISW}
 };
 
-NamedImmMapper A64DC_DCMapper = {
-       .Pairs = DCPairs,
-       .NumPairs = ARR_SIZE(DCPairs),
-       .TooBigImm = 0,
+A64NamedImmMapper A64DC_DCMapper = {
+       DCPairs,
+       ARR_SIZE(DCPairs),
+       0,
 };
 
-static NamedImmMapper_Mapping ICPairs[] = {
+static A64NamedImmMapper_Mapping ICPairs[] = {
        {"ialluis",  A64IC_IALLUIS},
        {"iallu", A64IC_IALLU},
        {"ivau", A64IC_IVAU}
 };
 
-NamedImmMapper A64IC_ICMapper = {
-       .Pairs = ICPairs,
-       .NumPairs = ARR_SIZE(ICPairs),
-       .TooBigImm = 0,
+A64NamedImmMapper A64IC_ICMapper = {
+       ICPairs,
+       ARR_SIZE(ICPairs),
+       0,
 };
 
-static NamedImmMapper_Mapping ISBPairs[] = {
+static A64NamedImmMapper_Mapping ISBPairs[] = {
        {"sy",  A64DB_SY},
 };
 
-NamedImmMapper A64ISB_ISBMapper = {
-       .Pairs = ISBPairs,
-       .NumPairs = ARR_SIZE(ISBPairs),
-       .TooBigImm = 16,
+A64NamedImmMapper A64ISB_ISBMapper = {
+       ISBPairs,
+       ARR_SIZE(ISBPairs),
+       16,
 };
 
-static NamedImmMapper_Mapping PRFMPairs[] = {
+static A64NamedImmMapper_Mapping PRFMPairs[] = {
        {"pldl1keep", A64PRFM_PLDL1KEEP},
        {"pldl1strm", A64PRFM_PLDL1STRM},
        {"pldl2keep", A64PRFM_PLDL2KEEP},
@@ -764,25 +794,25 @@ static NamedImmMapper_Mapping PRFMPairs[] = {
        {"pstl3strm", A64PRFM_PSTL3STRM}
 };
 
-NamedImmMapper A64PRFM_PRFMMapper = {
-       .Pairs = PRFMPairs,
-       .NumPairs = ARR_SIZE(PRFMPairs),
-       .TooBigImm = 32,
+A64NamedImmMapper A64PRFM_PRFMMapper = {
+       PRFMPairs,
+       ARR_SIZE(PRFMPairs),
+       32,
 };
 
-static NamedImmMapper_Mapping PStatePairs[] = {
+static A64NamedImmMapper_Mapping PStatePairs[] = {
        {"spsel", A64PState_SPSel},
        {"daifset", A64PState_DAIFSet},
        {"daifclr", A64PState_DAIFClr}
 };
 
-NamedImmMapper A64PState_PStateMapper = {
-       .Pairs = PStatePairs,
-       .NumPairs = ARR_SIZE(PStatePairs),
-       .TooBigImm = 0,
+A64NamedImmMapper A64PState_PStateMapper = {
+       PStatePairs,
+       ARR_SIZE(PStatePairs),
+       0,
 };
 
-static NamedImmMapper_Mapping MRSPairs[] = {
+static A64NamedImmMapper_Mapping MRSPairs[] = {
        {"mdccsr_el0", A64SysReg_MDCCSR_EL0},
        {"dbgdtrrx_el0", A64SysReg_DBGDTRRX_EL0},
        {"mdrar_el1", A64SysReg_MDRAR_EL1},
@@ -812,16 +842,16 @@ static NamedImmMapper_Mapping MRSPairs[] = {
        {"id_isar3_el1", A64SysReg_ID_ISAR3_EL1},
        {"id_isar4_el1", A64SysReg_ID_ISAR4_EL1},
        {"id_isar5_el1", A64SysReg_ID_ISAR5_EL1},
-       {"id_aa64pfr0_el1", A64SysReg_ID_AA64PFR0_EL1},
-       {"id_aa64pfr1_el1", A64SysReg_ID_AA64PFR1_EL1},
-       {"id_aa64dfr0_el1", A64SysReg_ID_AA64DFR0_EL1},
-       {"id_aa64dfr1_el1", A64SysReg_ID_AA64DFR1_EL1},
-       {"id_aa64afr0_el1", A64SysReg_ID_AA64AFR0_EL1},
-       {"id_aa64afr1_el1", A64SysReg_ID_AA64AFR1_EL1},
-       {"id_aa64isar0_el1", A64SysReg_ID_AA64ISAR0_EL1},
-       {"id_aa64isar1_el1", A64SysReg_ID_AA64ISAR1_EL1},
-       {"id_aa64mmfr0_el1", A64SysReg_ID_AA64MMFR0_EL1},
-       {"id_aa64mmfr1_el1", A64SysReg_ID_AA64MMFR1_EL1},
+       {"id_aa64pfr0_el1", A64SysReg_ID_A64PFR0_EL1},
+       {"id_aa64pfr1_el1", A64SysReg_ID_A64PFR1_EL1},
+       {"id_aa64dfr0_el1", A64SysReg_ID_A64DFR0_EL1},
+       {"id_aa64dfr1_el1", A64SysReg_ID_A64DFR1_EL1},
+       {"id_aa64afr0_el1", A64SysReg_ID_A64AFR0_EL1},
+       {"id_aa64afr1_el1", A64SysReg_ID_A64AFR1_EL1},
+       {"id_aa64isar0_el1", A64SysReg_ID_A64ISAR0_EL1},
+       {"id_aa64isar1_el1", A64SysReg_ID_A64ISAR1_EL1},
+       {"id_aa64mmfr0_el1", A64SysReg_ID_A64MMFR0_EL1},
+       {"id_aa64mmfr1_el1", A64SysReg_ID_A64MMFR1_EL1},
        {"mvfr0_el1", A64SysReg_MVFR0_EL1},
        {"mvfr1_el1", A64SysReg_MVFR1_EL1},
        {"mvfr2_el1", A64SysReg_MVFR2_EL1},
@@ -881,12 +911,13 @@ static NamedImmMapper_Mapping MRSPairs[] = {
        {"ich_elsr_el2", A64SysReg_ICH_ELSR_EL2}
 };
 
-SysRegMapper AArch64_MRSMapper = {
-       .InstPairs = MRSPairs,
-       .NumInstPairs = ARR_SIZE(MRSPairs),
+A64SysRegMapper AArch64_MRSMapper = {
+       NULL,
+       MRSPairs,
+       ARR_SIZE(MRSPairs),
 };
 
-static NamedImmMapper_Mapping MSRPairs[] = {
+static A64NamedImmMapper_Mapping MSRPairs[] = {
        {"dbgdtrtx_el0", A64SysReg_DBGDTRTX_EL0},
        {"oslar_el1", A64SysReg_OSLAR_EL1},
        {"pmswinc_el0", A64SysReg_PMSWINC_EL0},
@@ -904,79 +935,10 @@ static NamedImmMapper_Mapping MSRPairs[] = {
        {"icc_sgi0r_el1", A64SysReg_ICC_SGI0R_EL1}
 };
 
-SysRegMapper AArch64_MSRMapper = {
-       .InstPairs = MSRPairs,
-       .NumInstPairs = ARR_SIZE(MSRPairs),
+A64SysRegMapper AArch64_MSRMapper = {
+       NULL,
+       MSRPairs,
+       ARR_SIZE(MSRPairs),
 };
 
-// Encoding of the immediate for logical (immediate) instructions:
-//
-// | N | imms   | immr   | size | R            | S            |
-// |---+--------+--------+------+--------------+--------------|
-// | 1 | ssssss | rrrrrr |   64 | UInt(rrrrrr) | UInt(ssssss) |
-// | 0 | 0sssss | xrrrrr |   32 | UInt(rrrrr)  | UInt(sssss)  |
-// | 0 | 10ssss | xxrrrr |   16 | UInt(rrrr)   | UInt(ssss)   |
-// | 0 | 110sss | xxxrrr |    8 | UInt(rrr)    | UInt(sss)    |
-// | 0 | 1110ss | xxxxrr |    4 | UInt(rr)     | UInt(ss)     |
-// | 0 | 11110s | xxxxxr |    2 | UInt(r)      | UInt(s)      |
-// | 0 | 11111x | -      |      | UNALLOCATED  |              |
-//
-// Columns 'R', 'S' and 'size' specify a "bitmask immediate" of size bits in
-// which the lower S+1 bits are ones and the remaining bits are zero, then
-// rotated right by R bits, which is then replicated across the datapath.
-//
-// + Values of 'N', 'imms' and 'immr' which do not match the above table are
-//   RESERVED.
-// + If all 's' bits in the imms field are set then the instruction is
-//   RESERVED.
-// + The 'x' bits in the 'immr' field are IGNORED.
-bool A64Imms_isLogicalImmBits(unsigned RegWidth, uint32_t Bits, uint64_t *Imm)
-{
-       uint32_t N = Bits >> 12;
-       uint32_t ImmR = (Bits >> 6) & 0x3f;
-       uint32_t ImmS = Bits & 0x3f;
-
-       // N=1 encodes a 64-bit replication and is invalid for the 32-bit
-       // instructions.
-       if (RegWidth == 32 && N != 0) return false;
-
-       int Width = 0;
-       if (N == 1)
-               Width = 64;
-       else if ((ImmS & 0x20) == 0)
-               Width = 32;
-       else if ((ImmS & 0x10) == 0)
-               Width = 16;
-       else if ((ImmS & 0x08) == 0)
-               Width = 8;
-       else if ((ImmS & 0x04) == 0)
-               Width = 4;
-       else if ((ImmS & 0x02) == 0)
-               Width = 2;
-       else {
-               // ImmS  is 0b11111x: UNALLOCATED
-               return false;
-       }
-
-       int Num1s = (ImmS & (Width - 1)) + 1;
-
-       // All encodings which would map to -1 (signed) are RESERVED.
-       if (Num1s == Width) return false;
-
-       int Rotation = (ImmR & (Width - 1));
-       uint64_t Mask = (1ULL << Num1s) - 1;
-       uint64_t WidthMask = Width == 64 ? -1 : (1ULL << Width) - 1;
-       if (Rotation != 0 && Rotation != 64)
-               Mask = (Mask >> Rotation)
-                       | ((Mask << (Width - Rotation)) & WidthMask);
-
-       *Imm = Mask;
-       unsigned i;
-       for (i = 1; i < RegWidth / Width; ++i) {
-               Mask <<= Width;
-               *Imm |= Mask;
-       }
-
-       return true;
-}
-
+#endif
index 672232f..1dba3b4 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
 
 #ifndef CS_LLVM_AARCH64_BASEINFO_H
 #define CS_LLVM_AARCH64_BASEINFO_H
 
 #include <ctype.h>
 #include <stdint.h>
-#include <stdbool.h>
 #include <string.h>
 
-/// Instances of this class can perform bidirectional mapping from random
-/// identifier strings to operand encodings. For example "MSR" takes a named
-/// system-register which must be encoded somehow and decoded for printing. This
-/// central location means that the information for those transformations is not
-/// duplicated and remains in sync.
-///
-/// FIXME: currently the algorithm is a completely unoptimised linear
-/// search. Obviously this could be improved, but we would probably want to work
-/// out just how often these instructions are emitted before working on it. It
-/// might even be optimal to just reorder the tables for the common instructions
-/// rather than changing the algorithm.
-typedef struct NamedImmMapper_Mapping {
-       char *Name;
-       uint32_t Value;
-} NamedImmMapper_Mapping;
-
-typedef struct NamedImmMapper {
-       NamedImmMapper_Mapping *Pairs;
-       size_t NumPairs;
-       uint32_t TooBigImm;
-} NamedImmMapper;
-
-typedef struct SysRegMapper {
-       NamedImmMapper_Mapping *SysRegPairs;
-       NamedImmMapper_Mapping *InstPairs;
-       size_t NumInstPairs;
-} SysRegMapper;
+#ifndef __cplusplus
+#if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
+#define inline /* inline */
+#endif
+#endif
 
-extern SysRegMapper AArch64_MSRMapper;
-extern SysRegMapper AArch64_MRSMapper;
+inline static unsigned getWRegFromXReg(unsigned Reg)
+{
+       switch (Reg) {
+               case ARM64_REG_X0: return ARM64_REG_W0;
+               case ARM64_REG_X1: return ARM64_REG_W1;
+               case ARM64_REG_X2: return ARM64_REG_W2;
+               case ARM64_REG_X3: return ARM64_REG_W3;
+               case ARM64_REG_X4: return ARM64_REG_W4;
+               case ARM64_REG_X5: return ARM64_REG_W5;
+               case ARM64_REG_X6: return ARM64_REG_W6;
+               case ARM64_REG_X7: return ARM64_REG_W7;
+               case ARM64_REG_X8: return ARM64_REG_W8;
+               case ARM64_REG_X9: return ARM64_REG_W9;
+               case ARM64_REG_X10: return ARM64_REG_W10;
+               case ARM64_REG_X11: return ARM64_REG_W11;
+               case ARM64_REG_X12: return ARM64_REG_W12;
+               case ARM64_REG_X13: return ARM64_REG_W13;
+               case ARM64_REG_X14: return ARM64_REG_W14;
+               case ARM64_REG_X15: return ARM64_REG_W15;
+               case ARM64_REG_X16: return ARM64_REG_W16;
+               case ARM64_REG_X17: return ARM64_REG_W17;
+               case ARM64_REG_X18: return ARM64_REG_W18;
+               case ARM64_REG_X19: return ARM64_REG_W19;
+               case ARM64_REG_X20: return ARM64_REG_W20;
+               case ARM64_REG_X21: return ARM64_REG_W21;
+               case ARM64_REG_X22: return ARM64_REG_W22;
+               case ARM64_REG_X23: return ARM64_REG_W23;
+               case ARM64_REG_X24: return ARM64_REG_W24;
+               case ARM64_REG_X25: return ARM64_REG_W25;
+               case ARM64_REG_X26: return ARM64_REG_W26;
+               case ARM64_REG_X27: return ARM64_REG_W27;
+               case ARM64_REG_X28: return ARM64_REG_W28;
+               case ARM64_REG_FP: return ARM64_REG_W29;
+               case ARM64_REG_LR: return ARM64_REG_W30;
+               case ARM64_REG_SP: return ARM64_REG_WSP;
+               case ARM64_REG_XZR: return ARM64_REG_WZR;
+       }
 
-extern NamedImmMapper A64DB_DBarrierMapper;
-extern NamedImmMapper A64AT_ATMapper;
-extern NamedImmMapper A64DC_DCMapper;
-extern NamedImmMapper A64IC_ICMapper;
-extern NamedImmMapper A64ISB_ISBMapper;
-extern NamedImmMapper A64PRFM_PRFMMapper;
-extern NamedImmMapper A64PState_PStateMapper;
-extern NamedImmMapper A64TLBI_TLBIMapper;
+       // For anything else, return it unchanged.
+       return Reg;
+}
 
 // // Enums corresponding to AArch64 condition codes
 // The CondCodes constants map directly to the 4-bit encoding of the
 // condition field for predicated instructions.
-typedef enum A64CC_CondCodes {   // Meaning (integer)          Meaning (floating-point)
+typedef enum A64CC_CondCode { // Meaning (integer)     Meaning (floating-point)
        A64CC_EQ = 0,        // Equal                      Equal
        A64CC_NE,            // Not equal                  Not equal, or unordered
        A64CC_HS,            // Unsigned higher or same    >, ==, or unordered
@@ -85,15 +92,14 @@ typedef enum A64CC_CondCodes {   // Meaning (integer)          Meaning (floating
        A64CC_LE,            // Signed less than or equal  <, ==, or unordered
        A64CC_AL,            // Always (unconditional)     Always (unconditional)
        A64CC_NV,             // Always (unconditional)     Always (unconditional)
-       // Note the NV exists purely to disassemble 0b1111. Execution
-       // is "always".
+       // Note the NV exists purely to disassemble 0b1111. Execution is "always".
        A64CC_Invalid
-} A64CC_CondCodes;
+} A64CC_CondCode;
 
-inline static const char *A64CondCodeToString(A64CC_CondCodes CC)
+inline static char *getCondCodeName(A64CC_CondCode CC)
 {
        switch (CC) {
-               default: return 0;      // never reach
+               default: return NULL;   // never reach
                case A64CC_EQ:  return "eq";
                case A64CC_NE:  return "ne";
                case A64CC_HS:  return "hs";
@@ -113,6 +119,52 @@ inline static const char *A64CondCodeToString(A64CC_CondCodes CC)
        }
 }
 
+inline static A64CC_CondCode getInvertedCondCode(A64CC_CondCode Code)
+{
+       // To reverse a condition it's necessary to only invert the low bit:
+       return (A64CC_CondCode)((unsigned)Code ^ 0x1);
+}
+
+/// Instances of this class can perform bidirectional mapping from random
+/// identifier strings to operand encodings. For example "MSR" takes a named
+/// system-register which must be encoded somehow and decoded for printing. This
+/// central location means that the information for those transformations is not
+/// duplicated and remains in sync.
+///
+/// FIXME: currently the algorithm is a completely unoptimised linear
+/// search. Obviously this could be improved, but we would probably want to work
+/// out just how often these instructions are emitted before working on it. It
+/// might even be optimal to just reorder the tables for the common instructions
+/// rather than changing the algorithm.
+typedef struct A64NamedImmMapper_Mapping {
+       char *Name;
+       uint32_t Value;
+} A64NamedImmMapper_Mapping;
+
+typedef struct A64NamedImmMapper {
+       A64NamedImmMapper_Mapping *Pairs;
+       size_t NumPairs;
+       uint32_t TooBigImm;
+} A64NamedImmMapper;
+
+typedef struct A64SysRegMapper {
+       A64NamedImmMapper_Mapping *SysRegPairs;
+       A64NamedImmMapper_Mapping *InstPairs;
+       size_t NumInstPairs;
+} A64SysRegMapper;
+
+extern A64SysRegMapper AArch64_MSRMapper;
+extern A64SysRegMapper AArch64_MRSMapper;
+
+extern A64NamedImmMapper A64DB_DBarrierMapper;
+extern A64NamedImmMapper A64AT_ATMapper;
+extern A64NamedImmMapper A64DC_DCMapper;
+extern A64NamedImmMapper A64IC_ICMapper;
+extern A64NamedImmMapper A64ISB_ISBMapper;
+extern A64NamedImmMapper A64PRFM_PRFMMapper;
+extern A64NamedImmMapper A64PState_PStateMapper;
+extern A64NamedImmMapper A64TLBI_TLBIMapper;
+
 enum {
        A64AT_Invalid = -1,    // Op0 Op1  CRn   CRm   Op2
        A64AT_S1E1R = 0x43c0,  // 01  000  0111  1000  000
@@ -129,7 +181,7 @@ enum {
        A64AT_S12E0W = 0x63c7  // 01  100  0111  1000  111
 };
 
-enum DBValues {
+enum A64DBValues {
        A64DB_Invalid = -1,
        A64DB_OSHLD = 0x1,
        A64DB_OSHST = 0x2,
@@ -145,7 +197,7 @@ enum DBValues {
        A64DB_SY =    0xf
 };
 
-enum DCValues {
+enum A64DCValues {
        A64DC_Invalid = -1,   // Op1  CRn   CRm   Op2
        A64DC_ZVA   = 0x5ba1, // 01  011  0111  0100  001
        A64DC_IVAC  = 0x43b1, // 01  000  0111  0110  001
@@ -157,19 +209,19 @@ enum DCValues {
        A64DC_CISW  = 0x43f2  // 01  000  0111  1110  010
 };
 
-enum ICValues {
+enum A64ICValues {
        A64IC_Invalid = -1,     // Op1  CRn   CRm   Op2
        A64IC_IALLUIS = 0x0388, // 000  0111  0001  000
        A64IC_IALLU = 0x03a8,   // 000  0111  0101  000
        A64IC_IVAU = 0x1ba9     // 011  0111  0101  001
 };
 
-enum ISBValues {
+enum A64ISBValues {
        A64ISB_Invalid = -1,
        A64ISB_SY = 0xf
 };
 
-enum PRFMValues {
+enum A64PRFMValues {
        A64PRFM_Invalid = -1,
        A64PRFM_PLDL1KEEP = 0x00,
        A64PRFM_PLDL1STRM = 0x01,
@@ -191,7 +243,7 @@ enum PRFMValues {
        A64PRFM_PSTL3STRM = 0x15
 };
 
-enum PStateValues {
+enum A64PStateValues {
        A64PState_Invalid = -1,
        A64PState_SPSel = 0x05,
        A64PState_DAIFSet = 0x1e,
@@ -237,8 +289,7 @@ typedef enum A64Layout_VectorLayout {
        A64Layout_VL_D
 } A64Layout_VectorLayout;
 
-inline static const char *
-A64VectorLayoutToString(A64Layout_VectorLayout Layout)
+inline static char *A64VectorLayoutToString(A64Layout_VectorLayout Layout)
 {
        switch (Layout) {
                case A64Layout_VL_8B:  return ".8b";
@@ -257,7 +308,7 @@ A64VectorLayoutToString(A64Layout_VectorLayout Layout)
        }
 }
 
-enum SysRegROValues {
+enum A64SysRegROValues {
        A64SysReg_MDCCSR_EL0        = 0x9808, // 10  011  0000  0001  000
        A64SysReg_DBGDTRRX_EL0      = 0x9828, // 10  011  0000  0101  000
        A64SysReg_MDRAR_EL1         = 0x8080, // 10  000  0001  0000  000
@@ -287,16 +338,16 @@ enum SysRegROValues {
        A64SysReg_ID_ISAR3_EL1      = 0xc013, // 11  000  0000  0010  011
        A64SysReg_ID_ISAR4_EL1      = 0xc014, // 11  000  0000  0010  100
        A64SysReg_ID_ISAR5_EL1      = 0xc015, // 11  000  0000  0010  101
-       A64SysReg_ID_AA64PFR0_EL1   = 0xc020, // 11  000  0000  0100  000
-       A64SysReg_ID_AA64PFR1_EL1   = 0xc021, // 11  000  0000  0100  001
-       A64SysReg_ID_AA64DFR0_EL1   = 0xc028, // 11  000  0000  0101  000
-       A64SysReg_ID_AA64DFR1_EL1   = 0xc029, // 11  000  0000  0101  001
-       A64SysReg_ID_AA64AFR0_EL1   = 0xc02c, // 11  000  0000  0101  100
-       A64SysReg_ID_AA64AFR1_EL1   = 0xc02d, // 11  000  0000  0101  101
-       A64SysReg_ID_AA64ISAR0_EL1  = 0xc030, // 11  000  0000  0110  000
-       A64SysReg_ID_AA64ISAR1_EL1  = 0xc031, // 11  000  0000  0110  001
-       A64SysReg_ID_AA64MMFR0_EL1  = 0xc038, // 11  000  0000  0111  000
-       A64SysReg_ID_AA64MMFR1_EL1  = 0xc039, // 11  000  0000  0111  001
+       A64SysReg_ID_A64PFR0_EL1   = 0xc020, // 11  000  0000  0100  000
+       A64SysReg_ID_A64PFR1_EL1   = 0xc021, // 11  000  0000  0100  001
+       A64SysReg_ID_A64DFR0_EL1   = 0xc028, // 11  000  0000  0101  000
+       A64SysReg_ID_A64DFR1_EL1   = 0xc029, // 11  000  0000  0101  001
+       A64SysReg_ID_A64AFR0_EL1   = 0xc02c, // 11  000  0000  0101  100
+       A64SysReg_ID_A64AFR1_EL1   = 0xc02d, // 11  000  0000  0101  101
+       A64SysReg_ID_A64ISAR0_EL1  = 0xc030, // 11  000  0000  0110  000
+       A64SysReg_ID_A64ISAR1_EL1  = 0xc031, // 11  000  0000  0110  001
+       A64SysReg_ID_A64MMFR0_EL1  = 0xc038, // 11  000  0000  0111  000
+       A64SysReg_ID_A64MMFR1_EL1  = 0xc039, // 11  000  0000  0111  001
        A64SysReg_MVFR0_EL1         = 0xc018, // 11  000  0000  0011  000
        A64SysReg_MVFR1_EL1         = 0xc019, // 11  000  0000  0011  001
        A64SysReg_MVFR2_EL1         = 0xc01a, // 11  000  0000  0011  010
@@ -356,7 +407,7 @@ enum SysRegROValues {
        A64SysReg_ICH_ELSR_EL2      = 0xe65d  // 11  100  1100  1011  101
 };
 
-enum SysRegWOValues {
+enum A64SysRegWOValues {
        A64SysReg_DBGDTRTX_EL0      = 0x9828, // 10  011  0000  0101  000
        A64SysReg_OSLAR_EL1         = 0x8084, // 10  000  0001  0000  100
        A64SysReg_PMSWINC_EL0       = 0xdce4,  // 11  011  1001  1100  100
@@ -374,7 +425,7 @@ enum SysRegWOValues {
        A64SysReg_ICC_SGI0R_EL1     = 0xc65f  // 11  000  1100  1011  111
 };
 
-enum SysRegValues {
+enum A64SysRegValues {
        A64SysReg_Invalid = -1,               // Op0 Op1  CRn   CRm   Op2
        A64SysReg_OSDTRRX_EL1       = 0x8002, // 10  000  0000  0000  010
        A64SysReg_OSDTRTX_EL1       = 0x801a, // 10  000  0000  0011  010
@@ -854,7 +905,12 @@ enum SysRegValues {
        A64SysReg_ICH_LR15_EL2      = 0xe66f  // 11  100  1100  1101  111
 };
 
-enum TLBIValues {
+// Cyclone specific system registers
+enum A64CycloneSysRegValues {
+       A64SysReg_CPM_IOACC_CTL_EL3 = 0xff90
+};
+
+enum A64TLBIValues {
        A64TLBI_Invalid = -1,          // Op0 Op1  CRn   CRm   Op2
        A64TLBI_IPAS2E1IS    = 0x6401, // 01  100  1000  0000  001
        A64TLBI_IPAS2LE1IS   = 0x6405, // 01  100  1000  0000  101
@@ -892,12 +948,12 @@ enum TLBIValues {
 
 bool A64Imms_isLogicalImmBits(unsigned RegWidth, uint32_t Bits, uint64_t *Imm);
 
-char *NamedImmMapper_toString(NamedImmMapper *N, uint32_t Value, bool *Valid);
+char *A64NamedImmMapper_toString(A64NamedImmMapper *N, uint32_t Value, bool *Valid);
 
-uint32_t NamedImmMapper_fromString(NamedImmMapper *N, char *Name, bool *Valid);
+uint32_t A64NamedImmMapper_fromString(A64NamedImmMapper *N, char *Name, bool *Valid);
 
-bool NamedImmMapper_validImm(NamedImmMapper *N, uint32_t Value);
+bool A64NamedImmMapper_validImm(A64NamedImmMapper *N, uint32_t Value);
 
-void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *result);
+void A64SysRegMapper_toString(A64SysRegMapper *S, uint32_t Bits, bool *Valid, char *result);
 
 #endif
index 9bcac86..600d402 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-/* Capstone Disassembler Engine */
-/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
+
+#ifdef CAPSTONE_HAS_ARM64
 
 #include <stdio.h>     // DEBUG
 #include <stdlib.h>
 
 #include "../../cs_priv.h"
+#include "../../utils.h"
 
-#include "../../SubtargetFeature.h"
 #include "../../MCInst.h"
 #include "../../MCInstrDesc.h"
 #include "../../MCFixedLenDisassembler.h"
 #include "../../MCDisassembler.h"
 
 #include "AArch64BaseInfo.h"
+#include "AArch64AddressingModes.h"
 
-// Forward-declarations used in the auto-generated files.
-static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
-static DecodeStatus
-DecodeGPR64xspRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
-
-static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
-static DecodeStatus
-DecodeGPR32wspRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
 
-static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
-static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
-static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
-static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
-static DecodeStatus DecodeFPR64LoRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder);
+// Forward declare these because the autogenerated code will reference them.
+// Definitions are further down.
 static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst,
                unsigned RegNo, uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeFPR128LoRegisterClass(MCInst *Inst,
-               unsigned RegNo, uint64_t Address,
-               void *Decoder);
-
-static DecodeStatus DecodeGPR64noxzrRegisterClass(MCInst *Inst,
+static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst,
                unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
+static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeQPairRegisterClass(MCInst *Inst, unsigned RegNo,
+static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeDTripleRegisterClass(MCInst *Inst,
-               unsigned RegNo, uint64_t Address,
-               void *Decoder);
-static DecodeStatus DecodeQTripleRegisterClass(MCInst *Inst,
-               unsigned RegNo, uint64_t Address,
-               void *Decoder);
-static DecodeStatus DecodeDQuadRegisterClass(MCInst *Inst, unsigned RegNo,
+static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeQQuadRegisterClass(MCInst *Inst, unsigned RegNo,
+static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeAddrRegExtendOperand(MCInst *Inst,
-               unsigned OptionHiS,
+static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeBitfield32ImmOperand(MCInst *Inst,
-               unsigned Imm6Bits,
-               uint64_t Address,
+static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst,
+               unsigned RegNo, uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeCVT32FixedPosOperand(MCInst *Inst,
-               unsigned Imm6Bits,
+static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeFPZeroOperand(MCInst *Inst,
-               unsigned RmBits,
-               uint64_t Address,
+static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst,
+               unsigned RegNo, uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeShiftRightImm8(MCInst *Inst, unsigned Val,
-               uint64_t Address, void *Decoder);
-static DecodeStatus DecodeShiftRightImm16(MCInst *Inst, unsigned Val,
+static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeShiftRightImm32(MCInst *Inst, unsigned Val,
+static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeShiftRightImm64(MCInst *Inst, unsigned Val,
+static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeShiftLeftImm8(MCInst *Inst, unsigned Val,
-               uint64_t Address, void *Decoder);
-static DecodeStatus DecodeShiftLeftImm16(MCInst *Inst, unsigned Val,
+static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeShiftLeftImm32(MCInst *Inst, unsigned Val,
+static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeShiftLeftImm64(MCInst *Inst, unsigned Val,
+static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo,
                uint64_t Address,
                void *Decoder);
 
-static DecodeStatus DecodeMoveWideImmOperand(MCInst *Inst,
-               unsigned FullImm,
-               uint64_t Address,
-               void *Decoder, int RegWidth);
-
-static DecodeStatus DecodeLogicalImmOperand(MCInst *Inst,
-               unsigned Bits,
+static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm,
                uint64_t Address,
-               void *Decoder, int RegWidth);
-
-static DecodeStatus DecodeRegExtendOperand(MCInst *Inst,
-               unsigned ShiftAmount,
+               void *Decoder);
+static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus
-DecodeNeonMovImmShiftOperand(MCInst *Inst, unsigned ShiftAmount,
-               uint64_t Address, void *Decoder, A64SE_ShiftExtSpecifiers Ext, bool IsHalf);
-
-static DecodeStatus Decode32BitShiftOperand(MCInst *Inst,
-               unsigned ShiftAmount,
+static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm,
+               uint64_t Address, void *Decoder);
+static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm,
+               uint64_t Address, void *Decoder);
+static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm,
+               uint64_t Address, void *Decoder);
+static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm,
+               uint64_t Address, void *Decoder);
+static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst,
+               uint32_t insn,
                uint64_t Address,
                void *Decoder);
-static DecodeStatus DecodeBitfieldInstruction(MCInst *Inst, unsigned Insn,
+static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn,
+static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst,
+               uint32_t insn,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeLDSTPairInstruction(MCInst *Inst,
-               unsigned Insn,
+static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Address,
+               void *Decoder);
+static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst,
+               uint32_t insn,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeLoadPairExclusiveInstruction(MCInst *Inst,
-               unsigned Val,
+static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeNamedImmOperand(MCInst *Inst,
-               unsigned Val,
+static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Address,
+               void *Decoder);
+static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Address,
+               void *Decoder);
+static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn,
                uint64_t Address,
-               void *Decoder, NamedImmMapper *N);
-
-static DecodeStatus
-DecodeSysRegOperand(SysRegMapper *InstMapper,
-               MCInst *Inst, unsigned Val,
+               void *Decoder);
+static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Address,
+               void *Decoder);
+static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn,
                uint64_t Address, void *Decoder);
-
-static DecodeStatus DecodeMRSOperand(MCInst *Inst,
-               unsigned Val,
+static DecodeStatus DecodeBaseAddSubImm(MCInst *Inst, uint32_t insn,
+               uint64_t Address, void *Decoder);
+static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeMSROperand(MCInst *Inst,
-               unsigned Val,
+static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst,
+               uint32_t insn,
                uint64_t Address,
                void *Decoder);
+static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn,
+               uint64_t Address, void *Decoder);
 
-static DecodeStatus DecodeSingleIndexedInstruction(MCInst *Inst,
-               unsigned Val,
+static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn,
                uint64_t Address,
                void *Decoder);
-
-static DecodeStatus DecodeVLDSTPostInstruction(MCInst *Inst, unsigned Val,
-               uint64_t Address,
+static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
+static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
                void *Decoder);
-
-static DecodeStatus DecodeVLDSTLanePostInstruction(MCInst *Inst, unsigned Insn,
-               uint64_t Address,
+static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
+static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
                void *Decoder);
-
-static DecodeStatus DecodeSHLLInstruction(MCInst *Inst, unsigned Insn,
-               uint64_t Address,
+static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
+static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
                void *Decoder);
-
-static bool Check(DecodeStatus *Out, DecodeStatus In);
-
-#define GET_SUBTARGETINFO_ENUM
-#include "AArch64GenSubtargetInfo.inc"
-
-// Hacky: enable all features for disassembler
-static uint64_t getFeatureBits(int feature)
-{
-       // enable all features
-       return (uint64_t)-1;
-}
-
-#include "AArch64GenDisassemblerTables.inc"
-
-#define GET_INSTRINFO_ENUM
-#include "AArch64GenInstrInfo.inc"
-
-#define GET_REGINFO_ENUM
-#include "AArch64GenRegisterInfo.inc"
+static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
+static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
+static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
+static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
+static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder);
 
 static bool Check(DecodeStatus *Out, DecodeStatus In)
 {
        switch (In) {
+               default:        // never reach
+                       return true;
                case MCDisassembler_Success:
                        // Out stays the same.
                        return true;
@@ -238,38 +190,54 @@ static bool Check(DecodeStatus *Out, DecodeStatus In)
                case MCDisassembler_Fail:
                        *Out = In;
                        return false;
-               default:
-                       return false;   // never reach
        }
+       // llvm_unreachable("Invalid DecodeStatus!");
 }
 
-#define GET_REGINFO_MC_DESC
-#include "AArch64GenRegisterInfo.inc"
-void AArch64_init(MCRegisterInfo *MRI)
+// Hacky: enable all features for disassembler
+static uint64_t getFeatureBits(int feature)
 {
-       MCRegisterInfo_InitMCRegisterInfo(MRI, AArch64RegDesc, 420,
-                       0, 0, 
-                       AArch64MCRegisterClasses, 61,
-                       0, 0, 
-                       AArch64RegDiffLists,
-                       0, 
-                       AArch64SubRegIdxLists, 52,
-                       0);
+       // enable all features
+       return (uint64_t)-1;
 }
 
+#define GET_SUBTARGETINFO_ENUM
+#include "AArch64GenSubtargetInfo.inc"
+
+#include "AArch64GenDisassemblerTables.inc"
+
+#define GET_INSTRINFO_ENUM
+#include "AArch64GenInstrInfo.inc"
+
+#define GET_REGINFO_ENUM
+#define GET_REGINFO_MC_DESC
+#include "AArch64GenRegisterInfo.inc"
+
+#define Success MCDisassembler_Success
+#define Fail MCDisassembler_Fail
+#define SoftFail MCDisassembler_SoftFail
 
 static DecodeStatus _getInstruction(cs_struct *ud, MCInst *MI,
                const uint8_t *code, size_t code_len,
                uint16_t *Size,
                uint64_t Address, MCRegisterInfo *MRI)
 {
+       uint32_t insn;
+       DecodeStatus result;
+       int i;
+
        if (code_len < 4) {
                // not enough data
                *Size = 0;
                return MCDisassembler_Fail;
        }
 
-       uint32_t insn;
+       if (MI->flat_insn->detail) {
+               memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
+               for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm64.operands); i++)
+                       MI->flat_insn->detail->arm64.operands[i].vector_index = -1;
+       }
+
        if (ud->big_endian)
                insn = (code[3] << 0) | (code[2] << 8) |
                        (code[1] <<  16) | (code[0] <<  24);
@@ -278,7 +246,7 @@ static DecodeStatus _getInstruction(cs_struct *ud, MCInst *MI,
                        (code[1] <<  8) | (code[0] <<  0);
 
        // Calling the auto-generated decoder function.
-       DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address, MRI, 0);
+       result = decodeInstruction(DecoderTable32, MI, insn, Address, MRI, 0);
        if (result != MCDisassembler_Fail) {
                *Size = 4;
                return result;
@@ -289,7 +257,8 @@ static DecodeStatus _getInstruction(cs_struct *ud, MCInst *MI,
        return MCDisassembler_Fail;
 }
 
-bool AArch64_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info)
+bool AArch64_getInstruction(csh ud, const uint8_t *code, size_t code_len,
+               MCInst *instr, uint16_t *size, uint64_t address, void *info)
 {
        DecodeStatus status = _getInstruction((cs_struct *)ud, instr,
                        code, code_len,
@@ -299,1332 +268,1414 @@ bool AArch64_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst
        return status == MCDisassembler_Success;
 }
 
-static unsigned getReg(MCRegisterInfo *MRI, unsigned RC, unsigned RegNo)
+static const unsigned FPR128DecoderTable[] = {
+       AArch64_Q0,  AArch64_Q1,  AArch64_Q2,  AArch64_Q3,  AArch64_Q4,
+       AArch64_Q5,  AArch64_Q6,  AArch64_Q7,  AArch64_Q8,  AArch64_Q9,
+       AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14,
+       AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19,
+       AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24,
+       AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29,
+       AArch64_Q30, AArch64_Q31
+};
+
+static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
+{
+       unsigned Register;
+       if (RegNo > 31)
+               return Fail;
+
+       Register = FPR128DecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
+}
+
+static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       MCRegisterClass *rc = MCRegisterInfo_getRegClass(MRI, RC);
-       return rc->RegsBegin[RegNo];
+       if (RegNo > 15)
+               return Fail;
+
+       return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
 }
 
-static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static const unsigned FPR64DecoderTable[] = {
+       AArch64_D0,  AArch64_D1,  AArch64_D2,  AArch64_D3,  AArch64_D4,
+       AArch64_D5,  AArch64_D6,  AArch64_D7,  AArch64_D8,  AArch64_D9,
+       AArch64_D10, AArch64_D11, AArch64_D12, AArch64_D13, AArch64_D14,
+       AArch64_D15, AArch64_D16, AArch64_D17, AArch64_D18, AArch64_D19,
+       AArch64_D20, AArch64_D21, AArch64_D22, AArch64_D23, AArch64_D24,
+       AArch64_D25, AArch64_D26, AArch64_D27, AArch64_D28, AArch64_D29,
+       AArch64_D30, AArch64_D31
+};
+
+static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_GPR64RegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = FPR64DecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeGPR64xspRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static const unsigned FPR32DecoderTable[] = {
+       AArch64_S0,  AArch64_S1,  AArch64_S2,  AArch64_S3,  AArch64_S4,
+       AArch64_S5,  AArch64_S6,  AArch64_S7,  AArch64_S8,  AArch64_S9,
+       AArch64_S10, AArch64_S11, AArch64_S12, AArch64_S13, AArch64_S14,
+       AArch64_S15, AArch64_S16, AArch64_S17, AArch64_S18, AArch64_S19,
+       AArch64_S20, AArch64_S21, AArch64_S22, AArch64_S23, AArch64_S24,
+       AArch64_S25, AArch64_S26, AArch64_S27, AArch64_S28, AArch64_S29,
+       AArch64_S30, AArch64_S31
+};
+
+static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_GPR64xspRegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = FPR32DecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address,
+static const unsigned FPR16DecoderTable[] = {
+       AArch64_H0,  AArch64_H1,  AArch64_H2,  AArch64_H3,  AArch64_H4,
+       AArch64_H5,  AArch64_H6,  AArch64_H7,  AArch64_H8,  AArch64_H9,
+       AArch64_H10, AArch64_H11, AArch64_H12, AArch64_H13, AArch64_H14,
+       AArch64_H15, AArch64_H16, AArch64_H17, AArch64_H18, AArch64_H19,
+       AArch64_H20, AArch64_H21, AArch64_H22, AArch64_H23, AArch64_H24,
+       AArch64_H25, AArch64_H26, AArch64_H27, AArch64_H28, AArch64_H29,
+       AArch64_H30, AArch64_H31
+};
+
+static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
                void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_GPR32RegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = FPR16DecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeGPR32wspRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static const unsigned FPR8DecoderTable[] = {
+       AArch64_B0,  AArch64_B1,  AArch64_B2,  AArch64_B3,  AArch64_B4,
+       AArch64_B5,  AArch64_B6,  AArch64_B7,  AArch64_B8,  AArch64_B9,
+       AArch64_B10, AArch64_B11, AArch64_B12, AArch64_B13, AArch64_B14,
+       AArch64_B15, AArch64_B16, AArch64_B17, AArch64_B18, AArch64_B19,
+       AArch64_B20, AArch64_B21, AArch64_B22, AArch64_B23, AArch64_B24,
+       AArch64_B25, AArch64_B26, AArch64_B27, AArch64_B28, AArch64_B29,
+       AArch64_B30, AArch64_B31
+};
+
+static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_GPR32wspRegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = FPR8DecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static const unsigned GPR64DecoderTable[] = {
+       AArch64_X0,  AArch64_X1,  AArch64_X2,  AArch64_X3,  AArch64_X4,
+       AArch64_X5,  AArch64_X6,  AArch64_X7,  AArch64_X8,  AArch64_X9,
+       AArch64_X10, AArch64_X11, AArch64_X12, AArch64_X13, AArch64_X14,
+       AArch64_X15, AArch64_X16, AArch64_X17, AArch64_X18, AArch64_X19,
+       AArch64_X20, AArch64_X21, AArch64_X22, AArch64_X23, AArch64_X24,
+       AArch64_X25, AArch64_X26, AArch64_X27, AArch64_X28, AArch64_FP,
+       AArch64_LR,  AArch64_XZR
+};
+
+static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_FPR8RegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = GPR64DecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
+
+       Register = GPR64DecoderTable[RegNo];
+       if (Register == AArch64_XZR)
+               Register = AArch64_SP;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_FPR16RegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       MCOperand_CreateReg0(Inst, Register);
+
+       return Success;
 }
 
+static const unsigned GPR32DecoderTable[] = {
+       AArch64_W0,  AArch64_W1,  AArch64_W2,  AArch64_W3,  AArch64_W4,
+       AArch64_W5,  AArch64_W6,  AArch64_W7,  AArch64_W8,  AArch64_W9,
+       AArch64_W10, AArch64_W11, AArch64_W12, AArch64_W13, AArch64_W14,
+       AArch64_W15, AArch64_W16, AArch64_W17, AArch64_W18, AArch64_W19,
+       AArch64_W20, AArch64_W21, AArch64_W22, AArch64_W23, AArch64_W24,
+       AArch64_W25, AArch64_W26, AArch64_W27, AArch64_W28, AArch64_W29,
+       AArch64_W30, AArch64_WZR
+};
 
-static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_FPR32RegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = GPR32DecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_FPR64RegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = GPR32DecoderTable[RegNo];
+       if (Register == AArch64_WZR)
+               Register = AArch64_WSP;
+
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeFPR64LoRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static const unsigned VectorDecoderTable[] = {
+       AArch64_Q0,  AArch64_Q1,  AArch64_Q2,  AArch64_Q3,  AArch64_Q4,
+       AArch64_Q5,  AArch64_Q6,  AArch64_Q7,  AArch64_Q8,  AArch64_Q9,
+       AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14,
+       AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19,
+       AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24,
+       AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29,
+       AArch64_Q30, AArch64_Q31
+};
+
+static DecodeStatus DecodeVectorRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
+               void *Decoder)
 {
-       if (RegNo > 15)
-               return MCDisassembler_Fail;
+       unsigned Register;
+
+       if (RegNo > 31)
+               return Fail;
 
-       return DecodeFPR64RegisterClass(Inst, RegNo, Address, Decoder);
+       Register = VectorDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static const unsigned QQDecoderTable[] = {
+       AArch64_Q0_Q1,   AArch64_Q1_Q2,   AArch64_Q2_Q3,   AArch64_Q3_Q4,
+       AArch64_Q4_Q5,   AArch64_Q5_Q6,   AArch64_Q6_Q7,   AArch64_Q7_Q8,
+       AArch64_Q8_Q9,   AArch64_Q9_Q10,  AArch64_Q10_Q11, AArch64_Q11_Q12,
+       AArch64_Q12_Q13, AArch64_Q13_Q14, AArch64_Q14_Q15, AArch64_Q15_Q16,
+       AArch64_Q16_Q17, AArch64_Q17_Q18, AArch64_Q18_Q19, AArch64_Q19_Q20,
+       AArch64_Q20_Q21, AArch64_Q21_Q22, AArch64_Q22_Q23, AArch64_Q23_Q24,
+       AArch64_Q24_Q25, AArch64_Q25_Q26, AArch64_Q26_Q27, AArch64_Q27_Q28,
+       AArch64_Q28_Q29, AArch64_Q29_Q30, AArch64_Q30_Q31, AArch64_Q31_Q0
+};
+
+static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr, void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_FPR128RegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = QQDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeFPR128LoRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address, void *Decoder)
+static const unsigned QQQDecoderTable[] = {
+       AArch64_Q0_Q1_Q2,    AArch64_Q1_Q2_Q3,    AArch64_Q2_Q3_Q4,
+       AArch64_Q3_Q4_Q5,    AArch64_Q4_Q5_Q6,    AArch64_Q5_Q6_Q7,
+       AArch64_Q6_Q7_Q8,    AArch64_Q7_Q8_Q9,    AArch64_Q8_Q9_Q10,
+       AArch64_Q9_Q10_Q11,  AArch64_Q10_Q11_Q12, AArch64_Q11_Q12_Q13,
+       AArch64_Q12_Q13_Q14, AArch64_Q13_Q14_Q15, AArch64_Q14_Q15_Q16,
+       AArch64_Q15_Q16_Q17, AArch64_Q16_Q17_Q18, AArch64_Q17_Q18_Q19,
+       AArch64_Q18_Q19_Q20, AArch64_Q19_Q20_Q21, AArch64_Q20_Q21_Q22,
+       AArch64_Q21_Q22_Q23, AArch64_Q22_Q23_Q24, AArch64_Q23_Q24_Q25,
+       AArch64_Q24_Q25_Q26, AArch64_Q25_Q26_Q27, AArch64_Q26_Q27_Q28,
+       AArch64_Q27_Q28_Q29, AArch64_Q28_Q29_Q30, AArch64_Q29_Q30_Q31,
+       AArch64_Q30_Q31_Q0,  AArch64_Q31_Q0_Q1
+};
+
+static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr, void *Decoder)
 {
-       if (RegNo > 15)
-               return MCDisassembler_Fail;
+       unsigned Register;
+
+       if (RegNo > 31)
+               return Fail;
 
-       return DecodeFPR128RegisterClass(Inst, RegNo, Address, Decoder);
+       Register = QQQDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeGPR64noxzrRegisterClass(MCInst *Inst,
-               unsigned RegNo,
-               uint64_t Address,
+static const unsigned QQQQDecoderTable[] = {
+       AArch64_Q0_Q1_Q2_Q3,     AArch64_Q1_Q2_Q3_Q4,     AArch64_Q2_Q3_Q4_Q5,
+       AArch64_Q3_Q4_Q5_Q6,     AArch64_Q4_Q5_Q6_Q7,     AArch64_Q5_Q6_Q7_Q8,
+       AArch64_Q6_Q7_Q8_Q9,     AArch64_Q7_Q8_Q9_Q10,    AArch64_Q8_Q9_Q10_Q11,
+       AArch64_Q9_Q10_Q11_Q12,  AArch64_Q10_Q11_Q12_Q13, AArch64_Q11_Q12_Q13_Q14,
+       AArch64_Q12_Q13_Q14_Q15, AArch64_Q13_Q14_Q15_Q16, AArch64_Q14_Q15_Q16_Q17,
+       AArch64_Q15_Q16_Q17_Q18, AArch64_Q16_Q17_Q18_Q19, AArch64_Q17_Q18_Q19_Q20,
+       AArch64_Q18_Q19_Q20_Q21, AArch64_Q19_Q20_Q21_Q22, AArch64_Q20_Q21_Q22_Q23,
+       AArch64_Q21_Q22_Q23_Q24, AArch64_Q22_Q23_Q24_Q25, AArch64_Q23_Q24_Q25_Q26,
+       AArch64_Q24_Q25_Q26_Q27, AArch64_Q25_Q26_Q27_Q28, AArch64_Q26_Q27_Q28_Q29,
+       AArch64_Q27_Q28_Q29_Q30, AArch64_Q28_Q29_Q30_Q31, AArch64_Q29_Q30_Q31_Q0,
+       AArch64_Q30_Q31_Q0_Q1,   AArch64_Q31_Q0_Q1_Q2
+};
+
+static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
                void *Decoder)
 {
-       uint16_t Register;
-
-       if (RegNo > 30)
-               return MCDisassembler_Fail;
+       unsigned Register;
+       if (RegNo > 31)
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, AArch64_GPR64noxzrRegClassID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = QQQQDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeRegisterClassByID(MCInst *Inst, unsigned RegNo,
-               unsigned RegID,
-               void *Decoder)
+static const unsigned DDDecoderTable[] = {
+       AArch64_D0_D1,   AArch64_D1_D2,   AArch64_D2_D3,   AArch64_D3_D4,
+       AArch64_D4_D5,   AArch64_D5_D6,   AArch64_D6_D7,   AArch64_D7_D8,
+       AArch64_D8_D9,   AArch64_D9_D10,  AArch64_D10_D11, AArch64_D11_D12,
+       AArch64_D12_D13, AArch64_D13_D14, AArch64_D14_D15, AArch64_D15_D16,
+       AArch64_D16_D17, AArch64_D17_D18, AArch64_D18_D19, AArch64_D19_D20,
+       AArch64_D20_D21, AArch64_D21_D22, AArch64_D22_D23, AArch64_D23_D24,
+       AArch64_D24_D25, AArch64_D25_D26, AArch64_D26_D27, AArch64_D27_D28,
+       AArch64_D28_D29, AArch64_D29_D30, AArch64_D30_D31, AArch64_D31_D0
+};
+
+static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr, void *Decoder)
 {
-       uint16_t Register;
+       unsigned Register;
 
        if (RegNo > 31)
-               return MCDisassembler_Fail;
+               return Fail;
 
-       Register = (uint16_t)getReg(Decoder, RegID, RegNo);
-       MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
-       return MCDisassembler_Success;
+       Register = DDDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address,
-               void *Decoder)
+static const unsigned DDDDecoderTable[] = {
+       AArch64_D0_D1_D2,    AArch64_D1_D2_D3,    AArch64_D2_D3_D4,
+       AArch64_D3_D4_D5,    AArch64_D4_D5_D6,    AArch64_D5_D6_D7,
+       AArch64_D6_D7_D8,    AArch64_D7_D8_D9,    AArch64_D8_D9_D10,
+       AArch64_D9_D10_D11,  AArch64_D10_D11_D12, AArch64_D11_D12_D13,
+       AArch64_D12_D13_D14, AArch64_D13_D14_D15, AArch64_D14_D15_D16,
+       AArch64_D15_D16_D17, AArch64_D16_D17_D18, AArch64_D17_D18_D19,
+       AArch64_D18_D19_D20, AArch64_D19_D20_D21, AArch64_D20_D21_D22,
+       AArch64_D21_D22_D23, AArch64_D22_D23_D24, AArch64_D23_D24_D25,
+       AArch64_D24_D25_D26, AArch64_D25_D26_D27, AArch64_D26_D27_D28,
+       AArch64_D27_D28_D29, AArch64_D28_D29_D30, AArch64_D29_D30_D31,
+       AArch64_D30_D31_D0,  AArch64_D31_D0_D1
+};
+
+static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr, void *Decoder)
 {
-       return DecodeRegisterClassByID(Inst, RegNo, AArch64_DPairRegClassID,
-                       Decoder);
+       unsigned Register;
+
+       if (RegNo > 31)
+               return Fail;
+
+       Register = DDDDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeQPairRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address,
+static const unsigned DDDDDecoderTable[] = {
+       AArch64_D0_D1_D2_D3,     AArch64_D1_D2_D3_D4,     AArch64_D2_D3_D4_D5,
+       AArch64_D3_D4_D5_D6,     AArch64_D4_D5_D6_D7,     AArch64_D5_D6_D7_D8,
+       AArch64_D6_D7_D8_D9,     AArch64_D7_D8_D9_D10,    AArch64_D8_D9_D10_D11,
+       AArch64_D9_D10_D11_D12,  AArch64_D10_D11_D12_D13, AArch64_D11_D12_D13_D14,
+       AArch64_D12_D13_D14_D15, AArch64_D13_D14_D15_D16, AArch64_D14_D15_D16_D17,
+       AArch64_D15_D16_D17_D18, AArch64_D16_D17_D18_D19, AArch64_D17_D18_D19_D20,
+       AArch64_D18_D19_D20_D21, AArch64_D19_D20_D21_D22, AArch64_D20_D21_D22_D23,
+       AArch64_D21_D22_D23_D24, AArch64_D22_D23_D24_D25, AArch64_D23_D24_D25_D26,
+       AArch64_D24_D25_D26_D27, AArch64_D25_D26_D27_D28, AArch64_D26_D27_D28_D29,
+       AArch64_D27_D28_D29_D30, AArch64_D28_D29_D30_D31, AArch64_D29_D30_D31_D0,
+       AArch64_D30_D31_D0_D1,   AArch64_D31_D0_D1_D2
+};
+
+static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Addr,
                void *Decoder)
 {
-       return DecodeRegisterClassByID(Inst, RegNo, AArch64_QPairRegClassID,
-                       Decoder);
+       unsigned Register;
+
+       if (RegNo > 31)
+               return Fail;
+
+       Register = DDDDDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return Success;
 }
 
-static DecodeStatus DecodeDTripleRegisterClass(MCInst *Inst,
-               unsigned RegNo, uint64_t Address,
+static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
                void *Decoder)
 {
-       return DecodeRegisterClassByID(Inst, RegNo, AArch64_DTripleRegClassID,
-                       Decoder);
+       // scale{5} is asserted as 1 in tblgen.
+       Imm |= 0x20;  
+       MCOperand_CreateImm0(Inst, 64 - Imm);
+       return Success;
 }
 
-static DecodeStatus DecodeQTripleRegisterClass(MCInst *Inst,
-               unsigned RegNo, uint64_t Address,
+static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
                void *Decoder)
 {
-       return DecodeRegisterClassByID(Inst, RegNo, AArch64_QTripleRegClassID,
-                       Decoder);
+       MCOperand_CreateImm0(Inst, 64 - Imm);
+       return Success;
 }
 
-static DecodeStatus DecodeDQuadRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address,
-               void *Decoder)
+static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       return DecodeRegisterClassByID(Inst, RegNo, AArch64_DQuadRegClassID,
-                       Decoder);
+       int64_t ImmVal = Imm;
+
+       // Sign-extend 19-bit immediate.
+       if (ImmVal & (1 << (19 - 1)))
+               ImmVal |= ~((1LL << 19) - 1);
+
+       MCOperand_CreateImm0(Inst, ImmVal);
+       return Success;
 }
 
-static DecodeStatus DecodeQQuadRegisterClass(MCInst *Inst, unsigned RegNo,
-               uint64_t Address,
-               void *Decoder)
+static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm,
+               uint64_t Address, void *Decoder)
 {
-       return DecodeRegisterClassByID(Inst, RegNo, AArch64_QQuadRegClassID,
-                       Decoder);
+       MCOperand_CreateImm0(Inst, (Imm  >> 1) & 1);
+       MCOperand_CreateImm0(Inst, Imm & 1);
+       return Success;
 }
 
-static DecodeStatus DecodeAddrRegExtendOperand(MCInst *Inst,
-               unsigned OptionHiS,
-               uint64_t Address,
-               void *Decoder)
+static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm,
+               uint64_t Address, void *Decoder)
 {
-       // Option{1} must be 1. OptionHiS is made up of {Option{2}, Option{1},
-       // S}. Hence we want to check bit 1.
-       if (!(OptionHiS & 2))
-               return MCDisassembler_Fail;
+       bool ValidNamed;
+       char result[128];
 
-       MCInst_addOperand(Inst, MCOperand_CreateImm(OptionHiS));
-       return MCDisassembler_Success;
+       Imm |= 0x8000;
+       MCOperand_CreateImm0(Inst, Imm);
+
+       A64SysRegMapper_toString(&AArch64_MRSMapper, Imm, &ValidNamed, result);
+
+       return ValidNamed ? Success : Fail;
 }
 
-static DecodeStatus DecodeBitfield32ImmOperand(MCInst *Inst,
-               unsigned Imm6Bits,
+static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm,
                uint64_t Address,
                void *Decoder)
 {
-       // In the 32-bit variant, bit 6 must be zero. I.e. the immediate must be
-       // between 0 and 31.
-       if (Imm6Bits > 31)
-               return MCDisassembler_Fail;
+       bool ValidNamed;
+       char result[128];
+
+       Imm |= 0x8000;
+       MCOperand_CreateImm0(Inst, Imm);
 
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Imm6Bits));
-       return MCDisassembler_Success;
+       A64SysRegMapper_toString(&AArch64_MSRMapper, Imm, &ValidNamed, result);
+
+       return ValidNamed ? Success : Fail;
 }
 
-static DecodeStatus DecodeCVT32FixedPosOperand(MCInst *Inst,
-               unsigned Imm6Bits,
+static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn,
                uint64_t Address,
                void *Decoder)
 {
-       // 1 <= Imm <= 32. Encoded as 64 - Imm so: 63 >= Encoded >= 32.
-       if (Imm6Bits < 32)
-               return MCDisassembler_Fail;
+       // This decoder exists to add the dummy Lane operand to the MCInst, which must
+       // be 1 in assembly but has no other real manifestation.
+       unsigned Rd = fieldFromInstruction(Insn, 0, 5);
+       unsigned Rn = fieldFromInstruction(Insn, 5, 5);
+       unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
+
+       if (IsToVec) {
+               DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
+               DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
+       } else {
+               DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
+               DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
+       }
+
+       // Add the lane
+       MCOperand_CreateImm0(Inst, 1);
 
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Imm6Bits));
-       return MCDisassembler_Success;
+       return Success;
 }
 
-static DecodeStatus DecodeFPZeroOperand(MCInst *Inst,
-               unsigned RmBits, uint64_t Address, void *Decoder)
+static DecodeStatus DecodeVecShiftRImm(MCInst *Inst, unsigned Imm,
+               unsigned Add)
 {
-       // Any bits are valid in the instruction (they're architecturally ignored),
-       // but a code generator should insert 0.
-       MCInst_addOperand(Inst, MCOperand_CreateImm(0));
-       return MCDisassembler_Success;
+       MCOperand_CreateImm0(Inst, Add - Imm);
+       return Success;
 }
 
-static DecodeStatus DecodeShiftRightImm8(MCInst *Inst,
-               unsigned Val, uint64_t Address, void *Decoder)
+static DecodeStatus DecodeVecShiftLImm(MCInst *Inst, unsigned Imm,
+               unsigned Add)
 {
-       MCInst_addOperand(Inst, MCOperand_CreateImm(8 - Val));
-       return MCDisassembler_Success;
+       MCOperand_CreateImm0(Inst, (Imm + Add) & (Add - 1));
+       return Success;
 }
 
-static DecodeStatus DecodeShiftRightImm16(MCInst *Inst,
-               unsigned Val, uint64_t Address, void *Decoder)
+static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       MCInst_addOperand(Inst, MCOperand_CreateImm(16 - Val));
-       return MCDisassembler_Success;
+       return DecodeVecShiftRImm(Inst, Imm, 64);
 }
 
-static DecodeStatus DecodeShiftRightImm32(MCInst *Inst,
-               unsigned Val, uint64_t Address, void *Decoder)
+static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
+               void *Decoder)
 {
-       MCInst_addOperand(Inst, MCOperand_CreateImm(32 - Val));
-       return MCDisassembler_Success;
+       return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
 }
 
-static DecodeStatus DecodeShiftRightImm64(MCInst *Inst,
-               unsigned Val, uint64_t Address, void *Decoder)
+static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       MCInst_addOperand(Inst, MCOperand_CreateImm(64 - Val));
-       return MCDisassembler_Success;
+       return DecodeVecShiftRImm(Inst, Imm, 32);
 }
 
-static DecodeStatus DecodeShiftLeftImm8(MCInst *Inst, unsigned Val,
-               uint64_t Address,
+static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
                void *Decoder)
 {
-       if (Val > 7)
-               return MCDisassembler_Fail;
+       return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
+}
 
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
-       return MCDisassembler_Success;
+static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
+{
+       return DecodeVecShiftRImm(Inst, Imm, 16);
 }
 
-static DecodeStatus DecodeShiftLeftImm16(MCInst *Inst, unsigned Val,
-               uint64_t Address,
+static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm,
+               uint64_t Addr,
                void *Decoder)
 {
-       if (Val > 15)
-               return MCDisassembler_Fail;
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
-       return MCDisassembler_Success;
+       return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
 }
 
-static DecodeStatus DecodeShiftLeftImm32(MCInst *Inst, unsigned Val,
-               uint64_t Address,
-               void *Decoder)
+static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       if (Val > 31)
-               return MCDisassembler_Fail;
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
-       return MCDisassembler_Success;
+       return DecodeVecShiftRImm(Inst, Imm, 8);
 }
 
-static DecodeStatus DecodeShiftLeftImm64(MCInst *Inst, unsigned Val,
-               uint64_t Address,
-               void *Decoder)
+static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       if (Val > 63)
-               return MCDisassembler_Fail;
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
-       return MCDisassembler_Success;
+       return DecodeVecShiftLImm(Inst, Imm, 64);
 }
 
-static DecodeStatus DecodeMoveWideImmOperand(MCInst *Inst,
-               unsigned FullImm,
-               uint64_t Address,
-               void *Decoder, int RegWidth)
+static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       unsigned Imm16 = FullImm & 0xffff;
-       unsigned Shift = FullImm >> 16;
-
-       if (RegWidth == 32 && Shift > 1) return MCDisassembler_Fail;
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Imm16));
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Shift));
-       return MCDisassembler_Success;
+       return DecodeVecShiftLImm(Inst, Imm, 32);
 }
 
-static DecodeStatus DecodeLogicalImmOperand(MCInst *Inst,
-               unsigned Bits,
-               uint64_t Address,
-               void *Decoder, int RegWidth)
+static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       uint64_t Imm;
-       if (!A64Imms_isLogicalImmBits(RegWidth, Bits, &Imm))
-               return MCDisassembler_Fail;
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Bits));
-       return MCDisassembler_Success;
+       return DecodeVecShiftLImm(Inst, Imm, 16);
 }
 
-
-static DecodeStatus DecodeRegExtendOperand(MCInst *Inst,
-               unsigned ShiftAmount,
-               uint64_t Address,
-               void *Decoder)
+static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm,
+               uint64_t Addr, void *Decoder)
 {
-       // Only values 0-4 are valid for this 3-bit field
-       if (ShiftAmount > 4)
-               return MCDisassembler_Fail;
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(ShiftAmount));
-       return MCDisassembler_Success;
+       return DecodeVecShiftLImm(Inst, Imm, 8);
 }
 
-static DecodeStatus Decode32BitShiftOperand(MCInst *Inst,
-               unsigned ShiftAmount,
-               uint64_t Address,
+static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Addr,
                void *Decoder)
 {
-       // Only values below 32 are valid for a 32-bit register
-       if (ShiftAmount > 31)
-               return MCDisassembler_Fail;
+       unsigned Rd = fieldFromInstruction(insn, 0, 5);
+       unsigned Rn = fieldFromInstruction(insn, 5, 5);
+       unsigned Rm = fieldFromInstruction(insn, 16, 5);
+       unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
+       unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
+       unsigned shift = (shiftHi << 6) | shiftLo;
+
+       switch (MCInst_getOpcode(Inst)) {
+               default:
+                       return Fail;
+               case AArch64_ADDWrs:
+               case AArch64_ADDSWrs:
+               case AArch64_SUBWrs:
+               case AArch64_SUBSWrs:
+                       // if shift == '11' then ReservedValue()
+                       if (shiftHi == 0x3)
+                               return Fail;
+                       // Deliberate fallthrough
+               case AArch64_ANDWrs:
+               case AArch64_ANDSWrs:
+               case AArch64_BICWrs:
+               case AArch64_BICSWrs:
+               case AArch64_ORRWrs:
+               case AArch64_ORNWrs:
+               case AArch64_EORWrs:
+               case AArch64_EONWrs: {
+                               // if sf == '0' and imm6<5> == '1' then ReservedValue()
+                               if (shiftLo >> 5 == 1)
+                                       return Fail;
+                               DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
+                               DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
+                               DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+                               break;
+                       }
+               case AArch64_ADDXrs:
+               case AArch64_ADDSXrs:
+               case AArch64_SUBXrs:
+               case AArch64_SUBSXrs:
+                                // if shift == '11' then ReservedValue()
+                                if (shiftHi == 0x3)
+                                        return Fail;
+                                // Deliberate fallthrough
+               case AArch64_ANDXrs:
+               case AArch64_ANDSXrs:
+               case AArch64_BICXrs:
+               case AArch64_BICSXrs:
+               case AArch64_ORRXrs:
+               case AArch64_ORNXrs:
+               case AArch64_EORXrs:
+               case AArch64_EONXrs:
+                                DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+                                DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
+                                DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
+                                break;
+       }
 
-       MCInst_addOperand(Inst, MCOperand_CreateImm(ShiftAmount));
-       return MCDisassembler_Success;
+       MCOperand_CreateImm0(Inst, shift);
+       return Success;
 }
 
-static DecodeStatus DecodeBitfieldInstruction(MCInst *Inst, unsigned Insn,
-               uint64_t Address,
+static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn,
+               uint64_t Addr,
                void *Decoder)
 {
-       unsigned Rd = fieldFromInstruction(Insn, 0, 5);
-       unsigned Rn = fieldFromInstruction(Insn, 5, 5);
-       unsigned ImmS = fieldFromInstruction(Insn, 10, 6);
-       unsigned ImmR = fieldFromInstruction(Insn, 16, 6);
-       unsigned SF = fieldFromInstruction(Insn, 31, 1);
-
-       // Undef for 0b11 just in case it occurs. Don't want the compiler to optimise
-       // out assertions that it thinks should never be hit.
-       enum OpcTypes { SBFM = 0, BFM, UBFM, Undef } Opc;
-       Opc = (enum OpcTypes)fieldFromInstruction(Insn, 29, 2);
-
-       if (!SF) {
-               // ImmR and ImmS must be between 0 and 31 for 32-bit instructions.
-               if (ImmR > 31 || ImmS > 31)
-                       return MCDisassembler_Fail;
-       }
-
-       if (SF) {
-               DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
-               // BFM MCInsts use Rd as a source too.
-               if (Opc == BFM) DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
-               DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
-       } else {
-               DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
-               // BFM MCInsts use Rd as a source too.
-               if (Opc == BFM) DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
-               DecodeGPR32RegisterClass(Inst, Rn, Address, Decoder);
-       }
+       unsigned Rd = fieldFromInstruction(insn, 0, 5);
+       unsigned imm = fieldFromInstruction(insn, 5, 16);
+       unsigned shift = fieldFromInstruction(insn, 21, 2);
 
-       // ASR and LSR have more specific patterns so they won't get here:
-       //assert(!(ImmS == 31 && !SF && Opc != BFM)
-       //       && "shift should have used auto decode");
-       //assert(!(ImmS == 63 && SF && Opc != BFM)
-       //       && "shift should have used auto decode");
-
-       // Extension instructions similarly:
-       if (Opc == SBFM && ImmR == 0) {
-               //assert((ImmS != 7 && ImmS != 15) && "extension got here");
-               //assert((ImmS != 31 || SF == 0) && "extension got here");
-       } else if (Opc == UBFM && ImmR == 0) {
-               //assert((SF != 0 || (ImmS != 7 && ImmS != 15)) && "extension got here");
-       }
-
-       if (Opc == UBFM) {
-               // It might be a LSL instruction, which actually takes the shift amount
-               // itself as an MCInst operand.
-               if (SF && (ImmS + 1) % 64 == ImmR) {
-                       MCInst_setOpcode(Inst, AArch64_LSLxxi);
-                       MCInst_addOperand(Inst, MCOperand_CreateImm(63 - ImmS));
-                       return MCDisassembler_Success;
-               } else if (!SF && (ImmS + 1) % 32 == ImmR) {
-                       MCInst_setOpcode(Inst, AArch64_LSLwwi);
-                       MCInst_addOperand(Inst, MCOperand_CreateImm(31 - ImmS));
-                       return MCDisassembler_Success;
-               }
-       }
+       shift <<= 4;
 
-       // Otherwise it's definitely either an extract or an insert depending on which
-       // of ImmR or ImmS is larger.
-       unsigned ExtractOp = 0, InsertOp = 0;
-       switch (Opc) {
-               default: break; // never reach
-               case SBFM:
-                                ExtractOp = SF ? AArch64_SBFXxxii : AArch64_SBFXwwii;
-                                InsertOp = SF ? AArch64_SBFIZxxii : AArch64_SBFIZwwii;
-                                break;
-               case BFM:
-                                ExtractOp = SF ? AArch64_BFXILxxii : AArch64_BFXILwwii;
-                                InsertOp = SF ? AArch64_BFIxxii : AArch64_BFIwwii;
-                                break;
-               case UBFM:
-                                ExtractOp = SF ? AArch64_UBFXxxii : AArch64_UBFXwwii;
-                                InsertOp = SF ? AArch64_UBFIZxxii : AArch64_UBFIZwwii;
-                                break;
+       switch (MCInst_getOpcode(Inst)) {
+               default:
+                       return Fail;
+               case AArch64_MOVZWi:
+               case AArch64_MOVNWi:
+               case AArch64_MOVKWi:
+                       if (shift & (1U << 5))
+                               return Fail;
+                       DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
+                       break;
+               case AArch64_MOVZXi:
+               case AArch64_MOVNXi:
+               case AArch64_MOVKXi:
+                       DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+                       break;
        }
 
-       // Otherwise it's a boring insert or extract
-       MCInst_addOperand(Inst, MCOperand_CreateImm(ImmR));
-       MCInst_addOperand(Inst, MCOperand_CreateImm(ImmS));
-
-
-       if (ImmS < ImmR)
-               MCInst_setOpcode(Inst, InsertOp);
-       else
-               MCInst_setOpcode(Inst, ExtractOp);
+       if (MCInst_getOpcode(Inst) == AArch64_MOVKWi ||
+                       MCInst_getOpcode(Inst) == AArch64_MOVKXi)
+               MCInst_addOperand2(Inst, MCInst_getOperand(Inst, 0));
 
-       return MCDisassembler_Success;
+       MCOperand_CreateImm0(Inst, imm);
+       MCOperand_CreateImm0(Inst, shift);
+       return Success;
 }
 
-static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn,
-               uint64_t Address,
+static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Addr,
                void *Decoder)
 {
-       // This decoder exists to add the dummy Lane operand to the MCInst, which must
-       // be 1 in assembly but has no other real manifestation.
-       unsigned Rd = fieldFromInstruction(Insn, 0, 5);
-       unsigned Rn = fieldFromInstruction(Insn, 5, 5);
-       unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
+       unsigned Rt = fieldFromInstruction(insn, 0, 5);
+       unsigned Rn = fieldFromInstruction(insn, 5, 5);
+       unsigned offset = fieldFromInstruction(insn, 10, 12);
 
-       if (IsToVec) {
-               DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
-               DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
-       } else {
-               DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
-               DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
+       switch (MCInst_getOpcode(Inst)) {
+               default:
+                       return Fail;
+               case AArch64_PRFMui:
+                       // Rt is an immediate in prefetch.
+                       MCOperand_CreateImm0(Inst, Rt);
+                       break;
+               case AArch64_STRBBui:
+               case AArch64_LDRBBui:
+               case AArch64_LDRSBWui:
+               case AArch64_STRHHui:
+               case AArch64_LDRHHui:
+               case AArch64_LDRSHWui:
+               case AArch64_STRWui:
+               case AArch64_LDRWui:
+                       DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDRSBXui:
+               case AArch64_LDRSHXui:
+               case AArch64_LDRSWui:
+               case AArch64_STRXui:
+               case AArch64_LDRXui:
+                       DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDRQui:
+               case AArch64_STRQui:
+                       DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDRDui:
+               case AArch64_STRDui:
+                       DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDRSui:
+               case AArch64_STRSui:
+                       DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDRHui:
+               case AArch64_STRHui:
+                       DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDRBui:
+               case AArch64_STRBui:
+                       DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
        }
 
-       // Add the lane
-       MCInst_addOperand(Inst, MCOperand_CreateImm(1));
+       DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+       //if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4))
+       MCOperand_CreateImm0(Inst, offset);
 
-       return MCDisassembler_Success;
+       return Success;
 }
 
-static DecodeStatus DecodeLDSTPairInstruction(MCInst *Inst,
-               unsigned Insn,
-               uint64_t Address,
+static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Addr,
                void *Decoder)
 {
-       DecodeStatus Result = MCDisassembler_Success;
-       unsigned Rt = fieldFromInstruction(Insn, 0, 5);
-       unsigned Rn = fieldFromInstruction(Insn, 5, 5);
-       unsigned Rt2 = fieldFromInstruction(Insn, 10, 5);
-       unsigned SImm7 = fieldFromInstruction(Insn, 15, 7);
-       unsigned L = fieldFromInstruction(Insn, 22, 1);
-       unsigned V = fieldFromInstruction(Insn, 26, 1);
-       unsigned Opc = fieldFromInstruction(Insn, 30, 2);
-
-       // Not an official name, but it turns out that bit 23 distinguishes indexed
-       // from non-indexed operations.
-       unsigned Indexed = fieldFromInstruction(Insn, 23, 1);
-
-       if (Indexed && L == 0) {
-               // The MCInst for an indexed store has an out operand and 4 ins:
-               //    Rn_wb, Rt, Rt2, Rn, Imm
-               DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
+       bool IsLoad;
+       bool IsIndexed;
+       bool IsFP;
+       unsigned Rt = fieldFromInstruction(insn, 0, 5);
+       unsigned Rn = fieldFromInstruction(insn, 5, 5);
+       int32_t offset = fieldFromInstruction(insn, 12, 9);
+
+       // offset is a 9-bit signed immediate, so sign extend it to
+       // fill the unsigned.
+       if (offset & (1 << (9 - 1)))
+               offset |= ~((1LL << 9) - 1);
+
+       // First operand is always the writeback to the address register, if needed.
+       switch (MCInst_getOpcode(Inst)) {
+               default:
+                       break;
+               case AArch64_LDRSBWpre:
+               case AArch64_LDRSHWpre:
+               case AArch64_STRBBpre:
+               case AArch64_LDRBBpre:
+               case AArch64_STRHHpre:
+               case AArch64_LDRHHpre:
+               case AArch64_STRWpre:
+               case AArch64_LDRWpre:
+               case AArch64_LDRSBWpost:
+               case AArch64_LDRSHWpost:
+               case AArch64_STRBBpost:
+               case AArch64_LDRBBpost:
+               case AArch64_STRHHpost:
+               case AArch64_LDRHHpost:
+               case AArch64_STRWpost:
+               case AArch64_LDRWpost:
+               case AArch64_LDRSBXpre:
+               case AArch64_LDRSHXpre:
+               case AArch64_STRXpre:
+               case AArch64_LDRSWpre:
+               case AArch64_LDRXpre:
+               case AArch64_LDRSBXpost:
+               case AArch64_LDRSHXpost:
+               case AArch64_STRXpost:
+               case AArch64_LDRSWpost:
+               case AArch64_LDRXpost:
+               case AArch64_LDRQpre:
+               case AArch64_STRQpre:
+               case AArch64_LDRQpost:
+               case AArch64_STRQpost:
+               case AArch64_LDRDpre:
+               case AArch64_STRDpre:
+               case AArch64_LDRDpost:
+               case AArch64_STRDpost:
+               case AArch64_LDRSpre:
+               case AArch64_STRSpre:
+               case AArch64_LDRSpost:
+               case AArch64_STRSpost:
+               case AArch64_LDRHpre:
+               case AArch64_STRHpre:
+               case AArch64_LDRHpost:
+               case AArch64_STRHpost:
+               case AArch64_LDRBpre:
+               case AArch64_STRBpre:
+               case AArch64_LDRBpost:
+               case AArch64_STRBpost:
+                       DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+                       break;
        }
 
-       // You shouldn't load to the same register twice in an instruction...
-       if (L && Rt == Rt2)
-               Result = MCDisassembler_SoftFail;
-
-       // ... or do any operation that writes-back to a transfer register. But note
-       // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
-       if (Indexed && V == 0 && Rn != 31 && (Rt == Rn || Rt2 == Rn))
-               Result = MCDisassembler_SoftFail;
-
-       // Exactly how we decode the MCInst's registers depends on the Opc and V
-       // fields of the instruction. These also obviously determine the size of the
-       // operation so we can fill in that information while we're at it.
-       if (V) {
-               // The instruction operates on the FP/SIMD registers
-               switch (Opc) {
-                       default: return MCDisassembler_Fail;
-                       case 0:
-                                        DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
-                                        DecodeFPR32RegisterClass(Inst, Rt2, Address, Decoder);
-                                        break;
-                       case 1:
-                                        DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
-                                        DecodeFPR64RegisterClass(Inst, Rt2, Address, Decoder);
-                                        break;
-                       case 2:
-                                        DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
-                                        DecodeFPR128RegisterClass(Inst, Rt2, Address, Decoder);
-                                        break;
-               }
-       } else {
-               switch (Opc) {
-                       default: return MCDisassembler_Fail;
-                       case 0:
-                                        DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
-                                        DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder);
-                                        break;
-                       case 1:
-                                        //assert(L && "unexpected \"store signed\" attempt");
-                                        DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
-                                        DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
-                                        break;
-                       case 2:
-                                        DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
-                                        DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
-                                        break;
-               }
+       switch (MCInst_getOpcode(Inst)) {
+               default:
+                       return Fail;
+               case AArch64_PRFUMi:
+                       // Rt is an immediate in prefetch.
+                       MCOperand_CreateImm0(Inst, Rt);
+                       break;
+               case AArch64_STURBBi:
+               case AArch64_LDURBBi:
+               case AArch64_LDURSBWi:
+               case AArch64_STURHHi:
+               case AArch64_LDURHHi:
+               case AArch64_LDURSHWi:
+               case AArch64_STURWi:
+               case AArch64_LDURWi:
+               case AArch64_LDTRSBWi:
+               case AArch64_LDTRSHWi:
+               case AArch64_STTRWi:
+               case AArch64_LDTRWi:
+               case AArch64_STTRHi:
+               case AArch64_LDTRHi:
+               case AArch64_LDTRBi:
+               case AArch64_STTRBi:
+               case AArch64_LDRSBWpre:
+               case AArch64_LDRSHWpre:
+               case AArch64_STRBBpre:
+               case AArch64_LDRBBpre:
+               case AArch64_STRHHpre:
+               case AArch64_LDRHHpre:
+               case AArch64_STRWpre:
+               case AArch64_LDRWpre:
+               case AArch64_LDRSBWpost:
+               case AArch64_LDRSHWpost:
+               case AArch64_STRBBpost:
+               case AArch64_LDRBBpost:
+               case AArch64_STRHHpost:
+               case AArch64_LDRHHpost:
+               case AArch64_STRWpost:
+               case AArch64_LDRWpost:
+                       DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDURSBXi:
+               case AArch64_LDURSHXi:
+               case AArch64_LDURSWi:
+               case AArch64_STURXi:
+               case AArch64_LDURXi:
+               case AArch64_LDTRSBXi:
+               case AArch64_LDTRSHXi:
+               case AArch64_LDTRSWi:
+               case AArch64_STTRXi:
+               case AArch64_LDTRXi:
+               case AArch64_LDRSBXpre:
+               case AArch64_LDRSHXpre:
+               case AArch64_STRXpre:
+               case AArch64_LDRSWpre:
+               case AArch64_LDRXpre:
+               case AArch64_LDRSBXpost:
+               case AArch64_LDRSHXpost:
+               case AArch64_STRXpost:
+               case AArch64_LDRSWpost:
+               case AArch64_LDRXpost:
+                       DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDURQi:
+               case AArch64_STURQi:
+               case AArch64_LDRQpre:
+               case AArch64_STRQpre:
+               case AArch64_LDRQpost:
+               case AArch64_STRQpost:
+                       DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDURDi:
+               case AArch64_STURDi:
+               case AArch64_LDRDpre:
+               case AArch64_STRDpre:
+               case AArch64_LDRDpost:
+               case AArch64_STRDpost:
+                       DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDURSi:
+               case AArch64_STURSi:
+               case AArch64_LDRSpre:
+               case AArch64_STRSpre:
+               case AArch64_LDRSpost:
+               case AArch64_STRSpost:
+                       DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDURHi:
+               case AArch64_STURHi:
+               case AArch64_LDRHpre:
+               case AArch64_STRHpre:
+               case AArch64_LDRHpost:
+               case AArch64_STRHpost:
+                       DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_LDURBi:
+               case AArch64_STURBi:
+               case AArch64_LDRBpre:
+               case AArch64_STRBpre:
+               case AArch64_LDRBpost:
+               case AArch64_STRBpost:
+                       DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
        }
 
-       if (Indexed && L == 1) {
-               // The MCInst for an indexed load has 3 out operands and an 3 ins:
-               //    Rt, Rt2, Rn_wb, Rt2, Rn, Imm
-               DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
-       }
+       DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+       MCOperand_CreateImm0(Inst, offset);
 
+       IsLoad = fieldFromInstruction(insn, 22, 1);
+       IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
+       IsFP = fieldFromInstruction(insn, 26, 1);
 
-       DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
-       MCInst_addOperand(Inst, MCOperand_CreateImm(SImm7));
+       // Cannot write back to a transfer register (but xzr != sp).
+       if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
+               return SoftFail;
 
-       return Result;
+       return Success;
 }
 
-static DecodeStatus DecodeLoadPairExclusiveInstruction(MCInst *Inst,
-               uint32_t Val,
-               uint64_t Address,
+static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Addr,
                void *Decoder)
 {
-       unsigned Rt = fieldFromInstruction(Val, 0, 5);
-       unsigned Rn = fieldFromInstruction(Val, 5, 5);
-       unsigned Rt2 = fieldFromInstruction(Val, 10, 5);
-       unsigned MemSize = fieldFromInstruction(Val, 30, 2);
-
-       DecodeStatus S = MCDisassembler_Success;
-       if (Rt == Rt2) S = MCDisassembler_SoftFail;
-
-       switch (MemSize) {
-               case 2:
-                       if (!Check(&S, DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder)))
-                               return MCDisassembler_Fail;
-                       if (!Check(&S, DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder)))
-                               return MCDisassembler_Fail;
+       unsigned Rt = fieldFromInstruction(insn, 0, 5);
+       unsigned Rn = fieldFromInstruction(insn, 5, 5);
+       unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
+       unsigned Rs = fieldFromInstruction(insn, 16, 5);
+       unsigned Opcode = MCInst_getOpcode(Inst);
+
+       switch (Opcode) {
+               default:
+                       return Fail;
+               case AArch64_STLXRW:
+               case AArch64_STLXRB:
+               case AArch64_STLXRH:
+               case AArch64_STXRW:
+               case AArch64_STXRB:
+               case AArch64_STXRH:
+                       DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+                       // FALLTHROUGH
+               case AArch64_LDARW:
+               case AArch64_LDARB:
+               case AArch64_LDARH:
+               case AArch64_LDAXRW:
+               case AArch64_LDAXRB:
+               case AArch64_LDAXRH:
+               case AArch64_LDXRW:
+               case AArch64_LDXRB:
+               case AArch64_LDXRH:
+               case AArch64_STLRW:
+               case AArch64_STLRB:
+               case AArch64_STLRH:
+                       DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
                        break;
-               case 3:
-                       if (!Check(&S, DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder)))
-                               return MCDisassembler_Fail;
-                       if (!Check(&S, DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder)))
-                               return MCDisassembler_Fail;
+               case AArch64_STLXRX:
+               case AArch64_STXRX:
+                       DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+                       // FALLTHROUGH
+               case AArch64_LDARX:
+               case AArch64_LDAXRX:
+               case AArch64_LDXRX:
+               case AArch64_STLRX:
+                       DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       break;
+               case AArch64_STLXPW:
+               case AArch64_STXPW:
+                       DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+                       // FALLTHROUGH
+               case AArch64_LDAXPW:
+               case AArch64_LDXPW:
+                       DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+                       DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
+                       break;
+               case AArch64_STLXPX:
+               case AArch64_STXPX:
+                       DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+                       // FALLTHROUGH
+               case AArch64_LDAXPX:
+               case AArch64_LDXPX:
+                       DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
                        break;
-               default:
-                       break;  // never reach
        }
 
-       if (!Check(&S, DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder)))
-               return MCDisassembler_Fail;
+       DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
 
-       return S;
+       // You shouldn't load to the same register twice in an instruction...
+       if ((Opcode == AArch64_LDAXPW || Opcode == AArch64_LDXPW ||
+                               Opcode == AArch64_LDAXPX || Opcode == AArch64_LDXPX) &&
+                       Rt == Rt2)
+               return SoftFail;
+
+       return Success;
 }
 
-static DecodeStatus DecodeNamedImmOperand(MCInst *Inst,
-               unsigned Val,
-               uint64_t Address,
-               void *Decoder, NamedImmMapper *N)
+static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn,
+               uint64_t Addr,
+               void *Decoder)
 {
-       bool ValidNamed;
+       unsigned Rt = fieldFromInstruction(insn, 0, 5);
+       unsigned Rn = fieldFromInstruction(insn, 5, 5);
+       unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
+       int32_t offset = fieldFromInstruction(insn, 15, 7);
+       bool IsLoad = fieldFromInstruction(insn, 22, 1);
+       unsigned Opcode = MCInst_getOpcode(Inst);
+       bool NeedsDisjointWritebackTransfer = false;
+
+       // offset is a 7-bit signed immediate, so sign extend it to
+       // fill the unsigned.
+       if (offset & (1 << (7 - 1)))
+               offset |= ~((1LL << 7) - 1);
+
+       // First operand is always writeback of base register.
+       switch (Opcode) {
+               default:
+                       break;
+               case AArch64_LDPXpost:
+               case AArch64_STPXpost:
+               case AArch64_LDPSWpost:
+               case AArch64_LDPXpre:
+               case AArch64_STPXpre:
+               case AArch64_LDPSWpre:
+               case AArch64_LDPWpost:
+               case AArch64_STPWpost:
+               case AArch64_LDPWpre:
+               case AArch64_STPWpre:
+               case AArch64_LDPQpost:
+               case AArch64_STPQpost:
+               case AArch64_LDPQpre:
+               case AArch64_STPQpre:
+               case AArch64_LDPDpost:
+               case AArch64_STPDpost:
+               case AArch64_LDPDpre:
+               case AArch64_STPDpre:
+               case AArch64_LDPSpost:
+               case AArch64_STPSpost:
+               case AArch64_LDPSpre:
+               case AArch64_STPSpre:
+                       DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+                       break;
+       }
 
-       NamedImmMapper_toString(N, Val, &ValidNamed);
-       if (ValidNamed || NamedImmMapper_validImm(N, Val)) {
-               MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
-               return MCDisassembler_Success;
+       switch (Opcode) {
+               default:
+                       return Fail;
+               case AArch64_LDPXpost:
+               case AArch64_STPXpost:
+               case AArch64_LDPSWpost:
+               case AArch64_LDPXpre:
+               case AArch64_STPXpre:
+               case AArch64_LDPSWpre:
+                       NeedsDisjointWritebackTransfer = true;
+                       // Fallthrough
+               case AArch64_LDNPXi:
+               case AArch64_STNPXi:
+               case AArch64_LDPXi:
+               case AArch64_STPXi:
+               case AArch64_LDPSWi:
+                       DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
+                       break;
+               case AArch64_LDPWpost:
+               case AArch64_STPWpost:
+               case AArch64_LDPWpre:
+               case AArch64_STPWpre:
+                       NeedsDisjointWritebackTransfer = true;
+                       // Fallthrough
+               case AArch64_LDNPWi:
+               case AArch64_STNPWi:
+               case AArch64_LDPWi:
+               case AArch64_STPWi:
+                       DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+                       DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
+                       break;
+               case AArch64_LDNPQi:
+               case AArch64_STNPQi:
+               case AArch64_LDPQpost:
+               case AArch64_STPQpost:
+               case AArch64_LDPQi:
+               case AArch64_STPQi:
+               case AArch64_LDPQpre:
+               case AArch64_STPQpre:
+                       DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
+                       DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
+                       break;
+               case AArch64_LDNPDi:
+               case AArch64_STNPDi:
+               case AArch64_LDPDpost:
+               case AArch64_STPDpost:
+               case AArch64_LDPDi:
+               case AArch64_STPDi:
+               case AArch64_LDPDpre:
+               case AArch64_STPDpre:
+                       DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
+                       DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
+                       break;
+               case AArch64_LDNPSi:
+               case AArch64_STNPSi:
+               case AArch64_LDPSpost:
+               case AArch64_STPSpost:
+               case AArch64_LDPSi:
+               case AArch64_STPSi:
+               case AArch64_LDPSpre:
+               case AArch64_STPSpre:
+                       DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
+                       DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
+                       break;
        }
 
-       return MCDisassembler_Fail;
-}
+       DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+       MCOperand_CreateImm0(Inst, offset);
 
-static DecodeStatus DecodeSysRegOperand(SysRegMapper *Mapper,
-               MCInst *Inst,
-               unsigned Val,
-               uint64_t Address,
-               void *Decoder)
-{
-       bool ValidNamed;
-       char result[128];
-       SysRegMapper_toString(Mapper, Val, &ValidNamed, result);
+       // You shouldn't load to the same register twice in an instruction...
+       if (IsLoad && Rt == Rt2)
+               return SoftFail;
 
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
+       // ... or do any operation that writes-back to a transfer register. But note
+       // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
+       if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
+               return SoftFail;
 
-       return ValidNamed ? MCDisassembler_Success : MCDisassembler_Fail;
+       return Success;
 }
 
-static DecodeStatus DecodeMRSOperand(MCInst *Inst,
-               unsigned Val,
-               uint64_t Address,
+static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Addr,
                void *Decoder)
 {
-       return DecodeSysRegOperand(&AArch64_MRSMapper, Inst, Val, Address, Decoder);
+  unsigned Rd, Rn, Rm;
+  unsigned extend = fieldFromInstruction(insn, 10, 6);
+  unsigned shift = extend & 0x7;
+
+  if (shift > 4)
+    return Fail;
+
+  Rd = fieldFromInstruction(insn, 0, 5);
+  Rn = fieldFromInstruction(insn, 5, 5);
+  Rm = fieldFromInstruction(insn, 16, 5);
+
+  switch (MCInst_getOpcode(Inst)) {
+  default:
+    return Fail;
+  case AArch64_ADDWrx:
+  case AArch64_SUBWrx:
+    DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    break;
+  case AArch64_ADDSWrx:
+  case AArch64_SUBSWrx:
+    DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    break;
+  case AArch64_ADDXrx:
+  case AArch64_SUBXrx:
+    DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    break;
+  case AArch64_ADDSXrx:
+  case AArch64_SUBSXrx:
+    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    break;
+  case AArch64_ADDXrx64:
+  case AArch64_SUBXrx64:
+    DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
+    break;
+  case AArch64_SUBSXrx64:
+  case AArch64_ADDSXrx64:
+    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
+    break;
+  }
+
+  MCOperand_CreateImm0(Inst, extend);
+  return Success;
 }
 
-static DecodeStatus DecodeMSROperand(MCInst *Inst,
-               unsigned Val,
-               uint64_t Address,
+static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Addr,
                void *Decoder)
 {
-       return DecodeSysRegOperand(&AArch64_MSRMapper, Inst, Val, Address, Decoder);
-}
-
-static DecodeStatus DecodeSingleIndexedInstruction(MCInst *Inst,
-               unsigned Insn,
-               uint64_t Address,
-               void *Decoder)
-{
-       unsigned Rt = fieldFromInstruction(Insn, 0, 5);
-       unsigned Rn = fieldFromInstruction(Insn, 5, 5);
-       unsigned Imm9 = fieldFromInstruction(Insn, 12, 9);
-
-       unsigned Opc = fieldFromInstruction(Insn, 22, 2);
-       unsigned V = fieldFromInstruction(Insn, 26, 1);
-       unsigned Size = fieldFromInstruction(Insn, 30, 2);
-
-       if (Opc == 0 || (V == 1 && Opc == 2)) {
-               // It's a store, the MCInst gets: Rn_wb, Rt, Rn, Imm
-               DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
-       }
-
-       if (V == 0 && (Opc == 2 || Size == 3)) {
-               DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
-       } else if (V == 0) {
-               DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
-       } else if (V == 1 && (Opc & 2)) {
-               DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
+       unsigned Rd = fieldFromInstruction(insn, 0, 5);
+       unsigned Rn = fieldFromInstruction(insn, 5, 5);
+       unsigned Datasize = fieldFromInstruction(insn, 31, 1);
+       unsigned imm;
+
+       if (Datasize) {
+               if (MCInst_getOpcode(Inst) == AArch64_ANDSXri)
+                       DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+               else
+                       DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
+               DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
+               imm = fieldFromInstruction(insn, 10, 13);
+               if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 64))
+                       return Fail;
        } else {
-               switch (Size) {
-                       case 0:
-                               DecodeFPR8RegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 1:
-                               DecodeFPR16RegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 2:
-                               DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 3:
-                               DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-               }
-       }
-
-       if (Opc != 0 && (V != 1 || Opc != 2)) {
-               // It's a load, the MCInst gets: Rt, Rn_wb, Rn, Imm
-               DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
+               if (MCInst_getOpcode(Inst) == AArch64_ANDSWri)
+                       DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
+               else
+                       DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
+               DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
+               imm = fieldFromInstruction(insn, 10, 12);
+               if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 32))
+                       return Fail;
        }
 
-       DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(Imm9));
-
-       // N.b. The official documentation says undpredictable if Rt == Rn, but this
-       // takes place at the architectural rather than encoding level:
-       //
-       // "STR xzr, [sp], #4" is perfectly valid.
-       if (V == 0 && Rt == Rn && Rn != 31)
-               return MCDisassembler_SoftFail;
-       else
-               return MCDisassembler_Success;
+       MCOperand_CreateImm0(Inst, imm);
+       return Success;
 }
 
-static DecodeStatus DecodeNeonMovImmShiftOperand(MCInst *Inst, unsigned ShiftAmount,
-               uint64_t Address, void *Decoder, A64SE_ShiftExtSpecifiers Ext, bool IsHalf)
-{
-       bool IsLSL = false;
-       if (Ext == A64SE_LSL)
-               IsLSL = true;
-       else if (Ext != A64SE_MSL)
-               return MCDisassembler_Fail;
-
-       // MSL and LSLH accepts encoded shift amount 0 or 1.
-       if ((!IsLSL || (IsLSL && IsHalf)) && ShiftAmount != 0 && ShiftAmount != 1)
-               return MCDisassembler_Fail;
-
-       // LSL  accepts encoded shift amount 0, 1, 2 or 3.
-       if (IsLSL && ShiftAmount > 3)
-               return MCDisassembler_Fail;
-
-       MCInst_addOperand(Inst, MCOperand_CreateImm(ShiftAmount));
-       return MCDisassembler_Success;
-}
-
-// Decode post-index vector load/store instructions.
-// This is necessary as we need to decode Rm: if Rm == 0b11111, the last
-// operand is an immediate equal the the length of vector list in bytes,
-// or Rm is decoded to a GPR64noxzr register.
-static DecodeStatus DecodeVLDSTPostInstruction(MCInst *Inst, unsigned Insn,
-               uint64_t Address,
+static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn,
+               uint64_t Addr,
                void *Decoder)
 {
-       unsigned Rt = fieldFromInstruction(Insn, 0, 5);
-       unsigned Rn = fieldFromInstruction(Insn, 5, 5);
-       unsigned Rm = fieldFromInstruction(Insn, 16, 5);
-       unsigned Opcode = fieldFromInstruction(Insn, 12, 4);
-       unsigned IsLoad = fieldFromInstruction(Insn, 22, 1);
-       // 0 for 64bit vector list, 1 for 128bit vector list
-       unsigned Is128BitVec = fieldFromInstruction(Insn, 30, 1);
+       unsigned Rd = fieldFromInstruction(insn, 0, 5);
+       unsigned cmode = fieldFromInstruction(insn, 12, 4);
+       unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
+       imm |= fieldFromInstruction(insn, 5, 5);
 
-       unsigned NumVecs;
-       switch (Opcode) {
-               default:
-                       // llvm_unreachable("Invalid opcode for post-index load/store instructions");
-               case 0: // ld4/st4
-               case 2: // ld1/st1 with 4 vectors
-                       NumVecs = 4; break;
-               case 4: // ld3/st3
-               case 6: // ld1/st1 with 3 vectors
-                       NumVecs = 3; break;
-               case 7: // ld1/st1 with 1 vector
-                       NumVecs = 1; break;
-               case 8:  // ld2/st2
-               case 10: // ld1/st1 with 2 vectors
-                       NumVecs = 2; break;
-       }
+       if (MCInst_getOpcode(Inst) == AArch64_MOVID)
+               DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
+       else
+               DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
 
-       // Decode vector list of 1/2/3/4 vectors for load instructions.
-       if (IsLoad) {
-               switch (NumVecs) {
-                       case 1:
-                               Is128BitVec ? DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 2:
-                               Is128BitVec ? DecodeQPairRegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeDPairRegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 3:
-                               Is128BitVec ? DecodeQTripleRegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeDTripleRegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 4:
-                               Is128BitVec ? DecodeQQuadRegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeDQuadRegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-               }
-       }
+       MCOperand_CreateImm0(Inst, imm);
 
-       // Decode write back register, which is equal to Rn.
-       DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
-       DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
-
-       if (Rm == 31) // If Rm is 0x11111, add the vector list length in byte
-               MCInst_addOperand(Inst, MCOperand_CreateImm(NumVecs * (Is128BitVec ? 16 : 8)));
-       else // Decode Rm
-               DecodeGPR64noxzrRegisterClass(Inst, Rm, Address, Decoder);
-
-       // Decode vector list of 1/2/3/4 vectors for load instructions.
-       if (!IsLoad) {
-               switch (NumVecs) {
-                       case 1:
-                               Is128BitVec ? DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 2:
-                               Is128BitVec ? DecodeQPairRegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeDPairRegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 3:
-                               Is128BitVec ? DecodeQTripleRegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeDTripleRegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-                       case 4:
-                               Is128BitVec ? DecodeQQuadRegisterClass(Inst, Rt, Address, Decoder)
-                                       : DecodeDQuadRegisterClass(Inst, Rt, Address, Decoder);
-                               break;
-               }
+       switch (MCInst_getOpcode(Inst)) {
+               default:
+                       break;
+               case AArch64_MOVIv4i16:
+               case AArch64_MOVIv8i16:
+               case AArch64_MVNIv4i16:
+               case AArch64_MVNIv8i16:
+               case AArch64_MOVIv2i32:
+               case AArch64_MOVIv4i32:
+               case AArch64_MVNIv2i32:
+               case AArch64_MVNIv4i32:
+                       MCOperand_CreateImm0(Inst, (cmode & 6) << 2);
+                       break;
+               case AArch64_MOVIv2s_msl:
+               case AArch64_MOVIv4s_msl:
+               case AArch64_MVNIv2s_msl:
+               case AArch64_MVNIv4s_msl:
+                       MCOperand_CreateImm0(Inst, cmode & 1 ? 0x110 : 0x108);
+                       break;
        }
 
-       return MCDisassembler_Success;
+       return Success;
 }
 
-// Decode post-index vector load/store lane instructions.
-// This is necessary as we need to decode Rm: if Rm == 0b11111, the last
-// operand is an immediate equal the the length of the changed bytes,
-// or Rm is decoded to a GPR64noxzr register.
-static DecodeStatus DecodeVLDSTLanePostInstruction(MCInst *Inst, unsigned Insn,
-               uint64_t Address,
+static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst,
+               uint32_t insn, uint64_t Addr,
                void *Decoder)
 {
-       bool Is64bitVec = false;
-       bool IsLoadDup = false;
-       bool IsLoad =&n