i#1551 port to ARM: fix OP_cmp, OP_cmn, OP_tst: no dst, all srcs

Fixes the decoding table for OP_cmp, OP_cmn, OP_tst and re-generates their
INSTR_CREATE_ macros.

git-svn-id: https://dynamorio.googlecode.com/svn/trunk@3003 49cc7528-f6fd-11dd-9d1a-b59b2e1864b6
diff --git a/core/arch/arm/instr_create.h b/core/arch/arm/instr_create.h
index 39282c1..633a2af 100644
--- a/core/arch/arm/instr_create.h
+++ b/core/arch/arm/instr_create.h
@@ -734,35 +734,6 @@
    instr_create_1dst_1src((dc), OP_mvns, (Rd), (Rm_or_imm)))
 /* @} */ /* end doxygen group */
 
-/** @name Signature: (Rd, Rn_or_imm) */
-/* @{ */ /* start doxygen group (via DISTRIBUTE_GROUP_DOC=YES). */
-/**
- * This INSTR_CREATE_xxx macro creates an instr_t with opcode OP_xxx and
- * the given explicit operands, automatically supplying any implicit operands.
- * The operands should be listed with destinations first, followed by sources.
- * The ordering within these two groups should follow the conventional
- * assembly ordering.
- * \param dc The void * dcontext used to allocate memory for the instr_t.
- * \param Rd The destination register opnd_t operand.
- * \param Rn_or_imm The source register, or integer constant, opnd_t operand.
- */
-#define INSTR_CREATE_cmn(dc, Rd, Rn_or_imm) \
-  (opnd_is_reg(Rn_or_imm) ? \
-   INSTR_CREATE_cmn_shimm((dc), (Rd), (Rn_or_imm), \
-     OPND_CREATE_INT8(DR_SHIFT_NONE), OPND_CREATE_INT8(0)) : \
-   instr_create_1dst_1src((dc), OP_cmn, (Rd), (Rn_or_imm)))
-#define INSTR_CREATE_cmp(dc, Rd, Rn_or_imm) \
-  (opnd_is_reg(Rn_or_imm) ? \
-   INSTR_CREATE_cmp_shimm((dc), (Rd), (Rn_or_imm), \
-     OPND_CREATE_INT8(DR_SHIFT_NONE), OPND_CREATE_INT8(0)) : \
-   instr_create_1dst_1src((dc), OP_cmp, (Rd), (Rn_or_imm)))
-#define INSTR_CREATE_tst(dc, Rd, Rn_or_imm) \
-  (opnd_is_reg(Rn_or_imm) ? \
-   INSTR_CREATE_tst_shimm((dc), (Rd), (Rn_or_imm), \
-     OPND_CREATE_INT8(DR_SHIFT_NONE), OPND_CREATE_INT8(0)) : \
-   instr_create_1dst_1src((dc), OP_tst, (Rd), (Rn_or_imm)))
-/* @} */ /* end doxygen group */
-
 /** @name Signature: (Rn, Rm_or_imm) */
 /* @{ */ /* start doxygen group (via DISTRIBUTE_GROUP_DOC=YES). */
 /**
@@ -775,11 +746,26 @@
  * \param Rn The source register opnd_t operand.
  * \param Rm_or_imm The second source register, or integer constant, opnd_t operand.
  */
+#define INSTR_CREATE_cmn(dc, Rn, Rm_or_imm) \
+  (opnd_is_reg(Rm_or_imm) ? \
+   INSTR_CREATE_cmn_shimm((dc), (Rn), (Rm_or_imm), \
+     OPND_CREATE_INT8(DR_SHIFT_NONE), OPND_CREATE_INT8(0)) : \
+   instr_create_0dst_2src((dc), OP_cmn, (Rn), (Rm_or_imm)))
+#define INSTR_CREATE_cmp(dc, Rn, Rm_or_imm) \
+  (opnd_is_reg(Rm_or_imm) ? \
+   INSTR_CREATE_cmp_shimm((dc), (Rn), (Rm_or_imm), \
+     OPND_CREATE_INT8(DR_SHIFT_NONE), OPND_CREATE_INT8(0)) : \
+   instr_create_0dst_2src((dc), OP_cmp, (Rn), (Rm_or_imm)))
 #define INSTR_CREATE_teq(dc, Rn, Rm_or_imm) \
   (opnd_is_reg(Rm_or_imm) ? \
    INSTR_CREATE_teq_shimm((dc), (Rn), (Rm_or_imm), \
      OPND_CREATE_INT8(DR_SHIFT_NONE), OPND_CREATE_INT8(0)) : \
    instr_create_0dst_2src((dc), OP_teq, (Rn), (Rm_or_imm)))
