add @regs_read_count, @regs_write_count, @groups_count to @cs_insn. bump API to 1.4
diff --git a/arch/AArch64/mapping.c b/arch/AArch64/mapping.c
index e956044..dcf5f1d 100644
--- a/arch/AArch64/mapping.c
+++ b/arch/AArch64/mapping.c
@@ -1878,22 +1878,24 @@
 	int i = insn_find(insns, ARR_SIZE(insns), id);
 	if (i != -1) {
 		insn->id = insns[i].mapid;
+
 		memcpy(insn->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
+		insn->regs_read_count = count_positive(insns[i].regs_use);
+
 		memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
+		insn->regs_write_count = count_positive(insns[i].regs_mod);
+
 		memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
-		// call cs_reg_write() with handle = 1 to pass handle check
+		insn->groups_count = count_positive(insns[i].groups);
+
+		// call cs_reg_write() with handle = 1 to bypass handle check
 		// we only need to find if this insn modifies ARM64_REG_NZCV
 		insn->arm64.update_flags = cs_reg_write(1, insn, ARM64_REG_NZCV);
 
 		if (insns[i].branch || insns[i].indirect_branch) {
-			// this insn also belongs to JUMP group
-			int j;
-			for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
-				if (insn->groups[j] == 0) {
-					insn->groups[j] = ARM64_GRP_JUMP;
-					break;
-				}
-			}
+			// this insn also belongs to JUMP group. add JUMP group
+			insn->groups[insn->groups_count] = ARM64_GRP_JUMP;
+			insn->groups_count++;
 		}
 	}
 }
diff --git a/arch/ARM/mapping.c b/arch/ARM/mapping.c
index a7b8595..79e02ca 100644
--- a/arch/ARM/mapping.c
+++ b/arch/ARM/mapping.c
@@ -2302,20 +2302,24 @@
 	int i = insn_find(insns, ARR_SIZE(insns), id);
 	if (i != -1) {
 		insn->id = insns[i].mapid;
+
 		memcpy(insn->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
+		insn->regs_read_count = count_positive(insns[i].regs_use);
+
 		memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
+		insn->regs_write_count = count_positive(insns[i].regs_mod);
+
 		memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
+		insn->groups_count = count_positive(insns[i].groups);
+
+		// call cs_reg_write() with handle = 1 to bypass handle check
+		// we only need to find if this insn modifies ARM64_REG_NZCV
 		insn->arm.update_flags = cs_reg_write(1, insn, ARM_REG_CPSR);
 
 		if (insns[i].branch || insns[i].indirect_branch) {
-			// this insn also belongs to JUMP group
-			int j;
-			for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
-				if (insn->groups[j] == 0) {
-					insn->groups[j] = ARM_GRP_JUMP;
-					break;
-				}
-			}
+			// this insn also belongs to JUMP group. add JUMP group
+			insn->groups[insn->groups_count] = ARM_GRP_JUMP;
+			insn->groups_count++;
 		}
 	}
 }
