Replace <sys/dir.h> (and <dirent.h>) with "gdb_dirent.h".
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
index 86e36008fc54ce7da532689a1197bca91a19c710..4c71976c877e1eb0034b94e7bb4fa7483ace18ae 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-arm.c -- Assemble for the ARM
-   Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc.
    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
        Modified by David Taylor (dtaylor@armltd.co.uk)
 
@@ -52,9 +52,8 @@
 #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 */
+/* Architectures are the sum of the base and extensions */
 #define ARM_ARCH_V4    (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
 #define ARM_ARCH_V4T   (ARM_ARCH_V4 | ARM_THUMB)
 #define ARM_ARCH_V5    (ARM_ARCH_V4 | ARM_EXT_V5)
@@ -104,16 +103,16 @@ static boolean            pic_code = false;
 #endif
 
 /* This array holds the chars that always start a comment.  If the
-   pre-processor is disabled, these aren't very useful */
+   pre-processor is disabled, these aren't very useful */
 CONST char comment_chars[] = "@";
 
 /* This array holds the chars that only start a comment at the beginning of
    a line.  If the line seems to have the form '# 123 filename'
-   .line and .file directives will appear in the pre-processed output */
+   .line and .file directives will appear in the pre-processed output */
 /* Note that input_file.c hand checks for '#' at the beginning of the
    first line of the input file.  This is because the compiler outputs
-   #NO_APP at the beginning of its output. */
-/* Also note that comments like this one will always work. */
+   #NO_APP at the beginning of its output.  */
+/* Also note that comments like this one will always work.  */
 CONST char line_comment_chars[] = "#";
 
 #ifdef TE_LINUX
@@ -122,7 +121,8 @@ CONST char line_separator_chars[] = ";";
 CONST char line_separator_chars[] = "";
 #endif
 
-/* Chars that can be used to separate mant from exp in floating point nums */
+/* Chars that can be used to separate mant
+   from exp in floating point numbers.  */
 CONST char EXP_CHARS[] = "eE";
 
 /* Chars that mean this number is a floating point constant */
@@ -143,7 +143,7 @@ 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 */
+                                  does not support thumb instructions */
 typedef struct arm_fix
 {
   int thumb_mode;
@@ -197,7 +197,7 @@ CONST char * fp_const[] =
   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
 };
 
-/* Number of littlenums required to hold an extended precision number */
+/* Number of littlenums required to hold an extended precision number */
 #define MAX_LITTLENUMS 6
 
 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
@@ -226,7 +226,7 @@ struct asm_cond
   unsigned long value;
 };
 
-/* This is to save a hash look-up in the common case */
+/* This is to save a hash look-up in the common case */
 #define COND_ALWAYS 0xe0000000
 
 static CONST struct asm_cond conds[] = 
@@ -251,7 +251,7 @@ static CONST struct asm_cond conds[] =
 
 /* Warning: If the top bit of the set_bits is set, then the standard
    instruction bitmask is ignored, and the new bitmask is taken from
-   the set_bits: */
+   the set_bits:  */
 struct asm_flg
 {
   CONST char *  template;      /* Basic flag string */
@@ -381,42 +381,53 @@ static CONST struct asm_flg cplong_flag[] =
 struct asm_psr
 {
   CONST char *  template;
-  unsigned long number;
+  boolean       cpsr;
+  unsigned long field;
 };
 
-#define PSR_FIELD_MASK  0x000f0000
+#define SPSR_BIT   (1 << 22)  /* The bit that distnguishes CPSR and SPSR.  */
+#define PSR_SHIFT  16  /* How many bits to shift the PSR_xxx bits up by.  */
 
-#define PSR_FLAGS      0x00080000
-#define PSR_CONTROL    0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
-#define PSR_ALL                0x00090000
-
-#define CPSR_ALL       0
-#define SPSR_ALL       1
-#define CPSR_FLG       2
-#define SPSR_FLG       3
-#define CPSR_CTL       4
-#define SPSR_CTL       5
+#define PSR_c   (1 << 0)
+#define PSR_x   (1 << 1)
+#define PSR_s   (1 << 2)
+#define PSR_f   (1 << 3)
 
 static CONST struct asm_psr psrs[] =
 {
-  /* Valid <psr>'s */
-  {"cpsr",     CPSR_ALL},
-  {"cpsr_all", CPSR_ALL},
-  {"spsr",     SPSR_ALL},
-  {"spsr_all", SPSR_ALL},
-
-  /* Valid <psrf>'s */
-  {"cpsr_flg", CPSR_FLG},
-  {"spsr_flg", SPSR_FLG},
-  
-  /* Valid <psrc>'s */
-  {"cpsr_c",   CPSR_CTL},
-  {"cpsr_ctl", CPSR_CTL},
-  {"spsr_c",   SPSR_CTL},
-  {"spsr_ctl", SPSR_CTL}
+  {"CPSR",     true,  PSR_c | PSR_f},
+  {"CPSR_all", true,  PSR_c | PSR_f},
+  {"SPSR",     false, PSR_c | PSR_f},
+  {"SPSR_all", false, PSR_c | PSR_f},
+  {"CPSR_flg", true,  PSR_f},
+  {"CPSR_f",    true,  PSR_f},
+  {"SPSR_flg", false, PSR_f},
+  {"SPSR_f",    false, PSR_f}, 
+  {"CPSR_c",   true,  PSR_c},
+  {"CPSR_ctl", true,  PSR_c},
+  {"SPSR_c",   false, PSR_c},
+  {"SPSR_ctl", false, PSR_c},
+  {"CPSR_x",    true,  PSR_x},
+  {"CPSR_s",    true,  PSR_s},
+  {"SPSR_x",    false, PSR_x},
+  {"SPSR_s",    false, PSR_s},
+  /* For backwards compatability with older toolchain we also
+     support lower case versions of some of these flags.  */
+  {"cpsr",     true,  PSR_c | PSR_f},
+  {"cpsr_all", true,  PSR_c | PSR_f},
+  {"spsr",     false, PSR_c | PSR_f},
+  {"spsr_all", false, PSR_c | PSR_f},
+  {"cpsr_flg", true,  PSR_f},
+  {"cpsr_f",    true,  PSR_f},
+  {"spsr_flg", false, PSR_f},
+  {"spsr_f",    false, PSR_f}, 
+  {"cpsr_c",   true,  PSR_c},
+  {"cpsr_ctl", true,  PSR_c},
+  {"spsr_c",   false, PSR_c},
+  {"spsr_ctl", false, PSR_c}
 };
 
-/* Functions called by parser */
+/* Functions called by parser */
 /* ARM instructions */
 static void do_arit            PARAMS ((char *, unsigned long));
 static void do_cmp             PARAMS ((char *, unsigned long));
@@ -458,7 +469,7 @@ 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 CONST struct asm_psr * 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));
@@ -467,7 +478,7 @@ 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));
-static int psr_required_here   PARAMS ((char **, int, int));
+static int psr_required_here   PARAMS ((char **));
 static int co_proc_number      PARAMS ((char **));
 static int cp_opc_expr         PARAMS ((char **, int, int));
 static int cp_reg_required_here        PARAMS ((char **, int));
