Make copyright date lists comply with GNU requirement
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
index 22f2697a50bd61ca8229c8f7cfef0a1011817658..19ead2e3b7337f36ab59a1256f261345508ea4b9 100644 (file)
@@ -52,6 +52,7 @@
 #define ARM_HALFWORD    0x00000020     /* allow half word loads */
 #define ARM_THUMB       0x00000040     /* allow BX instruction  */
 #define ARM_EXT_V5     0x00000080      /* allow CLZ etc         */
+#define ARM_EXT_V5E     0x00000200     /* "El Segundo"          */
 
 /* Architectures are the sum of the base and extensions */
 #define ARM_ARCH_V4    (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
@@ -88,7 +89,8 @@
 #define FPU_DEFAULT FPU_ALL
 #endif
 
-#define streq(a,b)  (strcmp (a, b) == 0)
+#define streq(a, b)           (strcmp (a, b) == 0)
+#define skip_whitespace(str)  while (* (str) == ' ') ++ (str)
 
 static unsigned long   cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
 static int target_oabi = 0;
@@ -137,10 +139,11 @@ CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
 symbolS * GOT_symbol;          /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
 #endif
 
-CONST int md_reloc_size = 8;           /* Size of relocation record */
-
-static int thumb_mode = 0;      /* non-zero if assembling thumb instructions */
+CONST int md_reloc_size = 8;   /* Size of relocation record */
 