diff --git a/arch/Mips/mapping.c b/arch/Mips/mapping.c
index 8127c34..b70509d 100644
--- a/arch/Mips/mapping.c
+++ b/arch/Mips/mapping.c
@@ -1386,19 +1386,20 @@
 	for (i = 0; i < ARR_SIZE(alias_insns); i++) {
 		if (alias_insns[i].id == id) {
 			insn->id = alias_insns[i].mapid;
-			memcpy(insn->regs_read, alias_insns[i].regs_use, sizeof(alias_insns[i].regs_use));
-			memcpy(insn->regs_write, alias_insns[i].regs_mod, sizeof(alias_insns[i].regs_mod));
-			memcpy(insn->groups, alias_insns[i].groups, sizeof(alias_insns[i].groups));
+
+			memcpy(insn->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
+			insn->regs_read_count = count_positive(insns[i].regs_use);
+
+			memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
+			insn->regs_write_count = count_positive(insns[i].regs_mod);
+
+			memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
+			insn->groups_count = count_positive(insns[i].groups);
 
 			if (insns[i].branch || insns[i].indirect_branch) {
-				// this insn also belongs to JUMP group
-				int j;
-				for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
-					if (insn->groups[j] == 0) {
-						insn->groups[j] = MIPS_GRP_JUMP;
-						break;
-					}
-				}
+				// this insn also belongs to JUMP group. add JUMP group
+				insn->groups[insn->groups_count] = MIPS_GRP_JUMP;
+				insn->groups_count++;
 			}
 
 			return;
@@ -1408,19 +1409,20 @@
 	i = insn_find(insns, ARR_SIZE(insns), id);
 	if (i != -1) {
 		insn->id = insns[i].mapid;
+
 		memcpy(insn->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
+		insn->regs_read_count = count_positive(insns[i].regs_use);
+
 		memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
+		insn->regs_write_count = count_positive(insns[i].regs_mod);
+
 		memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
+		insn->groups_count = count_positive(insns[i].groups);
 
 		if (insns[i].branch || insns[i].indirect_branch) {
-			// this insn also belongs to JUMP group
-			int j;
-			for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
-				if (insn->groups[j] == 0) {
-					insn->groups[j] = MIPS_GRP_JUMP;
-					break;
-				}
-			}
+			// this insn also belongs to JUMP group. add JUMP group
+			insn->groups[insn->groups_count] = MIPS_GRP_JUMP;
+			insn->groups_count++;
 		}
 	}
 }
diff --git a/arch/X86/mapping.c b/arch/X86/mapping.c
index e6a3c2b..7c8f4a3 100644
--- a/arch/X86/mapping.c
+++ b/arch/X86/mapping.c
@@ -6576,19 +6576,20 @@
 	int i = insn_find(insns, ARR_SIZE(insns), id);
 	if (i != -1) {
 		insn->id = insns[i].mapid;
+
 		memcpy(insn->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
+		insn->regs_read_count = count_positive(insns[i].regs_use);
+
 		memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
+		insn->regs_write_count = count_positive(insns[i].regs_mod);
+
 		memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
+		insn->groups_count = count_positive(insns[i].groups);
 
 		if (insns[i].branch || insns[i].indirect_branch) {
-			// this insn also belongs to JUMP group
-			int j;
-			for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
-				if (insn->groups[j] == 0) {
-					insn->groups[j] = X86_GRP_JUMP;
-					break;
-				}
-			}
+			// this insn also belongs to JUMP group. add JUMP group
+			insn->groups[insn->groups_count] = X86_GRP_JUMP;
+			insn->groups_count++;
 		}
 	}
 }
diff --git a/cs.c b/cs.c
index bf8f3d6..1d90b02 100644
--- a/cs.c
+++ b/cs.c
@@ -29,7 +29,7 @@
 #include "utils.h"
 
 #define VERSION_MAJOR 1
-#define VERSION_MINOR 3
+#define VERSION_MINOR 4
 
 cs_err cs_errno(csh handle)
 {
@@ -366,7 +366,7 @@
 	if (!handle)
 		return false;
 
-	return arr_exist(insn->groups, ARR_SIZE(insn->groups), group_id);
+	return arr_exist(insn->groups, insn->groups_count, group_id);
 }
 
 bool cs_reg_read(csh handle, cs_insn *insn, unsigned int reg_id)
@@ -374,7 +374,7 @@
 	if (!handle)
 		return false;
 
-	return arr_exist(insn->regs_read, ARR_SIZE(insn->regs_read), reg_id);
+	return arr_exist(insn->regs_read, insn->regs_read_count, reg_id);
 }
 
 bool cs_reg_write(csh handle, cs_insn *insn, unsigned int reg_id)
@@ -382,7 +382,7 @@
 	if (!handle)
 		return false;
 
-	return arr_exist(insn->regs_write, ARR_SIZE(insn->regs_write), reg_id);
+	return arr_exist(insn->regs_write, insn->regs_write_count, reg_id);
 }
 
 int cs_op_count(csh ud, cs_insn *insn, unsigned int op_type)