@@ -497,13 +508,11 @@ static bfd_reloc_code_real_type   arm_parse_reloc PARAMS ((void));
 #endif
 
 /* ARM instructions take 4bytes in the object file, Thumb instructions
-   take 2: */
+   take 2:  */
 #define INSN_SIZE       4
 
 /* LONGEST_INST is the longest basic instruction name without conditions or 
- * flags.
- * ARM7M has 4 of length 5
- */
+   flags.  ARM7M has 4 of length 5.  */
 
 #define LONGEST_INST 5
 
@@ -547,9 +556,14 @@ static CONST struct asm_opcode insns[] =
   {"stm",   0x08000000, NULL,   stm_flags,   ARM_ANY,      do_ldmstm},
   {"ldm",   0x08100000, NULL,   ldm_flags,   ARM_ANY,      do_ldmstm},
   {"swi",   0x0f000000, NULL,   NULL,        ARM_ANY,      do_swi},
+#ifdef TE_WINCE
+  {"bl",    0x0b000000, NULL,   NULL,        ARM_ANY,      do_branch},
+  {"b",     0x0a000000, NULL,   NULL,        ARM_ANY,      do_branch},
+#else
   {"bl",    0x0bfffffe, NULL,   NULL,        ARM_ANY,      do_branch},
   {"b",     0x0afffffe, NULL,   NULL,        ARM_ANY,      do_branch},
-
+#endif
+  
 /* Pseudo ops */
   {"adr",   0x028f0000, NULL,   NULL,        ARM_ANY,      do_adr},
   {"adrl",  0x028f0000, NULL,   NULL,        ARM_ANY,      do_adrl},
@@ -566,8 +580,8 @@ static CONST struct asm_opcode insns[] =
   {"mrs",   0x010f0000, NULL,   NULL,        ARM_6UP,      do_mrs},
   {"msr",   0x0120f000, NULL,   NULL,        ARM_6UP,      do_msr},
 /* ScottB: our code uses 0x0128f000 for msr.
-   NickC:  but this is wrong because the bits 16 and 19 are handled
-           by the PSR_xxx defines above.  */
+   NickC:  but this is wrong because the bits 16 through 19 are
+           handled by the PSR_xxx defines above.  */
 
 /* ARM 7M long multiplies - need signed/unsigned flags! */
   {"smull", 0x00c00090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
@@ -626,7 +640,7 @@ static CONST struct asm_opcode insns[] =
   {"flt",   0x0e000110, "sde",  round_flags, FPU_ALL,      do_fp_from_reg},
   {"fix",   0x0e100110, NULL,   fix_flags,   FPU_ALL,      do_fp_to_reg},
 
-/* Generic copressor instructions */
+/* Generic copressor instructions */
   {"cdp",   0x0e000000, NULL,  NULL,         ARM_2UP,      do_cdp},
   {"ldc",   0x0c100000, NULL,  cplong_flag,  ARM_2UP,      do_lstc},
   {"stc",   0x0c000000, NULL,  cplong_flag,  ARM_2UP,      do_lstc},
@@ -634,8 +648,7 @@ static CONST struct asm_opcode insns[] =
   {"mrc",   0x0e100010, NULL,  NULL,         ARM_2UP,      do_co_reg},
 };
 
-/* defines for various bits that we will want to toggle */
-
+/* Defines for various bits that we will want to toggle.  */
 #define INST_IMMEDIATE 0x02000000
 #define OFFSET_REG     0x02000000
 #define HWOFFSET_IMM    0x00400000
@@ -650,8 +663,7 @@ static CONST struct asm_opcode insns[] =
 #define OPCODE_MASK    0xfe1fffff
 #define DATA_OP_SHIFT  21
 
-/* Codes to distinguish the arithmetic instructions */
-
+/* Codes to distinguish the arithmetic instructions.  */
 #define OPCODE_AND     0
 #define OPCODE_EOR     1
 #define OPCODE_SUB     2