+#define INSTR_CREATE_tst(dc, Rn, Rm_or_imm) \
+  (opnd_is_reg(Rm_or_imm) ? \
+   INSTR_CREATE_tst_shimm((dc), (Rn), (Rm_or_imm), \
+     OPND_CREATE_INT8(DR_SHIFT_NONE), OPND_CREATE_INT8(0)) : \
+   instr_create_0dst_2src((dc), OP_tst, (Rn), (Rm_or_imm)))
 /* @} */ /* end doxygen group */
 
 /** @name Signature: (Rd, imm, Rm) */
@@ -1082,28 +1068,6 @@
   instr_create_1dst_3src((dc), OP_ubfx, (Rd), (Rm), (imm), (imm2))
 /* @} */ /* end doxygen group */
 
-/** @name Signature: (Rd, Rn, shift, Rm) */
-/* @{ */ /* start doxygen group (via DISTRIBUTE_GROUP_DOC=YES). */
-/**
- * This INSTR_CREATE_xxx macro creates an instr_t with opcode OP_xxx and
- * the given explicit operands, automatically supplying any implicit operands.
- * The operands should be listed with destinations first, followed by sources.
- * The ordering within these two groups should follow the conventional
- * assembly ordering.
- * \param dc The void * dcontext used to allocate memory for the instr_t.
- * \param Rd The destination register opnd_t operand.
- * \param Rn The source register opnd_t operand.
- * \param shift The shift type integer constant opnd_t operand.
- * \param Rm The second source register opnd_t operand.
- */
-#define INSTR_CREATE_cmn_shreg(dc, Rd, Rn, shift, Rm) \
-  instr_create_1dst_3src((dc), OP_cmn, (Rd), (Rn), (shift), (Rm))
-#define INSTR_CREATE_cmp_shreg(dc, Rd, Rn, shift, Rm) \
-  instr_create_1dst_3src((dc), OP_cmp, (Rd), (Rn), (shift), (Rm))
-#define INSTR_CREATE_tst_shreg(dc, Rd, Rn, shift, Rm) \
-  instr_create_1dst_3src((dc), OP_tst, (Rd), (Rn), (shift), (Rm))
-/* @} */ /* end doxygen group */
-
 /** @name Signature: (Rd, Rm, shift, Rs) */
 /* @{ */ /* start doxygen group (via DISTRIBUTE_GROUP_DOC=YES). */
 /**
@@ -1138,8 +1102,14 @@
  * \param shift The shift type integer constant opnd_t operand.
  * \param Rs The third source register opnd_t operand.
  */
+#define INSTR_CREATE_cmn_shreg(dc, Rn, Rm, shift, Rs) \
+  instr_create_0dst_4src((dc), OP_cmn, (Rn), (Rm), (shift), (Rs))
+#define INSTR_CREATE_cmp_shreg(dc, Rn, Rm, shift, Rs) \
+  instr_create_0dst_4src((dc), OP_cmp, (Rn), (Rm), (shift), (Rs))
 #define INSTR_CREATE_teq_shreg(dc, Rn, Rm, shift, Rs) \
   instr_create_0dst_4src((dc), OP_teq, (Rn), (Rm), (shift), (Rs))
+#define INSTR_CREATE_tst_shreg(dc, Rn, Rm, shift, Rs) \
+  instr_create_0dst_4src((dc), OP_tst, (Rn), (Rm), (shift), (Rs))
 /* @} */ /* end doxygen group */
 
 /** @name Signature: (Rd, Rn, Rm, shift, Rs) */
@@ -1219,28 +1189,6 @@
   instr_create_1dst_3src((dc), OP_mvns, (Rd), (Rm), (shift), (imm))
 /* @} */ /* end doxygen group */
 
