PR gas/3172
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
index 1bfe5b307a3d5f67f1bc939646a3847685936d8a..19244d7d5c24f001e8cd9447b48c010d9f1df306 100644 (file)
 
 #ifdef OBJ_ELF
 #include "elf/arm.h"
-#include "dwarf2dbg.h"
 #include "dw2gencfi.h"
 #endif
 
-/* XXX Set this to 1 after the next binutils release.  */
-#define WARN_DEPRECATED 0
+#include "dwarf2dbg.h"
+
+#define WARN_DEPRECATED 1
 
 #ifdef OBJ_ELF
 /* Must be at least the size of the largest unwind opcode (currently two).  */
@@ -1261,7 +1261,9 @@ parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
           && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
       || (type == REG_TYPE_NSDQ
           && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD
-              || reg->type == REG_TYPE_NQ)))
+              || reg->type == REG_TYPE_NQ))
+      || (type == REG_TYPE_MMXWC
+         && (reg->type == REG_TYPE_MMXWCG)))
     type = reg->type;
 
   if (type != reg->type)
@@ -3448,7 +3450,7 @@ s_arm_unwind_save_mmxwr (void)
 
              op = 0xffff << (reg - 1);
              if (reg > 0
-                 || ((mask & op) == (1u << (reg - 1))))
+                 && ((mask & op) == (1u << (reg - 1))))
                {
                  op = (1 << (reg + i + 1)) - 1;
                  op &= ~((1 << reg) - 1);
@@ -3878,6 +3880,28 @@ static void s_arm_arch (int);
 static void s_arm_cpu (int);
 static void s_arm_fpu (int);
 
+#ifdef TE_PE
+
+static void
+pe_directive_secrel (int dummy ATTRIBUTE_UNUSED) 
+{
+  expressionS exp;
+
+  do
+    {
+      expression (&exp);
+      if (exp.X_op == O_symbol)
+       exp.X_op = O_secrel;
+
+      emit_expr (&exp, 4);
+    }
+  while (*input_line_pointer++ == ',');
+
+  input_line_pointer--;
+  demand_empty_rest_of_line ();
+}
+#endif /* TE_PE */
+
 /* This table describes all the machine specific pseudo-ops the assembler
    has to support.  The fields are:
      pseudo-op name without dot
@@ -3926,10 +3950,22 @@ const pseudo_typeS md_pseudo_table[] =
   { "eabi_attribute",  s_arm_eabi_attribute,   0 },
 #else
   { "word",       cons, 4},
+
+  /* These are used for dwarf.  */
+  {"2byte", cons, 2},
+  {"4byte", cons, 4},
+  {"8byte", cons, 8},
+  /* These are used for dwarf2.  */
+  { "file", (void (*) (int)) dwarf2_directive_file, 0 },
+  { "loc",  dwarf2_directive_loc,  0 },
+  { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
 #endif
   { "extend",     float_cons, 'x' },
   { "ldouble",    float_cons, 'x' },
   { "packed",     float_cons, 'p' },
+#ifdef TE_PE
+  {"secrel32", pe_directive_secrel, 0},
+#endif
   { 0, 0, 0 }
 };
 \f
@@ -5370,6 +5406,7 @@ enum operand_parse_code
   OP_RR_EXi,   /* ARM register or expression with imm prefix */
   OP_RF_IF,    /* FPA register or immediate */
   OP_RIWR_RIWC, /* iWMMXt R or C reg */
+  OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
 
   /* Optional operands.         */
   OP_oI7b,      /* immediate, prefix optional, 0 .. 7 */
@@ -5531,6 +5568,7 @@ parse_operands (char *str, const unsigned char *pattern)
         case OP_NILO:
           {
             po_reg_or_goto (REG_TYPE_NDQ, try_imm);
+           inst.operands[i].present = 1;
             i++;
             skip_past_comma (&str);
             po_reg_or_goto (REG_TYPE_NDQ, one_reg_only);
@@ -5748,9 +5786,10 @@ parse_operands (char *str, const unsigned char *pattern)
        case OP_RIWR_RIWC:
          {
            struct reg_entry *rege = arm_reg_parse_multi (&str);
-           if (rege->type != REG_TYPE_MMXWR
-               && rege->type != REG_TYPE_MMXWC
-               && rege->type != REG_TYPE_MMXWCG)
+           if (!rege
+               || (rege->type != REG_TYPE_MMXWR
+                   && rege->type != REG_TYPE_MMXWC
+                   && rege->type != REG_TYPE_MMXWCG))
              {
                inst.error = _("iWMMXt data or control register expected");
                goto failure;
@@ -5760,6 +5799,21 @@ parse_operands (char *str, const unsigned char *pattern)
          }
          break;
 
+       case OP_RIWC_RIWG:
+         {
+           struct reg_entry *rege = arm_reg_parse_multi (&str);
+           if (!rege
+               || (rege->type != REG_TYPE_MMXWC
+                   && rege->type != REG_TYPE_MMXWCG))
+             {
+               inst.error = _("iWMMXt control register expected");
+               goto failure;
+             }
+           inst.operands[i].reg = rege->number;
+           inst.operands[i].isreg = 1;
+         }
+         break;
+
          /* Misc */
        case OP_CPSF:    val = parse_cps_flags (&str);          break;
        case OP_ENDI:    val = parse_endian_specifier (&str);   break;
@@ -8186,13 +8240,13 @@ do_t_add_sub (void)
        narrow = (current_it_mask != 0);
       if (!inst.operands[2].isreg)
        {
+         int add;
+
+         add = (inst.instruction == T_MNEM_add
+                || inst.instruction == T_MNEM_adds);
          opcode = 0;
          if (inst.size_req != 4)
            {
-             int add;
-
-             add = (inst.instruction == T_MNEM_add
-                    || inst.instruction == T_MNEM_adds);
              /* Attempt to use a narrow opcode, with relaxation if
                 appropriate.  */
              if (Rd == REG_SP && Rs == REG_SP && !flags)
@@ -8222,12 +8276,24 @@ do_t_add_sub (void)
          if (inst.size_req == 4
              || (inst.size_req != 2 && !opcode))
            {
-             /* ??? Convert large immediates to addw/subw.  */
-             inst.instruction = THUMB_OP32 (inst.instruction);
-             inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+             if (Rs == REG_PC)
+               {
+                 /* Always use addw/subw.  */
+                 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
+                 inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
+               }
+             else
+               {
+                 inst.instruction = THUMB_OP32 (inst.instruction);
+                 inst.instruction = (inst.instruction & 0xe1ffffff)
+                                    | 0x10000000;
+                 if (flags)
+                   inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+                 else
+                   inst.reloc.type = BFD_RELOC_ARM_T32_ADD_IMM;
+               }
              inst.instruction |= inst.operands[0].reg << 8;
              inst.instruction |= inst.operands[1].reg << 16;
-             inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
            }
        }
       else
@@ -11554,16 +11620,12 @@ do_neon_dyadic_if_su_d (void)
   neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
 }
 
-static void
-do_neon_dyadic_if_i (void)
-{
-  neon_dyadic_misc (NT_unsigned, N_IF_32, 0);
-}
-
 static void
 do_neon_dyadic_if_i_d (void)
 {
-  neon_dyadic_misc (NT_unsigned, N_IF_32, 0);
+  /* The "untyped" case can't happen. Do this to stop the "U" bit being
+     affected if we specify unsigned args.  */
+  neon_dyadic_misc (NT_untyped, N_IF_32, 0);
 }
 
 enum vfp_or_neon_is_neon_bits
@@ -11778,7 +11840,11 @@ do_neon_mac_maybe_scalar (void)
       neon_mul_mac (et, neon_quad (rs));
     }
   else
-    do_neon_dyadic_if_i ();
+    {
+      /* The "untyped" case can't happen.  Do this to stop the "U" bit being
+        affected if we specify unsigned args.  */
+      neon_dyadic_misc (NT_untyped, N_IF_32, 0);
+    }
 }
 
 static void
@@ -12429,6 +12495,9 @@ do_neon_dyadic_narrow (void)
 {
   struct neon_type_el et = neon_check_type (3, NS_QDD,
     N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
+  /* Operand sign is unimportant, and the U bit is part of the opcode,
+     so force the operand type to integer.  */
+  et.type = NT_integer;
   neon_mixed_length (et, et.size / 2);
 }
 
@@ -13352,11 +13421,9 @@ output_relax_insn (void)
   symbolS *sym;
   int offset;
 
-#ifdef OBJ_ELF
   /* The size of the instruction is unknown, so tie the debug info to the
      start of the instruction.  */
   dwarf2_emit_insn (0);
-#endif
 
   switch (inst.reloc.exp.X_op)
     {
@@ -13424,9 +13491,7 @@ output_inst (const char * str)
                 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
                 inst.reloc.type);
 
-#ifdef OBJ_ELF
   dwarf2_emit_insn (inst.size);
-#endif
 }
 
 /* Tag values used in struct asm_opcode's tag field.  */
@@ -13523,11 +13588,14 @@ opcode_lookup (char **str)
   const struct asm_opcode *opcode;
   const struct asm_cond *cond;
   char save[2];
+  bfd_boolean neon_supported;
+  
+  neon_supported = ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1);
 
   /* Scan up to the end of the mnemonic, which must end in white space,
-     '.' (in unified mode only), or end of string.  */
+     '.' (in unified mode, or for Neon instructions), or end of string.  */
   for (base = end = *str; *end != '\0'; end++)
