arm: some operands can get subtracted from base register, thus have '-' sign associated. this adds subtracted field into cs_arm_op to provide this info. issue reported by Yegor Derevenets
diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c
index 4ca734b..b8ee52e 100644
--- a/arch/ARM/ARMInstPrinter.c
+++ b/arch/ARM/ARMInstPrinter.c
@@ -758,6 +758,7 @@
 	MCOperand *MO1 = MCInst_getOperand(MI, Op);
 	MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
 	MCOperand *MO3 = MCInst_getOperand(MI, Op + 2);
+	ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO3));
 
 	SStream_concat0(O, "[");
 	set_mem_access(MI, true);
@@ -770,14 +771,17 @@
 	if (!MCOperand_getReg(MO2)) {
 		unsigned tmp = getAM2Offset((unsigned int)MCOperand_getImm(MO3));
 		if (tmp) { // Don't print +0.
+			subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO3));
+
 			SStream_concat0(O, ", ");
 			if (tmp > HEX_THRESHOLD)
-				SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(getAM2Op((unsigned int)MCOperand_getImm(MO3))), tmp);
+				SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), tmp);
 			else
-				SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(getAM2Op((unsigned int)MCOperand_getImm(MO3))), tmp);
+				SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), tmp);
 			if (MI->csh->detail) {
 				MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (arm_shifter)getAM2Op((unsigned int)MCOperand_getImm(MO3));
 				MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = tmp;
+				MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
 			}
 		}
 		SStream_concat0(O, "]");
@@ -786,10 +790,11 @@
 	}
 
 	SStream_concat0(O, ", ");
-	SStream_concat0(O, ARM_AM_getAddrOpcStr(getAM2Op((unsigned int)MCOperand_getImm(MO3))));
+	SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
 	printRegName(MI->csh, O, MCOperand_getReg(MO2));
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
+		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
 	}
 
 	printRegImmShift(MI, O, getAM2ShiftOpc((unsigned int)MCOperand_getImm(MO3)),
@@ -852,28 +857,31 @@
 {
 	MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
 	MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
+	ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO2));
 
 	if (!MCOperand_getReg(MO1)) {
 		unsigned ImmOffs = getAM2Offset((unsigned int)MCOperand_getImm(MO2));
 		if (ImmOffs > HEX_THRESHOLD)
 			SStream_concat(O, "#%s0x%x",
-					ARM_AM_getAddrOpcStr(getAM2Op((unsigned int)MCOperand_getImm(MO2))), ImmOffs);
+					ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 		else
 			SStream_concat(O, "#%s%u",
-					ARM_AM_getAddrOpcStr(getAM2Op((unsigned int)MCOperand_getImm(MO2))), ImmOffs);
+					ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 		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 = ImmOffs;
+			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
 			MI->flat_insn->detail->arm.op_count++;
 		}
 		return;
 	}
 
-	SStream_concat0(O, ARM_AM_getAddrOpcStr(getAM2Op((unsigned int)MCOperand_getImm(MO2))));
+	SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
 	printRegName(MI->csh, O, MCOperand_getReg(MO1));
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
+		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
 		MI->flat_insn->detail->arm.op_count++;
 	}
 
@@ -890,7 +898,7 @@
 	MCOperand *MO1 = MCInst_getOperand(MI, Op);
 	MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
 	MCOperand *MO3 = MCInst_getOperand(MI, Op+2);
-	ARM_AM_AddrOpc op = getAM3Op((unsigned int)MCOperand_getImm(MO3));
+	ARM_AM_AddrOpc subtracted = getAM3Op((unsigned int)MCOperand_getImm(MO3));
 	unsigned ImmOffs;
 
 	SStream_concat0(O, "[");
@@ -902,11 +910,12 @@
 	set_mem_access(MI, false);
 
 	if (MCOperand_getReg(MO2)) {
-		SStream_concat(O, "%c", (char)op);
+		SStream_concat(O, "%c", (char)subtracted);
 		printRegName(MI->csh, O, MCOperand_getReg(MO2));
 		if (MI->csh->detail) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO2);
+			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
 			MI->flat_insn->detail->arm.op_count++;
 		}
 		return;
@@ -914,16 +923,17 @@
 
 	ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO3));
 	if (ImmOffs > HEX_THRESHOLD)
-		SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(op), ImmOffs);
+		SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 	else
-		SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(op), ImmOffs);
+		SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
 
-		if (op)
+		if (subtracted) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
-		else
+			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
+		} else
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = -(int)ImmOffs;
 
 		MI->flat_insn->detail->arm.op_count++;
@@ -936,7 +946,7 @@
 	MCOperand *MO1 = MCInst_getOperand(MI, Op);
 	MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
 	MCOperand *MO3 = MCInst_getOperand(MI, Op+2);
-	ARM_AM_AddrOpc op = getAM3Op((unsigned int)MCOperand_getImm(MO3));
+	ARM_AM_AddrOpc subtracted = getAM3Op((unsigned int)MCOperand_getImm(MO3));
 	unsigned ImmOffs;
 
 	SStream_concat0(O, "[");
