aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-12-06 01:25:29 +0000
committerMark Mitchell <mark@codesourcery.com>2003-12-06 01:25:29 +0000
commit09d92015d3d22d8191e795fe1fc09efdb7488c48 (patch)
tree142992246a6995eb9ba2182fad79bb1061fc7999 /gas
parent32edc941e1fb0863accee2ad345616f0d6af9517 (diff)
downloadgdb-09d92015d3d22d8191e795fe1fc09efdb7488c48.zip
gdb-09d92015d3d22d8191e795fe1fc09efdb7488c48.tar.gz
gdb-09d92015d3d22d8191e795fe1fc09efdb7488c48.tar.bz2
* 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. 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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog52
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/tc-arm.c1179
-rw-r--r--gas/doc/c-arm.texi10
-rw-r--r--gas/testsuite/ChangeLog10
-rw-r--r--gas/testsuite/gas/arm/archv6.d219
-rw-r--r--gas/testsuite/gas/arm/archv6.s216
-rw-r--r--gas/testsuite/gas/arm/arm.exp4
-rw-r--r--gas/testsuite/gas/arm/thumbv6.d19
-rw-r--r--gas/testsuite/gas/arm/thumbv6.s17
10 files changed, 1714 insertions, 14 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8ce8aec..679864c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/NEWS b/gas/NEWS
index 1f704d2..66c15c9 100644
--- 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.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a684350..a08b024 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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")
@@ -4701,6 +4861,951 @@ do_bxj (str)
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)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ inst.instruction |= WRITE_BACK;
+ str++;
+ }
+ end_of_line (str);
+}
+
+/* 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_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)
+ inst.error = BAD_ARGS;
+
+ else if (rd == REG_PC || rm == REG_PC)
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* 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_qadd16 (str)
+ char* str;
+{
+ int rd, rm, rn;
+
+ 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;
+
+ else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* 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_pkh_core (str, shift)
+ char* str;
+ int shift;
+{
+ int rd, rn, rm;
+
+ 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;
+ }
+
+ /* Check for optional shift immediate constant. */
+ if (skip_past_comma (&str) == FAIL)
+ {
+ 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;
+ }
+
+ 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))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+ skip_whitespace (str);
+
+ /* 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;
+ }
+ skip_whitespace (str);
+
+ /* Skip past ']'. */
+ if ((strlen (str) >= 1)
+ && strncmp (str, "]", 1) == 0)
+ str+=1;
+
+ end_of_line (str);
+}
+
+/* ARM V6 change processor state instruction (argument parse)
+ CPS, CPSIE, CSPID . */
+
+static void
+do_cps (str)
+ char * str;
+{
+ do_cps_mode (&str);
+ end_of_line (str);
+}
+
+static void
+do_cpsi (str)
+ char * str;
+{
+ do_cps_flags (&str, /*thumb_p=*/0);
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ skip_whitespace (str);
+ do_cps_mode (&str);
+ }
+ end_of_line (str);
+}
+
+static void
+do_cps_mode (str)
+ char **str;
+{
+ expressionS expr;
+
+ skip_whitespace (*str);
+
+ if (! is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+
+ (*str)++; /* Strip off the immediate signifier. */
+ if (my_get_expression (&expr, str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ /* 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)
+ {
+ inst.error = _("invalid constant");
+ return;
+ }
+
+ inst.instruction |= expr.X_add_number;
+ return;
+}
+
+static void
+do_cps_flags (str, thumb_p)
+ char **str;
+ int thumb_p;
+{
+ 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 }
+ };
+
+ int saw_a_flag = 0;
+
+ skip_whitespace (*str);
+
+ /* Get the a, f and i flags. */
+ while (**str && **str != ',')
+ {
+ 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)++;
+ }
+ if (!saw_a_flag)
+ inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
+}
+
/* THUMB V5 breakpoint instruction (argument parse)
BKPT <immed_8>. */
@@ -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}
};
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
index dfb5f86..1e010bf 100644
--- a/gas/doc/c-arm.texi
+++ b/gas/doc/c-arm.texi
@@ -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
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 84052ea..274770d 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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
index 0000000..73de75d
--- /dev/null
+++ b/gas/testsuite/gas/arm/archv6.d
@@ -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
index 0000000..50378b7
--- /dev/null
+++ b/gas/testsuite/gas/arm/archv6.s
@@ -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
diff --git a/gas/testsuite/gas/arm/arm.exp b/gas/testsuite/gas/arm/arm.exp
index 3d9685d..05c4f70 100644
--- a/gas/testsuite/gas/arm/arm.exp
+++ b/gas/testsuite/gas/arm/arm.exp
@@ -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
index 0000000..e8f54f5
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumbv6.d
@@ -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
index 0000000..b02d60c
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumbv6.s
@@ -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