* gas/arm/arm.exp: Add archv6 and thumbv6.
authorMark Mitchell <mark@codesourcery.com>
Sat, 6 Dec 2003 01:25:29 +0000 (01:25 +0000)
committerMark Mitchell <mark@codesourcery.com>
Sat, 6 Dec 2003 01:25:29 +0000 (01:25 +0000)
* gas/arm/archv6.d: New file.
* gas/arm/archv6.s: Likewise.
* gas/arm/thumbv6.d: Likewise.
* gas/arm/thumbv6.s: Likewise.

Add V6 support.
* config/tc-arm.c (ARM_EXT_V6): New macro.
(ARM_ARCH_V6): Likewise.
(SHIFT_IMMEDIATE): Likewise.
(SHIFT_LSL_OR_ASR_IMMEDIATE): Likewise.
(SHIFT_ASR_IMMEDIATE): Likewise.
(SHIFT_LSL_IMMMEDIATE): Likewise.
(do_cps): New function.
(do_cpsi): Likewise.
(do_ldrex): Likewise.
(do_pkhbt): Likewise.
(do_pkhtb): Likewise.
(do_qadd16): Likewise.
(do_rev): Likewise.
(do_rfe): Likewise.
(do_sxtah): Likewise.
(do_sxth): Likewise.
(do_setend): Likewise.
(do_smlad): Likewise.
(do_smlald): Likewise.
(do_smmul): Likewise.
(do_ssat): Likewise.
(do_usat): Likewise.
(do_srs): Likewise.
(do_ssat16): Likewise.
(do_usat16): Likewise.
(do_strex): Likewise.
(do_umaal): Likewise.
(do_cps_mode): Likewise.
(do_cps_flags): Likewise.
(do_endian_specifier): Likewise.
(do_pkh_core): Likewise.
(do_sat): Likewise.
(do_sat16): Likewise.
(insns): Add V6 instructions.
(do_t_cps): New function.
(do_t_cpy): Likewise.
(do_t_setend): Likewise.
(THUMB_CPY): New macro.
(tinsns): Add V6 instructions.
(decode_shift): Handle V6 restricted-shift options.
(thumb_mov_compare): Support CPY.
(arm_cores): Add arm1136js and arm1136jfs.
(arm_archs): Add armv6.
(arm_fpus): Add arm1136jfs.
* doc/c-arm.texi (ARM Options): Mention arm1136js, arm1136jfs, and
armv6 options.

* gas/arm/arm.exp: Add archv6 and thumbv6.
* gas/arm/archv6.d: New file.
* gas/arm/archv6.s: Likewise.
* gas/arm/thumbv6.d: Likewise.
* gas/arm/thumbv6.s: Likewise.

* arm-dis.c (print_arm_insn): Add 'W' macro.
* arm-opc.h (arm_opcodes): Add V6 instructions.
(thumb_opcodes): Likewise.

13 files changed:
gas/ChangeLog
gas/NEWS
gas/config/tc-arm.c
gas/doc/c-arm.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/archv6.d [new file with mode: 0644]
gas/testsuite/gas/arm/archv6.s [new file with mode: 0644]
gas/testsuite/gas/arm/arm.exp
gas/testsuite/gas/arm/thumbv6.d [new file with mode: 0644]
gas/testsuite/gas/arm/thumbv6.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/arm-dis.c
opcodes/arm-opc.h

index 8ce8aecfc979b48a5c275e6c101bf13041c17ad2..679864c4fc0a022fefe604ae68a703635687c72a 100644 (file)
@@ -1,3 +1,55 @@
+2003-12-05  Ricardo Anguiano <anguiano@codesourcery.com>
+           Mark Mitchell  <mark@codesourcery.com>
+           Richard Earnshaw  <rearnsha@arm.com>
+       
+       Add V6 support.
+       * config/tc-arm.c (ARM_EXT_V6): New macro.
+       (ARM_ARCH_V6): Likewise.
+       (SHIFT_IMMEDIATE): Likewise.
+       (SHIFT_LSL_OR_ASR_IMMEDIATE): Likewise.
+       (SHIFT_ASR_IMMEDIATE): Likewise.
+       (SHIFT_LSL_IMMMEDIATE): Likewise.
+       (do_cps): New function.
+       (do_cpsi): Likewise.
+       (do_ldrex): Likewise.
+       (do_pkhbt): Likewise.
+       (do_pkhtb): Likewise.
+       (do_qadd16): Likewise.
+       (do_rev): Likewise.
+       (do_rfe): Likewise.
+       (do_sxtah): Likewise.
+       (do_sxth): Likewise.
+       (do_setend): Likewise.
+       (do_smlad): Likewise.
+       (do_smlald): Likewise.
+       (do_smmul): Likewise.
+       (do_ssat): Likewise.
+       (do_usat): Likewise.
+       (do_srs): Likewise.
+       (do_ssat16): Likewise.
+       (do_usat16): Likewise.
+       (do_strex): Likewise.
+       (do_umaal): Likewise.
+       (do_cps_mode): Likewise.
+       (do_cps_flags): Likewise.
+       (do_endian_specifier): Likewise.
+       (do_pkh_core): Likewise.
+       (do_sat): Likewise.
+       (do_sat16): Likewise.
+       (insns): Add V6 instructions.
+       (do_t_cps): New function.
+       (do_t_cpy): Likewise.
+       (do_t_setend): Likewise.
+       (THUMB_CPY): New macro.
+       (tinsns): Add V6 instructions.
+       (decode_shift): Handle V6 restricted-shift options.
+       (thumb_mov_compare): Support CPY.
+       (arm_cores): Add arm1136js and arm1136jfs.
+       (arm_archs): Add armv6.
+       (arm_fpus): Add arm1136jfs.
+       * doc/c-arm.texi (ARM Options): Mention arm1136js, arm1136jfs, and
+       armv6 options.
+
 2003-12-06  Christian Groessler  <chris@groessler.org>
 
        * config/tc-z8k.c (parse_reg): Be case insensitive when checking
index 1f704d2a353463903e158a9b78cf28e03446b7a2..66c15c9232f298e072cea85e4d6ff651581416e5 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Added support for ARM V6.
+
 * Added support for sh4a and variants.
 
 * Support for Renesas M32R2 added.
index a684350462a23559c8b54784d7e4b227c8390ade..a08b024e934a98b1a9759143243db65c21a84db9 100644 (file)
@@ -55,6 +55,7 @@
 #define ARM_EXT_V5ExP   0x00000200     /* DSP core set.           */
 #define ARM_EXT_V5E     0x00000400     /* DSP Double transfers.   */
 #define ARM_EXT_V5J     0x00000800     /* Jazelle extension.      */
+#define ARM_EXT_V6       0x00001000     /* ARM V6.                 */
 
 /* Co-processor space extensions.  */
 #define ARM_CEXT_XSCALE   0x00800000   /* Allow MIA etc.          */
@@ -82,6 +83,7 @@
 #define ARM_ARCH_V5TExP        (ARM_ARCH_V5T   | ARM_EXT_V5ExP)
 #define ARM_ARCH_V5TE  (ARM_ARCH_V5TExP | ARM_EXT_V5E)
 #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE  | ARM_EXT_V5J)
+#define ARM_ARCH_V6     (ARM_ARCH_V5TEJ | ARM_EXT_V6)
 
 /* Processors with specific extensions in the co-processor space.  */
 #define ARM_ARCH_XSCALE        (ARM_ARCH_V5TE  | ARM_CEXT_XSCALE)
@@ -288,8 +290,16 @@ static const struct asm_shift_name shift_names [] =
   { "RRX", shift_properties + SHIFT_RRX }
 };
 
+/* Any kind of shift is accepted.  */
 #define NO_SHIFT_RESTRICT 1
-#define SHIFT_RESTRICT   0
+/* The shift operand must be an immediate value, not a register.  */
+#define SHIFT_IMMEDIATE          0
+/* The shift must be LSL or ASR and the operand must be an immediate.  */
+#define SHIFT_LSL_OR_ASR_IMMEDIATE 2
+/* The shift must be ASR and the operand must be an immediate.  */
+#define SHIFT_ASR_IMMEDIATE 3
+/* The shift must be LSL and the operand must be an immediate.  */
+#define SHIFT_LSL_IMMEDIATE 4
 
 #define NUM_FLOAT_VALS 8
 
@@ -856,6 +866,36 @@ static void do_co_reg2c            PARAMS ((char *));
 /* ARM v5TEJ.  */
 static void do_bxj             PARAMS ((char *));
 
+/* ARM V6. */
+static void do_cps              PARAMS ((char *));
+static void do_cpsi             PARAMS ((char *));
+static void do_ldrex            PARAMS ((char *));
+static void do_pkhbt            PARAMS ((char *));
+static void do_pkhtb            PARAMS ((char *));
+static void do_qadd16           PARAMS ((char *));
+static void do_rev              PARAMS ((char *));
+static void do_rfe              PARAMS ((char *));
+static void do_sxtah            PARAMS ((char *));
+static void do_sxth             PARAMS ((char *));
+static void do_setend           PARAMS ((char *));
+static void do_smlad            PARAMS ((char *));
+static void do_smlald           PARAMS ((char *));
+static void do_smmul            PARAMS ((char *));
+static void do_ssat             PARAMS ((char *));
+static void do_usat             PARAMS ((char *));
+static void do_srs              PARAMS ((char *));
+static void do_ssat16           PARAMS ((char *));
+static void do_usat16           PARAMS ((char *));
+static void do_strex            PARAMS ((char *));
+static void do_umaal            PARAMS ((char *));
+
+static void do_cps_mode         PARAMS ((char **));
+static void do_cps_flags        PARAMS ((char **, int));
+static int do_endian_specifier  PARAMS ((char *));
+static void do_pkh_core         PARAMS ((char *, int));
+static void do_sat              PARAMS ((char **, int));
+static void do_sat16            PARAMS ((char **, int));
+
 /* Coprocessor Instructions.  */
 static void do_cdp             PARAMS ((char *));
 static void do_lstc            PARAMS ((char *));