-/** @name Signature: (Rd, Rn, shift, imm) */
-/* @{ */ /* start doxygen group (via DISTRIBUTE_GROUP_DOC=YES). */
-/**
- * This INSTR_CREATE_xxx macro creates an instr_t with opcode OP_xxx and
- * the given explicit operands, automatically supplying any implicit operands.
- * The operands should be listed with destinations first, followed by sources.
- * The ordering within these two groups should follow the conventional
- * assembly ordering.
- * \param dc The void * dcontext used to allocate memory for the instr_t.
- * \param Rd The destination register opnd_t operand.
- * \param Rn The source register opnd_t operand.
- * \param shift The shift type integer constant opnd_t operand.
- * \param imm The integer constant opnd_t operand.
- */
-#define INSTR_CREATE_cmn_shimm(dc, Rd, Rn, shift, imm) \
-  instr_create_1dst_3src((dc), OP_cmn, (Rd), (Rn), (shift), (imm))
-#define INSTR_CREATE_cmp_shimm(dc, Rd, Rn, shift, imm) \
-  instr_create_1dst_3src((dc), OP_cmp, (Rd), (Rn), (shift), (imm))
-#define INSTR_CREATE_tst_shimm(dc, Rd, Rn, shift, imm) \
-  instr_create_1dst_3src((dc), OP_tst, (Rd), (Rn), (shift), (imm))
-/* @} */ /* end doxygen group */
-
 /** @name Signature: (Rn, Rm, shift, imm) */
 /* @{ */ /* start doxygen group (via DISTRIBUTE_GROUP_DOC=YES). */
 /**
@@ -1255,8 +1203,14 @@
  * \param shift The shift type integer constant opnd_t operand.
  * \param imm The integer constant opnd_t operand.
  */
+#define INSTR_CREATE_cmn_shimm(dc, Rn, Rm, shift, imm) \
+  instr_create_0dst_4src((dc), OP_cmn, (Rn), (Rm), (shift), (imm))
+#define INSTR_CREATE_cmp_shimm(dc, Rn, Rm, shift, imm) \
+  instr_create_0dst_4src((dc), OP_cmp, (Rn), (Rm), (shift), (imm))
 #define INSTR_CREATE_teq_shimm(dc, Rn, Rm, shift, imm) \
   instr_create_0dst_4src((dc), OP_teq, (Rn), (Rm), (shift), (imm))
+#define INSTR_CREATE_tst_shimm(dc, Rn, Rm, shift, imm) \
+  instr_create_0dst_4src((dc), OP_tst, (Rn), (Rm), (shift), (imm))
 /* @} */ /* end doxygen group */
 
 /** @name Signature: (Rd, Rn, Rm, shift, imm) */
diff --git a/core/arch/arm/table_a32_pred.c b/core/arch/arm/table_a32_pred.c
index d390fa3..6cd1b15 100644
--- a/core/arch/arm/table_a32_pred.c
+++ b/core/arch/arm/table_a32_pred.c
@@ -104,13 +104,13 @@
     {OP_rscs,    0x02f00000, "rscs",   RBw, xx, RAw, i12, xx, pred, fWNZCV, top4x[15][0x00]},
     /* 30 */
     {OP_movw,    0x03000000, "movw",   RBw, xx, i16x0_16, xx, xx, pred, x, END_LIST},
-    {OP_tst,     0x03100000, "tst",    RAw, xx, i12, xx, xx, pred, fWNZC, top4x[16][0x00]},
+    {OP_tst,     0x03100000, "tst",    xx, xx, RAw, i12, xx, pred, fWNZC, top4x[16][0x00]},
     {EXT_IMM1916,0x03200000, "(ext imm1916 0)", xx, xx, xx, xx, xx, no, x, 0},
     {OP_teq,     0x03300000, "teq",    xx, xx, RAw, i12, xx, pred, fWNZC, top4x[17][0x00]},
     {OP_movt,    0x03400000, "movt",   RBt, xx, i16x0_16, xx, xx, pred, x, END_LIST},
-    {OP_cmp,     0x03500000, "cmp",    RAw, xx, i12, xx, xx, pred, fWNZCV, top4x[18][0x00]},
+    {OP_cmp,     0x03500000, "cmp",    xx, xx, RAw, i12, xx, pred, fWNZCV, top4x[18][0x00]},
     {OP_msr,     0x03600000, "msr",    SPSR, xx, i4_16, i12, xx, pred, x, END_LIST},
-    {OP_cmn,     0x03700000, "cmn",    RAw, xx, i12, xx, xx, pred, fWNZCV, top4x[19][0x00]},
+    {OP_cmn,     0x03700000, "cmn",    xx, xx, RAw, i12, xx, pred, fWNZCV, top4x[19][0x00]},
     /* 38 */
     {OP_orr,     0x03800000, "orr",    RBw, xx, RAw, i12, xx, pred, x, top4x[20][0x00]},
     {OP_orrs,    0x03900000, "orrs",   RBw, xx, RAw, i12, xx, pred, fWNZCV, top4x[21][0x00]},