+static int thumb_mode = 0;      /* 0: assemble for ARM, 1: assemble for Thumb,
+                                  2: assemble for Thumb even though target cpu
+                                  does not support thumb instructions */
 typedef struct arm_fix
 {
   int thumb_mode;
@@ -415,54 +418,52 @@ static CONST struct asm_psr psrs[] =
 
 /* Functions called by parser */
 /* ARM instructions */
-static void do_arit            PARAMS ((char *operands, unsigned long flags));
-static void do_cmp             PARAMS ((char *operands, unsigned long flags));
-static void do_mov             PARAMS ((char *operands, unsigned long flags));
-static void do_ldst            PARAMS ((char *operands, unsigned long flags));
-static void do_ldmstm          PARAMS ((char *operands, unsigned long flags));
-static void do_branch          PARAMS ((char *operands, unsigned long flags));
-static void do_swi             PARAMS ((char *operands, unsigned long flags));
-/* Pseudo Op codes */
-static void do_adr             PARAMS ((char *operands, unsigned long flags));
-static void do_adrl            PARAMS ((char * operands, unsigned long flags));
-static void do_nop             PARAMS ((char *operands, unsigned long flags));
-/* ARM 2 */
-static void do_mul             PARAMS ((char *operands, unsigned long flags));
-static void do_mla             PARAMS ((char *operands, unsigned long flags));
-/* ARM 3 */
-static void do_swap            PARAMS ((char *operands, unsigned long flags));
-/* ARM 6 */
-static void do_msr             PARAMS ((char *operands, unsigned long flags));
-static void do_mrs             PARAMS ((char *operands, unsigned long flags));
-/* ARM 7M */
-static void do_mull            PARAMS ((char *operands, unsigned long flags));
-/* ARM THUMB */
-static void do_bx               PARAMS ((char *operands, unsigned long flags));
-
-/* Coprocessor Instructions */
-static void do_cdp             PARAMS ((char *operands, unsigned long flags));
-static void do_lstc            PARAMS ((char *operands, unsigned long flags));
-static void do_co_reg          PARAMS ((char *operands, unsigned long flags));
-static void do_fp_ctrl         PARAMS ((char *operands, unsigned long flags));
-static void do_fp_ldst         PARAMS ((char *operands, unsigned long flags));
-static void do_fp_ldmstm       PARAMS ((char *operands, unsigned long flags));
-static void do_fp_dyadic       PARAMS ((char *operands, unsigned long flags));
-static void do_fp_monadic      PARAMS ((char *operands, unsigned long flags));
-static void do_fp_cmp          PARAMS ((char *operands, unsigned long flags));
-static void do_fp_from_reg     PARAMS ((char *operands, unsigned long flags));
-static void do_fp_to_reg       PARAMS ((char *operands, unsigned long flags));
-
-static void fix_new_arm                PARAMS ((fragS *frag, int where, 
-                                        short int size, expressionS *exp,
-                                        int pc_rel, int reloc));
-static int arm_reg_parse       PARAMS ((char **ccp));
-static int arm_psr_parse       PARAMS ((char **ccp));
-static void symbol_locate      PARAMS ((symbolS *, CONST char *, segT,
-                                        valueT, fragS *));
+static void do_arit            PARAMS ((char *, unsigned long));
+static void do_cmp             PARAMS ((char *, unsigned long));
+static void do_mov             PARAMS ((char *, unsigned long));
+static void do_ldst            PARAMS ((char *, unsigned long));
+static void do_ldmstm          PARAMS ((char *, unsigned long));
+static void do_branch          PARAMS ((char *, unsigned long));
+static void do_swi             PARAMS ((char *, unsigned long));
+/* Pseudo Op codes */                                        
+static void do_adr             PARAMS ((char *, unsigned long));
+static void do_adrl            PARAMS ((char *, unsigned long));
+static void do_nop             PARAMS ((char *, unsigned long));
+/* ARM 2 */                                                  
+static void do_mul             PARAMS ((char *, unsigned long));
+static void do_mla             PARAMS ((char *, unsigned long));
+/* ARM 3 */                                                  
+static void do_swap            PARAMS ((char *, unsigned long));
+/* ARM 6 */                                                  
+static void do_msr             PARAMS ((char *, unsigned long));
+static void do_mrs             PARAMS ((char *, unsigned long));
+/* ARM 7M */                                                 
+static void do_mull            PARAMS ((char *, unsigned long));
+/* ARM THUMB */                                                      
+static void do_bx               PARAMS ((char *, unsigned long));
+
+                                                             
+/* Coprocessor Instructions */                               
+static void do_cdp             PARAMS ((char *, unsigned long));
+static void do_lstc            PARAMS ((char *, unsigned long));
+static void do_co_reg          PARAMS ((char *, unsigned long));
+static void do_fp_ctrl         PARAMS ((char *, unsigned long));
+static void do_fp_ldst         PARAMS ((char *, unsigned long));
+static void do_fp_ldmstm       PARAMS ((char *, unsigned long));
+static void do_fp_dyadic       PARAMS ((char *, unsigned long));
+static void do_fp_monadic      PARAMS ((char *, unsigned long));
+static void do_fp_cmp          PARAMS ((char *, unsigned long));
+static void do_fp_from_reg     PARAMS ((char *, unsigned long));
+static void do_fp_to_reg       PARAMS ((char *, unsigned long));
+
+static void fix_new_arm                PARAMS ((fragS *, int, short, expressionS *, int, int));
+static int arm_reg_parse       PARAMS ((char **));
+static int arm_psr_parse       PARAMS ((char **));
+static void symbol_locate      PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
 static int add_to_lit_pool     PARAMS ((void));
-static unsigned validate_immediate     PARAMS ((unsigned));
-static unsigned validate_immediate_twopart     PARAMS ((unsigned int, unsigned int *));
-static int validate_offset_imm PARAMS ((int, int));
+static unsigned validate_immediate PARAMS ((unsigned));
+static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
+static int validate_offset_imm PARAMS ((unsigned int, int));
 static void opcode_select      PARAMS ((int));
 static void end_of_line                PARAMS ((char *));
 static int reg_required_here   PARAMS ((char **, int));
@@ -476,8 +477,7 @@ static int cp_address_required_here PARAMS ((char **));
 static int my_get_float_expression     PARAMS ((char **));
 static int skip_past_comma     PARAMS ((char **));
 static int walk_no_bignums     PARAMS ((symbolS *));
-static int negate_data_op      PARAMS ((unsigned long *,
-                                        unsigned long));
+static int negate_data_op      PARAMS ((unsigned long *, unsigned long));
 static int data_op2            PARAMS ((char **));
 static int fp_op2              PARAMS ((char **));
 static long reg_list           PARAMS ((char **));
@@ -507,11 +507,16 @@ static bfd_reloc_code_real_type   arm_parse_reloc PARAMS ((void));
 
 #define LONGEST_INST 5
 
+
 struct asm_opcode 
 {
   CONST char *           template;     /* Basic string to match */
   unsigned long          value;                /* Basic instruction code */
-  CONST char *           comp_suffix;  /* Compulsory suffix that must follow conds */
+
+  /* Compulsory suffix that must follow conds. If "", then the
+     instruction is not conditional and must have no suffix. */
+  CONST char *           comp_suffix;  
+
   CONST struct asm_flg * flags;                /* Bits to toggle if flag 'n' set */
   unsigned long          variants;     /* Which CPU variants this exists for */
   /* Function to call to parse args */
@@ -638,7 +643,7 @@ static CONST struct asm_opcode insns[] =
 #define PRE_INDEX      0x01000000
 #define INDEX_UP       0x00800000
 #define WRITE_BACK     0x00200000
-#define MULTI_SET_PSR  0x00400000
+#define LDM_TYPE_2_OR_3        0x00400000
 
 #define LITERAL_MASK   0xf000f000
 #define COND_MASK      0xf0000000
@@ -664,30 +669,30 @@ static CONST struct asm_opcode insns[] =
 #define OPCODE_BIC     14
 #define OPCODE_MVN     15
 
-static void do_t_nop           PARAMS ((char *operands));
-static void do_t_arit          PARAMS ((char *operands));
-static void do_t_add           PARAMS ((char *operands));
-static void do_t_asr           PARAMS ((char *operands));
-static void do_t_branch9       PARAMS ((char *operands));
-static void do_t_branch12      PARAMS ((char *operands));
-static void do_t_branch23      PARAMS ((char *operands));
-static void do_t_bx            PARAMS ((char *operands));
-static void do_t_compare       PARAMS ((char *operands));
-static void do_t_ldmstm                PARAMS ((char *operands));
-static void do_t_ldr           PARAMS ((char *operands));
-static void do_t_ldrb          PARAMS ((char *operands));
-static void do_t_ldrh          PARAMS ((char *operands));
-static void do_t_lds           PARAMS ((char *operands));
-static void do_t_lsl           PARAMS ((char *operands));
-static void do_t_lsr           PARAMS ((char *operands));
-static void do_t_mov           PARAMS ((char *operands));
-static void do_t_push_pop      PARAMS ((char *operands));
-static void do_t_str           PARAMS ((char *operands));
-static void do_t_strb          PARAMS ((char *operands));
-static void do_t_strh          PARAMS ((char *operands));
-static void do_t_sub           PARAMS ((char *operands));
-static void do_t_swi           PARAMS ((char *operands));
-static void do_t_adr           PARAMS ((char *operands));
+static void do_t_nop           PARAMS ((char *));
+static void do_t_arit          PARAMS ((char *));
+static void do_t_add           PARAMS ((char *));
+static void do_t_asr           PARAMS ((char *));
+static void do_t_branch9       PARAMS ((char *));
+static void do_t_branch12      PARAMS ((char *));
+static void do_t_branch23      PARAMS ((char *));
+static void do_t_bx            PARAMS ((char *));
+static void do_t_compare       PARAMS ((char *));
+static void do_t_ldmstm                PARAMS ((char *));
+static void do_t_ldr           PARAMS ((char *));
+static void do_t_ldrb          PARAMS ((char *));
+static void do_t_ldrh          PARAMS ((char *));
+static void do_t_lds           PARAMS ((char *));
+static void do_t_lsl           PARAMS ((char *));
+static void do_t_lsr           PARAMS ((char *));
+static void do_t_mov           PARAMS ((char *));
+static void do_t_push_pop      PARAMS ((char *));
+static void do_t_str           PARAMS ((char *));
+static void do_t_strb          PARAMS ((char *));
+static void do_t_strh          PARAMS ((char *));
+static void do_t_sub           PARAMS ((char *));
+static void do_t_swi           PARAMS ((char *));
+static void do_t_adr           PARAMS ((char *));
 
 #define T_OPCODE_MUL 0x4340
 #define T_OPCODE_TST 0x4200
@@ -773,68 +778,69 @@ struct thumb_opcode
   CONST char *  template;      /* Basic string to match */
   unsigned long value;         /* Basic instruction code */
   int           size;
+  unsigned long          variants;    /* Which CPU variants this exists for */
   void (*       parms) PARAMS ((char *));  /* Function to call to parse args */
 };
 
 static CONST struct thumb_opcode tinsns[] =
 {
-  {"adc",      0x4140,         2,      do_t_arit},
-  {"add",      0x0000,         2,      do_t_add},
-  {"and",      0x4000,         2,      do_t_arit},
-  {"asr",      0x0000,         2,      do_t_asr},
-  {"b",                T_OPCODE_BRANCH, 2,     do_t_branch12},
-  {"beq",      0xd0fe,         2,      do_t_branch9},
-  {"bne",      0xd1fe,         2,      do_t_branch9},
-  {"bcs",      0xd2fe,         2,      do_t_branch9},
-  {"bhs",      0xd2fe,         2,      do_t_branch9},
-  {"bcc",      0xd3fe,         2,      do_t_branch9},
-  {"bul",      0xd3fe,         2,      do_t_branch9},
-  {"blo",      0xd3fe,         2,      do_t_branch9},
-  {"bmi",      0xd4fe,         2,      do_t_branch9},
-  {"bpl",      0xd5fe,         2,      do_t_branch9},
-  {"bvs",      0xd6fe,         2,      do_t_branch9},
-  {"bvc",      0xd7fe,         2,      do_t_branch9},
-  {"bhi",      0xd8fe,         2,      do_t_branch9},
-  {"bls",      0xd9fe,         2,      do_t_branch9},
-  {"bge",      0xdafe,         2,      do_t_branch9},
-  {"blt",      0xdbfe,         2,      do_t_branch9},
-  {"bgt",      0xdcfe,         2,      do_t_branch9},
-  {"ble",      0xddfe,         2,      do_t_branch9},
-  {"bic",      0x4380,         2,      do_t_arit},
-  {"bl",       0xf7fffffe,     4,      do_t_branch23},
-  {"bx",       0x4700,         2,      do_t_bx},
-  {"cmn",      T_OPCODE_CMN,   2,      do_t_arit},
-  {"cmp",      0x0000,         2,      do_t_compare},
-  {"eor",      0x4040,         2,      do_t_arit},
-  {"ldmia",    0xc800,         2,      do_t_ldmstm},
-  {"ldr",      0x0000,         2,      do_t_ldr},
-  {"ldrb",     0x0000,         2,      do_t_ldrb},
-  {"ldrh",     0x0000,         2,      do_t_ldrh},
-  {"ldrsb",    0x5600,         2,      do_t_lds},
-  {"ldrsh",    0x5e00,         2,      do_t_lds},
-  {"ldsb",     0x5600,         2,      do_t_lds},
-  {"ldsh",     0x5e00,         2,      do_t_lds},
-  {"lsl",      0x0000,         2,      do_t_lsl},
-  {"lsr",      0x0000,         2,      do_t_lsr},
-  {"mov",      0x0000,         2,      do_t_mov},
-  {"mul",      T_OPCODE_MUL,   2,      do_t_arit},
-  {"mvn",      T_OPCODE_MVN,   2,      do_t_arit},
-  {"neg",      T_OPCODE_NEG,   2,      do_t_arit},
-  {"orr",      0x4300,         2,      do_t_arit},
-  {"pop",      0xbc00,         2,      do_t_push_pop},
-  {"push",     0xb400,         2,      do_t_push_pop},
-  {"ror",      0x41c0,         2,      do_t_arit},
-  {"sbc",      0x4180,         2,      do_t_arit},
-  {"stmia",    0xc000,         2,      do_t_ldmstm},
-  {"str",      0x0000,         2,      do_t_str},
-  {"strb",     0x0000,         2,      do_t_strb},
-  {"strh",     0x0000,         2,      do_t_strh},
-  {"swi",      0xdf00,         2,      do_t_swi},
-  {"sub",      0x0000,         2,      do_t_sub},
-  {"tst",      T_OPCODE_TST,   2,      do_t_arit},
+  {"adc",      0x4140,         2,      ARM_THUMB, do_t_arit},
+  {"add",      0x0000,         2,      ARM_THUMB, do_t_add},
+  {"and",      0x4000,         2,      ARM_THUMB, do_t_arit},
+  {"asr",      0x0000,         2,      ARM_THUMB, do_t_asr},
+  {"b",                T_OPCODE_BRANCH, 2,     ARM_THUMB, do_t_branch12},
+  {"beq",      0xd0fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bne",      0xd1fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bcs",      0xd2fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bhs",      0xd2fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bcc",      0xd3fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bul",      0xd3fe,         2,      ARM_THUMB, do_t_branch9},
+  {"blo",      0xd3fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bmi",      0xd4fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bpl",      0xd5fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bvs",      0xd6fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bvc",      0xd7fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bhi",      0xd8fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bls",      0xd9fe,         2,      ARM_THUMB, do_t_branch9},
+  {"bge",      0xdafe,         2,      ARM_THUMB, do_t_branch9},
+  {"blt",      0xdbfe,         2,      ARM_THUMB, do_t_branch9},
+  {"bgt",      0xdcfe,         2,      ARM_THUMB, do_t_branch9},
+  {"ble",      0xddfe,         2,      ARM_THUMB, do_t_branch9},
+  {"bic",      0x4380,         2,      ARM_THUMB, do_t_arit},
+  {"bl",       0xf7fffffe,     4,      ARM_THUMB, do_t_branch23},
+  {"bx",       0x4700,         2,      ARM_THUMB, do_t_bx},
+  {"cmn",      T_OPCODE_CMN,   2,      ARM_THUMB, do_t_arit},
+  {"cmp",      0x0000,         2,      ARM_THUMB, do_t_compare},
+  {"eor",      0x4040,         2,      ARM_THUMB, do_t_arit},
+  {"ldmia",    0xc800,         2,      ARM_THUMB, do_t_ldmstm},
+  {"ldr",      0x0000,         2,      ARM_THUMB, do_t_ldr},
+  {"ldrb",     0x0000,         2,      ARM_THUMB, do_t_ldrb},
+  {"ldrh",     0x0000,         2,      ARM_THUMB, do_t_ldrh},
+  {"ldrsb",    0x5600,         2,      ARM_THUMB, do_t_lds},
+  {"ldrsh",    0x5e00,         2,      ARM_THUMB, do_t_lds},
+  {"ldsb",     0x5600,         2,      ARM_THUMB, do_t_lds},
+  {"ldsh",     0x5e00,         2,      ARM_THUMB, do_t_lds},
+  {"lsl",      0x0000,         2,      ARM_THUMB, do_t_lsl},
+  {"lsr",      0x0000,         2,      ARM_THUMB, do_t_lsr},
+  {"mov",      0x0000,         2,      ARM_THUMB, do_t_mov},
+  {"mul",      T_OPCODE_MUL,   2,      ARM_THUMB, do_t_arit},
+  {"mvn",      T_OPCODE_MVN,   2,      ARM_THUMB, do_t_arit},
+  {"neg",      T_OPCODE_NEG,   2,      ARM_THUMB, do_t_arit},
+  {"orr",      0x4300,         2,      ARM_THUMB, do_t_arit},
+  {"pop",      0xbc00,         2,      ARM_THUMB, do_t_push_pop},
+  {"push",     0xb400,         2,      ARM_THUMB, do_t_push_pop},
+  {"ror",      0x41c0,         2,      ARM_THUMB, do_t_arit},
+  {"sbc",      0x4180,         2,      ARM_THUMB, do_t_arit},
+  {"stmia",    0xc000,         2,      ARM_THUMB, do_t_ldmstm},
+  {"str",      0x0000,         2,      ARM_THUMB, do_t_str},
+  {"strb",     0x0000,         2,      ARM_THUMB, do_t_strb},
+  {"strh",     0x0000,         2,      ARM_THUMB, do_t_strh},
+  {"swi",      0xdf00,         2,      ARM_THUMB, do_t_swi},
+  {"sub",      0x0000,         2,      ARM_THUMB, do_t_sub},
+  {"tst",      T_OPCODE_TST,   2,      ARM_THUMB, do_t_arit},
   /* Pseudo ops: */
-  {"adr",       0x0000,         2,      do_t_adr},
-  {"nop",       0x46C0,         2,      do_t_nop},      /* mov r8,r8 */
+  {"adr",       0x0000,         2,      ARM_THUMB, do_t_adr},
+  {"nop",       0x46C0,         2,      ARM_THUMB, do_t_nop},      /* mov r8,r8 */
 };
 
 struct reg_entry
@@ -878,8 +884,10 @@ static CONST struct reg_entry reg_table[] =
   {NULL, 0}
 };
 
-#define bad_args       _("Bad arguments to instruction");
-#define bad_pc                 _("r15 not allowed here");
+#define BAD_ARGS       _("Bad arguments to instruction")
+#define BAD_PC                 _("r15 not allowed here")
+#define BAD_FLAGS      _("Instruction should not have flags")
+#define BAD_COND       _("Instruction is not conditional")
 
 static struct hash_control * arm_ops_hsh = NULL;
 static struct hash_control * arm_tops_hsh = NULL;
@@ -1130,11 +1138,10 @@ validate_immediate_twopart (val, highpart)
 
 static int
 validate_offset_imm (val, hwse)
-     int val;
+     unsigned int val;
      int hwse;
 {
-  if ((hwse && (val < -255 || val > 255))
-      || (val < -4095 || val > 4095))
+  if ((hwse && val > 255) || val > 4095)
      return FAIL;
   return val;
 }
@@ -1254,7 +1261,7 @@ s_force_thumb (ignore)
      
   if (! thumb_mode)
     {
-      thumb_mode = 1;
+      thumb_mode = 2;
       
       record_alignment (now_seg, 1);
     }
@@ -1359,11 +1366,13 @@ s_thumb_set (equiv)
   
   demand_empty_rest_of_line ();
 
-  /* XXX now we come to the Thumb specific bit of code.  */
+  /* XXX Now we come to the Thumb specific bit of code.  */
   
   THUMB_SET_FUNC (symbolP, 1);
   ARM_SET_THUMB (symbolP, 1);
+#if defined OBJ_ELF || defined OBJ_COFF
   ARM_SET_INTERWORK (symbolP, support_interwork);
+#endif
 }
 
 /* If we change section we must dump the literal pool first.  */
