* config/tc-mips.c: Use USE_STDARG and USE_VARARGS instead of NO_STDARG &c.
authorKen Raeburn <raeburn@cygnus>
Tue, 2 May 1995 19:33:00 +0000 (19:33 +0000)
committerKen Raeburn <raeburn@cygnus>
Tue, 2 May 1995 19:33:00 +0000 (19:33 +0000)
* config/tc-mips.c (mips_target_format): Changed to a function, checking flavor
and byte order at run time.
(md_parse_option, cases OPTION_EB and OPTION_EL): Set target_big_endian here.
(md_begin): Not here.
* config/tc-mips.h (mips_target_format): Adjust declaration.
(TARGET_FORMAT): Call mips_target_format.

* config/tc-mips.h (USE_GLOBAL_POINTER_OPT): Define in terms of OUTPUT_FLAVOR.
* config/tc-mips.c (g_switch_value, g_switch_seen): Define unconditionally.
(md_begin, mips_ip, md_parse_option, s_change_sec, s_option, s_abicalls,
nopic_need_relax): Check USE_GLOBAL_POINTER_OPT at run time, instead of
compiling conditionally on GPOPT.
(GPOPT): Don't define.
(md_shortopts): Always include -G.
(RDATA_SECTION_NAME): Select at run time.
(md_begin): Test for ELF format at run time instead of compile time.
(mips_ip, s_change_sec): Ditto.
(md_parse_option, cases OPTION_CALL_SHARED and OPTION_NON_SHARED): Ditto.
(OPTION_CALL_SHARED, OPTION_NON_SHARED, mips_regmask_frag): Define
unconditionally.

gas/config/tc-mips.c
gas/config/tc-mips.h

index 4fb2c0aeaf2891c1d5de18e781b4b3502473303c..54a45292672a269bad112005f55c0ee72581cfaa 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-mips.c -- assemble code for a MIPS chip.
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995 Free Software Foundation, Inc.
    Contributed by the OSF and Ralph Campbell.
    Written by Keith Knowles and Ralph Campbell, working independently.
    Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
 
 #include <ctype.h>
 
-#ifndef __STDC__
-#ifndef NO_STDARG
-#define NO_STDARG
-#endif
-#endif
-
-#ifndef NO_STDARG
+#ifdef USE_STDARG
 #include <stdarg.h>
-#else
-#ifndef NO_VARARGS
+#endif
+#ifdef USE_VARARGS
 #include <varargs.h>
-#endif /* NO_VARARGS */
-#endif /* NO_STDARG */
+#endif
 
 #include "opcode/mips.h"
 
 #ifdef OBJ_ELF
 #include "elf/mips.h"
+#endif
 
 static char *mips_regmask_frag;
-#endif
 
 #define AT  1
 #define PIC_CALL_REG 25
@@ -59,51 +52,33 @@ static char *mips_regmask_frag;
 #define FP  30
 #define RA  31
 
-/* Decide whether to do GP reference optimizations based on the object
-   file format.  */
-#undef GPOPT
-#ifdef OBJ_ECOFF
-#define GPOPT
-#endif
-#ifdef OBJ_ELF
-#define GPOPT
-#endif
+extern int target_big_endian;
 
 /* 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;
+const char *
+mips_target_format ()
+{
+  switch (OUTPUT_FLAVOR)
+    {
+    case bfd_target_aout_flavour:
+      return target_big_endian ? "a.out-mips-big" : "a.out-mips-little";
+    case bfd_target_ecoff_flavour:
+      return target_big_endian ? "ecoff-bigmips" : "ecoff-littlemips";
+    case bfd_target_elf_flavour:
+      return target_big_endian ? "elf32-bigmips" : "elf32-littlemips";
+    default:
+      abort ();
+    }
+}
 
 /* The name of the readonly data section.  */
-#ifdef OBJ_AOUT
-#define RDATA_SECTION_NAME ".data"
-#endif
-#ifdef OBJ_ECOFF
-#define RDATA_SECTION_NAME ".rdata"
-#endif
-#ifdef OBJ_ELF
-#define RDATA_SECTION_NAME ".rodata"
-#endif
+#define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
+                           ? ".data" \
+                           : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+                           ? ".rdata" \
+                           : OUTPUT_FLAVOR == bfd_target_elf_flavour \
+                           ? ".rodata" \
+                           : (abort (), ""))
 
 /* These variables are filled in with the masks of registers used.
    The object format code reads them and puts them in the appropriate
@@ -158,12 +133,10 @@ static int mips_nomove;
 static int mips_noat;
 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
 #define N_VFP   0xd4
@@ -511,11 +484,6 @@ const pseudo_typeS md_pseudo_table[] =
   {NULL}
 };
 \f
-const relax_typeS md_relax_table[] =
-{
-  { 0 }
-};
-
 static char *expr_end;
 
 static expressionS imm_expr;
@@ -523,9 +491,6 @@ static expressionS offset_expr;
 static bfd_reloc_code_real_type imm_reloc;
 static bfd_reloc_code_real_type offset_reloc;
 
-/* FIXME: This should be handled in a different way.  */
-extern int target_big_endian;
-
 /*
  * This function is called once, at assembler startup time.  It should
  * set up all the tables, etc. that the MD part of the assembler will need.
@@ -682,49 +647,48 @@ md_begin ()
   /* set the default alignment for the text section (2**2) */
   record_alignment (text_section, 2);
 
-  /* FIXME: This should be handled in a different way.  */
-  target_big_endian = byte_order == BIG_ENDIAN;
-
-#ifdef GPOPT
-  bfd_set_gp_size (stdoutput, g_switch_value);
-#endif
+  if (USE_GLOBAL_POINTER_OPT)
+    bfd_set_gp_size (stdoutput, g_switch_value);
 
-#ifdef OBJ_ELF
-  /* Sections must be aligned to 16 byte boundaries.  */
-  (void) bfd_set_section_alignment (stdoutput, text_section, 4);
-  (void) bfd_set_section_alignment (stdoutput, data_section, 4);
-  (void) bfd_set_section_alignment (stdoutput, bss_section, 4);
+  if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+    {
+      /* Sections must be aligned to 16 byte boundaries.  */
+      (void) bfd_set_section_alignment (stdoutput, text_section, 4);
+      (void) bfd_set_section_alignment (stdoutput, data_section, 4);
+      (void) bfd_set_section_alignment (stdoutput, bss_section, 4);
 
-  /* Create a .reginfo section for register masks and a .mdebug
-     section for debugging information.  */
-  {
-    segT seg;
-    subsegT subseg;
-    segT sec;
+      /* Create a .reginfo section for register masks and a .mdebug
+        section for debugging information.  */
+      {
+       segT seg;
+       subsegT subseg;
+       segT sec;
 
-    seg = now_seg;
-    subseg = now_subseg;
-    sec = subseg_new (".reginfo", (subsegT) 0);
+       seg = now_seg;
+       subseg = now_subseg;
+       sec = subseg_new (".reginfo", (subsegT) 0);
 
-    /* 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));
-    (void) bfd_set_section_alignment (stdoutput, sec, 2);
+       /* 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));
+       (void) bfd_set_section_alignment (stdoutput, sec, 2);
 
-    mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));
+#ifdef OBJ_ELF
+       mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));
+#endif
 
 #ifdef ECOFF_DEBUGGING
-    sec = subseg_new (".mdebug", (subsegT) 0);
-    (void) bfd_set_section_flags (stdoutput, sec,
-                                 SEC_HAS_CONTENTS | SEC_READONLY);
-    (void) bfd_set_section_alignment (stdoutput, sec, 2);
+       sec = subseg_new (".mdebug", (subsegT) 0);
+       (void) bfd_set_section_flags (stdoutput, sec,
+                                     SEC_HAS_CONTENTS | SEC_READONLY);
+       (void) bfd_set_section_alignment (stdoutput, sec, 2);
 #endif
 
-    subseg_set (seg, subseg);
-  }
-#endif /* OBJ_ELF */
+       subseg_set (seg, subseg);
+      }
+    }
 
 #ifndef ECOFF_DEBUGGING
   md_obj_begin ();
@@ -1387,7 +1351,7 @@ mips_emit_delays ()
    expression, the name of the instruction to build, an operand format
    string, and corresponding arguments.  */
 
-#ifndef NO_STDARG
+#ifdef USE_STDARG
 static void
 macro_build (char *place,
             int *counter,
@@ -1395,7 +1359,7 @@ macro_build (char *place,
             const char *name,
             const char *fmt,
             ...)
-#else /* ! defined (NO_STDARG) */
+#else
 static void
 macro_build (place, counter, ep, name, fmt, va_alist)
      char *place;
@@ -1404,13 +1368,13 @@ macro_build (place, counter, ep, name, fmt, va_alist)
      const char *name;
      const char *fmt;
      va_dcl
-#endif /* ! defined (NO_STDARG) */
+#endif
 {
   struct mips_cl_insn insn;
   bfd_reloc_code_real_type r;
   va_list args;
 
-#ifndef NO_STDARG
+#ifdef USE_STDARG
   va_start (args, fmt);
 #else
   va_start (args);
@@ -4794,10 +4758,9 @@ mips_ip (str, ip)
 
                if (*args == 'f'
                    || (*args == 'l'
-#ifdef GPOPT
-                       && (mips_pic == EMBEDDED_PIC
+                       && (! USE_GLOBAL_POINTER_OPT
+                           || mips_pic == EMBEDDED_PIC
                            || g_switch_value < 4)
-#endif
                        ))
                  {
                    imm_expr.X_op = O_constant;
@@ -4827,28 +4790,24 @@ mips_ip (str, ip)
                      default: /* unused default case avoids warnings.  */
                      case 'L':
                        newname = RDATA_SECTION_NAME;
-#ifdef GPOPT
-                       if (g_switch_value >= 8)
+                       if (USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)
                          newname = ".lit8";
-#endif
                        break;
                      case 'F':
                        newname = RDATA_SECTION_NAME;
                        break;
                      case 'l':
-#ifdef GPOPT
-                       assert (g_switch_value >= 4);
-#endif
+                       assert (!USE_GLOBAL_POINTER_OPT
+                               || g_switch_value >= 4);
                        newname = ".lit4";
                        break;
                      }
                    new_seg = subseg_new (newname, (subsegT) 0);
                    frag_align (*args == 'l' ? 2 : 3, 0);
-#ifdef OBJ_ELF
-                   record_alignment (new_seg, 4);
-#else
-                   record_alignment (new_seg, *args == 'l' ? 2 : 3);
-#endif
+                   if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+                     record_alignment (new_seg, 4);
+                   else
+                     record_alignment (new_seg, *args == 'l' ? 2 : 3);
                    if (seg == now_seg)
                      as_bad ("Can't use floating point insn in this section");
 
@@ -5227,11 +5186,8 @@ md_number_to_chars (buf, val, n)
     }
 }
 \f
-#ifdef GPOPT
 CONST char *md_shortopts = "O::g::G:";
-#else
-CONST char *md_shortopts = "O::g::";
-#endif
+
 struct option md_longopts[] = {
 #define OPTION_MIPS1 (OPTION_MD_BASE + 1)
   {"mips0", no_argument, NULL, OPTION_MIPS1},
@@ -5261,11 +5217,11 @@ struct option md_longopts[] = {
 #define OPTION_NO_M4650 (OPTION_MD_BASE + 14)
   {"no-m4650", no_argument, NULL, OPTION_NO_M4650},
 
-#ifdef OBJ_ELF
 #define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
+#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
+#ifdef OBJ_ELF
   {"KPIC", no_argument, NULL, OPTION_CALL_SHARED},
   {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
-#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
   {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
 #endif
 
@@ -5290,28 +5246,12 @@ md_parse_option (c, arg)
 
     case OPTION_EB:
       byte_order = BIG_ENDIAN;
-#ifdef OBJ_AOUT
-      mips_target_format = "a.out-mips-big";
-#endif
-#ifdef OBJ_ECOFF
-      mips_target_format = "ecoff-bigmips";
-#endif
-#ifdef OBJ_ELF
-      mips_target_format = "elf32-bigmips";
-#endif
+      target_big_endian = 1;
       break;
 
     case OPTION_EL:
       byte_order = LITTLE_ENDIAN;
-#ifdef OBJ_AOUT
-      mips_target_format = "a.out-mips-little";
-#endif
-#ifdef OBJ_ECOFF
-      mips_target_format = "ecoff-littlemips";
-#endif
-#ifdef OBJ_ELF
-      mips_target_format = "elf32-littlemips";
-#endif
+      target_big_endian = 0;
       break;
 
     case 'O':
@@ -5444,21 +5384,23 @@ md_parse_option (c, arg)
 
     case OPTION_MEMBEDDED_PIC:
       mips_pic = EMBEDDED_PIC;
-#ifdef GPOPT
-      if (g_switch_seen)
+      if (USE_GLOBAL_POINTER_OPT && g_switch_seen)
        {
          as_bad ("-G may not be used with embedded PIC code");
          return 0;
        }
       g_switch_value = 0x7fffffff;
-#endif
       break;
 
-#ifdef OBJ_ELF
   /* When generating ELF code, we permit -KPIC and -call_shared to
      select SVR4_PIC, and -non_shared to select no PIC.  This is
      intended to be compatible with Irix 5.  */
     case OPTION_CALL_SHARED:
+      if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+       {
+         as_bad ("-call_shared is supported only for ELF format");
+         return 0;
+       }
       mips_pic = SVR4_PIC;
       if (g_switch_seen && g_switch_value != 0)
        {
@@ -5469,13 +5411,21 @@ md_parse_option (c, arg)
       break;
 
     case OPTION_NON_SHARED:
+      if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+       {
+         as_bad ("-non_shared is supported only for ELF format");
+         return 0;
+       }
       mips_pic = NO_PIC;
       break;
-#endif /* OBJ_ELF */
 
-#ifdef GPOPT
     case 'G':
-      if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)
+      if (! USE_GLOBAL_POINTER_OPT)
+       {
+         as_bad ("-G is not supported for this configuration");
+         return 0;
+       }
+      else if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)
        {
          as_bad ("-G may not be used with SVR4 or embedded PIC code");
          return 0;
@@ -5484,7 +5434,6 @@ md_parse_option (c, arg)
        g_switch_value = atoi (arg);
       g_switch_seen = 1;
       break;
-#endif
 
     default:
       return 0;
@@ -5527,15 +5476,14 @@ long
 md_pcrel_from (fixP)
      fixS *fixP;
 {
-#ifndef OBJ_AOUT
-  if (fixP->fx_addsy != (symbolS *) NULL
+  if (OUTPUT_FLAVOR != bfd_target_aout_flavour
+      && fixP->fx_addsy != (symbolS *) NULL
       && ! S_IS_DEFINED (fixP->fx_addsy))
     {
       /* This makes a branch to an undefined symbol be a branch to the
         current location.  */
       return 4;
     }
-#endif
 
   /* return the address of the delay slot */
   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
@@ -5965,9 +5913,7 @@ static void
 s_change_sec (sec)
      int sec;
 {
-#ifdef GPOPT
   segT seg;
-#endif
 
   /* When generating embedded PIC code, we only use the .text, .lit8,
      .sdata and .sbss sections.  We change the .data and .rdata
@@ -5991,41 +5937,50 @@ s_change_sec (sec)
       break;
 
     case 'r':
-#ifdef GPOPT
-      seg = subseg_new (RDATA_SECTION_NAME,
-                       (subsegT) get_absolute_expression ());
-#ifdef OBJ_ELF
-      bfd_set_section_flags (stdoutput, seg,
-                            (SEC_ALLOC
-                             | SEC_LOAD
-                             | SEC_READONLY
-                             | SEC_RELOC
-                             | SEC_DATA));
-      bfd_set_section_alignment (stdoutput, seg, 4);
-#endif
-      demand_empty_rest_of_line ();
-#else /* ! defined (GPOPT) */
-      as_bad ("No read only data section in this object file format");
-      demand_empty_rest_of_line ();
-      return;
-#endif /* ! defined (GPOPT) */
+      if (USE_GLOBAL_POINTER_OPT)
+       {
+         seg = subseg_new (RDATA_SECTION_NAME,
+                           (subsegT) get_absolute_expression ());
+         if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+           {
+             bfd_set_section_flags (stdoutput, seg,
+                                    (SEC_ALLOC
+                                     | SEC_LOAD
+                                     | SEC_READONLY
+                                     | SEC_RELOC
+                                     | SEC_DATA));
+             bfd_set_section_alignment (stdoutput, seg, 4);
+           }
+         demand_empty_rest_of_line ();
+       }
+      else
+       {
+         as_bad ("No read only data section in this object file format");
+         demand_empty_rest_of_line ();
+         return;
+       }
       break;
 
     case 's':
-#ifdef GPOPT
-      seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
-#ifdef OBJ_ELF
-      bfd_set_section_flags (stdoutput, seg,
-                            SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
-      bfd_set_section_alignment (stdoutput, seg, 4);
-#endif
-      demand_empty_rest_of_line ();
-      break;
-#else /* ! defined (GPOPT) */
-      as_bad ("Global pointers not supported; recompile -G 0");
-      demand_empty_rest_of_line ();
-      return;
-#endif /* ! defined (GPOPT) */
+      if (USE_GLOBAL_POINTER_OPT)
+       {
+         seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
+         if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+           {
+             bfd_set_section_flags (stdoutput, seg,
+                                    SEC_ALLOC | SEC_LOAD | SEC_RELOC
+                                    | SEC_DATA);
+             bfd_set_section_alignment (stdoutput, seg, 4);
+           }
+         demand_empty_rest_of_line ();
+         break;
+       }
+      else
+       {
+         as_bad ("Global pointers not supported; recompile -G 0");
+         demand_empty_rest_of_line ();
+         return;
+       }
     }
 
   auto_align = 1;
@@ -6172,15 +6127,13 @@ s_option (x)
       else
        as_bad (".option pic%d not supported", i);
 
-#ifdef GPOPT
-      if (mips_pic == SVR4_PIC)
+      if (USE_GLOBAL_POINTER_OPT && mips_pic == SVR4_PIC)
        {
          if (g_switch_seen && g_switch_value != 0)
            as_warn ("-G may not be used with SVR4 PIC code");
          g_switch_value = 0;
          bfd_set_gp_size (stdoutput, 0);
        }
-#endif
     }
   else
     as_warn ("Unrecognized option \"%s\"", opt);
@@ -6291,11 +6244,12 @@ s_abicalls (ignore)
      int ignore;
 {
   mips_pic = SVR4_PIC;
-#ifdef GPOPT
-  if (g_switch_seen && g_switch_value != 0)
-    as_warn ("-G may not be used with SVR4 PIC code");
-  g_switch_value = 0;
-#endif
+  if (USE_GLOBAL_POINTER_OPT)
+    {
+      if (g_switch_seen && g_switch_value != 0)
+       as_warn ("-G may not be used with SVR4 PIC code");
+      g_switch_value = 0;
+    }
   bfd_set_gp_size (stdoutput, 0);
   demand_empty_rest_of_line ();
 }
@@ -6512,49 +6466,49 @@ static int nopic_need_relax (sym)
   if (sym == 0)
     return 0;
 
-#ifdef GPOPT
-  {
-    const char *symname;
-    int change;
-
-    /* Find out whether this symbol can be referenced off the GP
-       register.  It can be if it is smaller than the -G size or if it
-       is in the .sdata or .sbss section.  Certain symbols can not be
-       referenced off the GP, although it appears as though they can.  */
-    symname = S_GET_NAME (sym);
-    if (symname != (const char *) NULL
-       && (strcmp (symname, "eprol") == 0
-           || strcmp (symname, "etext") == 0
-           || strcmp (symname, "_gp") == 0
-           || strcmp (symname, "edata") == 0
-           || strcmp (symname, "_fbss") == 0
-           || strcmp (symname, "_fdata") == 0
-           || strcmp (symname, "_ftext") == 0
-           || strcmp (symname, "end") == 0
-           || strcmp (symname, "_gp_disp") == 0))
-      change = 1;
-    else if (! S_IS_DEFINED (sym)
-            && ((sym->ecoff_extern_size != 0
-                 && sym->ecoff_extern_size <= g_switch_value)
-                || (S_GET_VALUE (sym) != 0
-                    && S_GET_VALUE (sym) <= g_switch_value)))
-      change = 0;
-    else
-      {
-       const char *segname;
+  if (USE_GLOBAL_POINTER_OPT)
+    {
+      const char *symname;
+      int change;
+
+      /* Find out whether this symbol can be referenced off the GP
+        register.  It can be if it is smaller than the -G size or if
+        it is in the .sdata or .sbss section.  Certain symbols can
+        not be referenced off the GP, although it appears as though
+        they can.  */
+      symname = S_GET_NAME (sym);
+      if (symname != (const char *) NULL
+         && (strcmp (symname, "eprol") == 0
+             || strcmp (symname, "etext") == 0
+             || strcmp (symname, "_gp") == 0
+             || strcmp (symname, "edata") == 0
+             || strcmp (symname, "_fbss") == 0
+             || strcmp (symname, "_fdata") == 0
+             || strcmp (symname, "_ftext") == 0
+             || strcmp (symname, "end") == 0
+             || strcmp (symname, "_gp_disp") == 0))
+       change = 1;
+      else if (! S_IS_DEFINED (sym)
+              && ((sym->ecoff_extern_size != 0
+                   && sym->ecoff_extern_size <= g_switch_value)
+                  || (S_GET_VALUE (sym) != 0
+                      && S_GET_VALUE (sym) <= g_switch_value)))
+       change = 0;
+      else
+       {
+         const char *segname;
 
-       segname = segment_name (S_GET_SEGMENT (sym));
-       assert (strcmp (segname, ".lit8") != 0
-               && strcmp (segname, ".lit4") != 0);
-       change = (strcmp (segname, ".sdata") != 0
-                 && strcmp (segname, ".sbss") != 0);
-      }
-    return change;
-  }
-#else /* ! defined (GPOPT) */
-  /* We are not optimizing for the GP register.  */
-  return 1;
-#endif /* ! defined (GPOPT) */  
+         segname = segment_name (S_GET_SEGMENT (sym));
+         assert (strcmp (segname, ".lit8") != 0
+                 && strcmp (segname, ".lit4") != 0);
+         change = (strcmp (segname, ".sdata") != 0
+                   && strcmp (segname, ".sbss") != 0);
+       }
+      return change;
+    }
+  else
+    /* We are not optimizing for the GP register.  */
+    return 1;
 }
 
 /*ARGSUSED*/
@@ -6625,9 +6579,8 @@ tc_gen_reloc (section, fixp)
         is actually the difference between the reloc address and the
         subtrahend.  */
       reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
-#ifndef OBJ_ECOFF
-      as_fatal ("Double check fx_r_type in tc-mips.c:tc_gen_reloc");
-#endif
+      if (OUTPUT_FLAVOR != bfd_target_ecoff_flavour)
+       as_fatal ("Double check fx_r_type in tc-mips.c:tc_gen_reloc");
       fixp->fx_r_type = BFD_RELOC_GPREL32;
     }
   else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16)
@@ -6658,13 +6611,12 @@ tc_gen_reloc (section, fixp)
     reloc->addend = fixp->fx_addnumber;
   else
     {
-#ifndef OBJ_AOUT
-      /* A gruesome hack which is a result of the gruesome gas reloc
-        handling.  */
-      reloc->addend = reloc->address;
-#else
-      reloc->addend = -reloc->address;
-#endif
+      if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
+       /* A gruesome hack which is a result of the gruesome gas reloc
+          handling.  */
+       reloc->addend = reloc->address;
+      else
+       reloc->addend = -reloc->address;
     }
 
   /* If this is a variant frag, we may need to adjust the existing
@@ -6730,12 +6682,11 @@ tc_gen_reloc (section, fixp)
   /* To support a PC relative reloc when generating embedded PIC code
      for ECOFF, we use a Cygnus extension.  We check for that here to
      make sure that we don't let such a reloc escape normally.  */
-#ifdef OBJ_ECOFF
-  if (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
+  if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+      && fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
       && mips_pic != EMBEDDED_PIC)
     reloc->howto = NULL;
   else
-#endif
     reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
 
   if (reloc->howto == NULL)
index 9e0f4aa3dd6f2daf740a57c609612873782b5a3e..ba6d1b4750f4264442245274ba6c70e4c490e04c 100644 (file)
 #define MAX_RELOC_EXPANSION 3
 #define LOCAL_LABELS_FB
 
-#define LOCAL_LABEL(name) ((name)[0] == '$')
+/* The MIPS assembler appears to keep all symbols.  */
+#define LOCAL_LABEL(name) 0
 
 #define md_relax_frag(fragp, stretch)  (0)
 #define md_undefined_symbol(name)      (0)
 #define md_operand(x)
 
+/* We permit PC relative difference expressions when generating
+   embedded PIC code.  */
+#define DIFF_EXPR_OK
+
 #define LITTLE_ENDIAN   1234
 #define BIG_ENDIAN      4321
 
-/* If neither TARGET_BYTES_BIG_ENDIAN nor TARGET_BYTES_LITTLE_ENDIAN
-   is specified, default to big endian.  */
-#ifndef TARGET_BYTES_BIG_ENDIAN
+/* Default to big endian.  */
 #ifndef TARGET_BYTES_LITTLE_ENDIAN
-#define TARGET_BYTES_BIG_ENDIAN
-#endif
+#undef  TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN                1
 #endif
 
-#ifdef TARGET_BYTES_BIG_ENDIAN
+#if TARGET_BYTES_BIG_ENDIAN
 #define BYTE_ORDER     BIG_ENDIAN
 #else
 #define BYTE_ORDER      LITTLE_ENDIAN
 #endif
 
-#ifndef TARGET_FORMAT 
-#ifdef OBJ_AOUT
-#ifdef TARGET_BYTES_BIG_ENDIAN
-#define TARGET_FORMAT "a.out-mips-big"
-#else
-#define TARGET_FORMAT "a.out-mips-little"
-#endif
-#endif /* OBJ_AOUT */
-#ifdef OBJ_ECOFF
-#ifdef TARGET_BYTES_BIG_ENDIAN
-#define TARGET_FORMAT "ecoff-bigmips"
-#else
-#define TARGET_FORMAT "ecoff-littlemips"
-#endif
-#endif /* OBJ_ECOFF */
-#ifdef OBJ_ELF
-#ifdef TARGET_BYTES_BIG_ENDIAN
-#define TARGET_FORMAT "elf32-bigmips"
-#else
-#define TARGET_FORMAT "elf32-littlemips"
-#endif
-#endif /* OBJ_ELF */
-#endif /* ! defined (TARGET_FORMAT) */
+/* The endianness of the target format may change based on command
+   line arguments.  */
+#define TARGET_FORMAT mips_target_format()
+extern const char *mips_target_format ();
 
 struct mips_cl_insn {
     unsigned long              insn_opcode;
@@ -87,12 +71,23 @@ struct mips_cl_insn {
 
 extern int tc_get_register PARAMS ((int frame));
 
+#define md_parse_long_option(arg) mips_parse_long_option (arg)
+extern int mips_parse_long_option PARAMS ((const char *));
+
 #define tc_frob_label(sym) mips_define_label (sym)
 extern void mips_define_label PARAMS ((struct symbol *));
 
 #define TC_CONS_FIX_NEW cons_fix_new_mips
 extern void cons_fix_new_mips ();
 
+/* When generating embedded PIC code we must keep PC relative
+   relocations.  */
+#define TC_FORCE_RELOCATION(fixp) mips_force_relocation (fixp)
+extern int mips_force_relocation ();
+
+/* md_apply_fix sets fx_done correctly.  */
+#define TC_HANDLE_FX_DONE 1
+
 /* Register mask variables.  These are set by the MIPS assembly code
    and used by ECOFF and possibly other object file formats.  */
 extern unsigned long mips_gprmask;
@@ -117,3 +112,6 @@ extern void mips_elf_final_processing PARAMS ((void));
 
 extern void md_mips_end PARAMS ((void));
 #define md_end()       md_mips_end()
+
+#define USE_GLOBAL_POINTER_OPT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+                                || OUTPUT_FLAVOR == bfd_target_elf_flavour)