@@ -947,12 +957,14 @@
 
 	if (MCOperand_getReg(MO2)) {
 		SStream_concat0(O, ", ");
-		SStream_concat0(O, ARM_AM_getAddrOpcStr(op));
+		SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
 		printRegName(MI->csh, O, MCOperand_getReg(MO2));
 		if (MI->csh->detail) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
-			if (op)
+			if (subtracted) {
 				MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = -1;
+				MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
+			}
 		}
 		SStream_concat0(O, "]");
 		set_mem_access(MI, false);
@@ -962,17 +974,18 @@
 	//If the op is sub we have to print the immediate even if it is 0
 	ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO3));
 
-	if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM_sub)) {
+	if (AlwaysPrintImm0 || ImmOffs || (subtracted == ARM_AM_sub)) {
 		if (ImmOffs > HEX_THRESHOLD)
-			SStream_concat(O, ", #%s0x%x", ARM_AM_getAddrOpcStr(op), ImmOffs);
+			SStream_concat(O, ", #%s0x%x", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 		else
-			SStream_concat(O, ", #%s%u", ARM_AM_getAddrOpcStr(op), ImmOffs);
+			SStream_concat(O, ", #%s%u", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 	}
 
 	if (MI->csh->detail) {
-		if (op)
+		if (subtracted) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = (int)MCOperand_getImm(MO3);
-		else
+			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
+		} else
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = (int)-MCOperand_getImm(MO3);
 	}
 
@@ -1006,15 +1019,16 @@
 {
 	MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
 	MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
-	ARM_AM_AddrOpc op = getAM3Op((unsigned int)MCOperand_getImm(MO2));
+	ARM_AM_AddrOpc subtracted = getAM3Op((unsigned int)MCOperand_getImm(MO2));
 	unsigned ImmOffs;
 
 	if (MCOperand_getReg(MO1)) {
-		SStream_concat0(O, ARM_AM_getAddrOpcStr(op));
+		SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
 		printRegName(MI->csh, O, MCOperand_getReg(MO1));
 		if (MI->csh->detail) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
+			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
 			MI->flat_insn->detail->arm.op_count++;
 		}
 		return;
@@ -1022,15 +1036,16 @@
 
 	ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO2));
 	if (ImmOffs > HEX_THRESHOLD)
-		SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(op), ImmOffs);
+		SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 	else
-		SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(op), ImmOffs);
+		SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
 
-		if (op)
+		if (subtracted) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
-		else
+			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
+		} else
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = -(int)ImmOffs;
 
 		MI->flat_insn->detail->arm.op_count++;
@@ -1081,7 +1096,9 @@
 {
 	MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
 	MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
+	ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO2));
 	unsigned ImmOffs, Op;
+
 	if (!MCOperand_isReg(MO1)) {   // FIXME: This is for CP entries, but isn't right.
 		printOperand(MI, OpNum, O);
 		return;
@@ -1103,14 +1120,15 @@
 	if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) {
 		if (ImmOffs * 4 > HEX_THRESHOLD)
 			SStream_concat(O, ", #%s0x%x",
-					ARM_AM_getAddrOpcStr(ARM_AM_getAM5Op((unsigned int)MCOperand_getImm(MO2))),
+					ARM_AM_getAddrOpcStr(subtracted),
 					ImmOffs * 4);
 		else
 			SStream_concat(O, ", #%s%u",
-					ARM_AM_getAddrOpcStr(ARM_AM_getAM5Op((unsigned int)MCOperand_getImm(MO2))),
+					ARM_AM_getAddrOpcStr(subtracted),
 					ImmOffs * 4);
 		if (MI->csh->detail) {
 			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = ImmOffs * 4;
+			MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
 		}
 	}
 	SStream_concat0(O, "]");
diff --git a/include/arm.h b/include/arm.h
index 2458d88..fd2b138 100644
--- a/include/arm.h
+++ b/include/arm.h
@@ -212,6 +212,9 @@
 		arm_op_mem mem;		// base/index/scale/disp value for MEM operand
 		arm_setend_type setend; // SETEND instruction's operand type
 	};
+	// in some instructions, an operand can be subtracted or added to
+	// the base register,
+	bool subtracted; // if TRUE, this operand is subtracted. otherwise, it is added.
 } cs_arm_op;
 
 // Instruction structure
diff --git a/tests/test_arm.c b/tests/test_arm.c
index 0492b93..d6f85d6 100644
--- a/tests/test_arm.c
+++ b/tests/test_arm.c
@@ -99,6 +99,9 @@
 		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)
@@ -176,7 +179,7 @@
 //#define ARM_CODE "\x90\x04\x0E\x00"	// muleq	lr, r0, r4
 //#define ARM_CODE "\x90\x24\x0E\x00"	// muleq	lr, r0, r4
 //#define ARM_CODE "\xb6\x10\x5f\xe1"	// ldrh	r1, [pc, #-6]
-#define ARM_CODE "\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3\x00\x02\x01\xf1\x05\x40\xd0\xe8"
+#define ARM_CODE "\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00"
 //#define ARM_CODE2 "\xf0\x24"
 //#define ARM_CODE2 "\x83\xb0"
 #define ARM_CODE2 "\xd1\xe8\x00\xf0\xf0\x24\x04\x07\x1f\x3c\xf2\xc0\x00\x00\x4f\xf0\x00\x01\x46\x6c"