@@ -1374,7 +1383,11 @@ arm_s_text (ignore)
   if (now_seg != text_section)
     s_ltorg (0);
   
+#ifdef OBJ_ELF
+  obj_elf_text (ignore);
+#else
   s_text (ignore);
+#endif
 }
 
 static void
@@ -1389,7 +1402,11 @@ arm_s_data (ignore)
   else if (now_seg != data_section)
     s_ltorg (0);
   
+#ifdef OBJ_ELF
+  obj_elf_data (ignore);
+#else
   s_data (ignore);
+#endif
 }
 
 #ifdef OBJ_ELF
@@ -1477,10 +1494,9 @@ static void
 end_of_line (str)
      char * str;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
-  if (*str != '\0')
+  if (* str != '\0')
     inst.error = _("Garbage following instruction");
 }
 
@@ -1505,8 +1521,10 @@ skip_past_comma (str)
   return comma ? SUCCESS : FAIL;
 }
 
-/* A standard register must be given at this point.  Shift is the place to
-   put it in the instruction. */
+/* A standard register must be given at this point.
+   Shift is the place to put it in inst.instruction.
+   Restores input start point on err.
+   Returns the reg#, or FAIL. */
 
 static int
 reg_required_here (str, shift)
@@ -1528,7 +1546,7 @@ reg_required_here (str, shift)
   *str = start;
   
   /* In the few cases where we might be able to accept something else
-     this error can be overridden */
+     this error can be overridden */
   sprintf (buff, _("Register expected, not '%.100s'"), start);
   inst.error = buff;
 
@@ -1554,7 +1572,7 @@ psr_required_here (str, cpsr, spsr)
     }
 
   /* In the few cases where we might be able to accept something else
-     this error can be overridden */
+     this error can be overridden */
   inst.error = _("<psr(f)> expected");
 
   /* Restore the start point.  */
@@ -1564,12 +1582,11 @@ psr_required_here (str, cpsr, spsr)
 
 static int
 co_proc_number (str)
-     char **str;
+     char ** str;
 {
   int processor, pchar;
 
-  while (**str == ' ')
-    (*str)++;
+  skip_whitespace (* str);
 
   /* The data sheet seems to imply that just a number on its own is valid
      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
@@ -1609,8 +1626,7 @@ cp_opc_expr (str, where, length)
 {
   expressionS expr;
 
-  while (**str == ' ')
-    (*str)++;
+  skip_whitespace (* str);
 
   memset (&expr, '\0', sizeof (expr));
 
@@ -1648,10 +1664,10 @@ cp_reg_required_here (str, where)
     }
 
   /* In the few cases where we might be able to accept something else
-     this error can be overridden */
+     this error can be overridden */
   inst.error = _("Co-processor register expected");
 
-  /* Restore the start point */
+  /* Restore the start point */
   *str = start;
   return FAIL;
 }
@@ -1672,10 +1688,10 @@ fp_reg_required_here (str, where)
     }
 
   /* In the few cases where we might be able to accept something else
-     this error can be overridden */
+     this error can be overridden */
   inst.error = _("Floating point register expected");
 
-  /* Restore the start point */
+  /* Restore the start point */
   *str = start;
   return FAIL;
 }