@@ -1273,6 +1313,107 @@ static const struct asm_opcode insns[] =
   /*  ARM Architecture 5TEJ.  */
   {"bxj",       0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
 
+  /*  ARM V6.  */
+  { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
+  { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
+  { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
+  { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
+  { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
+  { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
+  { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
+  { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
+  { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
+  { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
+  { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
+  { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
+  { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
+  { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
+  { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
+  { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
+  { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
+  { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
+  { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
+  { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
+  { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
+  { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
+  { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
+  { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
+  { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
+  { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
+  { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
+  { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
+  { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
+  { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
+  { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
+  { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
+  { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
+  { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
+  { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
+  { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
+  { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
+  { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
+  { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
+  { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
+  { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
+  { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
+  { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
+  { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
+  { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
+  { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
+  { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
+  { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
+  { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
+  { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
+  { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
+  { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
+  { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
+  { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
+  { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
+  { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
+  { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
+  { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
+  { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
+  { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
+  { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
+  { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
+  { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
+  { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
+  { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
+  { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
+  { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
+  { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
+  { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
+  { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
+  { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
+  { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
+  { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
+  { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
+  { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
+  { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
+  { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
+  { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
+  { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
+  { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
+  { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
+  { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
+  { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
+  { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
+  { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
+  { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
+  { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
+  { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
+  { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
+  { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
+  { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
+  { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
+
   /* Core FPA instruction set (V1).  */
   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
@@ -2146,6 +2287,11 @@ static void do_t_adr             PARAMS ((char *));
 static void do_t_blx           PARAMS ((char *));
 static void do_t_bkpt          PARAMS ((char *));
 
+/* ARM V6.  */
+static void do_t_cps            PARAMS ((char *));
+static void do_t_cpy            PARAMS ((char *));
+static void do_t_setend         PARAMS ((char *));;
+
 #define T_OPCODE_MUL 0x4340
 #define T_OPCODE_TST 0x4200
 #define T_OPCODE_CMN 0x42c0
@@ -2214,6 +2360,7 @@ static int thumb_reg              PARAMS ((char ** str, int hi_lo));
 
 #define THUMB_MOVE 0
 #define THUMB_COMPARE 1
+#define THUMB_CPY 2
 
 #define THUMB_LOAD 0
 #define THUMB_STORE 1
@@ -2306,6 +2453,19 @@ static const struct thumb_opcode tinsns[] =
   /* Thumb v2 (ARMv5T).  */
   {"blx",      0,              0,      ARM_EXT_V5T, do_t_blx},
   {"bkpt",     0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
+
+  /* ARM V6.  */
+  {"cpsie",    0xb660,         2,      ARM_EXT_V6,  do_t_cps},
+  {"cpsid",     0xb670,                2,      ARM_EXT_V6,  do_t_cps},
+  {"cpy",      0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
+  {"rev",      0xba00,         2,      ARM_EXT_V6,  do_t_arit},
+  {"rev16",    0xba40,         2,      ARM_EXT_V6,  do_t_arit},
+  {"revsh",    0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
+  {"setend",   0xb650,         2,      ARM_EXT_V6,  do_t_setend},
+  {"sxth",     0xb200,         2,      ARM_EXT_V6,  do_t_arit},
+  {"sxtb",     0xb240,         2,      ARM_EXT_V6,  do_t_arit},
+  {"uxth",     0xb280,         2,      ARM_EXT_V6,  do_t_arit},
+  {"uxtb",     0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
 };
 
 #define BAD_ARGS       _("bad arguments to instruction")
@@ -4483,222 +4643,1167 @@ do_co_reg2c (str)
     as_tsktsk
       (_("Warning: instruction unpredictable when using r15"));
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 0) == FAIL)
+  if (skip_past_comma (& str) == FAIL
+      || cp_reg_required_here (& str, 0) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  end_of_line (str);
+}
+
+/* ARM V5 count-leading-zeroes instruction (argument parse)
+     CLZ{<cond>} <Rd>, <Rm>
+     Condition defaults to COND_ALWAYS.
+     Error if Rd or Rm are R15.  */
+
+static void
+do_clz (str)
+     char *        str;
+{
+  int rd, rm;
+
+  skip_whitespace (str);
+
+  if (((rd = reg_required_here (& str, 12)) == FAIL)
+      || (skip_past_comma (& str) == FAIL)
+      || ((rm = reg_required_here (& str, 0)) == FAIL))
+    inst.error = BAD_ARGS;
+
+  else if (rd == REG_PC || rm == REG_PC )
+    inst.error = BAD_PC;
+
+  else
+    end_of_line (str);
+}
+
+/* ARM V5 (argument parse)
+     LDC2{L} <coproc>, <CRd>, <addressing mode>
+     STC2{L} <coproc>, <CRd>, <addressing mode>
+     Instruction is not conditional, and has 0xf in the condition field.
+     Otherwise, it's the same as LDC/STC.  */
+
+static void
+do_lstc2 (str)
+     char *        str;
+{
+  skip_whitespace (str);
+
+  if (co_proc_number (& str) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+    }
+  else if (skip_past_comma (& str) == FAIL
+          || cp_reg_required_here (& str, 12) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+    }
+  else if (skip_past_comma (& str) == FAIL
+          || cp_address_required_here (&str, CP_WB_OK) == FAIL)
+    {
+      if (! inst.error)
+       inst.error = BAD_ARGS;
+    }
+  else
+    end_of_line (str);
+}
+
+/* ARM V5 (argument parse)
+     CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
+     Instruction is not conditional, and has 0xf in the condition field.
+     Otherwise, it's the same as CDP.  */
+
+static void
+do_cdp2 (str)
+     char *        str;
+{
+  skip_whitespace (str);
+
+  if (co_proc_number (& str) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || cp_opc_expr (& str, 20,4) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || cp_reg_required_here (& str, 12) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || cp_reg_required_here (& str, 16) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || cp_reg_required_here (& str, 0) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == SUCCESS)
+    {
+      if (cp_opc_expr (& str, 5, 3) == FAIL)
+       {
+         if (!inst.error)
+           inst.error = BAD_ARGS;
+         return;
+       }
+    }
+
+  end_of_line (str);
+}
+
+/* ARM V5 (argument parse)
+     MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
+     MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
+     Instruction is not conditional, and has 0xf in the condition field.
+     Otherwise, it's the same as MCR/MRC.  */
+
+static void
+do_co_reg2 (str)
+     char *        str;
+{
+  skip_whitespace (str);
+
+  if (co_proc_number (& str) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || cp_opc_expr (& str, 21, 3) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || reg_required_here (& str, 12) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || cp_reg_required_here (& str, 16) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == FAIL
+      || cp_reg_required_here (& str, 0) == FAIL)
+    {
+      if (!inst.error)
+       inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (skip_past_comma (& str) == SUCCESS)
+    {
+      if (cp_opc_expr (& str, 5, 3) == FAIL)
+       {
+         if (!inst.error)
+           inst.error = BAD_ARGS;
+         return;
+       }
+    }
+
+  end_of_line (str);
+}
+
+/* ARM v5TEJ.  Jump to Jazelle code.  */
+static void
+do_bxj (str)
+     char * str;
+{
+  int reg;
+
+  skip_whitespace (str);
+
+  if ((reg = reg_required_here (&str, 0)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
+  if (reg == REG_PC)
+    as_tsktsk (_("use of r15 in bxj is not really useful"));
+
+  end_of_line (str);
+}
+
+/* ARM V6 umaal (argument parse). */
+
+static void
+do_umaal (str)
+     char *str;
+{
+
+  int rdlo, rdhi, rm, rs;
+
+  skip_whitespace (str);
+  if ((rdlo = reg_required_here (& str, 12)) == FAIL
+      || skip_past_comma (& str) == FAIL
+      || (rdhi = reg_required_here (& str, 16)) == FAIL
+      || skip_past_comma (& str) == FAIL
+      || (rm = reg_required_here (& str, 0)) == FAIL
+      || skip_past_comma (& str) == FAIL
+      || (rm = reg_required_here (& str, 8)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;      
+    }
+
+  if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  end_of_line (str);
+}
+
+/* ARM V6 strex (argument parse). */
+
+static void 
+do_strex (str)
+     char *str;
+{
+  int rd, rm, rn;
+
+  /* Parse Rd, Rm,. */
+  skip_whitespace (str);
+  if ((rd = reg_required_here (& str, 12)) == FAIL
+      || skip_past_comma (& str) == FAIL
+      || (rm = reg_required_here (& str, 0)) == FAIL
+      || skip_past_comma (& str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  if (rd == REG_PC || rm == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+  if (rd == rm)
+    {
+      inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
+      return;
+    }
+
+  /* Skip past '['. */
+  if ((strlen (str) >= 1) 
+      && strncmp (str, "[", 1) == 0)
+    str+=1;
+  skip_whitespace (str);  
+
+  /* Parse Rn. */
+  if ((rn = reg_required_here (& str, 16)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  else if (rn == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+  if (rd == rn)
+    {
+      inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
+      return;
+    }
+  skip_whitespace (str);  
+
+  /* Skip past ']'. */
+  if ((strlen (str) >= 1) 
+      && strncmp (str, "]", 1) == 0)
+    str+=1;
+  
+  end_of_line (str);
+}
+
+/* ARM V6 ssat (argument parse). */
+
+static void
+do_ssat (str)
+     char* str;
+{
+  do_sat (&str, /*bias=*/-1);
+  end_of_line (str);
+}
+
+/* ARM V6 usat (argument parse). */
+
+static void
+do_usat (str)
+     char* str;
+{
+  do_sat (&str, /*bias=*/0);
+  end_of_line (str);
+}
+
+static void
+do_sat (str, bias)
+     char **str;
+     int    bias;
+{
+  int rd, rm;
+  expressionS expr;
+
+  skip_whitespace (*str);
+  
+  /* Parse <Rd>, field. */
+  if ((rd = reg_required_here (str, 12)) == FAIL
+      || skip_past_comma (str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  if (rd == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  /* Parse #<immed>,  field. */
+  if (is_immediate_prefix (**str))
+    (*str)++;
+  else
+    {
+      inst.error = _("immediate expression expected");
+      return;
+    }
+  if (my_get_expression (&expr, str))
+    {
+      inst.error = _("bad expression");
+      return;
+    }
+  if (expr.X_op != O_constant)
+    {
+      inst.error = _("constant expression expected");
+      return;
+    }
+  if (expr.X_add_number + bias < 0
+      || expr.X_add_number + bias > 31)
+    {
+      inst.error = _("immediate value out of range");
+      return;
+    }
+  inst.instruction |= (expr.X_add_number + bias) << 16;
+  if (skip_past_comma (str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  /* Parse <Rm> field. */
+  if ((rm = reg_required_here (str, 0)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  if (rm == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  if (skip_past_comma (str) == SUCCESS)
+    decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
+}
+
+/* ARM V6 ssat16 (argument parse). */
+
+static void
+do_ssat16 (str)
+     char *str;
+{
+  do_sat16 (&str, /*bias=*/-1);
+  end_of_line (str);
+}
+
+static void
+do_usat16 (str)
+     char *str;
+{
+  do_sat16 (&str, /*bias=*/0);
+  end_of_line (str);
+}
+
+static void
+do_sat16 (str, bias)
+     char **str;
+     int bias;
+{
+  int rd, rm;
+  expressionS expr;
+
+  skip_whitespace (*str);
+
+  /* Parse the <Rd> field. */
+  if ((rd = reg_required_here (str, 12)) == FAIL
+      || skip_past_comma (str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  if (rd == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  /* Parse #<immed>, field. */
+  if (is_immediate_prefix (**str))
+    (*str)++;
+  else
+    {
+      inst.error = _("immediate expression expected");
+      return;
+    }
+  if (my_get_expression (&expr, str))
+    {
+      inst.error = _("bad expression");
+      return;
+    }
+  if (expr.X_op != O_constant)
+    {
+      inst.error = _("constant expression expected");
+      return;
+    }
+  if (expr.X_add_number + bias < 0
+      || expr.X_add_number + bias > 15)
+    {
+      inst.error = _("immediate value out of range");
+      return;
+    }
+  inst.instruction |= (expr.X_add_number + bias) << 16;
+  if (skip_past_comma (str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  /* Parse <Rm> field. */
+  if ((rm = reg_required_here (str, 0)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  if (rm == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+}
+
+/* ARM V6 srs (argument parse). */
+
+static void
+do_srs (str)
+     char* str;
+{
+  char *exclam;
+  skip_whitespace (str);
+  exclam = strchr (str, '!');
+  if (exclam)
+    *exclam = '\0';
+  do_cps_mode (&str);
+  if (exclam)
+    *exclam = '!';
+  if (*str == '!') 
+    {
+      inst.instruction |= WRITE_BACK;
+      str++;
+    }
+  end_of_line (str);
+}
+
+/* ARM V6 SMMUL (argument parse). */
+
+static void
+do_smmul (str)
+     char* str;
+{
+  int rd, rm, rs;
+  
+  skip_whitespace (str);
+  if ((rd = reg_required_here (&str, 16)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rm = reg_required_here (&str, 0)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rs = reg_required_here (&str, 8)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (rd == REG_PC 
+      || rm == REG_PC
+      || rs == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  end_of_line (str);
+  
+}
+
+/* ARM V6 SMLALD (argument parse). */
+
+static void
+do_smlald (str)
+    char* str;
+{
+  int rdlo, rdhi, rm, rs;
+  skip_whitespace (str);
+  if ((rdlo = reg_required_here (&str, 12)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rdhi = reg_required_here (&str, 16)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rm = reg_required_here (&str, 0)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rs = reg_required_here (&str, 8)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  if (rdlo == REG_PC 
+      || rdhi == REG_PC 
+      || rm == REG_PC
+      || rs == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  end_of_line (str);
+}
+
+/* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual. 
+   smlad{x}{<cond>} Rd, Rm, Rs, Rn */
+
+static void 
+do_smlad (str)
+     char *str;
+{
+  int rd, rm, rs, rn;
+  
+  skip_whitespace (str);
+  if ((rd = reg_required_here (&str, 16)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rm = reg_required_here (&str, 0)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rs = reg_required_here (&str, 8)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rn = reg_required_here (&str, 12)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  
+  if (rd == REG_PC 
+      || rn == REG_PC 
+      || rs == REG_PC
+      || rm == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+
+  end_of_line (str);
+} 
+
+/* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
+   preserving the other bits.
+
+   setend <endian_specifier>, where <endian_specifier> is either 
+   BE or LE. */
+
+static void 
+do_setend (str)
+     char *str;
+{
+  if (do_endian_specifier (str))
+    inst.instruction |= 0x200;
+}
+
+/* Returns true if the endian-specifier indicates big-endianness.  */
+
+static int
+do_endian_specifier (str)
+     char *str;
+{
+  int big_endian = 0;
+
+  skip_whitespace (str);
+  if (strlen (str) < 2)
+    inst.error = _("missing endian specifier");
+  else if (strncasecmp (str, "BE", 2) == 0)
+    {
+      str += 2;
+      big_endian = 1;
+    }
+  else if (strncasecmp (str, "LE", 2) == 0)
+    str += 2;
+  else
+    inst.error = _("valid endian specifiers are be or le");
+
+  end_of_line (str);
+
+  return big_endian;
+}
+
+/* ARM V6 SXTH.
+
+   SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
+   Condition defaults to COND_ALWAYS.
+   Error if any register uses R15. */
+
+static void 
+do_sxth (str)
+     char *str;
+{
+  int rd, rm;
+  expressionS expr;
+  int rotation_clear_mask = 0xfffff3ff;
+  int rotation_eight_mask = 0x00000400;
+  int rotation_sixteen_mask = 0x00000800;
+  int rotation_twenty_four_mask = 0x00000c00;
+  
+  skip_whitespace (str);
+  if ((rd = reg_required_here (&str, 12)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rm = reg_required_here (&str, 0)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  else if (rd == REG_PC || rm == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+  
+  /* Zero out the rotation field. */
+  inst.instruction &= rotation_clear_mask;
+  
+  /* Check for lack of optional rotation field. */
+  if (skip_past_comma (&str) == FAIL)
+    {
+      end_of_line (str);
+      return;
+    }
+  
+  /* Move past 'ROR'. */
+  skip_whitespace (str);
+  if (strncasecmp (str, "ROR", 3) == 0)
+    str+=3;
+  else
+    {
+      inst.error = _("missing rotation field after comma");
+      return;
+    }
+  
+  /* Get the immediate constant. */
+  skip_whitespace (str);
+  if (is_immediate_prefix (* str))
+    str++;
+  else
+    {
+      inst.error = _("immediate expression expected");
+      return;
+    }
+  
+  if (my_get_expression (&expr, &str))
+    {
+      inst.error = _("bad expression");
+      return;
+    }
+
+  if (expr.X_op != O_constant)
+    {
+      inst.error = _("constant expression expected");
+      return;
+    }
+  
+  switch (expr.X_add_number) 
+    {
+    case 0:
+      /* Rotation field has already been zeroed. */
+      break;
+    case 8:
+      inst.instruction |= rotation_eight_mask;
+      break;
+
+    case 16:
+      inst.instruction |= rotation_sixteen_mask;
+      break;
+      
+    case 24:
+      inst.instruction |= rotation_twenty_four_mask;
+      break;
+
+    default:
+      inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
+      break;
+    }
+
+  end_of_line (str);
+  
+}
+
+/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
+   extends it to 32-bits, and adds the result to a value in another
+   register.  You can specify a rotation by 0, 8, 16, or 24 bits
+   before extracting the 16-bit value.
+   SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
+   Condition defaults to COND_ALWAYS.
+   Error if any register uses R15. */
+
+static void 
+do_sxtah (str)
+     char *str;
+{
+  int rd, rn, rm;
+  expressionS expr;
+  int rotation_clear_mask = 0xfffff3ff;
+  int rotation_eight_mask = 0x00000400;
+  int rotation_sixteen_mask = 0x00000800;
+  int rotation_twenty_four_mask = 0x00000c00;
+  
+  skip_whitespace (str);
+  if ((rd = reg_required_here (&str, 12)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rn = reg_required_here (&str, 16)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rm = reg_required_here (&str, 0)) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+
+  else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
+    }
+  
+  /* Zero out the rotation field. */
+  inst.instruction &= rotation_clear_mask;
+  
+  /* Check for lack of optional rotation field. */
+  if (skip_past_comma (&str) == FAIL)
+    {
+      end_of_line (str);
+      return;
+    }
+  
+  /* Move past 'ROR'. */
+  skip_whitespace (str);
+  if (strncasecmp (str, "ROR", 3) == 0)
+    str+=3;
+  else
+    {
+      inst.error = _("missing rotation field after comma");
+      return;
+    }
+  
+  /* Get the immediate constant. */
+  skip_whitespace (str);
+  if (is_immediate_prefix (* str))
+    str++;
+  else
+    {
+      inst.error = _("immediate expression expected");
+      return;
+    }
+  
+  if (my_get_expression (&expr, &str))
+    {
+      inst.error = _("bad expression");
+      return;
+    }
+
+  if (expr.X_op != O_constant)
+    {
+      inst.error = _("constant expression expected");
+      return;
+    }
+  
+  switch (expr.X_add_number) 
+    {
+    case 0:
+      /* Rotation field has already been zeroed. */
+      break;
+
+    case 8:
+      inst.instruction |= rotation_eight_mask;
+      break;
+
+    case 16:
+      inst.instruction |= rotation_sixteen_mask;
+      break;
+      
+    case 24:
+      inst.instruction |= rotation_twenty_four_mask;
+      break;
+
+    default:
+      inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
+      break;
+    }
+
+  end_of_line (str);
+  
+}
+   
+
+/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
+   word at the specified address and the following word
+   respectively. 
+   Unconditionally executed.
+   Error if Rn is R15.   
+*/
+
+static void
+do_rfe (str)
+     char *str;
+{
+  int rn;
+
+  skip_whitespace (str);
+  
+  if ((rn = reg_required_here (&str, 16)) == FAIL)
+    return;
+
+  if (rn == REG_PC)
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = BAD_PC;
       return;
     }
 
+  skip_whitespace (str);
+  
+  if (*str == '!')
+    {
+      inst.instruction |= WRITE_BACK;
+      str++;
+    }
   end_of_line (str);
 }
 
-/* ARM V5 count-leading-zeroes instruction (argument parse)
-     CLZ{<cond>} <Rd>, <Rm>
-     Condition defaults to COND_ALWAYS.
-     Error if Rd or Rm are R15.  */
+/* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
+   register (argument parse).
+   REV{<cond>} Rd, Rm.
+   Condition defaults to COND_ALWAYS.
+   Error if Rd or Rm are R15. */ 
 
 static void
-do_clz (str)
-     char *        str;
+do_rev (str)
+     char* str;
 {
   int rd, rm;
 
   skip_whitespace (str);
 
-  if (((rd = reg_required_here (& str, 12)) == FAIL)
-      || (skip_past_comma (& str) == FAIL)
-      || ((rm = reg_required_here (& str, 0)) == FAIL))
+  if ((rd = reg_required_here (&str, 12)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rm = reg_required_here (&str, 0)) == FAIL)
     inst.error = BAD_ARGS;
 
-  else if (rd == REG_PC || rm == REG_PC )
+  else if (rd == REG_PC || rm == REG_PC)
     inst.error = BAD_PC;
 
   else
     end_of_line (str);
 }
 
-/* ARM V5 (argument parse)
-     LDC2{L} <coproc>, <CRd>, <addressing mode>
-     STC2{L} <coproc>, <CRd>, <addressing mode>
-     Instruction is not conditional, and has 0xf in the condition field.
-     Otherwise, it's the same as LDC/STC.  */
+/* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
+   QADD16{<cond>} <Rd>, <Rn>, <Rm>  
+   Condition defaults to COND_ALWAYS.
+   Error if Rd, Rn or Rm are R15.  */
 
 static void
-do_lstc2 (str)
-     char *        str;
+do_qadd16 (str) 
+     char* str;
 {
+  int rd, rm, rn;
+
   skip_whitespace (str);
 
-  if (co_proc_number (& str) == FAIL)
-    {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
-    }
-  else if (skip_past_comma (& str) == FAIL
-          || cp_reg_required_here (& str, 12) == FAIL)
-    {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
-    }
-  else if (skip_past_comma (& str) == FAIL
-          || cp_address_required_here (&str, CP_WB_OK) == FAIL)
-    {
-      if (! inst.error)
-       inst.error = BAD_ARGS;
-    }
+  if ((rd = reg_required_here (&str, 12)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rn = reg_required_here (&str, 16)) == FAIL
+      || skip_past_comma (&str) == FAIL
+      || (rm = reg_required_here (&str, 0)) == FAIL)
+    inst.error = BAD_ARGS;
+
+  else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
+    inst.error = BAD_PC;
+
   else
     end_of_line (str);
 }
 
-/* ARM V5 (argument parse)
-     CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
-     Instruction is not conditional, and has 0xf in the condition field.
-     Otherwise, it's the same as CDP.  */
+/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
+   PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>} 
+   Condition defaults to COND_ALWAYS.
+   Error if Rd, Rn or Rm are R15.  */
+
+static void 
+do_pkhbt (str)
+     char* str;
+{
+  do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
+}
+
+/* ARM V6 PKHTB (Argument Parse). */
+
+static void 
+do_pkhtb (str)
+     char* str;
+{
+  do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
+}
 
 static void
-do_cdp2 (str)
-     char *        str;
+do_pkh_core (str, shift)
+     char* str;
+     int shift;
 {
-  skip_whitespace (str);
+  int rd, rn, rm;
 
-  if (co_proc_number (& str) == FAIL)
+  skip_whitespace (str);
+  if (((rd = reg_required_here (&str, 12)) == FAIL)
+      || (skip_past_comma (&str) == FAIL)
+      || ((rn = reg_required_here (&str, 16)) == FAIL)
+      || (skip_past_comma (&str) == FAIL)
+      || ((rm = reg_required_here (&str, 0)) == FAIL))
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = BAD_ARGS;
       return;
     }
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_opc_expr (& str, 20,4) == FAIL)
+  else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = BAD_PC;
       return;
     }
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 12) == FAIL)
+  /* Check for optional shift immediate constant. */
+  if (skip_past_comma (&str) == FAIL) 
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      if (shift == SHIFT_ASR_IMMEDIATE)
+       {
+         /* If the shift specifier is ommited, turn the instruction
+            into pkhbt rd, rm, rn.  First, switch the instruction
+            code, and clear the rn and rm fields.  */
+         inst.instruction &= 0xfff0f010;
+         /* Now, re-encode the registers.  */
+         inst.instruction |= (rm << 16) | rn;
+       }
       return;
     }
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 16) == FAIL)
+  decode_shift (&str, shift);
+}
+
+/* ARM V6 Load Register Exclusive instruction (argument parse).
+   LDREX{<cond>} <Rd, [<Rn>]
+   Condition defaults to COND_ALWAYS.
+   Error if Rd or Rn are R15. 
+   See ARMARMv6 A4.1.27: LDREX. */
+
+
+static void
+do_ldrex (str)
+     char * str;
+{
+  int rd, rn;
+
+  skip_whitespace (str);
+
+  /* Parse Rd. */
+  if (((rd = reg_required_here (&str, 12)) == FAIL)
+      || (skip_past_comma (&str) == FAIL))
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = BAD_ARGS;
       return;
     }
-
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 0) == FAIL)
+  else if (rd == REG_PC)
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = BAD_PC;
       return;
     }
+  skip_whitespace (str);  
 
-  if (skip_past_comma (& str) == SUCCESS)
+  /* Skip past '['. */
+  if ((strlen (str) >= 1) 
+      &&strncmp (str, "[", 1) == 0)
+    str+=1;
+  skip_whitespace (str);  
+
+  /* Parse Rn. */
+  if ((rn = reg_required_here (&str, 16)) == FAIL)
     {
-      if (cp_opc_expr (& str, 5, 3) == FAIL)
-       {
-         if (!inst.error)
-           inst.error = BAD_ARGS;
-         return;
-       }
+      inst.error = BAD_ARGS;
+      return;
+    }
+  else if (rn == REG_PC)
+    {
+      inst.error = BAD_PC;
+      return;
     }
+  skip_whitespace (str);  
 
+  /* Skip past ']'. */
+  if ((strlen (str) >= 1) 
+      && strncmp (str, "]", 1) == 0)
+    str+=1;
+  
   end_of_line (str);
 }
 
-/* ARM V5 (argument parse)
-     MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
-     MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
-     Instruction is not conditional, and has 0xf in the condition field.
-     Otherwise, it's the same as MCR/MRC.  */
+/* ARM V6 change processor state instruction (argument parse)
+      CPS, CPSIE, CSPID . */
 
 static void
-do_co_reg2 (str)
-     char *        str;
+do_cps (str)
+     char * str;
 {
-  skip_whitespace (str);
+  do_cps_mode (&str);
+  end_of_line (str);
+}
 
-  if (co_proc_number (& str) == FAIL)
-    {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
-      return;
-    }
+static void
+do_cpsi (str)
+     char * str;
+{
+  do_cps_flags (&str, /*thumb_p=*/0);
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_opc_expr (& str, 21, 3) == FAIL)
+  if (skip_past_comma (&str) == SUCCESS)
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
-      return;
+      skip_whitespace (str);
+      do_cps_mode (&str);
     }
+  end_of_line (str);
+}
 
-  if (skip_past_comma (& str) == FAIL
-      || reg_required_here (& str, 12) == FAIL)
+static void
+do_cps_mode (str)
+     char **str;
+{
+  expressionS expr;
+
+  skip_whitespace (*str);
+
+  if (! is_immediate_prefix (**str))
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = _("immediate expression expected");
       return;
     }
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 16) == FAIL)
+  (*str)++; /* Strip off the immediate signifier. */
+  if (my_get_expression (&expr, str))
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = _("bad expression");
       return;
     }
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 0) == FAIL)
+  if (expr.X_op != O_constant)
     {
-      if (!inst.error)
-       inst.error = BAD_ARGS;
+      inst.error = _("constant expression expected");
       return;
     }
-
-  if (skip_past_comma (& str) == SUCCESS)
+  
+  /* The mode is a 5 bit field.  Valid values are 0-31. */
+  if (((unsigned) expr.X_add_number) > 31
+      || (inst.reloc.exp.X_add_number) < 0)
     {
-      if (cp_opc_expr (& str, 5, 3) == FAIL)
-       {
-         if (!inst.error)
-           inst.error = BAD_ARGS;
-         return;
-       }
+      inst.error = _("invalid constant");
+      return;
     }
-
-  end_of_line (str);
+  
+  inst.instruction |= expr.X_add_number;
+  return;
 }
 
-/* ARM v5TEJ.  Jump to Jazelle code.  */
 static void
-do_bxj (str)
-     char * str;
+do_cps_flags (str, thumb_p)
+     char **str;
+     int    thumb_p;
 {
-  int reg;
+  struct cps_flag { 
+    char character;
+    unsigned long arm_value;
+    unsigned long thumb_value;
+  };
+  static struct cps_flag flag_table[] = {
+    {'a', 0x100, 0x4 },
+    {'i', 0x080, 0x2 },
+    {'f', 0x040, 0x1 }
+  };
 
-  skip_whitespace (str);
+  int saw_a_flag = 0;
 
-  if ((reg = reg_required_here (&str, 0)) == FAIL)
+  skip_whitespace (*str);
+
+  /* Get the a, f and i flags. */
+  while (**str && **str != ',')
     {
-      inst.error = BAD_ARGS;
-      return;
+      struct cps_flag *p;
+      struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
+      for (p = flag_table; p < q; ++p)
+       if (strncasecmp (*str, &p->character, 1) == 0)
+         {
+           inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
+           saw_a_flag = 1;
+           break;
+         }
+      if (p == q)
+       {
+         inst.error = _("unrecognized flag");
+         return;
+       }
+      (*str)++;
     }
-
-  /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
-  if (reg == REG_PC)
-    as_tsktsk (_("use of r15 in bxj is not really useful"));
-
-  end_of_line (str);
+  if (!saw_a_flag) 
+    inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
 }
 
 /* THUMB V5 breakpoint instruction (argument parse)
@@ -4930,6 +6035,35 @@ do_bkpt (str)
   end_of_line (str);
 }
 
+/* THUMB CPS instruction (argument parse).  */
+
+static void
+do_t_cps (str)
+     char *str;
+{
+  do_cps_flags (&str, /*thumb_p=*/1);
+  end_of_line (str);
+}
+
+/* THUMB CPY instruction (argument parse).  */
+
+static void
+do_t_cpy (str)
+     char *str;
+{
+  thumb_mov_compare (str, THUMB_CPY);
+}
+
+/* THUMB SETEND instruction (argument parse).  */
+
+static void
+do_t_setend (str)
+     char *str;
+{
+  if (do_endian_specifier (str))
+    inst.instruction |= 0x8;
+}
+
 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
 
 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
@@ -5777,13 +6911,12 @@ md_operand (expr)
     }
 }
 
-/* UNRESTRICT should be one if <shift> <register> is permitted for this
-   instruction.  */
+/* KIND indicates what kind of shifts are accepted.  */
 
 static int
-decode_shift (str, unrestrict)
+decode_shift (str, kind)
      char ** str;
-     int     unrestrict;
+     int     kind;
 {
   const struct asm_shift_name * shift;
   char * p;
@@ -5813,6 +6946,26 @@ decode_shift (str, unrestrict)
 
   assert (shift->properties->index == shift_properties[shift->properties->index].index);
 
+  if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
+      && shift->properties->index != SHIFT_LSL
+      && shift->properties->index != SHIFT_ASR)
+    {
+      inst.error = _("'LSL' or 'ASR' required");
+      return FAIL;
+    }
+  else if (kind == SHIFT_LSL_IMMEDIATE
+          && shift->properties->index != SHIFT_LSL)
+    {
+      inst.error = _("'LSL' required");
+      return FAIL;
+    }
+  else if (kind == SHIFT_ASR_IMMEDIATE
+          && shift->properties->index != SHIFT_ASR)
+    {
+      inst.error = _("'ASR' required");
+      return FAIL;
+    }
+    
   if (shift->properties->index == SHIFT_RRX)
     {
       * str = p;
@@ -5822,7 +6975,7 @@ decode_shift (str, unrestrict)
 
   skip_whitespace (p);
 
-  if (unrestrict && reg_required_here (& p, 8) != FAIL)
+  if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
     {
       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
       * str = p;
@@ -5830,7 +6983,7 @@ decode_shift (str, unrestrict)
     }
   else if (! is_immediate_prefix (* p))
     {
-      inst.error = (unrestrict
+      inst.error = (NO_SHIFT_RESTRICT
                    ? _("shift requires register or #expression")
                    : _("shift requires #expression"));
       * str = p;
@@ -6309,7 +7462,7 @@ ldst_extend (str)
 
       inst.instruction |= add | OFFSET_REG;
       if (skip_past_comma (str) == SUCCESS)
-       return decode_shift (str, SHIFT_RESTRICT);
+       return decode_shift (str, SHIFT_IMMEDIATE);
 
       return SUCCESS;
     }
@@ -8900,7 +10053,7 @@ thumb_mov_compare (str, move)
       return;
     }
 
-  if (is_immediate_prefix (*str))
+  if (move != THUMB_CPY && is_immediate_prefix (*str))
     {
       str++;
       if (my_get_expression (&inst.reloc.exp, &str))
@@ -8911,7 +10064,7 @@ thumb_mov_compare (str, move)
 
   if (Rs != FAIL)
     {
-      if (Rs < 8 && Rd < 8)
+      if (move != THUMB_CPY && Rs < 8 && Rd < 8)
        {
          if (move == THUMB_MOVE)
            /* A move of two lowregs is encoded as ADD Rd, Rs, #0
@@ -8925,7 +10078,7 @@ thumb_mov_compare (str, move)
        {
          if (move == THUMB_MOVE)
            inst.instruction = T_OPCODE_MOV_HR;
-         else
+         else if (move != THUMB_CPY)
            inst.instruction = T_OPCODE_CMP_HR;
 
          if (Rd > 7)
@@ -12197,6 +13350,8 @@ static struct arm_cpu_option_table arm_cpus[] =
   {"arm1020",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
   {"arm1020t",         ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
   {"arm1020e",         ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
+  {"arm1136js",                ARM_ARCH_V6,     FPU_NONE},
+  {"arm1136jfs",       ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
   /* ??? XSCALE is really an architecture.  */
   {"xscale",           ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
   /* ??? iwmmxt is not a processor.  */
@@ -12235,6 +13390,7 @@ static struct arm_arch_option_table arm_archs[] =
   {"armv5te",          ARM_ARCH_V5TE,   FPU_ARCH_VFP},
   {"armv5texp",                ARM_ARCH_V5TExP, FPU_ARCH_VFP},
   {"armv5tej",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
+  {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
   {"xscale",           ARM_ARCH_XSCALE, FPU_ARCH_VFP},
   {"iwmmxt",           ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
   {NULL, 0, 0}
@@ -12282,6 +13438,7 @@ static struct arm_fpu_option_table arm_fpus[] =
   {"vfpxd",            FPU_ARCH_VFP_V1xD},
   {"arm1020t",         FPU_ARCH_VFP_V1},
   {"arm1020e",         FPU_ARCH_VFP_V2},
+  {"arm1136jfs",       FPU_ARCH_VFP_V2},
   {NULL, 0}
 };
 
index dfb5f8653d73d1e31eafcea8057b7020c768a7cf..1e010bfb701edccfe197b2003e35ae1f66d4e2b2 100644 (file)
@@ -90,6 +90,8 @@ recognized:
 @code{arm1020},
 @code{arm1020t},
 @code{arm1020e}, 
+@code{arm1136js},
+@code{arm1136jfs},
 @code{ep9312} (ARM920 with Cirrus Maverick coprocessor),
 @code{i80200} (Intel XScale processor)
 @code{iwmmxt} (Intel(r) XScale processor with Wireless MMX(tm) technology coprocessor)
@@ -128,7 +130,8 @@ names are recognized:
 @code{armv5t},
 @code{armv5txm},
 @code{armv5te},
-@code{armv5texp}
+@code{armv5texp},
+@code{armv6},
 @code{iwmmxt}
 and
 @code{xscale}.
@@ -161,9 +164,10 @@ The following format options are recognized:
 @code{vfp10-r0},
 @code{vfp9},
 @code{vfpxd},
-@code{arm1020t}
+@code{arm1020t},
+@code{arm1020e},
 and
-@code{arm1020e}.
+@code{arm1136jfs}.
 
 In addition to determining which instructions are assembled, this option
 also affects the way in which the @code{.double} assembler directive behaves
index 84052ea99980d43bfc5e4d307abdfd9751dae76b..274770dc651160755d86f325b580ecbaab8aba8d 100644 (file)
@@ -1,3 +1,13 @@
+2003-12-05  Ricardo Anguiano <anguiano@codesourcery.com>
+           Mark Mitchell  <mark@codesourcery.com>
+           Richard Earnshaw  <rearnsha@arm.com>
+
+       * gas/arm/arm.exp: Add archv6 and thumbv6.
+       * gas/arm/archv6.d: New file.
+       * gas/arm/archv6.s: Likewise.
+       * gas/arm/thumbv6.d: Likewise.
+       * gas/arm/thumbv6.s: Likewise.
+
 2003-12-06  Christian Groessler  <chris@groessler.org>
 
        * gas/z8k/ctrl-names.d: New file.
diff --git a/gas/testsuite/gas/arm/archv6.d b/gas/testsuite/gas/arm/archv6.d
new file mode 100644 (file)
index 0000000..73de75d
--- /dev/null
@@ -0,0 +1,219 @@
+#name: ARM V6 instructions
+#as: -march=armv6
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <[^>]*> f102000f ?       cps     #15
+0+004 <[^>]*> f10c00c0 ?       cpsid   if
+0+008 <[^>]*> f10800c0 ?       cpsie   if
+0+00c <[^>]*> e1942f9f ?       ldrex   r2, \[r4\]
+0+010 <[^>]*> 11984f9f ?       ldrexne r4, \[r8\]
+0+014 <[^>]*> fc4570c3 ?       mcrr2   0, 12, r7, r5, cr3
+0+018 <[^>]*> fc5570c3 ?       mrrc2   0, 12, r7, r5, cr3
+0+01c <[^>]*> e6852018 ?       pkhbt   r2, r5, r8
+0+020 <[^>]*> e6852198 ?       pkhbt   r2, r5, r8, LSL #3
+0+024 <[^>]*> e6852198 ?       pkhbt   r2, r5, r8, LSL #3
+0+028 <[^>]*> 06852198 ?       pkhbteq r2, r5, r8, LSL #3
+0+02c <[^>]*> e6882015 ?       pkhbt   r2, r8, r5
+0+030 <[^>]*> e68521d8 ?       pkhtb   r2, r5, r8, ASR #3
+0+034 <[^>]*> e68521d8 ?       pkhtb   r2, r5, r8, ASR #3
+0+038 <[^>]*> 068521d8 ?       pkhtbeq r2, r5, r8, ASR #3
+0+03c <[^>]*> e6242f17 ?       qadd16  r2, r4, r7
+0+040 <[^>]*> 16242f17 ?       qadd16ne        r2, r4, r7
+0+044 <[^>]*> e6242f97 ?       qadd8   r2, r4, r7
+0+048 <[^>]*> 16242f97 ?       qadd8ne r2, r4, r7
+0+04c <[^>]*> e6242f37 ?       qaddsubx        r2, r4, r7
+0+050 <[^>]*> 16242f37 ?       qaddsubxne      r2, r4, r7
+0+054 <[^>]*> e6242f77 ?       qsub16  r2, r4, r7
+0+058 <[^>]*> 16242f77 ?       qsub16ne        r2, r4, r7
+0+05c <[^>]*> e6242ff7 ?       qsub8   r2, r4, r7
+0+060 <[^>]*> 16242ff7 ?       qsub8ne r2, r4, r7
+0+064 <[^>]*> e6242f57 ?       qsubaddx        r2, r4, r7
+0+068 <[^>]*> e6242f57 ?       qsubaddx        r2, r4, r7
+0+06c <[^>]*> e6bf2f34 ?       rev     r2, r4
+0+070 <[^>]*> e6bf2fb4 ?       rev16   r2, r4
+0+074 <[^>]*> 16bf3fb5 ?       rev16ne r3, r5
+0+078 <[^>]*> 16bf3f35 ?       revne   r3, r5
+0+07c <[^>]*> e6ff2fb4 ?       revsh   r2, r4
+0+080 <[^>]*> 16ff3fb5 ?       revshne r3, r5
+0+084 <[^>]*> f8120a00 ?       rfeda   r2
+0+088 <[^>]*> f9320a00 ?       rfedb   r2!
+0+08c <[^>]*> f8120a00 ?       rfeda   r2
+0+090 <[^>]*> f9320a00 ?       rfedb   r2!
+0+094 <[^>]*> f9b20a00 ?       rfeib   r2!
+0+098 <[^>]*> f8920a00 ?       rfeia   r2
+0+09c <[^>]*> f8920a00 ?       rfeia   r2
+0+0a0 <[^>]*> f9b20a00 ?       rfeib   r2!
+0+0a4 <[^>]*> e6142f17 ?       sadd16  r2, r4, r7
+0+0a8 <[^>]*> 16142f17 ?       sadd16ne        r2, r4, r7
+0+0ac <[^>]*> e6b42075 ?       sxtah   r2, r4, r5
+0+0b0 <[^>]*> e6b42475 ?       sxtah   r2, r4, r5, ROR #8
+0+0b4 <[^>]*> 16b42075 ?       sxtahne r2, r4, r5
+0+0b8 <[^>]*> 16b42475 ?       sxtahne r2, r4, r5, ROR #8
+0+0bc <[^>]*> e6142f97 ?       sadd8   r2, r4, r7
+0+0c0 <[^>]*> 16142f97 ?       sadd8ne r2, r4, r7
+0+0c4 <[^>]*> e6842075 ?       sxtab16 r2, r4, r5
+0+0c8 <[^>]*> e6842475 ?       sxtab16 r2, r4, r5, ROR #8
+0+0cc <[^>]*> 16842075 ?       sxtab16ne       r2, r4, r5
+0+0d0 <[^>]*> 16842475 ?       sxtab16ne       r2, r4, r5, ROR #8
+0+0d4 <[^>]*> e6a42075 ?       sxtab   r2, r4, r5
+0+0d8 <[^>]*> e6a42475 ?       sxtab   r2, r4, r5, ROR #8
+0+0dc <[^>]*> 16a42075 ?       sxtabne r2, r4, r5
+0+0e0 <[^>]*> 16a42475 ?       sxtabne r2, r4, r5, ROR #8
+0+0e4 <[^>]*> e6142f37 ?       saddaddx        r2, r4, r7
+0+0e8 <[^>]*> 16142f37 ?       saddaddxne      r2, r4, r7
+0+0ec <[^>]*> e68210b3 ?       sel     r1, r2, r3
+0+0f0 <[^>]*> 168210b3 ?       selne   r1, r2, r3
+0+0f4 <[^>]*> f1010200 ?       setend  be
+0+0f8 <[^>]*> f1010000 ?       setend  le
+0+0fc <[^>]*> e6342f17 ?       shadd16 r2, r4, r7
+0+100 <[^>]*> 16342f17 ?       shadd16ne       r2, r4, r7
+0+104 <[^>]*> e6342f97 ?       shadd8  r2, r4, r7
+0+108 <[^>]*> 16342f97 ?       shadd8ne        r2, r4, r7
+0+10c <[^>]*> e6342f37 ?       shaddsubx       r2, r4, r7
+0+110 <[^>]*> 16342f37 ?       shaddsubxne     r2, r4, r7
+0+114 <[^>]*> e6342f77 ?       shsub16 r2, r4, r7
+0+118 <[^>]*> 16342f77 ?       shsub16ne       r2, r4, r7
+0+11c <[^>]*> e6342ff7 ?       shsub8  r2, r4, r7
+0+120 <[^>]*> 16342ff7 ?       shsub8ne        r2, r4, r7
+0+124 <[^>]*> e6342f57 ?       shsubaddx       r2, r4, r7
+0+128 <[^>]*> 16342f57 ?       shsubaddxne     r2, r4, r7
+0+12c <[^>]*> e7014312 ?       smlad   r1, r2, r3, r4
+0+130 <[^>]*> d7014312 ?       smladle r1, r2, r3, r4
+0+134 <[^>]*> e7014332 ?       smladx  r1, r2, r3, r4
+0+138 <[^>]*> d7014332 ?       smladxle        r1, r2, r3, r4
+0+13c <[^>]*> e7421413 ?       smlald  r1, r2, r3, r4
+0+140 <[^>]*> d7421413 ?       smlaldle        r1, r2, r3, r4
+0+144 <[^>]*> e7421433 ?       smlaldx r1, r2, r3, r4
+0+148 <[^>]*> d7421433 ?       smlaldxle       r1, r2, r3, r4
+0+14c <[^>]*> e7014352 ?       smlsd   r1, r2, r3, r4
+0+150 <[^>]*> d7014352 ?       smlsdle r1, r2, r3, r4
+0+154 <[^>]*> e7014372 ?       smlsdx  r1, r2, r3, r4
+0+158 <[^>]*> d7014372 ?       smlsdxle        r1, r2, r3, r4
+0+15c <[^>]*> e7421453 ?       smlsld  r1, r2, r3, r4
+0+160 <[^>]*> d7421453 ?       smlsldle        r1, r2, r3, r4
+0+164 <[^>]*> e7421473 ?       smlsldx r1, r2, r3, r4
+0+168 <[^>]*> d7421473 ?       smlsldxle       r1, r2, r3, r4
+0+16c <[^>]*> e7514312 ?       smmla   r1, r2, r3, r4
+0+170 <[^>]*> d7514312 ?       smmlale r1, r2, r3, r4
+0+174 <[^>]*> e7514332 ?       smmlar  r1, r2, r3, r4
+0+178 <[^>]*> d7514332 ?       smmlarle        r1, r2, r3, r4
+0+17c <[^>]*> e75143d2 ?       smmls   r1, r2, r3, r4
+0+180 <[^>]*> d75143d2 ?       smmlsle r1, r2, r3, r4
+0+184 <[^>]*> e75143f2 ?       smmlsr  r1, r2, r3, r4
+0+188 <[^>]*> d75143f2 ?       smmlsrle        r1, r2, r3, r4
+0+18c <[^>]*> e751f312 ?       smmul   r1, r2, r3
+0+190 <[^>]*> d751f312 ?       smmulle r1, r2, r3
+0+194 <[^>]*> e751f332 ?       smmulr  r1, r2, r3
+0+198 <[^>]*> d751f332 ?       smmulrle        r1, r2, r3
+0+19c <[^>]*> e701f312 ?       smuad   r1, r2, r3
+0+1a0 <[^>]*> d701f312 ?       smuadle r1, r2, r3
+0+1a4 <[^>]*> e701f332 ?       smuadx  r1, r2, r3
+0+1a8 <[^>]*> d701f332 ?       smuadxle        r1, r2, r3
+0+1ac <[^>]*> e701f352 ?       smusd   r1, r2, r3
+0+1b0 <[^>]*> d701f352 ?       smusdle r1, r2, r3
+0+1b4 <[^>]*> e701f372 ?       smusdx  r1, r2, r3
+0+1b8 <[^>]*> d701f372 ?       smusdxle        r1, r2, r3
+0+1bc <[^>]*> f8cd0510 ?       srsia   #16
+0+1c0 <[^>]*> f9ed0510 ?       srsib   #16!
+0+1c4 <[^>]*> e6a01012 ?       ssat    r1, #1, r2
+0+1c8 <[^>]*> e6a01152 ?       ssat    r1, #1, r2, ASR #2
+0+1cc <[^>]*> e6a01112 ?       ssat    r1, #1, r2, LSL #2
+0+1d0 <[^>]*> e6a01f31 ?       ssat16  r1, #1, r1
+0+1d4 <[^>]*> d6a01f31 ?       ssat16le        r1, #1, r1
+0+1d8 <[^>]*> e6142f77 ?       ssub16  r2, r4, r7
+0+1dc <[^>]*> 16142f77 ?       ssub16ne        r2, r4, r7
+0+1e0 <[^>]*> e6142ff7 ?       ssub8   r2, r4, r7
+0+1e4 <[^>]*> 16142ff7 ?       ssub8ne r2, r4, r7
+0+1e8 <[^>]*> e6142f57 ?       ssubaddx        r2, r4, r7
+0+1ec <[^>]*> 16142f57 ?       ssubaddxne      r2, r4, r7
+0+1f0 <[^>]*> e1831f92 ?       strex   r1, r2, \[r3\]
+0+1f4 <[^>]*> 11831f92 ?       strexne r1, r2, \[r3\]
+0+1f8 <[^>]*> e6bf2075 ?       sxth r2,r5
+0+1fc <[^>]*> e6bf2475 ?       sxth r2,r5, ROR #8
+0+200 <[^>]*> 16bf2075 ?       sxthne r2,r5
+0+204 <[^>]*> 16bf2475 ?       sxthne r2,r5, ROR #8
+0+208 <[^>]*> e68f2075 ?       sxtb16 r2,r5
+0+20c <[^>]*> e68f2475 ?       sxtb16 r2,r5, ROR #8
+0+210 <[^>]*> 168f2075 ?       sxtb16ne r2,r5
+0+214 <[^>]*> 168f2475 ?       sxtb16ne r2,r5, ROR #8
+0+218 <[^>]*> e6af2075 ?       sxtb r2,r5
+0+21c <[^>]*> e6af2475 ?       sxtb r2,r5, ROR #8
+0+220 <[^>]*> 16af2075 ?       sxtbne r2,r5
+0+224 <[^>]*> 16af2475 ?       sxtbne r2,r5, ROR #8
+0+228 <[^>]*> e6542f17 ?       uadd16  r2, r4, r7
+0+22c <[^>]*> 16542f17 ?       uadd16ne        r2, r4, r7
+0+230 <[^>]*> e6f32075 ?       uxtah   r2, r3, r5
+0+234 <[^>]*> e6f32475 ?       uxtah   r2, r3, r5, ROR #8
+0+238 <[^>]*> 16f32075 ?       uxtahne r2, r3, r5
+0+23c <[^>]*> 16f32475 ?       uxtahne r2, r3, r5, ROR #8
+0+240 <[^>]*> e6542f97 ?       uadd8   r2, r4, r7
+0+244 <[^>]*> 16542f97 ?       uadd8ne r2, r4, r7
+0+248 <[^>]*> e6c32075 ?       uxtab16 r2, r3, r5
+0+24c <[^>]*> e6c32475 ?       uxtab16 r2, r3, r5, ROR #8
+0+250 <[^>]*> 16c32075 ?       uxtab16ne       r2, r3, r5
+0+254 <[^>]*> 16c32475 ?       uxtab16ne       r2, r3, r5, ROR #8
+0+258 <[^>]*> e6e32075 ?       uxtab   r2, r3, r5
+0+25c <[^>]*> e6e32475 ?       uxtab   r2, r3, r5, ROR #8
+0+260 <[^>]*> 16e32075 ?       uxtabne r2, r3, r5
+0+264 <[^>]*> 16e32475 ?       uxtabne r2, r3, r5, ROR #8
+0+268 <[^>]*> e6542f37 ?       uaddsubx        r2, r4, r7
+0+26c <[^>]*> 16542f37 ?       uaddsubxne      r2, r4, r7
+0+270 <[^>]*> e6742f17 ?       uhadd16 r2, r4, r7
+0+274 <[^>]*> 16742f17 ?       uhadd16ne       r2, r4, r7
+0+278 <[^>]*> e6742f97 ?       uhadd8  r2, r4, r7
+0+27c <[^>]*> 16742f97 ?       uhadd8ne        r2, r4, r7
+0+280 <[^>]*> e6742f37 ?       uhaddsubx       r2, r4, r7
+0+284 <[^>]*> 16742f37 ?       uhaddsubxne     r2, r4, r7
+0+288 <[^>]*> e6742f77 ?       uhsub16 r2, r4, r7
+0+28c <[^>]*> 16742f77 ?       uhsub16ne       r2, r4, r7
+0+290 <[^>]*> e6742ff7 ?       uhsub8  r2, r4, r7
+0+294 <[^>]*> 16742ff7 ?       uhsub8ne        r2, r4, r7
+0+298 <[^>]*> e6742f57 ?       uhsubaddx       r2, r4, r7
+0+29c <[^>]*> 16742f57 ?       uhsubaddxne     r2, r4, r7
+0+2a0 <[^>]*> e0421493 ?       umaal   r1, r2, r3, r4
+0+2a4 <[^>]*> d0421493 ?       umaalle r1, r2, r3, r4
+0+2a8 <[^>]*> e6642f17 ?       uqadd16 r2, r4, r7
+0+2ac <[^>]*> 16642f17 ?       uqadd16ne       r2, r4, r7
+0+2b0 <[^>]*> e6642f97 ?       uqadd8  r2, r4, r7
+0+2b4 <[^>]*> 16642f97 ?       uqadd8ne        r2, r4, r7
+0+2b8 <[^>]*> e6642f37 ?       uqaddsubx       r2, r4, r7
+0+2bc <[^>]*> 16642f37 ?       uqaddsubxne     r2, r4, r7
+0+2c0 <[^>]*> e6642f77 ?       uqsub16 r2, r4, r7
+0+2c4 <[^>]*> 16642f77 ?       uqsub16ne       r2, r4, r7
+0+2c8 <[^>]*> e6642ff7 ?       uqsub8  r2, r4, r7
+0+2cc <[^>]*> 16642ff7 ?       uqsub8ne        r2, r4, r7
+0+2d0 <[^>]*> e6642f57 ?       uqsubaddx       r2, r4, r7
+0+2d4 <[^>]*> 16642f57 ?       uqsubaddxne     r2, r4, r7
+0+2d8 <[^>]*> e781f312 ?       usad8   r1, r2, r3
+0+2dc <[^>]*> 1781f312 ?       usad8ne r1, r2, r3
+0+2e0 <[^>]*> e7814312 ?       usada8  r1, r2, r3, r4
+0+2e4 <[^>]*> 17814312 ?       usada8ne        r1, r2, r3, r4
+0+2e8 <[^>]*> e6ef1012 ?       usat    r1, #15, r2
+0+2ec <[^>]*> e6ef1252 ?       usat    r1, #15, r2, ASR #4
+0+2f0 <[^>]*> e6ef1212 ?       usat    r1, #15, r2, LSL #4
+0+2f4 <[^>]*> e6ef1f32 ?       usat16  r1, #15, r2
+0+2f8 <[^>]*> d6ef1f32 ?       usat16le        r1, #15, r2
+0+2fc <[^>]*> d6ef1012 ?       usatle  r1, #15, r2
+0+300 <[^>]*> d6ef1252 ?       usatle  r1, #15, r2, ASR #4
+0+304 <[^>]*> d6ef1212 ?       usatle  r1, #15, r2, LSL #4
+0+308 <[^>]*> e6542f77 ?       usub16  r2, r4, r7
+0+30c <[^>]*> 16542f77 ?       usub16ne        r2, r4, r7
+0+310 <[^>]*> e6542ff7 ?       usub8   r2, r4, r7
+0+314 <[^>]*> 16542ff7 ?       usub8ne r2, r4, r7
+0+318 <[^>]*> e6542f57 ?       usubaddx        r2, r4, r7
+0+31c <[^>]*> 16542f57 ?       usubaddxne      r2, r4, r7
+0+320 <[^>]*> e6ff2075 ?       uxth r2,r5
+0+324 <[^>]*> e6ff2475 ?       uxth r2,r5, ROR #8
+0+328 <[^>]*> 16ff2075 ?       uxthne r2,r5
+0+32c <[^>]*> 16ff2475 ?       uxthne r2,r5, ROR #8
+0+330 <[^>]*> e6cf2075 ?       uxtb16 r2,r5
+0+334 <[^>]*> e6cf2475 ?       uxtb16 r2,r5, ROR #8
+0+338 <[^>]*> 16cf2075 ?       uxtb16ne r2,r5
+0+33c <[^>]*> 16cf2475 ?       uxtb16ne r2,r5, ROR #8
+0+340 <[^>]*> e6ef2075 ?       uxtb r2,r5
+0+344 <[^>]*> e6ef2475 ?       uxtb r2,r5, ROR #8
+0+348 <[^>]*> 16ef2075 ?       uxtbne r2,r5
+0+34c <[^>]*> 16ef2475 ?       uxtbne r2,r5, ROR #8
diff --git a/gas/testsuite/gas/arm/archv6.s b/gas/testsuite/gas/arm/archv6.s
new file mode 100644 (file)
index 0000000..50378b7
--- /dev/null
@@ -0,0 +1,216 @@
+.text
+.align 0
+
+label:
+       cps #15
+       cpsid if
+       cpsie if
+       ldrex r2, [r4]
+       ldrexne r4, [r8]
+       mcrr2 p0, 12, r7, r5, c3
+       mrrc2 p0, 12, r7, r5, c3
+       pkhbt   r2, r5, r8
+       pkhbt   r2, r5, r8, LSL #3
+       pkhbtal r2, r5, r8, LSL #3
+       pkhbteq r2, r5, r8, LSL #3      
+       pkhtb   r2, r5, r8      @ Equivalent to pkhbt r2, r8, r5.
+       pkhtb   r2, r5, r8, ASR #3
+       pkhtbal r2, r5, r8, ASR #3
+       pkhtbeq r2, r5, r8, ASR #3
+       qadd16  r2, r4, r7
+       qadd16ne r2, r4, r7     
+       qadd8   r2, r4, r7
+       qadd8ne r2, r4, r7
+       qaddsubx        r2, r4, r7
+       qaddsubxne      r2, r4, r7
+       qsub16   r2, r4, r7
+       qsub16ne r2, r4, r7
+       qsub8    r2, r4, r7
+       qsub8ne r2, r4, r7
+       qsubaddx         r2, r4, r7
+       qsubaddx r2, r4, r7
+       rev     r2, r4
+       rev16   r2, r4
+       rev16ne   r3, r5
+       revne   r3, r5
+       revsh   r2, r4
+       revshne   r3, r5
+       rfeda   r2
+       rfedb   r2!
+       rfeea   r2
+       rfeed   r2!
+       rfefa   r2!
+       rfefd   r2
+       rfeia   r2
+       rfeib   r2!
+       sadd16   r2, r4, r7
+       sadd16ne r2, r4, r7
+       sxtah r2, r4, r5
+       sxtah r2, r4, r5, ROR #8
+       sxtahne r2, r4, r5
+       sxtahne r2, r4, r5, ROR #8
+       sadd8    r2, r4, r7
+       sadd8ne r2, r4, r7
+       sxtab16 r2, r4, r5
+       sxtab16 r2, r4, r5, ROR #8
+       sxtab16ne r2, r4, r5
+       sxtab16ne r2, r4, r5, ROR #8
+       sxtab r2, r4, r5
+       sxtab r2, r4, r5, ROR #8
+       sxtabne r2, r4, r5
+       sxtabne r2, r4, r5, ROR #8
+       saddsubx         r2, r4, r7
+       saddsubxne r2, r4, r7
+       sel r1, r2, r3
+       selne r1, r2, r3
+       setend be
+       setend le
+       shadd16  r2, r4, r7
+       shadd16ne r2, r4, r7
+       shadd8   r2, r4, r7
+       shadd8ne r2, r4, r7
+       shaddsubx        r2, r4, r7
+       shaddsubxne r2, r4, r7
+       shsub16  r2, r4, r7
+       shsub16ne r2, r4, r7
+       shsub8   r2, r4, r7
+       shsub8ne r2, r4, r7
+       shsubaddx        r2, r4, r7
+       shsubaddxne r2, r4, r7
+       smlad r1,r2,r3,r4
+       smladle r1,r2,r3,r4
+       smladx r1,r2,r3,r4
+       smladxle r1,r2,r3,r4
+       smlald r1,r2,r3,r4
+       smlaldle r1,r2,r3,r4
+       smlaldx r1,r2,r3,r4
+       smlaldxle r1,r2,r3,r4
+       smlsd r1,r2,r3,r4
+       smlsdle r1,r2,r3,r4
+       smlsdx r1,r2,r3,r4
+       smlsdxle r1,r2,r3,r4    
+       smlsld r1,r2,r3,r4      
+       smlsldle r1,r2,r3,r4
+       smlsldx r1,r2,r3,r4
+       smlsldxle r1,r2,r3,r4   
+       smmla r1,r2,r3,r4       
+       smmlale r1,r2,r3,r4
+       smmlar r1,r2,r3,r4
+       smmlarle r1,r2,r3,r4    
+       smmls r1,r2,r3,r4       
+       smmlsle r1,r2,r3,r4
+       smmlsr r1,r2,r3,r4
+       smmlsrle r1,r2,r3,r4    
+       smmul r1,r2,r3
+       smmulle r1,r2,r3
+       smmulr r1,r2,r3
+       smmulrle r1,r2,r3
+       smuad r1,r2,r3
+       smuadle r1,r2,r3
+       smuadx r1,r2,r3
+       smuadxle r1,r2,r3
+       smusd r1,r2,r3
+       smusdle r1,r2,r3
+       smusdx r1,r2,r3
+       smusdxle r1,r2,r3
+       srsia #16
+       srsib #16!
+       ssat r1, #1, r2
+       ssat r1, #1, r2, ASR #2
+       ssat r1, #1, r2, LSL #2
+       ssat16 r1, #1, r1
+       ssat16le r1, #1, r1
+       ssub16   r2, r4, r7
+       ssub16ne r2, r4, r7
+       ssub8    r2, r4, r7
+       ssub8ne r2, r4, r7
+       ssubaddx         r2, r4, r7
+       ssubaddxne r2, r4, r7
+       strex r1, r2, [r3]
+       strexne r1, r2, [r3]
+       sxth r2, r5
+       sxth r2, r5, ROR #8
+       sxthne r2, r5
+       sxthne r2, r5, ROR #8
+       sxtb16 r2, r5
+       sxtb16 r2, r5, ROR #8
+       sxtb16ne r2, r5
+       sxtb16ne r2, r5, ROR #8
+       sxtb r2, r5
+       sxtb r2, r5, ROR #8
+       sxtbne r2, r5
+       sxtbne r2, r5, ROR #8
+       uadd16   r2, r4, r7
+       uadd16ne r2, r4, r7
+       uxtah r2, r3, r5
+       uxtah r2, r3, r5, ROR #8
+       uxtahne r2, r3, r5
+       uxtahne r2, r3, r5, ROR #8
+       uadd8    r2, r4, r7
+       uadd8ne r2, r4, r7
+       uxtab16 r2, r3, r5
+       uxtab16 r2, r3, r5, ROR #8
+       uxtab16ne r2, r3, r5
+       uxtab16ne r2, r3, r5, ROR #8
+       uxtab r2, r3, r5
+       uxtab r2, r3, r5, ROR #8
+       uxtabne r2, r3, r5
+       uxtabne r2, r3, r5, ROR #8
+       uaddsubx         r2, r4, r7
+       uaddsubxne r2, r4, r7
+       uhadd16  r2, r4, r7
+       uhadd16ne r2, r4, r7
+       uhadd8   r2, r4, r7
+       uhadd8ne r2, r4, r7
+       uhaddsubx        r2, r4, r7
+       uhaddsubxne r2, r4, r7
+       uhsub16  r2, r4, r7
+       uhsub16ne r2, r4, r7
+       uhsub8   r2, r4, r7
+       uhsub8ne r2, r4, r7
+       uhsubaddx        r2, r4, r7
+       uhsubaddxne r2, r4, r7
+       umaal   r1, r2, r3, r4
+       umaalle r1, r2, r3, r4  
+       uqadd16  r2, r4, r7
+       uqadd16ne r2, r4, r7
+       uqadd8   r2, r4, r7
+       uqadd8ne r2, r4, r7
+       uqaddsubx        r2, r4, r7
+       uqaddsubxne r2, r4, r7
+       uqsub16  r2, r4, r7
+       uqsub16ne r2, r4, r7
+       uqsub8   r2, r4, r7
+       uqsub8ne r2, r4, r7
+       uqsubaddx        r2, r4, r7
+       uqsubaddxne r2, r4, r7
+       usad8 r1, r2, r3
+       usad8ne r1, r2, r3
+       usada8 r1, r2, r3, r4
+       usada8ne r1, r2, r3, r4
+       usat r1, #15, r2
+       usat r1, #15, r2, ASR #4
+       usat r1, #15, r2, LSL #4
+       usat16 r1, #15, r2
+       usat16le r1, #15, r2
+       usatle r1, #15, r2
+       usatle r1, #15, r2, ASR #4
+       usatle r1, #15, r2, LSL #4
+       usub16   r2, r4, r7
+       usub16ne r2, r4, r7
+       usub8    r2, r4, r7
+       usub8ne r2, r4, r7
+       usubaddx         r2, r4, r7
+       usubaddxne r2, r4, r7
+       uxth r2, r5
+       uxth r2, r5, ROR #8
+       uxthne r2, r5
+       uxthne r2, r5, ROR #8
+       uxtb16 r2, r5
+       uxtb16 r2, r5, ROR #8
+       uxtb16ne r2, r5
+       uxtb16ne r2, r5, ROR #8
+       uxtb r2, r5
+       uxtb r2, r5, ROR #8
+       uxtbne r2, r5
+       uxtbne r2, r5, ROR #8
index 3d9685db9bfce7d135365bc50ecce4530b2278ce..05c4f70278e226ea8f553312ffeac88850746068 100644 (file)
@@ -66,6 +66,10 @@ if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then {
 
     run_dump_test "maverick"
     
+    run_dump_test "archv6"
+
+    run_dump_test "thumbv6"
+
     if {[istarget *-*-elf*] || [istarget *-*-linux*]} then {
        run_dump_test "pic"
 
diff --git a/gas/testsuite/gas/arm/thumbv6.d b/gas/testsuite/gas/arm/thumbv6.d
new file mode 100644 (file)
index 0000000..e8f54f5
--- /dev/null
@@ -0,0 +1,19 @@
+#name: THUMB V6 instructions
+#as: -march=armv6 -mthumb
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <[^>]*> b666 *   cpsie   ai
+0+002 <[^>]*> b675 *   cpsid   af
+0+004 <[^>]*> 4623 *   cpy     r3, r4
+0+006 <[^>]*> ba3a *   rev     r2, r7
+0+008 <[^>]*> ba4d *   rev16   r5, r1
+0+00a <[^>]*> baf3 *   revsh   r3, r6
+0+00c <[^>]*> b658 *   setend  be      
+0+00e <[^>]*> b650 *   setend  le      
+0+010 <[^>]*> b208 *   sxth    r0, r1
+0+012 <[^>]*> b251 *   sxtb    r1, r2
+0+014 <[^>]*> b2a3 *   uxth    r3, r4
+0+016 <[^>]*> b2f5 *   uxtb    r5, r6
diff --git a/gas/testsuite/gas/arm/thumbv6.s b/gas/testsuite/gas/arm/thumbv6.s
new file mode 100644 (file)
index 0000000..b02d60c
--- /dev/null
@@ -0,0 +1,17 @@
+.text
+.align 0
+
+.thumb
+label:
+       cpsie  ia
+       cpsid  af
+       cpy    r3, r4
+       rev    r2, r7
+       rev16  r5, r1
+       revsh  r3, r6
+       setend be
+       setend le
+       sxth   r0, r1
+       sxtb   r1, r2
+       uxth   r3, r4
+       uxtb   r5, r6
index 389fb76ef940859d62d65aa45719b602dc8b7f84..1d181fd0b2cf9b7d10e6144686fc035ae473015b 100644 (file)
@@ -1,3 +1,11 @@
+2003-12-05  Ricardo Anguiano <anguiano@codesourcery.com>
+           Mark Mitchell  <mark@codesourcery.com>
+           Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-dis.c (print_arm_insn): Add 'W' macro.
+       * arm-opc.h (arm_opcodes): Add V6 instructions.
+       (thumb_opcodes): Likewise.
+
 2003-12-04  Alan Modra  <amodra@bigpond.net.au>
 
        * openrisc-asm.c: Regenerate.
index d4ba196b85251c0a621b4d6c6d074523c61d7c9e..e918dafa28bba2afe9835ec06138fccad61114cb 100644 (file)
@@ -639,6 +639,16 @@ print_insn_arm (pc, info, given)
                                  func (stream, "%d", reg);
                                }
                                break;
+                             case 'W':
+                               {
+                                 long reg;
+                                 
+                                 reg = given >> bitstart;
+                                 reg &= (2 << (bitend - bitstart)) - 1;
+                                 
+                                 func (stream, "%d", reg + 1);
+                               }
+                               break;
                              case 'x':
                                {
                                  long reg;
index 22313cb1a893c2de8a26712d3eb17ffc80f8fd14..b59f2d30fc27f396c9238852681403857308cbfd 100644 (file)
@@ -35,6 +35,7 @@ struct thumb_opcode
    %<bitfield>d                print the bitfield in decimal
    %<bitfield>x                print the bitfield in hex
    %<bitfield>X                print the bitfield as 1 hex digit without leading "0x"
+   %<bitfield>w         print the bitfield plus one in decimal 
    %<bitfield>r                print as an ARM register
    %<bitfield>f                print a floating point constant if >7 else a
                        floating point register
@@ -161,6 +162,132 @@ static const struct arm_opcode arm_opcodes[] =
     {0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
     {0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
 
+    /* ARM V6 instructions. */
+    {0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
+    {0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
+    {0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
+    {0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
+    {0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
+    {0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
+    {0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
+    {0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
+    {0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
+    {0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
+    {0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
+    {0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
+    {0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
+    {0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
+    {0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
+    {0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
+    {0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
+    {0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
+    {0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
+    {0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
+    {0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
+    {0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
+    {0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
+    {0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
+    {0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
+    {0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
+    {0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
+    {0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
+    {0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
+    {0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
+    {0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
+    {0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
+    {0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
+    {0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
+    {0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
+    {0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
+    {0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
+    {0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
+    {0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
+    {0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
+    {0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
+    {0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
+    {0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
+    {0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
+    {0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
+    {0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
+    {0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
+    {0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
+    {0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
+    {0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
+    {0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
+    {0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
+    {0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
+    {0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
+    {0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
+    {0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
+    {0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
+    {0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
+    {0x068000b0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
+    {0xf1010000, 0xfffffc00, "setend\t%9?ble"},
+    {0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
+    {0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
+    {0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+    {0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
+    {0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+    {0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
+    {0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
+    {0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+    {0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+    {0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
+    {0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
+    {0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
+    {0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
+    {0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
+    {0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
+    {0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
+    {0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
+    {0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+    {0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
+    {0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
+    {0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
+    {0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
+
     /* V5 Instructions.  */
     {0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
     {0xfa000000, 0xfe000000, "blx\t%B"},
@@ -459,6 +586,19 @@ static const struct thumb_opcode thumb_opcodes[] =
 {
   /* Thumb instructions.  */
 
+  /* ARM V6.  */
+  {0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
+  {0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
+  {0x4600, 0xffc0, "cpy\t%0-2r, %3-5r"},
+  {0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
+  {0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
+  {0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
+  {0xb650, 0xfff7, "setend\t%3?ble\t"},
+  {0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
+  {0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
+  {0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
+  {0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
+
   /* ARM V5 ISA extends Thumb.  */
   {0xbe00, 0xff00, "bkpt\t%0-7x"},
   {0x4780, 0xff87, "blx\t%3-6r"},      /* note: 4 bit register number.  */