cstool : print all debug information for all arch.
diff --git a/cstool/cstool.c b/cstool/cstool.c
index 910e3ff..f2f5e70 100644
--- a/cstool/cstool.c
+++ b/cstool/cstool.c
@@ -10,6 +10,13 @@
 #define VERSION "1.0"
 
 void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins);
+void print_insn_detail_arm(csh handle, cs_insn *ins);
+void print_insn_detail_arm64(csh handle, cs_insn *ins);
+void print_insn_detail_mips(csh handle, cs_insn *ins);
+void print_insn_detail_ppc(csh handle, cs_insn *ins);
+void print_insn_detail_sparc(csh handle, cs_insn *ins);
+void print_insn_detail_sysz(csh handle, cs_insn *ins);
+void print_insn_detail_xcore(csh handle, cs_insn *ins);
 
 // convert hexchar to hexnum
 static uint8_t char_to_hexnum(char c)
@@ -117,8 +124,8 @@
 	cs_insn *insn;
 	cs_err err;
     cs_mode md;
-    char *platform;
-    bool x86_arch = false, debug_flag = false;
+    char *arch;
+    bool debug_flag = false;
 
 	if (argc != 3 && argc != 4 && argc != 5) {
 		usage(argv[0]);
@@ -166,68 +173,80 @@
     }
 	
 	if (!strcmp(mode, "arm")) {
+        arch = "arm";
 		err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle);
 	}
 
 	if (!strcmp(mode, "armb")) {
+        arch = "arm";
 		err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "arml")) {
+        arch = "arm";
 		err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "thumb")) {
-		err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &handle);
+        arch = "arm";
+        err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "thumbbe")) {
+        arch = "arm";
 		err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "thumble")) {
+        arch = "arm";
 		err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "arm64")) {
+        arch = "arm64";
 		err = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "mips")) {
+        arch = "mips";
 		err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "mipsbe")) {
+        arch = "mips";
 		err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "mips64")) {
+        arch = "mips";
 		err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "mips64be")) {
+        arch = "mips";
 		err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "x16")) {
-		x86_arch = true;
+		arch = "x86";
 		err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
 	}
 
 	if (!strcmp(mode, "x32")) {
         md = CS_MODE_32;
-        platform = "x32";
-		x86_arch = true;
+		arch = "x86";
 		err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
 	}
 
 	if (!strcmp(mode, "x64")) {
-		x86_arch = true;
+        md = CS_MODE_64;
+        arch = "x86";
 		err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
 	}
 
 	if (!strcmp(mode, "x16att")) {
-		x86_arch = true;
+        md = CS_MODE_16;
+        arch = "x86";
 		err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
 		if (!err) {
 			cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
@@ -235,7 +254,8 @@
 	}
 
 	if (!strcmp(mode,"x32att")) {
-		x86_arch = true;
+        md = CS_MODE_32;
+        arch = "x86";
 		err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
 		if (!err) {
 			cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
@@ -243,7 +263,8 @@
 	}
 
 	if (!strcmp(mode,"x64att")) {
-		x86_arch = true;
+        md = CS_MODE_64;
+        arch = "x86";
 		err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
 		if (!err) {
 			cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
@@ -251,22 +272,27 @@
 	}
 
 	if (!strcmp(mode,"ppc64")) {
+        arch = "ppc";
 		err = cs_open(CS_ARCH_PPC, CS_MODE_64+CS_MODE_LITTLE_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode,"ppc64be")) {
+         arch = "ppc";
 		err = cs_open(CS_ARCH_PPC,CS_MODE_64+CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode,"sparc")) {
+        arch = "sparc";
 		err = cs_open(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode, "systemz") || !strcmp(mode, "sysz") || !strcmp(mode, "s390x")) {
+        arch = "sysz";
 		err = cs_open(CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN, &handle);
 	}
 
 	if (!strcmp(mode,"xcore")) {
+        arch = "xcore";
 		err = cs_open(CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN, &handle);
 	}
 
@@ -292,16 +318,44 @@
 			}
 			// X86 instruction size is variable.
 			// align assembly instruction after the opcode
-			if (x86_arch) {
+			if (!strcmp(arch, "x86")) {
 				for (; j < 16; j++) {
 					printf("  ");
 				}
 			}
 			printf("  %s\t%s\n", insn[i].mnemonic, insn[i].op_str);
-            if (debug_flag) {
-                if (x86_arch) {
+            if (debug_flag) {//different mode should call different print functions
+                if (!strcmp(arch, "x86")) {
                     print_insn_detail_x86(handle, md, &insn[i]);
                 }
+                
+                if (!strcmp(arch, "arm")) {
+                    print_insn_detail_arm(handle, &insn[i]);
+                }
+                
+                if (!strcmp(arch,"arm64")) {
+                    print_insn_detail_arm64(handle,&insn[i]);
+                }
+                
+                if (!strcmp(arch, "mips")) {
+                    print_insn_detail_mips(handle, &insn[i]);
+                }
+                
+                if (!strcmp(arch, "ppc")) {
+                    print_insn_detail_ppc(handle, &insn[i]);
+                }
+                
+                if (!strcmp(arch, "sparc")) {
+                    print_insn_detail_sparc(handle, &insn[i]);
+                }
+                
+                if (!strcmp(arch, "sysz")) {
+                    print_insn_detail_sysz(handle, &insn[i]);
+                }
+                
+                if (!strcmp(arch, "xcore")) {
+                    print_insn_detail_xcore(handle, &insn[i]);
+                }
             }
 		}
 		cs_free(insn, count);
diff --git a/cstool/cstool_arm.c b/cstool/cstool_arm.c
new file mode 100644
index 0000000..7f4f814
--- /dev/null
+++ b/cstool/cstool_arm.c
@@ -0,0 +1,127 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <platform.h>
+#include <capstone.h>
+
+
+static void print_string_hex(char *comment, unsigned char *str, size_t len)
+{
+    unsigned char *c;
+    
+    printf("%s", comment);
+    for (c = str; c < str + len; c++) {
+        printf("0x%02x ", *c & 0xff);
+    }
+    
+    printf("\n");
+}
+
+void print_insn_detail_arm(csh handle, cs_insn *ins)
+{
+    cs_arm *arm;
+    int i;
+    
+    // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
+    if (ins->detail == NULL)
+        return;
+    
+    arm = &(ins->detail->arm);
+    
+    if (arm->op_count)
+        printf("\top_count: %u\n", arm->op_count);
+    
+    for (i = 0; i < arm->op_count; i++) {
+        cs_arm_op *op = &(arm->operands[i]);
+        switch((int)op->type) {
+            default:
+                break;
+            case ARM_OP_REG:
+                printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
+                break;
+            case ARM_OP_IMM:
+                printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
+                break;
+            case ARM_OP_FP:
+#if defined(_KERNEL_MODE)
+                // Issue #681: Windows kernel does not support formatting float point
+                printf("\t\toperands[%u].type: FP = <float_point_unsupported>\n", i);
+#else
+                printf("\t\toperands[%u].type: FP = %f\n", i, op->fp);
+#endif
+                break;
+            case ARM_OP_MEM:
+                printf("\t\toperands[%u].type: MEM\n", i);
+                if (op->mem.base != X86_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.base: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.base));
+                if (op->mem.index != X86_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.index: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.index));
+                if (op->mem.scale != 1)
+                    printf("\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale);
+                if (op->mem.disp != 0)
+                    printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
+                
+                break;
+            case ARM_OP_PIMM:
+                printf("\t\toperands[%u].type: P-IMM = %u\n", i, op->imm);
+                break;
+            case ARM_OP_CIMM:
+                printf("\t\toperands[%u].type: C-IMM = %u\n", i, op->imm);
+                break;
+            case ARM_OP_SETEND:
+                printf("\t\toperands[%u].type: SETEND = %s\n", i, op->setend == ARM_SETEND_BE? "be" : "le");
+                break;
+            case ARM_OP_SYSREG:
+                printf("\t\toperands[%u].type: SYSREG = %u\n", i, op->reg);
+                break;
+        }
+        
+        if (op->shift.type != ARM_SFT_INVALID && op->shift.value) {
+            if (op->shift.type < ARM_SFT_ASR_REG)
+                // shift with constant value
+                printf("\t\t\tShift: %u = %u\n", op->shift.type, op->shift.value);
+            else
+                // shift with register
+                printf("\t\t\tShift: %u = %s\n", op->shift.type,
+                       cs_reg_name(handle, op->shift.value));
+        }
+        
+        if (op->vector_index != -1) {
+            printf("\t\toperands[%u].vector_index = %u\n", i, op->vector_index);
+        }
+        
+        if (op->subtracted)
+            printf("\t\tSubtracted: True\n");
+    }
+    
+    if (arm->cc != ARM_CC_AL && arm->cc != ARM_CC_INVALID)
+        printf("\tCode condition: %u\n", arm->cc);
+    
+    if (arm->update_flags)
+        printf("\tUpdate-flags: True\n");
+    
+    if (arm->writeback)
+        printf("\tWrite-back: True\n");
+    
+    if (arm->cps_mode)
+        printf("\tCPSI-mode: %u\n", arm->cps_mode);
+    
+    if (arm->cps_flag)
+        printf("\tCPSI-flag: %u\n", arm->cps_flag);
+    
+    if (arm->vector_data)
+        printf("\tVector-data: %u\n", arm->vector_data);
+    
+    if (arm->vector_size)
+        printf("\tVector-size: %u\n", arm->vector_size);
+    
+    if (arm->usermode)
+        printf("\tUser-mode: True\n");
+    
+    if (arm->mem_barrier)
+        printf("\tMemory-barrier: %u\n", arm->mem_barrier);
+    
+    printf("\n");
+}
diff --git a/cstool/cstool_arm64.c b/cstool/cstool_arm64.c
new file mode 100644
index 0000000..138e7bb
--- /dev/null
+++ b/cstool/cstool_arm64.c
@@ -0,0 +1,116 @@
+/* Capstone Disassembler Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <platform.h>
+#include <capstone.h>
+
+
+static void print_string_hex(char *comment, unsigned char *str, size_t len)
+{
+    unsigned char *c;
+    
+    printf("%s", comment);
+    for (c = str; c < str + len; c++) {
+        printf("0x%02x ", *c & 0xff);
+    }
+    
+    printf("\n");
+}
+
+void print_insn_detail_arm64(csh handle, cs_insn *ins)
+{
+    cs_arm64 *arm64;
+    int i;
+    
+    // detail can be NULL if SKIPDATA option is turned ON
+    if (ins->detail == NULL)
+        return;
+    
+    arm64 = &(ins->detail->arm64);
+    if (arm64->op_count)
+        printf("\top_count: %u\n", arm64->op_count);
+    
+    for (i = 0; i < arm64->op_count; i++) {
+        cs_arm64_op *op = &(arm64->operands[i]);
+        switch(op->type) {
+            default:
+                break;
+            case ARM64_OP_REG:
+                printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
+                break;
+            case ARM64_OP_IMM:
+                printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
+                break;
+            case ARM64_OP_FP:
+#if defined(_KERNEL_MODE)
+                // Issue #681: Windows kernel does not support formatting float point
+                printf("\t\toperands[%u].type: FP = <float_point_unsupported>\n", i);
+#else
+                printf("\t\toperands[%u].type: FP = %f\n", i, op->fp);
+#endif
+                break;
+            case ARM64_OP_MEM:
+                printf("\t\toperands[%u].type: MEM\n", i);
+                if (op->mem.base != ARM64_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base));
+                if (op->mem.index != ARM64_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(handle, op->mem.index));
+                if (op->mem.disp != 0)
+                    printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
+                
+                break;
+            case ARM64_OP_CIMM:
+                printf("\t\toperands[%u].type: C-IMM = %u\n", i, (int)op->imm);
+                break;
+            case ARM64_OP_REG_MRS:
+                printf("\t\toperands[%u].type: REG_MRS = 0x%x\n", i, op->reg);
+                break;
+            case ARM64_OP_REG_MSR:
+                printf("\t\toperands[%u].type: REG_MSR = 0x%x\n", i, op->reg);
+                break;
+            case ARM64_OP_PSTATE:
+                printf("\t\toperands[%u].type: PSTATE = 0x%x\n", i, op->pstate);
+                break;
+            case ARM64_OP_SYS:
+                printf("\t\toperands[%u].type: SYS = 0x%x\n", i, op->sys);
+                break;
+            case ARM64_OP_PREFETCH:
+                printf("\t\toperands[%u].type: PREFETCH = 0x%x\n", i, op->prefetch);
+                break;
+            case ARM64_OP_BARRIER:
+                printf("\t\toperands[%u].type: BARRIER = 0x%x\n", i, op->barrier);
+                break;
+        }
+        
+        if (op->shift.type != ARM64_SFT_INVALID &&
+            op->shift.value)
+            printf("\t\t\tShift: type = %u, value = %u\n",
+                   op->shift.type, op->shift.value);
+        
+        if (op->ext != ARM64_EXT_INVALID)
+            printf("\t\t\tExt: %u\n", op->ext);
+        
+        if (op->vas != ARM64_VAS_INVALID)
+            printf("\t\t\tVector Arrangement Specifier: 0x%x\n", op->vas);
+        
+        if (op->vess != ARM64_VESS_INVALID)
+            printf("\t\t\tVector Element Size Specifier: %u\n", op->vess);
+        
+        if (op->vector_index != -1)
+            printf("\t\t\tVector Index: %u\n", op->vector_index);
+    }
+    
+    if (arm64->update_flags)
+        printf("\tUpdate-flags: True\n");
+    
+    if (arm64->writeback)
+        printf("\tWrite-back: True\n");
+    
+    if (arm64->cc)
+        printf("\tCode-condition: %u\n", arm64->cc);
+    
+    printf("\n");
+}
diff --git a/cstool/cstool_mips.c b/cstool/cstool_mips.c
new file mode 100644
index 0000000..07a362f
--- /dev/null
+++ b/cstool/cstool_mips.c
@@ -0,0 +1,61 @@
+/* Capstone Disassembler Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <platform.h>
+#include <capstone.h>
+
+
+static void print_string_hex(char *comment, unsigned char *str, size_t len)
+{
+    unsigned char *c;
+    
+    printf("%s", comment);
+    for (c = str; c < str + len; c++) {
+        printf("0x%02x ", *c & 0xff);
+    }
+    
+    printf("\n");
+}
+
+void print_insn_detail_mips(csh handle, cs_insn *ins)
+{
+    int i;
+    cs_mips *mips;
+    
+    // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
+    if (ins->detail == NULL)
+        return;
+    
+    mips = &(ins->detail->mips);
+    if (mips->op_count)
+        printf("\top_count: %u\n", mips->op_count);
+    
+    for (i = 0; i < mips->op_count; i++) {
+        cs_mips_op *op = &(mips->operands[i]);
+        switch((int)op->type) {
+            default:
+                break;
+            case MIPS_OP_REG:
+                printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
+                break;
+            case MIPS_OP_IMM:
+                printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
+                break;
+            case MIPS_OP_MEM:
+                printf("\t\toperands[%u].type: MEM\n", i);
+                if (op->mem.base != X86_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.base: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.base));
+                if (op->mem.disp != 0)
+                    printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
+                
+                break;
+        }
+        
+    }
+    
+    printf("\n");
+}
diff --git a/cstool/cstool_ppc.c b/cstool/cstool_ppc.c
new file mode 100644
index 0000000..3f639f1
--- /dev/null
+++ b/cstool/cstool_ppc.c
@@ -0,0 +1,104 @@
+/* Capstone Disassembler Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
+
+#include <stdio.h>
+
+#include <platform.h>
+#include <capstone.h>
+
+static csh handle;
+
+static void print_string_hex(char *comment, unsigned char *str, size_t len)
+{
+    unsigned char *c;
+    
+    printf("%s", comment);
+    for (c = str; c < str + len; c++) {
+        printf("0x%02x ", *c & 0xff);
+    }
+    
+    printf("\n");
+}
+
+static const char* get_bc_name(int bc)
+{
+    switch(bc) {
+        default:
+        case PPC_BC_INVALID:
+            return ("invalid");
+        case PPC_BC_LT:
+            return ("lt");
+        case PPC_BC_LE:
+            return ("le");
+        case PPC_BC_EQ:
+            return ("eq");
+        case PPC_BC_GE:
+            return ("ge");
+        case PPC_BC_GT:
+            return ("gt");
+        case PPC_BC_NE:
+            return ("ne");
+        case PPC_BC_UN:
+            return ("un");
+        case PPC_BC_NU:
+            return ("nu");
+        case PPC_BC_SO:
+            return ("so");
+        case PPC_BC_NS:
+            return ("ns");
+    }
+}
+
+void print_insn_detail_ppc(csh handle, cs_insn *ins)
+{
+    cs_ppc *ppc;
+    int i;
+    
+    // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
+    if (ins->detail == NULL)
+        return;
+    
+    ppc = &(ins->detail->ppc);
+    if (ppc->op_count)
+        printf("\top_count: %u\n", ppc->op_count);
+    
+    for (i = 0; i < ppc->op_count; i++) {
+        cs_ppc_op *op = &(ppc->operands[i]);
+        switch((int)op->type) {
+            default:
+                break;
+            case PPC_OP_REG:
+                printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
+                break;
+            case PPC_OP_IMM:
+                printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
+                break;
+            case PPC_OP_MEM:
+                printf("\t\toperands[%u].type: MEM\n", i);
+                if (op->mem.base != PPC_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.base: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.base));
+                if (op->mem.disp != 0)
+                    printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
+                
+                break;
+            case PPC_OP_CRX:
+                printf("\t\toperands[%u].type: CRX\n", i);
+                printf("\t\t\toperands[%u].crx.scale: %d\n", i, op->crx.scale);
+                printf("\t\t\toperands[%u].crx.reg: %s\n", i, cs_reg_name(handle, op->crx.reg));
+                printf("\t\t\toperands[%u].crx.cond: %s\n", i, get_bc_name(op->crx.cond));
+                break;
+        }
+    }
+    
+    if (ppc->bc != 0)
+        printf("\tBranch code: %u\n", ppc->bc);
+    
+    if (ppc->bh != 0)
+        printf("\tBranch hint: %u\n", ppc->bh);
+    
+    if (ppc->update_cr0)
+        printf("\tUpdate-CR0: True\n");
+    
+    printf("\n");
+}
diff --git a/cstool/cstool_sparc.c b/cstool/cstool_sparc.c
new file mode 100644
index 0000000..9ee37ce
--- /dev/null
+++ b/cstool/cstool_sparc.c
@@ -0,0 +1,68 @@
+/* Capstone Disassembler Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
+
+#include <stdio.h>
+
+#include <platform.h>
+#include <capstone.h>
+
+
+static void print_string_hex(char *comment, unsigned char *str, size_t len)
+{
+    unsigned char *c;
+    
+    printf("%s", comment);
+    for (c = str; c < str + len; c++) {
+        printf("0x%02x ", *c & 0xff);
+    }
+    
+    printf("\n");
+}
+
+void print_insn_detail_sparc(csh handle, cs_insn *ins)
+{
+    cs_sparc *sparc;
+    int i;
+    
+    // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
+    if (ins->detail == NULL)
+        return;
+    
+    sparc = &(ins->detail->sparc);
+    if (sparc->op_count)
+        printf("\top_count: %u\n", sparc->op_count);
+    
+    for (i = 0; i < sparc->op_count; i++) {
+        cs_sparc_op *op = &(sparc->operands[i]);
+        switch((int)op->type) {
+            default:
+                break;
+            case SPARC_OP_REG:
+                printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
+                break;
+            case SPARC_OP_IMM:
+                printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
+                break;
+            case SPARC_OP_MEM:
+                printf("\t\toperands[%u].type: MEM\n", i);
+                if (op->mem.base != X86_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.base: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.base));
+                if (op->mem.index != X86_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.index: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.index));
+                if (op->mem.disp != 0)
+                    printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
+                
+                break;
+        }
+    }
+    
+    if (sparc->cc != 0)
+        printf("\tCode condition: %u\n", sparc->cc);
+    
+    if (sparc->hint != 0)
+        printf("\tHint code: %u\n", sparc->hint);
+    
+    printf("\n");
+}
diff --git a/cstool/cstool_systemz.c b/cstool/cstool_systemz.c
new file mode 100644
index 0000000..c5c5f56
--- /dev/null
+++ b/cstool/cstool_systemz.c
@@ -0,0 +1,70 @@
+/* Capstone Disassembler Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
+
+#include <stdio.h>
+
+#include <platform.h>
+#include <capstone.h>
+
+
+static void print_string_hex(char *comment, unsigned char *str, size_t len)
+{
+    unsigned char *c;
+    
+    printf("%s", comment);
+    for (c = str; c < str + len; c++) {
+        printf("0x%02x ", *c & 0xff);
+    }
+    
+    printf("\n");
+}
+
+void print_insn_detail_sysz(csh handle, cs_insn *ins)
+{
+    cs_sysz *sysz;
+    int i;
+    
+    // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
+    if (ins->detail == NULL)
+        return;
+    
+    sysz = &(ins->detail->sysz);
+    if (sysz->op_count)
+        printf("\top_count: %u\n", sysz->op_count);
+    
+    for (i = 0; i < sysz->op_count; i++) {
+        cs_sysz_op *op = &(sysz->operands[i]);
+        switch((int)op->type) {
+            default:
+                break;
+            case SYSZ_OP_REG:
+                printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
+                break;
+            case SYSZ_OP_ACREG:
+                printf("\t\toperands[%u].type: ACREG = %u\n", i, op->reg);
+                break;
+            case SYSZ_OP_IMM:
+                printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
+                break;
+            case SYSZ_OP_MEM:
+                printf("\t\toperands[%u].type: MEM\n", i);
+                if (op->mem.base != SYSZ_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.base: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.base));
+                if (op->mem.index != SYSZ_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.index: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.index));
+                if (op->mem.length != 0)
+                    printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length);
+                if (op->mem.disp != 0)
+                    printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
+                
+                break;
+        }
+    }
+    
+    if (sysz->cc != 0)
+        printf("\tCode condition: %u\n", sysz->cc);
+    
+    printf("\n");
+}
diff --git a/cstool/cstool_xcore.c b/cstool/cstool_xcore.c
new file mode 100644
index 0000000..8062137
--- /dev/null
+++ b/cstool/cstool_xcore.c
@@ -0,0 +1,65 @@
+/* Capstone Disassembler Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
+
+#include <stdio.h>
+
+#include <platform.h>
+#include <capstone.h>
+
+
+static void print_string_hex(char *comment, unsigned char *str, size_t len)
+{
+    unsigned char *c;
+    
+    printf("%s", comment);
+    for (c = str; c < str + len; c++) {
+        printf("0x%02x ", *c & 0xff);
+    }
+    
+    printf("\n");
+}
+
+void print_insn_detail_xcore(csh handle, cs_insn *ins)
+{
+    cs_xcore *xcore;
+    int i;
+    
+    // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
+    if (ins->detail == NULL)
+        return;
+    
+    xcore = &(ins->detail->xcore);
+    if (xcore->op_count)
+        printf("\top_count: %u\n", xcore->op_count);
+    
+    for (i = 0; i < xcore->op_count; i++) {
+        cs_xcore_op *op = &(xcore->operands[i]);
+        switch((int)op->type) {
+            default:
+                break;
+            case XCORE_OP_REG:
+                printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
+                break;
+            case XCORE_OP_IMM:
+                printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
+                break;
+            case XCORE_OP_MEM:
+                printf("\t\toperands[%u].type: MEM\n", i);
+                if (op->mem.base != XCORE_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.base: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.base));
+                if (op->mem.index != XCORE_REG_INVALID)
+                    printf("\t\t\toperands[%u].mem.index: REG = %s\n",
+                           i, cs_reg_name(handle, op->mem.index));
+                if (op->mem.disp != 0)
+                    printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
+                if (op->mem.direct != 1)
+                    printf("\t\t\toperands[%u].mem.direct: -1\n", i);
+                
+                
+                break;
+        }
+    }
+    
+    printf("\n");
+}