@@ -457,8 +457,8 @@
     {OP_ldrsbt,  0x00f000d0, "ldrsbt", RBw, RAw, MP44b, RAw, i8x0_8, pred, x, top4x[11][0x04]},/*PUW=011*/
     {OP_ldrsht,  0x00f000f0, "ldrsht", RBw, RAw, MP44h, RAw, i8x0_8, pred, x, top4x[11][0x05]},/*PUW=011*/
   }, { /* 16 */
-    {OP_tst,     0x01100000, "tst",    xx, RAw, RDw, sh2, i5, pred, fWNZC, top4x[16][0x01]},
-    {OP_tst,     0x01100010, "tst",    xx, RAw, RDw, sh2, RCb, pred, fWNZC, END_LIST},
+    {OP_tst,     0x01100000, "tst",    xx, RAw, RDw, sh2, i5, pred|srcX4, fWNZC, top4x[16][0x01]},
+    {OP_tst,     0x01100010, "tst",    xx, RAw, RDw, sh2, RCb, pred|srcX4, fWNZC, END_LIST},
     {INVALID,    0x01100090, "(bad)",  xx, xx, xx, xx, xx, no, x, NA},
     {OP_ldrh,    0x011000b0, "ldrh",   RBw, xx, MNRh, xx, xx, pred, x, top4x[25][0x03]},/*PUW=100*/
     {OP_ldrsb,   0x011000d0, "ldrsb",  RBw, xx, MNRb, xx, xx, pred, x, top4x[25][0x04]},/*PUW=100*/
@@ -471,15 +471,15 @@
     {OP_ldrsb,   0x013000d0, "ldrsb",  RBw, RAw, MNRb, RAw, RDNw, pred, x, top4x[13][0x04]},/*PUW=101*/
     {OP_ldrsh,   0x013000f0, "ldrsh",  RBw, RAw, MNRh, RAw, RDNw, pred, x, top4x[13][0x05]},/*PUW=101*/
   }, { /* 18 */
-    {OP_cmp,     0x01500000, "cmp",    RAw, xx, RDw, sh2, i5, pred, fWNZCV, top4x[18][0x01]},
-    {OP_cmp,     0x01500010, "cmp",    RAw, xx, RDw, sh2, RCb, pred, fWNZCV, END_LIST},
+    {OP_cmp,     0x01500000, "cmp",    xx, RAw, RDw, sh2, i5, pred|srcX4, fWNZCV, top4x[18][0x01]},
+    {OP_cmp,     0x01500010, "cmp",    xx, RAw, RDw, sh2, RCb, pred|srcX4, fWNZCV, END_LIST},
     {INVALID,    0x01500090, "(bad)",  xx, xx, xx, xx, xx, no, x, NA},
     {OP_ldrh,    0x015000b0, "ldrh",   RBw, xx, MN44h, xx, xx, pred, x, top4x[16][0x03]},/*PUW=100*/
     {OP_ldrsb,   0x015000d0, "ldrsb",  RBw, xx, MN44b, xx, xx, pred, x, top4x[16][0x04]},/*PUW=100*/
     {OP_ldrsh,   0x015000f0, "ldrsh",  RBw, xx, MN44h, xx, xx, pred, x, top4x[16][0x05]},/*PUW=100*/
   }, { /* 19 */
-    {OP_cmn,     0x01700000, "cmn",    RAw, xx, RDw, sh2, i5, pred, fWNZCV, top4x[19][0x01]},
-    {OP_cmn,     0x01700010, "cmn",    RAw, xx, RDw, sh2, RCb, pred, fWNZCV, END_LIST},
+    {OP_cmn,     0x01700000, "cmn",    xx, RAw, RDw, sh2, i5, pred|srcX4, fWNZCV, top4x[19][0x01]},
+    {OP_cmn,     0x01700010, "cmn",    xx, RAw, RDw, sh2, RCb, pred|srcX4, fWNZCV, END_LIST},
     {INVALID,    0x01700090, "(bad)",  xx, xx, xx, xx, xx, no, x, NA},
     {OP_ldrh,    0x017000b0, "ldrh",   RBw, RAw, MN44h, RAw, n8x0_8, pred, x, top4[5][0x0b]},/*PUW=101*/
     {OP_ldrsb,   0x017000d0, "ldrsb",  RBw, RAw, MN44b, RAw, n8x0_8, pred, x, top4x[17][0x04]},/*PUW=101*/