add CS_OPT_UNSIGNED option to print immediate in unsigned form. only ARM is supported for now (issue #585)
diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c
index 39773bc..4f10cef 100644
--- a/arch/ARM/ARMInstPrinter.c
+++ b/arch/ARM/ARMInstPrinter.c
@@ -34,6 +34,7 @@
 #define GET_SUBTARGETINFO_ENUM
 #include "ARMGenSubtargetInfo.inc"
 
+
 static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo);
 
 // Autogenerated by tblgen.
@@ -847,28 +848,14 @@
 				imm += (int32_t)MI->address + 8;
 			}
 
-			if (imm >= 0) {
-				if (imm > HEX_THRESHOLD)
-					SStream_concat(O, "#0x%x", imm);
-				else
-					SStream_concat(O, "#%u", imm);
-			} else {
-				SStream_concat(O, "#0x%x", imm);
-			}
+			printUInt32Bang(O, imm);
 		} else {
 			switch(MI->flat_insn->id) {
 				default:
-					if (imm >= 0) {
-						if (imm > HEX_THRESHOLD)
-							SStream_concat(O, "#0x%x", imm);
-						else
-							SStream_concat(O, "#%u", imm);
-					} else {
-						if (imm < -HEX_THRESHOLD)
-							SStream_concat(O, "#-0x%x", -imm);
-						else
-							SStream_concat(O, "#-%u", -imm);
-					}
+					if (MI->csh->imm_unsigned)
+						printUInt32Bang(O, imm);
+					else
+						printInt32Bang(O, imm);
 					break;
 				case ARM_INS_AND:
 				case ARM_INS_ORR:
@@ -876,10 +863,7 @@
 				case ARM_INS_BIC:
 				case ARM_INS_MVN:
 					// do not print number in negative form
-					if (imm >= 0 && imm <= HEX_THRESHOLD)
-						SStream_concat(O, "#%u", imm);
-					else
-						SStream_concat(O, "#0x%x", imm);
+					printUInt32Bang(O, imm);
 					break;
 			}
 		}
@@ -912,10 +896,7 @@
 	if (isSub) {
 		SStream_concat(O, "#-0x%x", -OffImm);
 	} else {
-		if (OffImm > HEX_THRESHOLD)
-			SStream_concat(O, "#0x%x", OffImm);
-		else
-			SStream_concat(O, "#%u", OffImm);
+		printUInt32Bang(O, OffImm);
 	}
 
 	SStream_concat0(O, "]");
@@ -1386,10 +1367,7 @@
 	int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
 
 	//assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
-	if (lsb > HEX_THRESHOLD)
-		SStream_concat(O, "#0x%x", lsb);
-	else
-		SStream_concat(O, "#%u", lsb);
+	printUInt32Bang(O, lsb);
 
 	if (width > HEX_THRESHOLD)
 		SStream_concat(O, ", #0x%x", width);
@@ -1895,10 +1873,9 @@
 static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
 {
 	unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)) * 4;
