arc/gas: default mach is arc700, initialised in md_begin
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
index 82cff9aebd8300e35fb94c150a1642986f459143..5633905425ebee6e779eee2a944519e554961774 100644 (file)
@@ -311,12 +311,12 @@ static void assemble_insn
    const struct arc_flags *, int, struct arc_insn *);
 
 /* The cpu for which we are generating code.  */
-static unsigned arc_target = ARC_OPCODE_BASE;
-static const char *arc_target_name = "<all>";
-static unsigned arc_features = 0x00;
+static unsigned arc_target;
+static const char *arc_target_name;
+static unsigned arc_features;
 
 /* The default architecture.  */
-static int arc_mach_type = bfd_mach_arc_arcv2;
+static int arc_mach_type;
 
 /* Non-zero if the cpu type has been explicitly specified.  */
 static int mach_type_specified_p = 0;
@@ -343,11 +343,9 @@ static const struct cpu_type
   { "arc700", ARC_OPCODE_ARC700,  bfd_mach_arc_arc700,
     E_ARC_MACH_ARC700,  0x00},
   { "arcem",  ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
-    EF_ARC_CPU_ARCV2EM, 0x00},
+    EF_ARC_CPU_ARCV2EM, ARC_CD},
   { "archs",  ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
     EF_ARC_CPU_ARCV2HS, ARC_CD},
-  { "all",    ARC_OPCODE_BASE,    bfd_mach_arc_arcv2,
-    0x00, 0x00 },
   { 0, 0, 0, 0, 0 }
 };
 
@@ -569,6 +567,35 @@ md_number_to_chars_midend (char *buf, valueT val, int n)
     }
 }
 
+/* Select an appropriate entry from CPU_TYPES based on ARG and initialise
+   the relevant static global variables.  */
+
+static void
+arc_select_cpu (const char *arg)
+{
+  int cpu_flags = EF_ARC_CPU_GENERIC;
+  int i;
+
+  for (i = 0; cpu_types[i].name; ++i)
+    {
+      if (!strcasecmp (cpu_types[i].name, arg))
+        {
+          arc_target = cpu_types[i].flags;
+          arc_target_name = cpu_types[i].name;
+          arc_features = cpu_types[i].features;
+          arc_mach_type = cpu_types[i].mach;
+          cpu_flags = cpu_types[i].eflags;
+          break;
+        }
+    }
+
+  if (!cpu_types[i].name)
+    as_fatal (_("unknown architecture: %s\n"), arg);
+
+  if (cpu_flags != EF_ARC_CPU_GENERIC)
+    arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
+}
+
 /* Here ends all the ARCompact extension instruction assembling
    stuff.  */
 
@@ -591,10 +618,31 @@ arc_extra_reloc (int r_type)
       lab = symbol_find_or_make (lab_name);
       restore_line_pointer (c);
     }
+
+  /* These relocations exist as a mechanism for the compiler to tell the
+     linker how to patch the code if the tls model is optimised.  However,
+     the relocation itself does not require any space within the assembler
+     fragment, and so we pass a size of 0.
+
+     The lines that generate these relocations look like this:
+
+         .tls_gd_ld @.tdata`bl __tls_get_addr@plt
+
+     The '.tls_gd_ld @.tdata' is processed first and generates the
+     additional relocation, while the 'bl __tls_get_addr@plt' is processed
+     second and generates the additional branch.
+
+     It is possible that the additional relocation generated by the
+     '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
+     while the 'bl __tls_get_addr@plt' will be generated as the first thing
+     in the next fragment.  This will be fine; both relocations will still
+     appear to be at the same address in the generated object file.
+     However, this only works as the additional relocation is generated
+     with size of 0 bytes.  */
   fixS *fixP
     = fix_new (frag_now,       /* Which frag?  */
               frag_now_fix (), /* Where in that frag?  */
-              2,               /* size: 1, 2, or 4 usually.  */
+              0,               /* size: 1, 2, or 4 usually.  */
               sym,             /* X_add_symbol.  */
               0,               /* X_add_number.  */
               FALSE,           /* TRUE if PC-relative relocation.  */
@@ -2027,7 +2075,7 @@ md_assemble (char *str)
 /* Callback to insert a register into the hash table.  */
 
 static void
-declare_register (char *name, int number)
+declare_register (const char *name, int number)
 {
   const char *err;
   symbolS *regS = symbol_create (name, reg_section,
@@ -2067,6 +2115,9 @@ md_begin (void)
 {
   unsigned int i;
 
+  if (!mach_type_specified_p)
+    arc_select_cpu ("arc700");
+
   /* The endianness can be chosen "at the factory".  */
   target_big_endian = byte_order == BIG_ENDIAN;
 
@@ -2853,8 +2904,6 @@ arc_parse_name (const char *name,
 int
 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
 {
-  int cpu_flags = EF_ARC_CPU_GENERIC;
-
   switch (c)
     {
     case OPTION_ARC600:
@@ -2872,37 +2921,8 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
 
     case OPTION_MCPU:
       {
-       int i;
-       char *s = alloca (strlen (arg) + 1);
-
-       {
-         char *t = s;
-         char *arg1 = arg;
-
-         do
-           *t = TOLOWER (*arg1++);
-         while (*t++);
-       }
-
-       for (i = 0; cpu_types[i].name; ++i)
-         {
-           if (!strcmp (cpu_types[i].name, s))
-             {
-               arc_target      = cpu_types[i].flags;
-               arc_target_name = cpu_types[i].name;
-               arc_features    = cpu_types[i].features;
-               arc_mach_type   = cpu_types[i].mach;
-               cpu_flags       = cpu_types[i].eflags;
-
-               mach_type_specified_p = 1;
-               break;
-             }
-         }
-
-       if (!cpu_types[i].name)
-         {
-           as_fatal (_("unknown architecture: %s\n"), arg);
-         }
+        arc_select_cpu (arg);
+        mach_type_specified_p = 1;
        break;
       }
 
@@ -2956,9 +2976,6 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
       return 0;
     }
 
-  if (cpu_flags != EF_ARC_CPU_GENERIC)
-    arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
-
   return 1;
 }
 
@@ -3551,7 +3568,7 @@ tc_arc_fix_adjustable (fixS *fixP)
       break;
     }
 
-  return 0; /* FIXME! return 1, fix it in the linker.  */
+  return 1;
 }
 
 /* Compute the reloc type of an expression EXP.  */
This page took 0.025365 seconds and 4 git commands to generate.