@@ -748,7 +760,7 @@ static void do_t_adr                PARAMS ((char *));
 
 static int thumb_reg           PARAMS ((char ** str, int hi_lo));
 
-#define THUMB_SIZE     2       /* Size of thumb instruction */
+#define THUMB_SIZE     2       /* Size of thumb instruction */
 #define THUMB_REG_LO   0x1
 #define THUMB_REG_HI   0x2
 #define THUMB_REG_ANY  0x3
@@ -768,7 +780,7 @@ static int thumb_reg                PARAMS ((char ** str, int hi_lo));
 
 #define THUMB_PP_PC_LR 0x0100
 
-/* These three are used for immediate shifts, do not alter */
+/* These three are used for immediate shifts, do not alter */
 #define THUMB_WORD 2
 #define THUMB_HALFWORD 1
 #define THUMB_BYTE 0
@@ -806,6 +818,7 @@ static CONST struct thumb_opcode tinsns[] =
   {"blt",      0xdbfe,         2,      ARM_THUMB, do_t_branch9},
   {"bgt",      0xdcfe,         2,      ARM_THUMB, do_t_branch9},
   {"ble",      0xddfe,         2,      ARM_THUMB, do_t_branch9},
+  {"bal",      0xdefe,         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},
@@ -857,7 +870,7 @@ struct reg_entry
 #define REG_LR  14
 #define REG_SP  13
 
-/* These are the standard names.  Users can add aliases with .req */
+/* These are the standard names.  Users can add aliases with .req  */
 static CONST struct reg_entry reg_table[] =
 {
   /* Processor Register Numbers.  */
@@ -907,10 +920,9 @@ static struct hash_control * arm_psr_hsh = NULL;
 
 /* This table describes all the machine specific pseudo-ops the assembler
    has to support.  The fields are:
-   pseudo-op name without dot
-   function to call to execute this pseudo-op
-   Integer arg to pass to the function
-   */
+     pseudo-op name without dot
+     function to call to execute this pseudo-op
+     Integer arg to pass to the function.  */
 
 static void s_req PARAMS ((int));
 static void s_align PARAMS ((int));
@@ -1002,12 +1014,13 @@ add_to_lit_pool ()
     current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
                                   (valueT) 0, &zero_address_frag);
 
-  /* Check if this literal value is already in the pool: */
+  /* Check if this literal value is already in the pool:  */
   while (lit_count < next_literal_pool_place)
     {
       if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
           && inst.reloc.exp.X_op == O_constant
-          && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
+          && literals[lit_count].exp.X_add_number
+            == inst.reloc.exp.X_add_number
           && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
         break;
       lit_count++;
@@ -1086,8 +1099,8 @@ symbol_locate (symbolP, name, segment, valu, frag)
 #endif /* DEBUG_SYMS */
 }
 
-/* Check that an immediate is valid, and if so, convert it to the right format.  */
-
+/* Check that an immediate is valid, and if so,
+   convert it to the right format.  */
 static unsigned int
 validate_immediate (val)
      unsigned int val;
@@ -1107,7 +1120,6 @@ validate_immediate (val)
 /* Check to see if an immediate can be computed as two seperate immediate
    values, added together.  We already know that this value cannot be
    computed by just one ARM instruction.  */
-
 static unsigned int
 validate_immediate_twopart (val, highpart)
      unsigned int val;
@@ -1158,14 +1170,14 @@ validate_offset_imm (val, hwse)
     
 static void
 s_req (a)