-	if (tmp > HEX_THRESHOLD)
-		SStream_concat(O, "#0x%x", tmp);
-	else
-		SStream_concat(O, "#%u", tmp);
+
+	printUInt32Bang(O, tmp);
+
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
@@ -1910,10 +1887,8 @@
 {
 	unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
 	unsigned tmp = Imm == 0 ? 32 : Imm;
-	if (tmp > HEX_THRESHOLD)
-		SStream_concat(O, "#0x%x", tmp);
-	else
-		SStream_concat(O, "#%u", tmp);
+
+	printUInt32Bang(O, tmp);
 
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
@@ -1988,10 +1963,7 @@
 	if (ImmOffs) {
 		tmp = ImmOffs * Scale;
 		SStream_concat0(O, ", ");
-		if (tmp > HEX_THRESHOLD)
-			SStream_concat(O, "#0x%x", tmp);
-		else
-			SStream_concat(O, "#%u", tmp);
+		printUInt32Bang(O, tmp);
 		if (MI->csh->detail)
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
 	}
@@ -2184,10 +2156,7 @@
 	if (MCOperand_getImm(MO2)) {
 		SStream_concat0(O, ", ");
 		tmp = (unsigned int)MCOperand_getImm(MO2) * 4;
-		if (tmp > HEX_THRESHOLD)
-			SStream_concat(O, "#0x%x", tmp);
-		else
-			SStream_concat(O, "#%u", tmp);
+		printUInt32Bang(O, tmp);
 		if (MI->csh->detail)
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
 	}
@@ -2209,17 +2178,7 @@
 			MI->flat_insn->detail->arm.op_count++;
 		}
 	} else {
-		if (OffImm < 0) {
-			if (OffImm < -HEX_THRESHOLD)
-				SStream_concat(O, "#-0x%x", -OffImm);
-			else
-				SStream_concat(O, "#-%u", -OffImm);
-		} else {
-			if (OffImm > HEX_THRESHOLD)
-				SStream_concat(O, "#0x%x", OffImm);
-			else
-				SStream_concat(O, "#%u", OffImm);
-		}
+		printInt32Bang(O, OffImm);
 		if (MI->csh->detail) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
@@ -2245,17 +2204,7 @@
 			MI->flat_insn->detail->arm.op_count++;
 		}
 	} else {
-		if (OffImm < 0) {
-			if (OffImm < -HEX_THRESHOLD)
-				SStream_concat(O, "#-0x%x", -OffImm);
-			else
-				SStream_concat(O, "#-%u", -OffImm);
-		} else {
-			if (OffImm > HEX_THRESHOLD)
-				SStream_concat(O, "#0x%x", OffImm);
-			else
-				SStream_concat(O, "#%u", OffImm);
-		}
+		printInt32Bang(O, OffImm);
 		if (MI->csh->detail) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
@@ -2417,10 +2366,8 @@
 	unsigned tmp;
 
 	tmp = 16 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
-	if (tmp > HEX_THRESHOLD)
-		SStream_concat(O, "#0x%x", tmp);
-	else
-		SStream_concat(O, "#%u", tmp);
+	printUInt32Bang(O, tmp);
+
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
@@ -2433,10 +2380,8 @@
 	unsigned tmp;
 
 	tmp = 32 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
-	if (tmp > HEX_THRESHOLD)
-		SStream_concat(O, "#0x%x", tmp);
-	else
-		SStream_concat(O, "#%u", tmp);
+	printUInt32Bang(O, tmp);
+
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py
index 5943c88..cba23d7 100644
--- a/bindings/python/capstone/__init__.py
+++ b/bindings/python/capstone/__init__.py
@@ -161,6 +161,7 @@
 CS_OPT_SKIPDATA = 5  # Skip data when disassembling
 CS_OPT_SKIPDATA_SETUP = 6      # Setup user-defined function for SKIPDATA option
 CS_OPT_MNEMONIC = 7  # Customize instruction mnemonic
+CS_OPT_UNSIGNED = 8  # Print immediate in unsigned form
 
 # Capstone option value
 CS_OPT_OFF = 0             # Turn OFF an option - default option of CS_OPT_DETAIL
@@ -771,6 +772,7 @@
             self._syntax = None
 
         self._detail = False  # by default, do not produce instruction details
+        self._imm_unsigned = False  # by default, print immediate operands as signed numbers
         self._diet = cs_support(CS_SUPPORT_DIET)
         self._x86reduce = cs_support(CS_SUPPORT_X86_REDUCE)
 
@@ -900,6 +902,25 @@
         self._detail = opt
 
 
+    # is detail mode enable?
+    @property
+    def imm_unsigned(self):
+        return self._imm_unsigned
+
+
+    # modify detail mode.
+    @imm_unsigned.setter
+    def imm_unsigned(self, opt):  # opt is boolean type, so must be either 'True' or 'False'
+        if opt == False:
+            status = _cs.cs_option(self.csh, CS_OPT_UNSIGNED, CS_OPT_OFF)
+        else:
+            status = _cs.cs_option(self.csh, CS_OPT_UNSIGNED, CS_OPT_ON)
+        if status != CS_ERR_OK:
+            raise CsError(status)
+        # save detail
+        self._imm_unsigned = opt
+
+
     # return disassembly mode of this engine.
     @property
     def mode(self):
diff --git a/cs.c b/cs.c
index 8f22d7b..ebd8109 100644
--- a/cs.c
+++ b/cs.c
@@ -423,6 +423,10 @@
 		default:
 			break;
 
+		case CS_OPT_UNSIGNED:
+			handle->imm_unsigned = (cs_opt_value)value;
+			return CS_ERR_OK;
+
 		case CS_OPT_DETAIL:
 			handle->detail = (cs_opt_value)value;
 			return CS_ERR_OK;
diff --git a/cs_priv.h b/cs_priv.h
index 7818cd2..bb7cb0d 100644
--- a/cs_priv.h
+++ b/cs_priv.h
@@ -63,7 +63,7 @@
 	PostPrinter_t post_printer;
 	cs_err errnum;
 	ARM_ITStatus ITBlock;	// for Arm only
-	cs_opt_value detail;
+	cs_opt_value detail, imm_unsigned;
 	int syntax;	// asm syntax for simple printer such as ARM, Mips & PPC
 	bool doing_mem;	// handling memory operand in InstPrinter code
 	unsigned short *insn_cache;	// index caching for mapping.c
diff --git a/include/capstone/capstone.h b/include/capstone/capstone.h
index 3e61a90..164db6b 100644
--- a/include/capstone/capstone.h
+++ b/include/capstone/capstone.h
@@ -151,11 +151,12 @@
 	CS_OPT_SKIPDATA, // Skip data when disassembling. Then engine is in SKIPDATA mode.
 	CS_OPT_SKIPDATA_SETUP, // Setup user-defined function for SKIPDATA option
 	CS_OPT_MNEMONIC, // Customize instruction mnemonic
+	CS_OPT_UNSIGNED, // print immediate operands in unsigned form
 } cs_opt_type;
 
 // Runtime option value (associated with option type above)
 typedef enum cs_opt_value {
-	CS_OPT_OFF = 0,  // Turn OFF an option - default option of CS_OPT_DETAIL, CS_OPT_SKIPDATA.
+	CS_OPT_OFF = 0,  // Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
 	CS_OPT_ON = 3, // Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
 	CS_OPT_SYNTAX_DEFAULT = 0, // Default asm syntax (CS_OPT_SYNTAX).
 	CS_OPT_SYNTAX_INTEL, // X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX).