* config/tc-mips.c (file_mips_isa): New static variable.
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index 68c9c3908912e758aac994cdbe222a7341617648..d99f2a11dea9035feb150974a7b3482813b2dcf5 100644 (file)
@@ -65,15 +65,44 @@ static char *mips_regmask_frag;
 #define GPOPT
 #endif
 
+/* The default target format to use.  */
+#ifdef OBJ_AOUT
+#ifdef TARGET_BYTES_BIG_ENDIAN
+#define DEFAULT_TARGET_FORMAT "a.out-mips-big"
+#else
+#define DEFAULT_TARGET_FORMAT "a.out-mips-little"
+#endif
+#endif /* OBJ_AOUT */
+#ifdef OBJ_ECOFF
+#ifdef TARGET_BYTES_BIG_ENDIAN
+#define DEFAULT_TARGET_FORMAT "ecoff-bigmips"
+#else
+#define DEFAULT_TARGET_FORMAT "ecoff-littlemips"
+#endif
+#endif /* OBJ_ECOFF */
+#ifdef OBJ_ELF
+#ifdef TARGET_BYTES_BIG_ENDIAN
+#define DEFAULT_TARGET_FORMAT "elf32-bigmips"
+#else
+#define DEFAULT_TARGET_FORMAT "elf32-littlemips"
+#endif
+#endif /* OBJ_ELF */
+
+const char *mips_target_format = DEFAULT_TARGET_FORMAT;
+
 /* These variables are filled in with the masks of registers used.
    The object format code reads them and puts them in the appropriate
    place.  */
 unsigned long mips_gprmask;
 unsigned long mips_cprmask[4];
 
-/* MIPS ISA (Instruction Set Architecture) level.  */
+/* MIPS ISA (Instruction Set Architecture) level (may be changed
+   temporarily using .set mipsN).  */
 static int mips_isa = -1;
 
+/* MIPS ISA we are using for this output file.  */
+static int file_mips_isa;
+
 /* MIPS PIC level.  0 is normal, non-PIC code.  2 means to generate
    SVR4 ABI PIC calls.  1 doesn't mean anything.  */
 static int mips_pic;
@@ -88,6 +117,8 @@ static int mips_nobopt;
 #ifdef GPOPT
 /* The size of the small data section.  */
 static int g_switch_value = 8;
+/* Whether the -G option was used.  */
+static int g_switch_seen = 0;
 #endif
 
 #define N_RMASK 0xc4
@@ -376,6 +407,13 @@ const pseudo_typeS md_pseudo_table[] =
   {"double", s_float_cons, 'd'},
   {"extern", s_extern, 0},
   {"float", s_float_cons, 'f'},
+  {"hword", s_cons, 1},
+  {"int", s_cons, 2},
+  {"long", s_cons, 2},
+  {"octa", s_cons, 4},
+  {"quad", s_cons, 3},
+  {"short", s_cons, 1},
+  {"single", s_float_cons, 'f'},
   {"space", s_mips_space, 0},
   {"text", s_change_sec, 't'},
   {"word", s_cons, 2},
@@ -405,7 +443,6 @@ const relax_typeS md_relax_table[] =
   { 0 }
 };
 
-
 static char *expr_end;
 
 static expressionS imm_expr;
@@ -457,6 +494,8 @@ md_begin ()
   if (! ok)
     as_warn ("Could not set architecture and machine");
 
+  file_mips_isa = mips_isa;
+
   op_hash = hash_new ();
 
   for (i = 0; i < NUMOPCODES;)
@@ -520,8 +559,8 @@ md_begin ()
     subseg = now_subseg;
     sec = subseg_new (".reginfo", (subsegT) 0);
 
-    /* I don't know why this section should be loaded, but the ABI
-       says that SHF_ALLOC should be set.  */
+    /* The ABI says this section should be loaded so that the running
+       program can access it.  */
     (void) bfd_set_section_flags (stdoutput, sec,
                                  (SEC_ALLOC | SEC_LOAD
                                   | SEC_READONLY | SEC_DATA));
@@ -1280,7 +1319,7 @@ macro_build (place, counter, ep, name, fmt, va_alist)
                  || r == BFD_RELOC_MIPS_LITERAL
                  || r == BFD_RELOC_LO16
                  || r == BFD_RELOC_MIPS_GOT16
-                 || r== BFD_RELOC_MIPS_CALL16);
+                 || r == BFD_RELOC_MIPS_CALL16);
          continue;
 
        case 'u':
@@ -1518,7 +1557,7 @@ load_address (counter, reg, ep)
       /* If this is a reference to a GP relative symbol, we want
           addiu        $reg,$gp,<sym>          (BFD_RELOC_MIPS_GPREL)
         Otherwise we want
-          lui          $reg,$gp,<sym>          (BFD_RELOC_HI16_S)
+          lui          $reg,<sym>              (BFD_RELOC_HI16_S)
           addiu        $reg,$reg,<sym>         (BFD_RELOC_LO16)
         If we have an addend, we always use the latter form.  */
       if (ep->X_add_number != 0)
@@ -2690,9 +2729,11 @@ macro (ip)
                               treg, (int) BFD_RELOC_MIPS_GPREL, GP);
                  p = frag_var (rs_machine_dependent, 8, 0,
                                RELAX_ENCODE (4, 8, 0, 4, 0,
-                                             mips_warn_about_macros),
+                                             (mips_warn_about_macros
+                                              || (used_at && mips_noat))),
                                offset_expr.X_add_symbol, (long) 0,
                                (char *) NULL);
+                 used_at = 0;
                }
              macro_build_lui (p, &icnt, &offset_expr, tempreg);
              if (p != NULL)
@@ -3012,7 +3053,7 @@ macro (ip)
                           (int) BFD_RELOC_MIPS_GPREL, tempreg);
              p = frag_var (rs_machine_dependent, 12 + off, 0,
                            RELAX_ENCODE (8 + off, 12 + off, 0, 4 + off, 1,
-                                         used_at && mips_noat),
+                                         used_at && mips_noat),
                            offset_expr.X_add_symbol, (long) 0,
                            (char *) NULL);
 
@@ -3748,8 +3789,7 @@ mips_ip (str, ip)
              ++insn;
              continue;
            }
-         insn_error = "ERROR: instruction not supported on this processor";
-         return;
+         as_warn ("Instruction not supported on this processor");
        }
 
       ip->insn_mo = insn;
@@ -4519,6 +4559,30 @@ md_parse_option (argP, cntP, vecP)
   if (strcmp (*argP, "EL") == 0
       || strcmp (*argP, "EB") == 0)
     {
+      if ((*argP)[1] == 'B')
+       byte_order = BIG_ENDIAN;
+      else
+       byte_order = LITTLE_ENDIAN;
+
+#ifdef OBJ_AOUT
+      if ((*argP)[1] == 'B')
+       mips_target_format = "a.out-mips-big";
+      else
+       mips_target_format = "a.out-mips-little";
+#endif
+#ifdef OBJ_ECOFF
+      if ((*argP)[1] == 'B')
+       mips_target_format = "ecoff-bigmips";
+      else
+       mips_target_format = "ecoff-littlemips";
+#endif
+#ifdef OBJ_ELF
+      if ((*argP)[1] == 'B')
+       mips_target_format = "elf32-bigmips";
+      else
+       mips_target_format = "elf32-littlemips";
+#endif
+
       /* FIXME: This breaks -L -EL.  */
       flagseen['L'] = 0;
       *argP = "";
@@ -4627,6 +4691,7 @@ md_parse_option (argP, cntP, vecP)
        }
       else
        as_warn ("Number expected after -G");
+      g_switch_seen = 1;
       *argP = "";
       return 1;
     }
@@ -5063,6 +5128,14 @@ s_option (x)
       mips_pic = atoi (opt + 3);
       /* Supposedly no other values are used.  */
       assert (mips_pic == 0 || mips_pic == 2);
+
+      if (mips_pic == 2)
+       {
+         if (g_switch_seen && g_switch_value != 0)
+           as_warn ("-G may not be used with PIC code");
+         g_switch_value = 0;
+         bfd_set_gp_size (stdoutput, 0);
+       }
     }
   else
     as_warn ("Unrecognized option \"%s\"", opt);
@@ -5131,6 +5204,20 @@ s_mipsset (x)
     {
       mips_nobopt = 1;
     }
+  else if (strncmp (name, "mips", 4) == 0)
+    {
+      int isa;
+
+      /* Permit the user to change the ISA on the fly.  Needless to
+        say, misuse can cause serious problems.  */
+      isa = atoi (name + 4);
+      if (isa == 0)
+       mips_isa = file_mips_isa;
+      else if (isa < 1 || isa > 3)
+       as_bad ("unknown ISA level");
+      else
+       mips_isa = isa;
+    }
   else
     {
       as_warn ("Tried to set unrecognized symbol: %s\n", name);
This page took 0.025271 seconds and 4 git commands to generate.