-     int a;
+     int a ATTRIBUTE_UNUSED;
 {
   as_bad (_("Invalid syntax for .req directive."));
 }
 
 static void
 s_bss (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   /* We don't support putting frags in the BSS segment, we fake it by
      marking in_bss, then looking at s_skip for clues?.. */
@@ -1175,7 +1187,7 @@ s_bss (ignore)
 
 static void
 s_even (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (!need_pass_2)            /* Never make frag if expect extra pass. */
     frag_align (1, 0, 0);
@@ -1187,7 +1199,7 @@ s_even (ignore)
 
 static void
 s_ltorg (ignored)
-     int ignored;
+     int ignored ATTRIBUTE_UNUSED;
 {
   int lit_count = 0;
   char sym_name[20];
@@ -1215,7 +1227,7 @@ s_ltorg (ignored)
 #endif
   
   while (lit_count < next_literal_pool_place)
-    /* First output the expression in the instruction to the pool */
+    /* First output the expression in the instruction to the pool */
     emit_expr (&(literals[lit_count++].exp), 4); /* .word */
 
   next_literal_pool_place = 0;
@@ -1224,7 +1236,7 @@ s_ltorg (ignored)
 
 static void
 s_align (unused)       /* Same as s_align_ptwo but align 0 => align 2 */
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   register int temp;
   register long temp_fill;
@@ -1260,7 +1272,7 @@ s_align (unused)  /* Same as s_align_ptwo but align 0 => align 2 */
 
 static void
 s_force_thumb (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   /* If we are not already in thumb mode go into it, EVEN if
      the target processor does not support thumb instructions.
@@ -1280,7 +1292,7 @@ s_force_thumb (ignore)
 
 static void
 s_thumb_func (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   /* The following label is the name/address of the start of a Thumb function.
      We need to know this for the interworking support.  */
@@ -1466,7 +1478,7 @@ opcode_select (width)
 
 static void
 s_arm (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   opcode_select (32);
   demand_empty_rest_of_line ();
@@ -1474,7 +1486,7 @@ s_arm (ignore)
 
 static void
 s_thumb (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   opcode_select (16);
   demand_empty_rest_of_line ();
@@ -1482,7 +1494,7 @@ s_thumb (ignore)
 
 static void
 s_code (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   register int temp;
 
@@ -1533,8 +1545,7 @@ skip_past_comma (str)
 /* 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. */
-
+   Returns the reg#, or FAIL.  */
 static int
 reg_required_here (str, shift)
      char ** str;
@@ -1562,27 +1573,65 @@ reg_required_here (str, shift)
   return FAIL;
 }
 
+static CONST struct asm_psr *
+arm_psr_parse (ccp)
+     register char ** ccp;
+{
+  char * start = * ccp;
+  char   c;
+  char * p;
+  CONST struct asm_psr * psr;
+
+  p = start;
+
+  /* Skip to the end of the next word in the input stream.  */
+  do
+    {
+      c = *p++;
+    }
+  while (isalpha (c) || c == '_');
+
+  /* Terminate the word.  */
+  *--p = 0;
+
+  /* Now locate the word in the psr hash table.  */
+  psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
+
+  /* Restore the input stream.  */
+  *p = c;
+
+  /* If we found a valid match, advance the
+     stream pointer past the end of the word.  */
+  *ccp = p;
+
+  return psr;
+}
+
+/* Parse the input looking for a PSR flag.  */
 static int
-psr_required_here (str, cpsr, spsr)
+psr_required_here (str)
      char ** str;
-     int     cpsr;
-     int     spsr;
 {
-  int    psr;
   char * start = *str;
-  psr = arm_psr_parse (str);
+  CONST struct asm_psr * psr;
   
-  if  (psr == cpsr || psr == spsr)
+  psr = arm_psr_parse (str);
+
+  if (psr)
     {
-      if (psr == spsr)
-       inst.instruction |= 1 << 22;
+      /* If this is the SPSR that is being modified, set the R bit.  */
+      if (! psr->cpsr)
+       inst.instruction |= SPSR_BIT;
+
+      /* Set the psr flags in the MSR instruction.  */
+      inst.instruction |= psr->field << PSR_SHIFT;
       
       return SUCCESS;
     }
 
-  /* In the few cases where we might be able to accept something else
-     this error can be overridden.  */
-  inst.error = _("<psr(f)> expected");
+  /* In the few cases where we might be able to accept
+     something else this error can be overridden.  */
+  inst.error = _("flag for {c}psr instruction expected");
 
   /* Restore the start point.  */
   *str = start;
@@ -1874,104 +1923,110 @@ do_mrs (str, flags)
       return;
     }
 
-  if (skip_past_comma (&str) == FAIL
-      || psr_required_here (& str, CPSR_ALL, SPSR_ALL) == FAIL)
+  if (skip_past_comma (&str) == FAIL)
+    {
+      inst.error = _("comma expected after register name");
+      return;
+    }
+
+  skip_whitespace (str);
+
+  if (   strcmp (str, "CPSR") == 0
+      || strcmp (str, "SPSR") == 0
+        /* Lower case versions for backwards compatability.  */
+      || strcmp (str, "cpsr") == 0
+      || strcmp (str, "spsr") == 0)
+    str += 4;
+  /* This is for backwards compatability with older toolchains.  */
+  else if (strcmp (str, "cpsr_all") == 0
+          || strcmp (str, "spsr_all") == 0)
+    str += 7;
+  else
     {
-      inst.error = _("<psr> expected");
+      inst.error = _("{C|S}PSR expected");
       return;
     }
 
+  if (* str == 's' || * str == 'S')
+    inst.instruction |= SPSR_BIT;
+  
   inst.instruction |= flags;
   end_of_line (str);
-  return;
 }
 
-/* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression".  */
+/* Two possible forms:
+      "{C|S}PSR_<field>, Rm",
+      "{C|S}PSR_f, #expression".  */
 static void
 do_msr (str, flags)
      char * str;
      unsigned long flags;
 {
-  int reg;
+  skip_whitespace (str);
+
+  if (psr_required_here (& str) == FAIL)
+    return;
+    
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = _("comma missing after psr flags");
+      return;
+    }
 
   skip_whitespace (str);
 
-  if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS)
+  if (reg_required_here (& str, 0) != FAIL)
     {
-      inst.instruction |= PSR_ALL;
+      inst.error = NULL; 
+      inst.instruction |= flags;
+      end_of_line (str);
+      return;
+    }
 
-      /* Sytax should be "<psr>, Rm" */
-      if (skip_past_comma (&str) == FAIL
-         || (reg = reg_required_here (&str, 0)) == FAIL)
-       {
-         inst.error = BAD_ARGS;
-         return;
-       }
+  if (! is_immediate_prefix (* str))
+    {
+      inst.error = _("only a register or immediate value can follow a psr flag");
+      return;
+    }
+
+  str ++;
+  inst.error = NULL;
+  
+  if (my_get_expression (& inst.reloc.exp, & str))
+    {
+      inst.error = _("only a register or immediate value can follow a psr flag");
+      return;
+    }
+  
+  if (inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
+    {
+      inst.error = _("can only set flag field with immediate value");
+      return;
+    }
+  
+  flags |= INST_IMMEDIATE;
+         
+  if (inst.reloc.exp.X_add_symbol)
+    {
+      inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+      inst.reloc.pc_rel = 0;
     }
   else
     {
-      if (psr_required_here (& str, CPSR_FLG, SPSR_FLG) == SUCCESS)
-       inst.instruction |= PSR_FLAGS;
-      else if (psr_required_here (& str, CPSR_CTL, SPSR_CTL) == SUCCESS)
-       inst.instruction |= PSR_CONTROL;
-      else
-       {
-         inst.error = BAD_ARGS;
-         return;
-       }
+      unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
       
-      if (skip_past_comma (&str) == FAIL)
+      if (value == (unsigned) FAIL)
        {
-         inst.error = BAD_ARGS;
+         inst.error = _("Invalid constant");
          return;
        }
       
-      /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
-      
-      if ((reg = reg_required_here (& str, 0)) != FAIL)
-       ;
-      /* Immediate expression.  */
-      else if (is_immediate_prefix (* str))
-       {
-         str ++;
-         inst.error = NULL;
-         
-         if (my_get_expression (& inst.reloc.exp, & str))
-           {
-             inst.error = _("Register or shift expression expected");
-             return;
-           }
-
-         if (inst.reloc.exp.X_add_symbol)
-           {
-             inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-             inst.reloc.pc_rel = 0;
-           }
-         else
-           {
-             unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
-             if (value == FAIL)
-               {
-                 inst.error = _("Invalid constant");
-                 return;
-               }
-
-             inst.instruction |= value;
-           }
-
-         flags |= INST_IMMEDIATE;
-       }
-      else
-       {
-         inst.error = _("Error: unrecognised syntax for second argument to msr instruction");
-         return;
-       }
+      inst.instruction |= value;
     }
 
   inst.error = NULL; 
   inst.instruction |= flags;
   end_of_line (str);
-  return;
 }
 
 /* Long Multiply Parser
@@ -2459,7 +2514,7 @@ negate_data_op (instruction, value)
       return FAIL;
     }
 
-  if (value == FAIL)
+  if (value == (unsigned) FAIL)
     return FAIL;
 
   *instruction &= OPCODE_MASK;
@@ -2642,8 +2697,7 @@ do_adr (str, flags)
      unsigned long 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" */
-
+     into a relative address of the form "add rd, pc, #label-.-8".  */
   skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL
@@ -2654,14 +2708,15 @@ do_adr (str, flags)
        inst.error = BAD_ARGS;
       return;
     }
+  
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
+  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
   inst.reloc.pc_rel = 1;
   inst.instruction |= flags;
+  
   end_of_line (str);
-  return;
 }
 
 static void
@@ -3020,7 +3075,9 @@ do_ldst (str, flags)
         }
       else
         inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+#ifndef TE_WINCE
       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust */
+#endif
       inst.reloc.pc_rel = 1;
       inst.instruction |= (REG_PC << 16);
       pre_inc = 1;
@@ -3294,7 +3351,7 @@ do_swap (str, flags)
 static void
 do_branch (str, flags)
      char *        str;
-     unsigned long flags;
+     unsigned long flags ATTRIBUTE_UNUSED;
 {
   if (my_get_expression (&inst.reloc.exp, &str))
     return;
@@ -3340,7 +3397,7 @@ do_branch (str, flags)
 static void
 do_bx (str, flags)
      char *        str;
-     unsigned long flags;
+     unsigned long flags ATTRIBUTE_UNUSED;
 {
   int reg;
 
@@ -3361,7 +3418,7 @@ do_bx (str, flags)
 static void
 do_cdp (str, flags)
      char *        str;
-     unsigned long flags;
+     unsigned long flags ATTRIBUTE_UNUSED;
 {
   /* Co-processor data operation.
      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
@@ -3528,7 +3585,7 @@ do_co_reg (str, flags)
 static void
 do_fp_ctrl (str, flags)
      char *        str;
-     unsigned long flags;
+     unsigned long flags ATTRIBUTE_UNUSED;
 {
   /* FP control registers.
      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
@@ -3549,7 +3606,7 @@ do_fp_ctrl (str, flags)
 static void
 do_fp_ldst (str, flags)
      char *        str;
-     unsigned long flags;
+     unsigned long flags ATTRIBUTE_UNUSED;
 {
   skip_whitespace (str);
 
@@ -4116,6 +4173,7 @@ thumb_add_sub (str, subtract)
            }
        }
     }
+  
   end_of_line (str);
 }
 
@@ -4140,7 +4198,7 @@ thumb_shift (str, shift)
     {
       /* Two operand immediate format, set Rs to Rd.  */
       Rs = Rd;
-      str++;
+      str ++;
       if (my_get_expression (&inst.reloc.exp, &str))
        return;
     }
@@ -4225,6 +4283,7 @@ thumb_shift (str, shift)
 
       inst.instruction |= Rd | (Rs << 3);
     }
+  
   end_of_line (str);
 }
 
@@ -4901,11 +4960,15 @@ static void
 do_t_adr (str)
      char * str;
 {
+  int reg;
+
   /* 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" */
+     into a relative address of the form "add rd, pc, #label-.-4" */
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 4) == FAIL  /* Store Rd in temporary location inside instruction.  */
+  /* Store Rd in temporary location inside instruction.  */
+  if ((reg = reg_required_here (&str, 4)) == FAIL
+      || (reg > 7)  /* For Thumb reg must be r0..r7.  */
       || skip_past_comma (&str) == FAIL
       || my_get_expression (&inst.reloc.exp, &str))
     {
@@ -4915,9 +4978,10 @@ do_t_adr (str)
     }
 
   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
-  inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
+  inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
   inst.reloc.pc_rel = 1;
-  inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
+  inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
+  
   end_of_line (str);
 }
 
@@ -4974,7 +5038,8 @@ set_constant_flonums ()
 void
 md_begin ()
 {
-  int i;
+  unsigned mach;
+  unsigned int i;
   
   if (   (arm_ops_hsh = hash_new ()) == NULL
       || (arm_tops_hsh = hash_new ()) == NULL
@@ -5004,7 +5069,7 @@ md_begin ()
   {
     unsigned int flags = 0;
     
-    /* Set the flags in the private structure */
+    /* Set the flags in the private structure */
     if (uses_apcs_26)      flags |= F_APCS26;
     if (support_interwork) flags |= F_INTERWORK;
     if (uses_apcs_float)   flags |= F_APCS_FLOAT;
@@ -5015,47 +5080,43 @@ md_begin ()
   }
 #endif
   
-  {
-    unsigned mach;
-    
-    /* Record the CPU type as well */
-    switch (cpu_variant & ARM_CPU_MASK)
-      {
-      case ARM_2:
-       mach = bfd_mach_arm_2;
-       break;
-       
-      case ARM_3: /* also ARM_250 */
-       mach = bfd_mach_arm_2a;
-       break;
-
-      default:
-      case ARM_6 | ARM_3 | ARM_2:      /* Actually no CPU type defined */
+  /* Record the CPU type as well.  */
+  switch (cpu_variant & ARM_CPU_MASK)
+    {
+    case ARM_2:
+      mach = bfd_mach_arm_2;
+      break;
+      
+    case ARM_3:                /* Also ARM_250.  */
+      mach = bfd_mach_arm_2a;
+      break;
+      
+    default:
+    case ARM_6 | ARM_3 | ARM_2:        /* Actually no CPU type defined.  */
+      mach = bfd_mach_arm_4;
+      break;
+      
+    case ARM_7:                /* Also ARM_6.  */
+      mach = bfd_mach_arm_3;
+      break;
+    }
+  
+  /* Catch special cases.  */
+  if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
+    {
+      if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
+       mach = bfd_mach_arm_5T;
+      else if (cpu_variant & ARM_EXT_V5)
+       mach = bfd_mach_arm_5;
+      else if (cpu_variant & ARM_THUMB)
+       mach = bfd_mach_arm_4T;
+      else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
        mach = bfd_mach_arm_4;
-       break;
-       
-      case ARM_7:                      /* also ARM_6 */
-       mach = bfd_mach_arm_3;
-       break;
-      }
-
-    /* Catch special cases.  */
-    if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
-      {
-       if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
-         mach = bfd_mach_arm_5T;
-       else if (cpu_variant & ARM_EXT_V5)
-         mach = bfd_mach_arm_5;
-       else if (cpu_variant & ARM_THUMB)
-         mach = bfd_mach_arm_4T;
-       else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
-         mach = bfd_mach_arm_4;
-       else if (cpu_variant & ARM_LONGMUL)
-         mach = bfd_mach_arm_3M;
-      }
-       
-    bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
-  }
+      else if (cpu_variant & ARM_LONGMUL)
+       mach = bfd_mach_arm_3M;
+    }
+  
+  bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
 }
 
 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
@@ -5206,13 +5267,19 @@ md_pcrel_from (fixP)
       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
     }
 