-    if (*end == ' ' || (unified_syntax && *end == '.'))
+    if (*end == ' ' || ((unified_syntax || neon_supported) && *end == '.'))
       break;
 
   if (end == base)
@@ -13538,9 +13606,11 @@ opcode_lookup (char **str)
     {
       int offset = 2;
       
-      if (end[1] == 'w')
+      /* The .w and .n suffixes are only valid if the unified syntax is in
+         use.  */
+      if (unified_syntax && end[1] == 'w')
        inst.size_req = 4;
-      else if (end[1] == 'n')
+      else if (unified_syntax && end[1] == 'n')
        inst.size_req = 2;
       else
         offset = 0;
@@ -13551,7 +13621,8 @@ opcode_lookup (char **str)
 
       if (end[offset] == '.')      
        {
-         /* See if we have a Neon type suffix.  */
+         /* See if we have a Neon type suffix (possible in either unified or
+             non-unified ARM syntax mode).  */
           if (parse_neon_type (&inst.vectype, str) == FAIL)
            return 0;
         }
@@ -13779,7 +13850,7 @@ md_assemble (char *str)
        ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
                                arm_ext_v6t2);
     }
-  else
+  else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
     {
       /* Check that this instruction is supported for this CPU.  */
       if (!opcode->avariant ||
@@ -13812,6 +13883,12 @@ md_assemble (char *str)
        ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
                                *opcode->avariant);
     }