diff --git a/include/capstone.h b/include/capstone.h
index 0a22260..b710fdb 100644
--- a/include/capstone.h
+++ b/include/capstone.h
@@ -64,8 +64,13 @@
 	char op_str[96];
 
 	unsigned int regs_read[32]; // list of implicit registers read by this instruction
+	unsigned int regs_read_count; // number of implicit registers read by this insn
+
 	unsigned int regs_write[32]; // list of implicit registers modified by this instruction
+	unsigned int regs_write_count; // number of implicit registers modified by this insn
+
 	unsigned int groups[8]; // list of group this instruction belong to
+	unsigned int groups_count; // number of groups this insn belongs to
 
 	// Architecture-specific instruction info
 	union {
diff --git a/tests/test.c b/tests/test.c
index 7502c83..7a481c7 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -185,8 +185,11 @@
 	printf("@mnemonic: %u\n", offsetof(cs_insn, mnemonic));
 	printf("@op_str: %u\n", offsetof(cs_insn, op_str));
 	printf("@regs_read: %u\n", offsetof(cs_insn, regs_read));
+	printf("@regs_read_count: %u\n", offsetof(cs_insn, regs_read_count));
 	printf("@regs_write: %u\n", offsetof(cs_insn, regs_write));
+	printf("@regs_write_count: %u\n", offsetof(cs_insn, regs_write_count));
 	printf("@groups: %u\n", offsetof(cs_insn, groups));
+	printf("@groups_count: %u\n", offsetof(cs_insn, groups_count));
 	printf("@arch: %u\n", offsetof(cs_insn, x86));
 #endif
 
diff --git a/tests/test_detail.c b/tests/test_detail.c
index d196190..851d9a7 100644
--- a/tests/test_detail.c
+++ b/tests/test_detail.c
@@ -156,33 +156,27 @@
 						i->id, cs_insn_name(handle, i->id));
 
 				// print implicit registers used by this instruction
-				if (i->regs_read[0] != 0) {
+				if (i->regs_read_count > 0) {
 					printf("\tImplicit registers read: ");
-					for (n = 0; n < 32; n++) {
-						if (i->regs_read[n] == 0)
-							break;
+					for (n = 0; n < i->regs_read_count; n++) {
 						printf("%s ", cs_reg_name(handle, i->regs_read[n]));
 					}
 					printf("\n");
 				}
 
 				// print implicit registers modified by this instruction
-				if (i->regs_write[0] != 0) {
+				if (i->regs_write_count > 0) {
 					printf("\tImplicit registers modified: ");
-					for (n = 0; n < 32; n++) {
-						if (i->regs_write[n] == 0)
-							break;
+					for (n = 0; n < i->regs_write_count; n++) {
 						printf("%s ", cs_reg_name(handle, i->regs_write[n]));
 					}
 					printf("\n");
 				}
 
 				// print the groups this instruction belong to
-				if (i->groups[0] != 0) {
+				if (i->groups_count > 0) {
 					printf("\tThis instruction belongs to groups: ");
-					for (n = 0; n < 8; n++) {
-						if (i->groups[n] == 0)
-							break;
+					for (n = 0; n < i->groups_count; n++) {
 						printf("%u ", i->groups[n]);
 					}
 					printf("\n");
diff --git a/utils.c b/utils.c
index 882ef2d..539ab14 100644
--- a/utils.c
+++ b/utils.c
@@ -66,3 +66,13 @@
 	return 0;
 }
 
+// count number of positive members in a list.
+// NOTE: list must be guaranteed to end in 0
+unsigned int count_positive(unsigned int *list)
+{
+	unsigned int c;
+
+	for (c = 0; list[c] > 0; c++);
+
+	return c;
+}
diff --git a/utils.h b/utils.h
index 89f0b71..357341d 100644
--- a/utils.h
+++ b/utils.h
@@ -41,6 +41,10 @@
 // return 0 if not found
 unsigned int insn_reverse_id(insn_map *insns, unsigned int max, unsigned int id);
 
+// count number of positive members in a list.
+// NOTE: list must be guaranteed to end in 0
+unsigned int count_positive(unsigned int *list);
+
 #define ARR_SIZE(a) (sizeof(a)/sizeof(a[0]))
 
 #endif