+#ifdef TE_WINCE
+  /* The pattern was adjusted to accomodate CE's off-by-one fixups,
+     so we un-adjust here to compensate for the accomodation.  */
+  return fixP->fx_where + fixP->fx_frag->fr_address + 8;
+#else
   return fixP->fx_where + fixP->fx_frag->fr_address;
+#endif
 }
 
 /* Round up a section size to the appropriate boundary. */
 valueT
 md_section_align (segment, size)
-     segT   segment;
+     segT   segment ATTRIBUTE_UNUSED;
      valueT size;
 {
 #ifdef OBJ_ELF
@@ -5229,7 +5296,7 @@ md_section_align (segment, size)
 /* ARGSUSED */
 symbolS *
 md_undefined_symbol (name)
-     char * name;
+     char * name ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_ELF
   if (name[0] == '_' && name[1] == 'G'
@@ -5294,33 +5361,6 @@ arm_reg_parse (ccp)
   return FAIL;
 }
 
-static int
-arm_psr_parse (ccp)
-     register char ** ccp;
-{
-  char * start = * ccp;
-  char   c;
-  char * p;
-  CONST struct asm_psr * psr;
-
-  p = start;
-  c = *p++;
-  while (isalpha (c) || c == '_')
-    c = *p++;
-
-  *--p = 0;  
-  psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
-  *p = c;
-
-  if (psr)
-    {
-      *ccp = p;
-      return psr->number;
-    }
-
-  return FAIL;
-}
-
 int
 md_apply_fix3 (fixP, val, seg)
      fixS *      fixP;
@@ -5357,6 +5397,7 @@ md_apply_fix3 (fixP, val, seg)
        {
          if (target_oabi
              && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
+               || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
                ))
            value = 0;
          else
@@ -5545,16 +5586,81 @@ md_apply_fix3 (fixP, val, seg)
     case BFD_RELOC_ARM_PCREL_BRANCH:
       newval = md_chars_to_number (buf, INSN_SIZE);
 
+      /* Sign-extend a 24-bit number.  */
+#define SEXT24(x)      ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
+
 #ifdef OBJ_ELF
       if (! target_oabi)
-        value = fixP->fx_offset;
+       value = fixP->fx_offset;
+#endif
+
+      /* We are going to store value (shifted right by two) in the
+        instruction, in a 24 bit, signed field.  Thus we need to check
+        that none of the top 8 bits of the shifted value (top 7 bits of
+         the unshifted, unsigned value) are set, or that they are all set.  */
+      if ((value & ~ ((offsetT) 0x1ffffff)) != 0
+         && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
+       {
+#ifdef OBJ_ELF
+         /* Normally we would be stuck at this point, since we cannot store
+            the absolute address that is the destination of the branch in the
+            24 bits of the branch instruction.  If however, we happen to know
+            that the destination of the branch is in the same section as the
+            branch instruciton itself, then we can compute the relocation for
+            ourselves and not have to bother the linker with it.
+            
+            FIXME: The tests for OBJ_ELF and ! target_oabi are only here
+            because I have not worked out how to do this for OBJ_COFF or
+            target_oabi.  */
+         if (! target_oabi
+             && fixP->fx_addsy != NULL
+             && S_IS_DEFINED (fixP->fx_addsy)
+             && S_GET_SEGMENT (fixP->fx_addsy) == seg)
+           {
+             /* Get pc relative value to go into the branch.  */
+             value = * val;
+
+             /* Permit a backward branch provided that enough bits are set.
+                Allow a forwards branch, provided that enough bits are clear.  */
+             if ((value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
+                 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
+               fixP->fx_done = 1;
+           }
+         
+         if (! fixP->fx_done)
 #endif
-      value  = (value >> 2) & 0x00ffffff;
-      value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
-      newval = value | (newval & 0xff000000);
+           as_bad_where (fixP->fx_file, fixP->fx_line,
+                         _("gas can't handle same-section branch dest >= 0x04000000"));
+       }
+
+      value >>= 2;
+      value += SEXT24 (newval);
+      
+      if ((value & ~ ((offsetT) 0xffffff)) != 0
+         && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("out of range branch"));
+      
+      newval = (value & 0x00ffffff) | (newval & 0xff000000);
       md_number_to_chars (buf, newval, INSN_SIZE);
       break;
 
+    case BFD_RELOC_ARM_PCREL_BLX:
+      {
+       offsetT hbit;
+       newval = md_chars_to_number (buf, INSN_SIZE);
+
+#ifdef OBJ_ELF
+       if (! target_oabi)
+           value = fixP->fx_offset;
+#endif
+       hbit   = (value >> 1) & 1;
+       value  = (value >> 2) & 0x00ffffff;
+       value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
+       newval = value | (newval & 0xfe000000) | (hbit << 24);
+       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);
@@ -5588,6 +5694,7 @@ md_apply_fix3 (fixP, val, seg)
       md_number_to_chars (buf, newval, THUMB_SIZE);
       break;
 
+    case BFD_RELOC_THUMB_PCREL_BLX:
     case BFD_RELOC_THUMB_PCREL_BRANCH23:
       {
         offsetT newval2;
@@ -5848,7 +5955,7 @@ md_apply_fix3 (fixP, val, seg)
    format.  */
 arelent *
 tc_gen_reloc (section, fixp)
-     asection * section;
+     asection * section ATTRIBUTE_UNUSED;
      fixS * fixp;
 {
   arelent * reloc;
@@ -5894,10 +6001,12 @@ tc_gen_reloc (section, fixp)
        }
 
     case BFD_RELOC_ARM_PCREL_BRANCH:
+    case BFD_RELOC_ARM_PCREL_BLX:
     case BFD_RELOC_RVA:      
     case BFD_RELOC_THUMB_PCREL_BRANCH9:
     case BFD_RELOC_THUMB_PCREL_BRANCH12:
     case BFD_RELOC_THUMB_PCREL_BRANCH23:
+    case BFD_RELOC_THUMB_PCREL_BLX:
     case BFD_RELOC_VTABLE_ENTRY:
     case BFD_RELOC_VTABLE_INHERIT:
       code = fixp->fx_r_type;
@@ -5992,8 +6101,8 @@ tc_gen_reloc (section, fixp)
 
 int
 md_estimate_size_before_relax (fragP, segtype)
-     fragS * fragP;
-     segT    segtype;
+     fragS * fragP ATTRIBUTE_UNUSED;
+     segT    segtype ATTRIBUTE_UNUSED;
 {
   as_fatal (_("md_estimate_size_before_relax\n"));
   return 1;
@@ -6110,10 +6219,12 @@ md_assemble (str)
         keep trying with progressively smaller basic instructions until one
         matches, or we run out of opcode.  */
       q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
+
       for (; q != str; q--)
        {
          c = *q;
          *q = '\0';
+
          opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
          *q = c;
          
@@ -6295,7 +6406,8 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
          else if (regnum != FAIL)
            {
              if (reg != regnum)
-               as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
+               as_warn (_("ignoring redefinition of register alias '%s'"),
+                        copy_of_str );
              
              /* Do not warn about redefinitions to the same alias.  */
            }
@@ -6327,7 +6439,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 architectures
+ *            -m[arm]v[2345[t]]       Arm architectures
  *            -mall                   All (except the ARM1)
  *    FP variants:
  *            -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
@@ -6579,20 +6691,25 @@ md_parse_option (c, arg)
 
            case '8':
              if (streq (str, "8") || streq (str, "810"))
-               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
+               cpu_variant = (cpu_variant & ~ARM_ANY)
+                 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
              else
                goto bad;
              break;
              
            case '9':
              if (streq (str, "9"))
-               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
+               cpu_variant = (cpu_variant & ~ARM_ANY)
+                 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
              else if (streq (str, "920"))
-               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
+               cpu_variant = (cpu_variant & ~ARM_ANY)
+                 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
              else if (streq (str, "920t"))
-               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
+               cpu_variant = (cpu_variant & ~ARM_ANY)
+                 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
              else if (streq (str, "9tdmi"))
-               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
+               cpu_variant = (cpu_variant & ~ARM_ANY)
+                 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
              else
                goto bad;
              break;
@@ -6602,21 +6719,28 @@ md_parse_option (c, arg)
              if (streq (str, "strongarm")
                  || streq (str, "strongarm110")
                  || streq (str, "strongarm1100"))
-               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
+               cpu_variant = (cpu_variant & ~ARM_ANY)
+                 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
              else
                goto bad;
              break;
                
            case 'v':
-             /* Select variant based on architecture rather than processor */
+             /* Select variant based on architecture rather than processor */
              switch (*++str)
                {
                case '2':
                  switch (*++str)
                    {
-                   case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
-                   case 0:   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
-                   default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
+                   case 'a':
+                     cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
+                     break;
+                   case 0:
+                     cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
+                     break;
+                   default:
+                     as_bad (_("Invalid architecture variant -m%s"), arg);
+                     break;
                    }
                  break;
                  
@@ -6627,7 +6751,9 @@ md_parse_option (c, arg)
                    {
                    case 'm': cpu_variant |= ARM_LONGMUL; break;
                    case 0:   break;
-                   default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
+                   default:
+                     as_bad (_("Invalid architecture variant -m%s"), arg);
+                     break;
                    }
                  break;
                  
@@ -6638,7 +6764,9 @@ md_parse_option (c, arg)
                    {
                    case 't': cpu_variant |= ARM_THUMB; break;
                    case 0:   break;
-                   default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
+                   default:
+                     as_bad (_("Invalid architecture variant -m%s"), arg);
+                     break;
                    }
                  break;
 
@@ -6647,9 +6775,10 @@ md_parse_option (c, arg)
                  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;
+                   default:
+                     as_bad (_("Invalid architecture variant -m%s"), arg);
+                     break;
                    }
                  break;
                  
@@ -6684,8 +6813,7 @@ void
 md_show_usage (fp)
      FILE * fp;
 {
-  fprintf (fp,
-_("\
+  fprintf (fp, _("\
  ARM Specific Assembler Options:\n\
   -m[arm][<processor name>] select processor variant\n\
   -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
@@ -6694,29 +6822,20 @@ _("\
   -mall                     allow any instruction\n\
   -mfpa10, -mfpa11          select floating point architecture\n\
   -mfpe-old                 don't allow floating-point multiple instructions\n\
-  -mno-fpu                  don't allow any floating-point instructions.\n"));
-  fprintf (fp,
-_("\
+  -mno-fpu                  don't allow any floating-point instructions.\n\
   -k                        generate PIC code.\n"));
 #if defined OBJ_COFF || defined OBJ_ELF
-  fprintf (fp,
-_("\
-  -mapcs-32, -mapcs-26      specify which ARM Procedure Calling Standard to use\n"));
-  fprintf (fp,
-_("\
-  -mapcs-float              floating point args are passed in FP regs\n"));
-  fprintf (fp,
-_("\
+  fprintf (fp, _("\
+  -mapcs-32, -mapcs-26      specify which ARM Procedure Calling Standard to use\n\
+  -mapcs-float              floating point args are passed in FP regs\n\
   -mapcs-reentrant          the code is position independent/reentrant\n"));
   #endif
 #ifdef OBJ_ELF
-  fprintf (fp,
-_("\
+  fprintf (fp, _("\
   -moabi                    support the old ELF ABI\n"));
 #endif
 #ifdef ARM_BI_ENDIAN
-  fprintf (fp,
-_("\
+  fprintf (fp, _("\
   -EB                       assemble code for a big endian cpu\n\
   -EL                       assemble code for a little endian cpu\n"));
 #endif
@@ -6890,21 +7009,25 @@ arm_adjust_symtab ()
 #endif
 #ifdef OBJ_ELF
   symbolS *         sym;
-  elf_symbol_type * elf_sym;
   char              bind;
 
   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
     {
       if (ARM_IS_THUMB (sym))
         {
+         elf_symbol_type * elf_sym;
+         
          elf_sym = elf_symbol (symbol_get_bfdsym (sym));
          bind = ELF_ST_BIND (elf_sym);
          
-         /* If it's a .thumb_func, declare it as so, else tag label as .code 16.  */
+         /* If it's a .thumb_func, declare it as so,
+            otherwise tag label as .code 16.  */
          if (THUMB_IS_FUNC (sym))
-           elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
+           elf_sym->internal_elf_sym.st_info =
+             ELF_ST_INFO (bind, STT_ARM_TFUNC);
          else
-           elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_16BIT);
+           elf_sym->internal_elf_sym.st_info =
+             ELF_ST_INFO (bind, STT_ARM_16BIT);
          }
      }
 #endif
@@ -7027,6 +7150,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_BLX
+      || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)    
     return 1;
   
@@ -7038,7 +7163,7 @@ arm_parse_reloc ()
 {
   char   id[16];
   char * ip;
-  int    i;
+  unsigned int i;
   static struct
   {
     char * str;
@@ -7106,7 +7231,8 @@ s_arm_elf_cons (nbytes)
           int size = bfd_get_reloc_size (howto);
 
           if (size > nbytes)
-            as_bad ("%s relocations do not fit in %d bytes", howto->name, nbytes);
+            as_bad ("%s relocations do not fit in %d bytes",
+                   howto->name, nbytes);
           else
             {
               register char * p = frag_more ((int) nbytes);
@@ -7121,7 +7247,7 @@ s_arm_elf_cons (nbytes)
     }
   while (*input_line_pointer++ == ',');
 
-  input_line_pointer--;                /* Put terminator back into stream. */
+  input_line_pointer--;                /* Put terminator back into stream.  */
   demand_empty_rest_of_line ();
 }
 
This page took 0.039981 seconds and 4 git commands to generate.