@@ -1686,8 +1702,7 @@ cp_address_offset (str)
 {
   int offset;
 
-  while (**str == ' ')
-    (*str)++;
+  skip_whitespace (* str);
 
   if (! is_immediate_prefix (**str))
     {
@@ -1742,14 +1757,12 @@ cp_address_required_here (str)
       int reg;
 
       p++;
-      while (*p == ' ')
-       p++;
+      skip_whitespace (p);
 
       if ((reg = reg_required_here (& p, 16)) == FAIL)
        return FAIL;
 
-      while (*p == ' ')
-       p++;
+      skip_whitespace (p);
 
       if (*p == ']')
        {
@@ -1787,8 +1800,7 @@ cp_address_required_here (str)
          if (cp_address_offset (& p) == FAIL)
            return FAIL;
 
-         while (*p == ' ')
-           p++;
+         skip_whitespace (p);
 
          if (*p++ != ']')
            {
@@ -1796,8 +1808,7 @@ cp_address_required_here (str)
              return FAIL;
            }
 
-         while (*p == ' ')
-           p++;
+         skip_whitespace (p);
 
          if (*p == '!')
            {
@@ -1834,8 +1845,8 @@ do_nop (str, flags)
      char * str;
      unsigned long flags;
 {
-  /* Do nothing really */
-  inst.instruction |= flags; /* This is pointless */
+  /* Do nothing really */
+  inst.instruction |= flags; /* This is pointless */
   end_of_line (str);
   return;
 }
@@ -1845,13 +1856,12 @@ do_mrs (str, flags)
      char *str;
      unsigned long flags;
 {
-  /* Only one syntax */
-  while (*str == ' ')
-    str++;
+  /* Only one syntax.  */
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
@@ -1867,7 +1877,7 @@ do_mrs (str, flags)
   return;
 }
 
-/* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
+/* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
 static void
 do_msr (str, flags)
      char * str;
@@ -1875,8 +1885,7 @@ do_msr (str, flags)
 {
   int reg;
 
-  while (*str == ' ')
-    str ++;
+  skip_whitespace (str);
 
   if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS)
     {
@@ -1886,7 +1895,7 @@ do_msr (str, flags)
       if (skip_past_comma (&str) == FAIL
          || (reg = reg_required_here (&str, 0)) == FAIL)
        {
-         inst.error = bad_args;
+         inst.error = BAD_ARGS;
          return;
        }
     }
@@ -1898,13 +1907,13 @@ do_msr (str, flags)
        inst.instruction |= PSR_CONTROL;
       else
        {
-         inst.error = bad_args;
+         inst.error = BAD_ARGS;
          return;
        }
       
       if (skip_past_comma (&str) == FAIL)
        {
-         inst.error = bad_args;
+         inst.error = BAD_ARGS;
          return;
        }
       
@@ -1912,7 +1921,7 @@ do_msr (str, flags)
       
       if ((reg = reg_required_here (& str, 0)) != FAIL)
        ;
-      /* Immediate expression */
+      /* Immediate expression */
       else if (is_immediate_prefix (* str))
        {
          str ++;
@@ -1969,27 +1978,26 @@ do_mull (str, flags)
 {
   int rdlo, rdhi, rm, rs;
 
-  /* only one format "rdlo, rdhi, rm, rs" */
-  while (*str == ' ')
-    str++;
+  /* Only one format "rdlo, rdhi, rm, rs" */
+  skip_whitespace (str);
 
   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (skip_past_comma (&str) == FAIL
       || (rdhi = reg_required_here (&str, 16)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (skip_past_comma (&str) == FAIL
       || (rm = reg_required_here (&str, 0)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
@@ -2000,13 +2008,13 @@ do_mull (str, flags)
   if (skip_past_comma (&str) == FAIL
       || (rs = reg_required_here (&str, 8)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
    
@@ -2022,32 +2030,31 @@ do_mul (str, flags)
 {
   int rd, rm;
   
-  /* only one format "rd, rm, rs" */
-  while (*str == ' ')
-    str++;
+  /* Only one format "rd, rm, rs" */
+  skip_whitespace (str);
 
   if ((rd = reg_required_here (&str, 16)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (rd == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
 
   if (skip_past_comma (&str) == FAIL
       || (rm = reg_required_here (&str, 0)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (rm == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
 
@@ -2057,13 +2064,13 @@ do_mul (str, flags)
   if (skip_past_comma (&str) == FAIL
       || (rm = reg_required_here (&str, 8)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (rm == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
 
@@ -2079,32 +2086,31 @@ do_mla (str, flags)
 {
   int rd, rm;
 
-  /* only one format "rd, rm, rs, rn" */
-  while (*str == ' ')
-    str++;
+  /* Only one format "rd, rm, rs, rn" */
+  skip_whitespace (str);
 
   if ((rd = reg_required_here (&str, 16)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (rd == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
 
   if (skip_past_comma (&str) == FAIL
       || (rm = reg_required_here (&str, 0)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (rm == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
 
@@ -2116,13 +2122,13 @@ do_mla (str, flags)
       || skip_past_comma (&str) == FAIL
       || (rm = reg_required_here (&str, 12)) == FAIL)
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
   if (rd == REG_PC || rm == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
 
@@ -2275,8 +2281,7 @@ decode_shift (str, unrestrict)
   char * p;
   char   c;
     
-  while (**str == ' ')
-    (*str)++;
+  skip_whitespace (* str);
     
   for (p = *str; isalpha (*p); p++)
     ;
@@ -2301,9 +2306,8 @@ decode_shift (str, unrestrict)
          return SUCCESS;
        }
 
-      while (*p == ' ')
-       p++;
-
+      skip_whitespace (p);
+      
       if (unrestrict && reg_required_here (&p, 8) != FAIL)
        {
          inst.instruction |= shft->value | SHIFT_BY_REG;
@@ -2461,16 +2465,14 @@ data_op2 (str)
   int value;
   expressionS expr;
 
-  while (**str == ' ')
-    (*str)++;
+  skip_whitespace (* str);
     
   if (reg_required_here (str, 0) != FAIL)
     {
       if (skip_past_comma (str) == SUCCESS)
-       {
-         /* Shift operation on register */
-         return decode_shift (str, NO_SHIFT_RESTRICT);
-       }
+       /* Shift operation on register.  */
+       return decode_shift (str, NO_SHIFT_RESTRICT);
+
       return SUCCESS;
     }
   else
@@ -2480,6 +2482,7 @@ data_op2 (str)
        {
          (*str)++;
          inst.error = NULL;
+         
          if (my_get_expression (&inst.reloc.exp, str))
            return FAIL;
 
@@ -2549,8 +2552,7 @@ static int
 fp_op2 (str)
      char ** str;
 {
-  while (**str == ' ')
-    (*str)++;
+  skip_whitespace (* str);
 
   if (fp_reg_required_here (str, 0) != FAIL)
     return SUCCESS;
@@ -2562,8 +2564,8 @@ fp_op2 (str)
          int i;
 
          inst.error = NULL;
-         while (**str == ' ')
-           (*str)++;
+
+         skip_whitespace (* str);
 
          /* First try and match exact strings, this is to guarantee that
             some formats will work even for cross assembly */
@@ -2607,8 +2609,7 @@ do_arit (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL
       || skip_past_comma (&str) == FAIL
@@ -2617,7 +2618,7 @@ do_arit (str, flags)
       || data_op2 (&str) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -2634,15 +2635,14 @@ do_adr (str, flags)
   /* This is a pseudo-op of the form "adr rd, label" to be converted
      into a relative address of the form "add rd, pc, #label-.-8" */
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL
       || skip_past_comma (&str) == FAIL
       || my_get_expression (&inst.reloc.exp, &str))
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
   /* Frag hacking will turn this into a sub instruction if the offset turns
@@ -2665,15 +2665,14 @@ do_adrl (str, flags)
        add rd, pc, #low(label-.-8)"
        add rd, rd, #high(label-.-8)"   */
 
-  while (* str == ' ')
-    str ++;
+  skip_whitespace (str);
 
   if (reg_required_here (& str, 12) == FAIL
       || skip_past_comma (& str) == FAIL
       || my_get_expression (& inst.reloc.exp, & str))
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
   
@@ -2695,13 +2694,12 @@ do_cmp (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 16) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -2709,7 +2707,7 @@ do_cmp (str, flags)
       || data_op2 (&str) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -2726,13 +2724,12 @@ do_mov (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -2740,7 +2737,7 @@ do_mov (str, flags)
       || data_op2 (&str) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -2853,13 +2850,12 @@ do_ldst (str, flags)
       flags = 0;
     }
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
     
   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -2874,29 +2870,29 @@ do_ldst (str, flags)
       int reg;
 
       str++;
-      while (*str == ' ')
-       str++;
+
+      skip_whitespace (str);
 
       if ((reg = reg_required_here (&str, 16)) == FAIL)
        return;
 
-      conflict_reg = (((conflict_reg == reg)
-                      && (inst.instruction & LOAD_BIT))
-                     ? 1 : 0);
+      /* Conflicts can occur on stores as well as loads.  */
+      conflict_reg = (conflict_reg == reg);
 
-      while (*str == ' ')
-       str++;
+      skip_whitespace (str);
 
       if (*str == ']')
        {
-         str++;
+         str ++;
+         
          if (skip_past_comma (&str) == SUCCESS)
            {
              /* [Rn],... (post inc) */
              if (ldst_extend (&str, halfword) == FAIL)
                return;
              if (conflict_reg)
-               as_warn (_("destination register same as write-back base\n"));
+               as_warn (_("%s register same as write-back base"),
+                        (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
            }
          else
            {
@@ -2904,13 +2900,13 @@ do_ldst (str, flags)
               if (halfword)
                 inst.instruction |= HWOFFSET_IMM;
 
-              while (*str == ' ')
-               str++;
+              skip_whitespace (str);
 
               if (*str == '!')
                {
                  if (conflict_reg)
-                  as_warn (_("destination register same as write-back base\n"));
+                  as_warn (_("%s register same as write-back base"),
+                           (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
                  str++;
                  inst.instruction |= WRITE_BACK;
                }
@@ -2933,8 +2929,7 @@ do_ldst (str, flags)
          if (ldst_extend (&str, halfword) == FAIL)
            return;
 
-         while (*str == ' ')
-           str++;
+         skip_whitespace (str);
 
          if (*str++ != ']')
            {
@@ -2942,13 +2937,13 @@ do_ldst (str, flags)
              return;
            }
 
-         while (*str == ' ')
-           str++;
+         skip_whitespace (str);
 
          if (*str == '!')
            {
              if (conflict_reg)
-               as_tsktsk (_("destination register same as write-back base\n"));
+               as_warn (_("%s register same as write-back base"),
+                        (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
              str++;
              inst.instruction |= WRITE_BACK;
            }
@@ -2959,8 +2954,7 @@ do_ldst (str, flags)
       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
       str++;
 
-      while (*str == ' ')
-       str++;
+      skip_whitespace (str);
 
       if (my_get_expression (&inst.reloc.exp, &str))
        return;
@@ -3054,8 +3048,7 @@ reg_list (strp)
            {
              int reg;
            
-             while (*str == ' ')
-               str++;
+             skip_whitespace (str);
 
              if ((reg = reg_required_here (& str, -1)) == FAIL)
                return FAIL;
@@ -3093,8 +3086,7 @@ reg_list (strp)
            } while (skip_past_comma (&str) != FAIL
                     || (in_range = 1, *str++ == '-'));
          str--;
-         while (*str == ' ')
-           str++;
+         skip_whitespace (str);
 
          if (*str++ != '}')
            {
@@ -3145,8 +3137,7 @@ reg_list (strp)
            }
        }
 
-      while (*str == ' ')
-       str++;
+      skip_whitespace (str);
 
       if (*str == '|' || *str == '+')
        {
@@ -3167,8 +3158,7 @@ do_ldmstm (str, flags)
   int base_reg;
   long range;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
     return;
@@ -3179,8 +3169,8 @@ do_ldmstm (str, flags)
       return;
     }
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
+
   if (*str == '!')
     {
       flags |= WRITE_BACK;
@@ -3191,14 +3181,14 @@ do_ldmstm (str, flags)
       || (range = reg_list (&str)) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
   if (*str == '^')
     {
       str++;
-      flags |= MULTI_SET_PSR;
+      flags |= LDM_TYPE_2_OR_3;
     }
 
   inst.instruction |= flags | range;
@@ -3211,8 +3201,7 @@ do_swi (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
   
   /* Allow optional leading '#'.  */
   if (is_immediate_prefix (*str))
@@ -3237,8 +3226,7 @@ do_swap (str, flags)
 {
   int reg;
   
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((reg = reg_required_here (&str, 12)) == FAIL)
     return;
@@ -3253,7 +3241,7 @@ do_swap (str, flags)
       || (reg = reg_required_here (&str, 0)) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3266,24 +3254,22 @@ do_swap (str, flags)
   if (skip_past_comma (&str) == FAIL
       || *str++ != '[')
     {
-      inst.error = bad_args;
+      inst.error = BAD_ARGS;
       return;
     }
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((reg = reg_required_here (&str, 16)) == FAIL)
     return;
 
   if (reg == REG_PC)
     {
-      inst.error = bad_pc;
+      inst.error = BAD_PC;
       return;
     }
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (*str++ != ']')
     {
@@ -3349,17 +3335,18 @@ do_bx (str, flags)
 {
   int reg;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((reg = reg_required_here (&str, 0)) == FAIL)
-    return;
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
   if (reg == REG_PC)
-    as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
+    inst.error = BAD_PC;
 
   end_of_line (str);
-  return;
 }
 
 static void
@@ -3369,13 +3356,12 @@ do_cdp (str, flags)
 {
   /* Co-processor data operation.
      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (co_proc_number (&str) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3383,7 +3369,7 @@ do_cdp (str, flags)
       || cp_opc_expr (&str, 20,4) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3391,7 +3377,7 @@ do_cdp (str, flags)
       || cp_reg_required_here (&str, 12) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3399,7 +3385,7 @@ do_cdp (str, flags)
       || cp_reg_required_here (&str, 16) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3407,7 +3393,7 @@ do_cdp (str, flags)
       || cp_reg_required_here (&str, 0) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3416,7 +3402,7 @@ do_cdp (str, flags)
       if (cp_opc_expr (&str, 5, 3) == FAIL)
        {
          if (!inst.error)
-           inst.error = bad_args;
+           inst.error = BAD_ARGS;
          return;
        }
     }
@@ -3433,13 +3419,12 @@ do_lstc (str, flags)
   /* Co-processor register load/store.
      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (co_proc_number (&str) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3447,7 +3432,7 @@ do_lstc (str, flags)
       || cp_reg_required_here (&str, 12) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3455,7 +3440,7 @@ do_lstc (str, flags)
       || cp_address_required_here (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3472,13 +3457,12 @@ do_co_reg (str, flags)
   /* Co-processor register transfer.
      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (co_proc_number (&str) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3486,7 +3470,7 @@ do_co_reg (str, flags)
       || cp_opc_expr (&str, 21, 3) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3494,7 +3478,7 @@ do_co_reg (str, flags)
       || reg_required_here (&str, 12) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3502,7 +3486,7 @@ do_co_reg (str, flags)
       || cp_reg_required_here (&str, 16) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3510,7 +3494,7 @@ do_co_reg (str, flags)
       || cp_reg_required_here (&str, 0) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3519,10 +3503,14 @@ do_co_reg (str, flags)
       if (cp_opc_expr (&str, 5, 3) == FAIL)
        {
          if (!inst.error)
-           inst.error = bad_args;
+           inst.error = BAD_ARGS;
          return;
        }
     }
+  if (flags)
+    {
+      inst.error = BAD_COND;
+    }
 
   end_of_line (str);
   return;
@@ -3536,13 +3524,12 @@ do_fp_ctrl (str, flags)
   /* FP control registers.
      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3555,8 +3542,7 @@ do_fp_ldst (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   switch (inst.suffix)
     {
@@ -3578,7 +3564,7 @@ do_fp_ldst (str, flags)
   if (fp_reg_required_here (&str, 12) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3586,7 +3572,7 @@ do_fp_ldst (str, flags)
       || cp_address_required_here (&str) == FAIL)
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3600,13 +3586,12 @@ do_fp_ldmstm (str, flags)
 {
   int num_regs;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (fp_reg_required_here (&str, 12) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3664,23 +3649,21 @@ do_fp_ldmstm (str, flags)
          || *str != '[')
        {
          if (! inst.error)
-           inst.error = bad_args;
+           inst.error = BAD_ARGS;
          return;
        }
 
       str++;
-      while (*str == ' ')
-       str++;
+      skip_whitespace (str);
 
       if ((reg = reg_required_here (&str, 16)) == FAIL)
        return;
 
-      while (*str == ' ')
-       str++;
+      skip_whitespace (str);
 
       if (*str != ']')
        {
-         inst.error = bad_args;
+         inst.error = BAD_ARGS;
          return;
        }
 
@@ -3728,7 +3711,7 @@ do_fp_ldmstm (str, flags)
           || cp_address_required_here (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3740,8 +3723,7 @@ do_fp_dyadic (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   switch (inst.suffix)
     {
@@ -3760,7 +3742,7 @@ do_fp_dyadic (str, flags)
   if (fp_reg_required_here (&str, 12) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3768,7 +3750,7 @@ do_fp_dyadic (str, flags)
       || fp_reg_required_here (&str, 16) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3776,7 +3758,7 @@ do_fp_dyadic (str, flags)
       || fp_op2 (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3790,8 +3772,7 @@ do_fp_monadic (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   switch (inst.suffix)
     {
@@ -3810,7 +3791,7 @@ do_fp_monadic (str, flags)
   if (fp_reg_required_here (&str, 12) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3818,7 +3799,7 @@ do_fp_monadic (str, flags)
       || fp_op2 (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3832,13 +3813,12 @@ do_fp_cmp (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (fp_reg_required_here (&str, 16) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3846,7 +3826,7 @@ do_fp_cmp (str, flags)
       || fp_op2 (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3860,8 +3840,7 @@ do_fp_from_reg (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   switch (inst.suffix)
     {
@@ -3880,7 +3859,7 @@ do_fp_from_reg (str, flags)
   if (fp_reg_required_here (&str, 16) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3888,7 +3867,7 @@ do_fp_from_reg (str, flags)
       || reg_required_here (&str, 12) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3902,8 +3881,7 @@ do_fp_to_reg (str, flags)
      char *        str;
      unsigned long flags;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL)
     return;
@@ -3912,7 +3890,7 @@ do_fp_to_reg (str, flags)
       || fp_reg_required_here (&str, 0) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -3972,14 +3950,13 @@ thumb_add_sub (str, subtract)
 {
   int Rd, Rs, Rn = FAIL;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -4140,14 +4117,13 @@ thumb_shift (str, shift)
 {
   int Rd, Rs, Rn = FAIL;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -4250,14 +4226,13 @@ thumb_mov_compare (str, move)
 {
   int Rd, Rs = FAIL;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -4340,14 +4315,13 @@ thumb_load_store (str, load_store, size)
 {
   int Rd, Rb, Ro = FAIL;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -4386,8 +4360,7 @@ thumb_load_store (str, load_store, size)
       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
       str++;
 
-      while (*str == ' ')
-       str++;
+      skip_whitespace (str);
 
       if (my_get_expression (& inst.reloc.exp, & str))
        return;
@@ -4551,18 +4524,14 @@ do_t_arit (str)
 {
   int Rd, Rs, Rn;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
-  if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
-    return;
-
-  if (skip_past_comma (&str) == FAIL
+  if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+      || skip_past_comma (&str) == FAIL
       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
     {
-      if (! inst.error)
-       inst.error = bad_args;
-      return;
+       inst.error = BAD_ARGS;
+       return;
     }
 
   if (skip_past_comma (&str) != FAIL)
@@ -4575,7 +4544,7 @@ do_t_arit (str)
          || inst.instruction == T_OPCODE_NEG
          || inst.instruction == T_OPCODE_MVN)
        {
-         inst.error = bad_args;
+         inst.error = BAD_ARGS;
          return;
        }
 
@@ -4644,7 +4613,7 @@ find_real_start (symbolP)
   const char * name = S_GET_NAME (symbolP);
   symbolS *    new_target;
 
-  /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
+  /* This definiton must agree with the one in gcc/config/arm/thumb.c */
 #define STUB_NAME ".real_start_of"
 
   if (name == NULL)
@@ -4677,8 +4646,9 @@ static void
 do_t_branch23 (str)
      char * str;
 {
-  if (my_get_expression (&inst.reloc.exp, &str))
+  if (my_get_expression (& inst.reloc.exp, & str))
     return;
+  
   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
   inst.reloc.pc_rel = 1;
   end_of_line (str);
@@ -4700,8 +4670,7 @@ do_t_bx (str)
 {
   int reg;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
     return;
@@ -4730,8 +4699,7 @@ do_t_ldmstm (str)
   int Rb;
   long range;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
     return;
@@ -4745,7 +4713,7 @@ do_t_ldmstm (str)
       || (range = reg_list (&str)) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -4794,8 +4762,7 @@ do_t_lds (str)
 {
   int Rd, Rb, Ro;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
       || skip_past_comma (&str) == FAIL
@@ -4841,13 +4808,12 @@ do_t_push_pop (str)
 {
   long range;
 
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if ((range = reg_list (&str)) == FAIL)
     {
       if (! inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -4912,8 +4878,7 @@ static void
 do_t_swi (str)
      char * str;
 {
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (my_get_expression (&inst.reloc.exp, &str))
     return;
@@ -4929,15 +4894,14 @@ do_t_adr (str)
 {
   /* This is a pseudo-op of the form "adr rd, label" to be converted
      into a relative address of the form "add rd, pc, #label-.-4" */
-  while (*str == ' ')
-    str++;
+  skip_whitespace (str);
 
   if (reg_required_here (&str, 4) == FAIL  /* Store Rd in temporary location inside instruction.  */
       || skip_past_comma (&str) == FAIL
       || my_get_expression (&inst.reloc.exp, &str))
     {
       if (!inst.error)
-       inst.error = bad_args;
+       inst.error = BAD_ARGS;
       return;
     }
 
@@ -5066,7 +5030,7 @@ md_begin ()
        break;
       }
 
-    /* Catch special cases */
+    /* Catch special cases */
     if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
       {
        if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
@@ -5090,8 +5054,7 @@ md_begin ()
    This knows about the endian-ness of the target machine and does
    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
    2 (short) and 4 (long)  Floating numbers are put out as a series of
-   LITTLENUMS (shorts, here at least)
-   */
+   LITTLENUMS (shorts, here at least).  */
 void
 md_number_to_chars (buf, val, n)
      char * buf;
@@ -5230,7 +5193,7 @@ md_pcrel_from (fixP)
     {
       /* PC relative addressing on the Thumb is slightly odd
         as the bottom two bits of the PC are forced to zero
-        for the calculation */
+        for the calculation */
       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
     }
 
@@ -5244,12 +5207,11 @@ md_section_align (segment, size)
      valueT size;
 {
 #ifdef OBJ_ELF
-  /* Don't align the dwarf2 debug sections */
-  if (!strncmp (segment->name, ".debug", 5))
-    return size;
-#endif
+  return size;
+#else
   /* Round all sects to multiple of 4 */
   return (size + 3) & ~3;
+#endif
 }
 
 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.  Otherwise 
@@ -5385,14 +5347,15 @@ md_apply_fix3 (fixP, val, seg)
          && S_GET_SEGMENT (fixP->fx_addsy) != seg)
        {
          if (target_oabi
-             && fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
+             && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
+               ))
            value = 0;
          else
            value += md_pcrel_from (fixP);
        }
     }
 
-  fixP->fx_addnumber = value;  /* Remember value for emit_reloc */
+  fixP->fx_addnumber = value;  /* Remember value for emit_reloc */
 
   switch (fixP->fx_r_type)
     {
@@ -5406,7 +5369,7 @@ md_apply_fix3 (fixP, val, seg)
          && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
        {
          as_bad_where (fixP->fx_file, fixP->fx_line,
-                       _("invalid constant (%lx) after fixup\n"),
+                       _("invalid constant (%lx) after fixup"),
                        (unsigned long) value);
          break;
        }
@@ -5440,7 +5403,7 @@ md_apply_fix3 (fixP, val, seg)
            else
              {
                as_bad_where (fixP->fx_file, fixP->fx_line,
-                             _("Unable to compute ADRL instructions for PC offset of 0x%x\n"), value);
+                             _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
                break;
              }
 
@@ -5461,13 +5424,16 @@ md_apply_fix3 (fixP, val, seg)
 
     case BFD_RELOC_ARM_OFFSET_IMM:
       sign = value >= 0;
-      if ((value = validate_offset_imm (value, 0)) == FAIL)
+      
+      if (value < 0)
+       value = - value;
+      
+      if (validate_offset_imm (value, 0) == FAIL)
         {
-          as_bad (_("bad immediate value for offset (%ld)"), (long) value);
+         as_bad_where (fixP->fx_file, fixP->fx_line, 
+                        _("bad immediate value for offset (%ld)"), (long) value);
           break;
         }
-      if (value < 0)
-       value = -value;
 
       newval = md_chars_to_number (buf, INSN_SIZE);
       newval &= 0xff7ff000;
@@ -5478,19 +5444,21 @@ md_apply_fix3 (fixP, val, seg)
      case BFD_RELOC_ARM_OFFSET_IMM8:
      case BFD_RELOC_ARM_HWLITERAL:
       sign = value >= 0;
-      if ((value = validate_offset_imm (value, 1)) == FAIL)
+      
+      if (value < 0)
+       value = - value;
+
+      if (validate_offset_imm (value, 1) == FAIL)
         {
           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
            as_bad_where (fixP->fx_file, fixP->fx_line, 
-                       _("invalid literal constant: pool needs to be closer\n"));
+                       _("invalid literal constant: pool needs to be closer"));
           else
-            as_bad (_("bad immediate value for offset (%ld)"), (long) value);
+            as_bad (_("bad immediate value for half-word offset (%ld)"),
+                   (long) value);
           break;
         }
 
-      if (value < 0)
-       value = -value;
-
       newval = md_chars_to_number (buf, INSN_SIZE);
       newval &= 0xff7ff0f0;
       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
@@ -5499,13 +5467,14 @@ md_apply_fix3 (fixP, val, seg)
 
     case BFD_RELOC_ARM_LITERAL:
       sign = value >= 0;
+      
       if (value < 0)
-       value = -value;
+       value = - value;
 
-      if ((value = validate_offset_imm (value, 0)) == FAIL)
+      if (validate_offset_imm (value, 0) == FAIL)
        {
          as_bad_where (fixP->fx_file, fixP->fx_line, 
-                       _("invalid literal constant: pool needs to be closer\n"));
+                       _("invalid literal constant: pool needs to be closer"));
          break;
        }
 
@@ -5577,6 +5546,7 @@ md_apply_fix3 (fixP, val, seg)
       md_number_to_chars (buf, newval, INSN_SIZE);
       break;
 
+
     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
       newval = md_chars_to_number (buf, THUMB_SIZE);
       {
@@ -5619,6 +5589,9 @@ md_apply_fix3 (fixP, val, seg)
         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
         if (diff & 0x400000)
          diff |= ~0x3fffff;
+#ifdef OBJ_ELF
+       value = fixP->fx_offset;
+#endif
         value += diff;
         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
          as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -5717,7 +5690,7 @@ md_apply_fix3 (fixP, val, seg)
 
          if ((value + 2) & ~0x3fe)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("Invalid offset"));
+                         _("Invalid offset, value too big (0x%08X)"), value);
 
           /* Round up, since pc will be rounded down.  */
          newval |= (value + 2) >> 2;
@@ -5726,28 +5699,28 @@ md_apply_fix3 (fixP, val, seg)
        case 9: /* SP load/store */
          if (value & ~0x3fc)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("Invalid offset"));
+                         _("Invalid offset, value too big (0x%08X)"), value);
          newval |= value >> 2;
          break;
 
        case 6: /* Word load/store */
          if (value & ~0x7c)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("Invalid offset"));
+                         _("Invalid offset, value too big (0x%08X)"), value);
          newval |= value << 4; /* 6 - 2 */
          break;
 
        case 7: /* Byte load/store */
          if (value & ~0x1f)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("Invalid offset"));
+                         _("Invalid offset, value too big (0x%08X)"), value);
          newval |= value << 6;
          break;
 
        case 8: /* Halfword load/store */
          if (value & ~0x3e)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("Invalid offset"));
+                         _("Invalid offset, value too big (0x%08X)"), value);
          newval |= value << 5; /* 6 - 1 */
          break;
 
@@ -5856,7 +5829,7 @@ md_apply_fix3 (fixP, val, seg)
     case BFD_RELOC_NONE:
     default:
       as_bad_where (fixP->fx_file, fixP->fx_line,
-                   _("Bad relocation fixup type (%d)\n"), fixP->fx_r_type);
+                   _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
     }
 
   return 1;
@@ -5971,7 +5944,7 @@ tc_gen_reloc (section, fixp)
          case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
          case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
          case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
-         default:                         type = "<unknown>";    break;
+         default:                         type = _("<unknown>"); break;
          }
        as_bad_where (fixp->fx_file, fixp->fx_line,
                      _("Can not represent %s relocation in this object file format (%d)"),
@@ -6029,6 +6002,7 @@ output_inst PARAMS ((void))
     }
 
   to = frag_more (inst.size);
+  
   if (thumb_mode && (inst.size > THUMB_SIZE))
     {
       assert (inst.size == (2 * THUMB_SIZE));
@@ -6077,8 +6051,7 @@ md_assemble (str)
   memset (&inst, '\0', sizeof (inst));
   inst.reloc.type = BFD_RELOC_NONE;
 
-  if (*str == ' ')
-    str++;                     /* Skip leading white space */
+  skip_whitespace (str);
   
   /* Scan up to the end of the op-code, which must end in white space or
      end of string.  */
@@ -6103,6 +6076,13 @@ md_assemble (str)
       
       if (opcode)
        {
+         /* Check that this instruction is supported for this CPU.  */
+         if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
+            {
+               as_bad (_("selected processor does not support this opcode"));
+               return;
+            }
+
          inst.instruction = opcode->value;
          inst.size = opcode->size;
          (*opcode->parms)(p);
@@ -6113,12 +6093,13 @@ md_assemble (str)
   else
     {
       CONST struct asm_opcode * opcode;
+      unsigned long cond_code;
 
       inst.size = INSN_SIZE;
       /* p now points to the end of the opcode, probably white space, but we
         have to break the opcode up in case it contains condionals and flags;
         keep trying with progressively smaller basic instructions until one
-        matches, or we run out of opcode. */
+        matches, or we run out of opcode.  */
       q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
       for (; q != str; q--)
        {
@@ -6132,18 +6113,25 @@ md_assemble (str)
              unsigned long flag_bits = 0;
              char * r;
 
-             /* Check that this instruction is supported for this CPU */
+             /* Check that this instruction is supported for this CPU */
              if ((opcode->variants & cpu_variant) == 0)
                goto try_shorter;
 
              inst.instruction = opcode->value;
-             if (q == p)               /* Just a simple opcode */
+             if (q == p)               /* Just a simple opcode */
                {
-                 if (opcode->comp_suffix != 0)
-                   as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
-                           opcode->comp_suffix);
+                 if (opcode->comp_suffix)
+                   {
+                      if (*opcode->comp_suffix != '\0')
+                        as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
+                            str, opcode->comp_suffix);
+                      else
+                        /* Not a conditional instruction. */
+                        (*opcode->parms)(q, 0);
+                   }
                  else
                    {
+                     /* A conditional instruction with default condition. */
                      inst.instruction |= COND_ALWAYS;
                      (*opcode->parms)(q, 0);
                    }
@@ -6151,7 +6139,7 @@ md_assemble (str)
                  return;
                }
 
-             /* Now check for a conditional */
+             /* Not just a simple opcode.  Check if extra is a conditional. */
              r = q;
              if (p - r >= 2)
                {
@@ -6167,18 +6155,33 @@ md_assemble (str)
                        as_tsktsk (
 _("Warning: Use of the 'nv' conditional is deprecated\n"));
 
-                     inst.instruction |= cond->value;
+                     cond_code = cond->value;
                      r += 2;
                    }
                  else
-                   inst.instruction |= COND_ALWAYS;
+                   cond_code = COND_ALWAYS;
                }
              else
-               inst.instruction |= COND_ALWAYS;
+               cond_code = COND_ALWAYS;
 
-             /* if there is a compulsory suffix, it should come here, before
-                any optional flags. */
-             if (opcode->comp_suffix)
+             /* Apply the conditional, or complain it's not allowed. */
+             if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
+               {
+                  /* Instruction isn't conditional */
+                  if (cond_code != COND_ALWAYS)
+                    {
+                      as_bad (_("Opcode `%s' is unconditional\n"), str);
+                      return;
+                    }
+               }
+             else
+               /* Instruction is conditional: set the condition into it. */
+               inst.instruction |= cond_code;       
+
+
+             /* If there is a compulsory suffix, it should come here, before
+                any optional flags.  */
+             if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
                {
                  CONST char *s = opcode->comp_suffix;
 
@@ -6242,11 +6245,9 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
     }
 
   /* It wasn't an instruction, but it might be a register alias of the form
-     alias .req reg
-     */
+     alias .req reg */
   q = p;
-  while (*q == ' ')
-    q++;
+  skip_whitespace (q);
 
   c = *p;
   *p = '\0';
@@ -6258,8 +6259,7 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
       char * r;
       
       q += 4;
-      while (*q == ' ')
-       q++;
+      skip_whitespace (q);
 
       for (r = q; *r != '\0'; r++)
        if (*r == ' ')
@@ -6279,20 +6279,16 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
          if (reg == FAIL)
            {
              if (regnum != FAIL)
-               {
-                 insert_reg_alias (str, regnum);
-               }
+               insert_reg_alias (str, regnum);
              else
-               {
-                 as_warn (_("register '%s' does not exist\n"), q);
-               }
+               as_warn (_("register '%s' does not exist\n"), q);
            }
          else if (regnum != FAIL)
            {
              if (reg != regnum)
                as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
              
-             /* Do not warn abpout redefinitions to the same alias.  */
+             /* Do not warn about redefinitions to the same alias.  */
            }
          else
            as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
@@ -6322,7 +6318,7 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
  *            -m[arm]8[10]            Arm 8 processors
  *            -m[arm]9[20][tdmi]      Arm 9 processors
  *            -mstrongarm[110[0]]     StrongARM processors
- *            -m[arm]v[2345]         Arm architecures
+ *            -m[arm]v[2345]         Arm architectures
  *            -mall                   All (except the ARM1)
  *    FP variants:
  *            -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
@@ -6411,7 +6407,8 @@ md_parse_option (c, arg)
             }
           else if (streq (str, "thumb-interwork"))
             {
-              cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCH_V4;
+             if ((cpu_variant & ARM_THUMB) == 0)
+               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
 #if defined OBJ_COFF || defined OBJ_ELF
               support_interwork = true;
 #endif
@@ -6533,6 +6530,7 @@ md_parse_option (c, arg)
                case 70:
                case 700:
                case 710:
+               case 720:
                case 7100:
                case 7500:
                  break;
@@ -6589,6 +6587,7 @@ md_parse_option (c, arg)
              else
                goto bad;
              break;
+
              
            case 's':
              if (streq (str, "strongarm")
@@ -6633,13 +6632,13 @@ md_parse_option (c, arg)
                    default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
                    }
                  break;
-                 
+
                case '5':
                  cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
-                 
                  switch (*++str)
                    {
                    case 't': cpu_variant |= ARM_THUMB; break;
+                   case 'e': cpu_variant |= ARM_EXT_V5E; break;
                    case 0:   break;
                    default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
                    }
@@ -6659,9 +6658,11 @@ md_parse_option (c, arg)
        }
       break;
 
+#if defined OBJ_ELF || defined OBJ_COFF
     case 'k':
       pic_code = 1;
       break;
+#endif
       
     default:
       return 0;
@@ -6678,7 +6679,7 @@ md_show_usage (fp)
 _("\
  ARM Specific Assembler Options:\n\
   -m[arm][<processor name>] select processor variant\n\
-  -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
+  -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
   -mthumb                   only allow Thumb instructions\n\
   -mthumb-interwork         mark the assembled code as supporting interworking\n\
   -mall                     allow any instruction\n\
@@ -6788,17 +6789,17 @@ cons_fix_new_arm (frag, where, size, exp)
 }
 
 /* A good place to do this, although this was probably not intended
* for this kind of use.  We need to dump the literal pool before
* references are made to a null symbol pointer.  */
  for this kind of use.  We need to dump the literal pool before
  references are made to a null symbol pointer.  */
 void
 arm_cleanup ()
 {
-  if (current_poolP != NULL)
-    {
-      subseg_set (text_section, 0); /* Put it at the end of text section */
-      s_ltorg (0);
-      listing_prev_line ();
-    }
+  if (current_poolP == NULL)
+    return;
+  
+  subseg_set (text_section, 0); /* Put it at the end of text section.  */
+  s_ltorg (0);
+  listing_prev_line ();
 }
 
 void
@@ -6920,9 +6921,7 @@ arm_canonicalize_symbol_name (name)
 
   if (thumb_mode && (len = strlen (name)) > 5
       && streq (name + len - 5, "/data"))
-    {
-      *(name + len - 5) = 0;
-    }
+    *(name + len - 5) = 0;
 
   return name;
 }
@@ -6965,7 +6964,6 @@ boolean
 arm_fix_adjustable (fixP)
    fixS * fixP;
 {
-
   if (fixP->fx_addsy == NULL)
     return 1;
   
@@ -7017,7 +7015,8 @@ arm_force_relocation (fixp)
 {
   if (   fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
-      || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)    
+      || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
+      || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)    
     return 1;
   
   return 0;
@@ -7044,7 +7043,7 @@ arm_parse_reloc ()
     /* Added support for parsing "var(PLT)" branch instructions */
     /* generated by GCC for PLT relocs */
     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
-    NULL, 0,         BFD_RELOC_UNUSED
+    { NULL, 0,         BFD_RELOC_UNUSED }
 #undef MAP    
   };
 
This page took 0.057876 seconds and 4 git commands to generate.