+  else
+    {
+      as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
+               "-- `%s'"), str);
+      return;
+    }
   output_inst (str);
 }
 
@@ -13877,9 +13954,7 @@ arm_frob_label (symbolS * sym)
       label_is_thumb_function_name = FALSE;
     }
 
-#ifdef OBJ_ELF
   dwarf2_emit_label (sym);
-#endif
 }
 
 int
@@ -14746,7 +14821,7 @@ static const struct asm_opcode insns[] =
  TCE(mls,      0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
  TCE(movw,     3000000, f2400000, 2, (RRnpc, HALF),                mov16, t_mov16),
  TCE(movt,     3400000, f2c00000, 2, (RRnpc, HALF),                mov16, t_mov16),
- TCE(rbit,     3ff0f30, fa90f0a0, 2, (RR, RR),                     rd_rm, t_rbit),
+ TCE(rbit,     6ff0f30, fa90f0a0, 2, (RR, RR),                     rd_rm, t_rbit),
 
  TC3(ldrht,    03000b0, f8300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
  TC3(ldrsht,   03000f0, f9300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
@@ -14755,7 +14830,9 @@ static const struct asm_opcode insns[] =
 
   UT(cbnz,      b900,    2, (RR, EXP), t_czb),
   UT(cbz,       b100,    2, (RR, EXP), t_czb),
- /* ARM does not really have an IT instruction.  */
+ /* ARM does not really have an IT instruction, so always allow it.  */
+#undef ARM_VARIANT
+#define ARM_VARIANT &arm_ext_v1
  TUE(it,        0, bf08, 1, (COND),    it, t_it),
  TUE(itt,       0, bf0c, 1, (COND),    it, t_it),
  TUE(ite,       0, bf04, 1, (COND),    it, t_it),
@@ -15464,14 +15541,13 @@ static const struct asm_opcode insns[] =
  nUF(vcltq,     vclt,    3, (RNQ,  oRNQ,  RNDQ_I0), neon_cmp_inv),
  nUF(vcle,      vcle,    3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
  nUF(vcleq,     vcle,    3, (RNQ,  oRNQ,  RNDQ_I0), neon_cmp_inv),
-  /* Comparison. Type I8 I16 I32 F32. Non-immediate -> neon_dyadic_if_i.  */
+  /* Comparison. Type I8 I16 I32 F32.  */
  nUF(vceq,      vceq,    3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
  nUF(vceqq,     vceq,    3, (RNQ,  oRNQ,  RNDQ_I0), neon_ceq),
   /* As above, D registers only.  */
  nUF(vpmax,     vpmax,   3, (RND, oRND, RND), neon_dyadic_if_su_d),
  nUF(vpmin,     vpmin,   3, (RND, oRND, RND), neon_dyadic_if_su_d),
   /* Int and float variants, signedness unimportant.  */
-  /* If not scalar, fall back to neon_dyadic_if_i.  */
  nUF(vmlaq,     vmla,    3, (RNQ,  oRNQ,  RNDQ_RNSC), neon_mac_maybe_scalar),
  nUF(vmlsq,     vmls,    3, (RNQ,  oRNQ,  RNDQ_RNSC), neon_mac_maybe_scalar),
  nUF(vpadd,     vpadd,   3, (RND,  oRND,  RND),       neon_dyadic_if_i_d),
@@ -15700,7 +15776,7 @@ static const struct asm_opcode insns[] =
  cCE(tinsrb,   e600010, 3, (RIWR, RR, I7),         iwmmxt_tinsr),
  cCE(tinsrh,   e600050, 3, (RIWR, RR, I7),         iwmmxt_tinsr),
  cCE(tinsrw,   e600090, 3, (RIWR, RR, I7),         iwmmxt_tinsr),
- cCE(tmcr,     e000110, 2, (RIWC, RR),             rn_rd),
+ cCE(tmcr,     e000110, 2, (RIWC_RIWG, RR),        rn_rd),
  cCE(tmcrr,    c400000, 3, (RIWR, RR, RR),         rm_rd_rn),
  cCE(tmia,     e200010, 3, (RIWR, RR, RR),         iwmmxt_tmia),
  cCE(tmiaph,   e280010, 3, (RIWR, RR, RR),         iwmmxt_tmia),
@@ -15711,7 +15787,7 @@ static const struct asm_opcode insns[] =
  cCE(tmovmskb, e100030, 2, (RR, RIWR),             rd_rn),
  cCE(tmovmskh, e500030, 2, (RR, RIWR),             rd_rn),
  cCE(tmovmskw, e900030, 2, (RR, RIWR),             rd_rn),
- cCE(tmrc,     e100110, 2, (RR, RIWC),             rd_rn),
+ cCE(tmrc,     e100110, 2, (RR, RIWC_RIWG),        rd_rn),
  cCE(tmrrc,    c500000, 3, (RR, RR, RIWR),         rd_rn_rm),
  cCE(torcb,    e13f150, 1, (RR),                   iwmmxt_tandorc),
  cCE(torch,    e53f150, 1, (RR),                   iwmmxt_tandorc),
@@ -16136,7 +16212,10 @@ md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
          insn = THUMB_OP32 (opcode);
          insn |= (old_op & 0xf0) << 4;
          put_thumb32_insn (buf, insn);
-         reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
+         if (opcode == T_MNEM_add_pc)
+           reloc_type = BFD_RELOC_ARM_T32_IMM12;
+         else
+           reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
        }
       else
        reloc_type = BFD_RELOC_ARM_THUMB_ADD;
@@ -16153,7 +16232,10 @@ md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
          insn |= (old_op & 0xf0) << 4;
          insn |= (old_op & 0xf) << 16;
          put_thumb32_insn (buf, insn);
-         reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
+         if (insn & (1 << 20))
+           reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
+         else
+           reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
        }
       else
        reloc_type = BFD_RELOC_ARM_THUMB_ADD;
@@ -16344,12 +16426,22 @@ valueT
 md_section_align (segT  segment ATTRIBUTE_UNUSED,
                  valueT size)
 {
-#ifdef OBJ_ELF
-  return size;
-#else
-  /* Round all sects to multiple of 4. */
-  return (size + 3) & ~3;
+#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
+  if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
+    {
+      /* For a.out, force the section size to be aligned.  If we don't do
+        this, BFD will align it for us, but it will not write out the
+        final bytes of the section.  This may be a bug in BFD, but it is
+        easier to fix it here since that is how the other a.out targets
+        work.  */
+      int align;
+
+      align = bfd_get_section_alignment (stdoutput, segment);
+      size = ((size + (1 << align) - 1) & ((valueT) -1 << align));
+    }
 #endif
+
+  return size;
 }
 
 /* This is called from HANDLE_ALIGN in write.c.         Fill in the contents
@@ -16849,6 +16941,16 @@ create_unwind_entry (int have_data)
   return 0;
 }
 
+
+/* Initialize the DWARF-2 unwind information for this procedure.  */
+
+void
+tc_arm_frame_initial_instructions (void)
+{
+  cfi_add_CFA_def_cfa (REG_SP, 0);
+}
+#endif /* OBJ_ELF */
+
 /* Convert REGNAME to a DWARF-2 register number.  */
 
 int
@@ -16862,15 +16964,18 @@ tc_arm_regname_to_dw2regnum (char *regname)
   return reg;
 }
 
-/* Initialize the DWARF-2 unwind information for this procedure.  */
-
+#ifdef TE_PE
 void
-tc_arm_frame_initial_instructions (void)
+tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
 {
-  cfi_add_CFA_def_cfa (REG_SP, 0);
-}
-#endif /* OBJ_ELF */
+  expressionS expr;
 
+  expr.X_op = O_secrel;
+  expr.X_add_symbol = symbol;
+  expr.X_add_number = 0;
+  emit_expr (&expr, size);
+}
+#endif
 
 /* MD interface: Symbol and relocation handling.  */
 
@@ -17561,6 +17666,7 @@ md_apply_fix (fixS *    fixP,
       break;
 
     case BFD_RELOC_ARM_T32_IMMEDIATE:
+    case BFD_RELOC_ARM_T32_ADD_IMM:
     case BFD_RELOC_ARM_T32_IMM12:
     case BFD_RELOC_ARM_T32_ADD_PC12:
       /* We claim that this fixup has been processed here,
@@ -17581,15 +17687,21 @@ md_apply_fix (fixS *  fixP,
       newval <<= 16;
       newval |= md_chars_to_number (buf+2, THUMB_SIZE);
 
-      /* FUTURE: Implement analogue of negate_data_op for T32.  */
-      if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE)
+      newimm = FAIL;
+      if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
+         || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
        {
          newimm = encode_thumb32_immediate (value);
          if (newimm == (unsigned int) FAIL)
            newimm = thumb32_negate_data_op (&newval, value);
        }
-      else
+      if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE
+         && newimm == (unsigned int) FAIL)
        {
+         /* Turn add/sum into addw/subw.  */
+         if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
+           newval = (newval & 0xfeffffff) | 0x02000000;
+
          /* 12 bit immediate for addw/subw.  */
          if (value < 0)
            {
@@ -17855,6 +17967,9 @@ md_apply_fix (fixS *    fixP,
     case BFD_RELOC_ARM_ROSEGREL32:
     case BFD_RELOC_ARM_SBREL32:
     case BFD_RELOC_32_PCREL:
+#ifdef TE_PE
+    case BFD_RELOC_32_SECREL:
+#endif
       if (fixP->fx_done || !seg->use_rela_p)
 #ifdef TE_WINCE
        /* For WinCE we only do this for pcrel fixups.  */
@@ -18393,6 +18508,9 @@ tc_gen_reloc (asection *section, fixS *fixp)
     case BFD_RELOC_THUMB_PCREL_BLX:
     case BFD_RELOC_VTABLE_ENTRY:
     case BFD_RELOC_VTABLE_INHERIT:
+#ifdef TE_PE
+    case BFD_RELOC_32_SECREL:
+#endif
       code = fixp->fx_r_type;
       break;
 
@@ -18575,6 +18693,14 @@ cons_fix_new_arm (fragS *      frag,
       break;
     }
 
+#ifdef TE_PE
+  if (exp->X_op == O_secrel)
+  {
+    exp->X_op = O_symbol;
+    type = BFD_RELOC_32_SECREL;
+  }
+#endif
+
   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
 }
 
@@ -18608,6 +18734,7 @@ arm_force_relocation (struct fix * fixp)
   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
+      || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
       || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
       || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
       || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12)
@@ -18843,6 +18970,16 @@ set_constant_flonums (void)
       abort ();
 }
 
+/* Auto-select Thumb mode if it's the only available instruction set for the
+   given architecture.  */
+
+static void
+autoselect_thumb_from_cpu_variant (void)
+{
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
+    opcode_select (16);
+}
+
 void
 md_begin (void)
 {
@@ -18943,6 +19080,8 @@ md_begin (void)
 
   ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
 
+  autoselect_thumb_from_cpu_variant ();
+
   arm_arch_used = thumb_arch_used = arm_arch_none;
 
 #if defined OBJ_COFF || defined OBJ_ELF
This page took 0.043355 seconds and 4 git commands to generate.