* config/tc-sparc.c (md_shortopts): Add "K:" if OBJ_ELF.
authorIan Lance Taylor <ian@airs.com>
Wed, 5 Jul 1995 21:52:10 +0000 (21:52 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 5 Jul 1995 21:52:10 +0000 (21:52 +0000)
(md_parse_option): If OBJ_ELF, check for -K.  Die if -K PIC, since
PIC code is not currently supported.

* as.c (parse_args): Change std_shortopts to be an array rather
than a constant string.  Only include 'K' if WORKING_DOT_WORD is
not defined.  Only check for 'K' in that case as well.
* as.h (flag_warn_displacement): Only declare if WORKING_DOT_WORD
is not defined.
PR 7131.

gas/ChangeLog
gas/as.c
gas/as.h
gas/config/tc-sparc.c

index 57a14261bd50144a030f9c6a6deb33addec41edf..121d05d8bceaacc4dd4fd404ac679a7cbffc2668 100644 (file)
@@ -1,5 +1,15 @@
 Wed Jul  5 12:01:49 1995  Ian Lance Taylor  <ian@cygnus.com>
 
+       * config/tc-sparc.c (md_shortopts): Add "K:" if OBJ_ELF.
+       (md_parse_option): If OBJ_ELF, check for -K.  Die if -K PIC, since
+       PIC code is not currently supported.
+
+       * as.c (parse_args): Change std_shortopts to be an array rather
+       than a constant string.  Only include 'K' if WORKING_DOT_WORD is
+       not defined.  Only check for 'K' in that case as well.
+       * as.h (flag_warn_displacement): Only declare if WORKING_DOT_WORD
+       is not defined.
+
        * conf.in: Add undef of HAVE_SBRK.
 
        * config/obj-coff.c (obj_coff_line): Call listing_source_line, in
index 5a937b38eb7747e3488886646e5d1b305cd48de5..d439a95bb50d88a3876357bd6ef5bfeb3179913d 100644 (file)
--- a/gas/as.c
+++ b/gas/as.c
@@ -214,13 +214,22 @@ parse_args (pargc, pargv)
 
   char *shortopts;
   extern CONST char *md_shortopts;
-#ifdef VMS
-  /* -v takes an argument on VMS, so we don't make it a generic option.  */
-  CONST char *std_shortopts = "-JKLRWZfa::DI:o:wX";
-#else
-  CONST char *std_shortopts = "-JKLRWZfa::DI:o:vwX";
+  static const char std_shortopts[] =
+    {
+      '-', 'J',
+#ifndef WORKING_DOT_WORD
+      /* -K is not meaningful if .word is not being hacked.  */
+      'K',
 #endif
-
+      'L', 'R', 'W', 'Z', 'f', 'a', ':', ':', 'D', 'I', ':', 'o', ':',
+#ifndef VMS
+      /* -v takes an argument on VMS, so we don't make it a generic
+         option.  */
+      'v',
+#endif
+      'w', 'X',
+      '\0'
+    };
   struct option *longopts;
   extern struct option md_longopts[];
   extern size_t md_longopts_size;
@@ -348,9 +357,11 @@ parse_args (pargc, pargv)
          flag_signed_overflow_ok = 1;
          break;
 
+#ifndef WORKING_DOT_WORD
        case 'K':
          flag_warn_displacement = 1;
          break;
+#endif
 
        case 'L':
          flag_keep_locals = 1;
index 7477388a723a3df202b87b89008da22d9b7a4655..252106c5f0248b7131cc7f7f2125f30e51de464c 100644 (file)
--- a/gas/as.h
+++ b/gas/as.h
@@ -473,7 +473,9 @@ COMMON fragS bss_address_frag;
 COMMON unsigned char flag_no_comments; /* -f */
 COMMON unsigned char flag_debug; /* -D */
 COMMON unsigned char flag_signed_overflow_ok; /* -J */
+#ifndef WORKING_DOT_WORD
 COMMON unsigned char flag_warn_displacement; /* -K */
+#endif
 
 /* True if local symbols should be retained.  */
 COMMON unsigned char flag_keep_locals; /* -L */
@@ -627,6 +629,9 @@ valueT add_to_literal_pool PARAMS ((struct symbol *, valueT, segT, int));
 #include "tc.h"
 #include "obj.h"
 
+#ifdef USE_EMULATIONS
+#include "emul.h"
+#endif
 #include "listing.h"
 
 #ifndef LOCAL_LABELS_DOLLAR
index 5fa7d9dae60b31a2096d17476fa6d858bc965e5f..5bfa901fc2be4decc18299048bbf0b208676353b 100644 (file)
@@ -38,8 +38,6 @@ static int warn_on_bump;
 
 extern int target_big_endian;
 
-const relax_typeS md_relax_table[1];
-
 /* handle of the OPCODE hash table */
 static struct hash_control *op_hash;
 
@@ -77,8 +75,6 @@ const pseudo_typeS md_pseudo_table[] =
   {NULL, 0, 0},
 };
 
-const int md_short_jump_size = 4;
-const int md_long_jump_size = 4;
 const int md_reloc_size = 12;  /* Size of relocation record */
 
 /* This array holds the chars that always start a comment.  If the
@@ -719,7 +715,7 @@ sparc_ip (str)
   char *s;
   const char *args;
   char c;
-  struct sparc_opcode *insn;
+  const struct sparc_opcode *insn;
   char *argsStart;
   unsigned long opcode;
   unsigned int mask = 0;
@@ -745,10 +741,10 @@ sparc_ip (str)
       break;
 
     default:
-      as_bad ("Unknown opcode: `%s'", str);
-      exit (1);
+      as_fatal ("Unknown opcode: `%s'", str);
     }
-  if ((insn = (struct sparc_opcode *) hash_find (op_hash, str)) == NULL)
+  insn = (struct sparc_opcode *) hash_find (op_hash, str);
+  if (insn == NULL)
     {
       as_bad ("Unknown opcode: `%s'", str);
       return;
@@ -1544,23 +1540,6 @@ sparc_ip (str)
 
            case 'A':
              {
-#ifdef NO_V9
-               char *push = input_line_pointer;
-               expressionS e;
-
-               input_line_pointer = s;
-
-               expression (&e);
-               if (e.X_op == O_constant)
-                 {
-                   opcode |= e.X_add_number << 5;
-                   s = input_line_pointer;
-                   input_line_pointer = push;
-                   continue;
-                 }             /* if absolute */
-
-               break;
-#else
                int asi = 0;
 
                /* Parse an asi.  */
@@ -1585,11 +1564,19 @@ sparc_ip (str)
                        goto error;
                      }
                  }
-               else if (isdigit (*s))
+               else
                  {
                    char *push = input_line_pointer;
+                   expressionS e;
                    input_line_pointer = s;
-                   asi = get_absolute_expression ();
+
+                   expression (&e);
+                   if (e.X_op != O_constant)
+                     {
+                       error_message = ": constant required for ASI";
+                       goto error;
+                     }
+                   asi = e.X_add_number;
                    s = input_line_pointer;
                    input_line_pointer = push;
                    
@@ -1599,14 +1586,8 @@ sparc_ip (str)
                        goto error;
                      }
                  }
-               else
-                 {
-                   error_message = ": unrecognizable asi";
-                   goto error;
-                 }
                opcode |= ASI (asi);
                continue;
-#endif
              }                 /* alternate space */
 
            case 'p':
@@ -1718,7 +1699,8 @@ sparc_ip (str)
        {
          /* Args don't match. */
          if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
-             && !strcmp (insn->name, insn[1].name))
+             && (insn->name == insn[1].name
+                 || !strcmp (insn->name, insn[1].name)))
            {
              ++insn;
              s = argsStart;
@@ -1895,9 +1877,18 @@ md_apply_fix (fixP, value)
 #ifdef OBJ_ELF
   /* FIXME: SPARC ELF relocations don't use an addend in the data
      field itself.  This whole approach should be somehow combined
-     with the calls to bfd_perform_relocation.  */
+     with the calls to bfd_perform_relocation.  Also, the value passed
+     in by fixup_segment includes the value of a defined symbol.  We
+     don't want to include the value of an externally visible symbol.  */
   if (fixP->fx_addsy != NULL)
-    return 1;
+    {
+      if (S_IS_EXTERN (fixP->fx_addsy)
+         && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section
+         && S_GET_SEGMENT (fixP->fx_addsy) != undefined_section
+         && ! bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy)))
+       fixP->fx_addnumber -= S_GET_VALUE (fixP->fx_addsy);
+      return 1;
+    }
 #endif
 
   /* This is a hack.  There should be a better way to
@@ -2107,6 +2098,8 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_32_PCREL_S2:
     case BFD_RELOC_SPARC13:
     case BFD_RELOC_SPARC_BASE13:
+    case BFD_RELOC_SPARC_WDISP16:
+    case BFD_RELOC_SPARC_WDISP19:
     case BFD_RELOC_SPARC_WDISP22:
     case BFD_RELOC_64:
     case BFD_RELOC_SPARC_10:
@@ -2133,16 +2126,25 @@ tc_gen_reloc (section, fixp)
   assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
 
   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
+#ifdef OBJ_AOUT
+
+  if (reloc->howto->pc_relative == 0)
+    reloc->addend = fixp->fx_addnumber;
+  else
+    reloc->addend = fixp->fx_offset - reloc->address;
+
+#else /* elf or coff */
+
   if (reloc->howto->pc_relative == 0)
     reloc->addend = fixp->fx_addnumber;
-#if defined (OBJ_ELF) || defined (OBJ_COFF)
   else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
     reloc->addend = (section->vma
                     + fixp->fx_addnumber
                     + md_pcrel_from (fixp));
-#endif
   else
-    reloc->addend = fixp->fx_offset - reloc->address;
+    reloc->addend = fixp->fx_offset;
+
+#endif
 
   return reloc;
 }
@@ -2237,7 +2239,7 @@ print_insn (insn)
  */
 
 #ifdef OBJ_ELF
-CONST char *md_shortopts = "A:VQ:sq";
+CONST char *md_shortopts = "A:K:VQ:sq";
 #else
 CONST char *md_shortopts = "A:";
 #endif
@@ -2314,6 +2316,15 @@ md_parse_option (c, arg)
     case 'q':
       /* quick -- native assembler does fewer checks */
       break;
+
+    case 'K':
+      if (strcmp (arg, "PIC") != 0)
+       as_warn ("Unrecognized option following -K");
+      else
+       {
+         as_warn ("gas does not currently support PIC code for the SPARC");
+         as_fatal ("use /usr/ccs/bin/as instead");
+       }
 #endif
 
     default:
@@ -2358,17 +2369,6 @@ md_undefined_symbol (name)
   return 0;
 }                              /* md_undefined_symbol() */
 
-/* Parse an operand that is machine-specific.
-   We just return without modifying the expression if we have nothing
-   to do. */
-
-/* ARGSUSED */
-void 
-md_operand (expressionP)
-     expressionS *expressionP;
-{
-}
-
 /* Round up a section size to the appropriate boundary. */
 valueT
 md_section_align (segment, size)
@@ -2378,7 +2378,8 @@ md_section_align (segment, size)
 #ifndef OBJ_ELF
   /* This is not right for ELF; a.out wants it, and COFF will force
      the alignment anyways.  */
-  valueT align = (valueT) 1 << (valueT) (stdoutput->xvec->align_power_min);
+  valueT align = ((valueT) 1
+                 << (valueT) bfd_get_section_alignment (stdoutput, segment));
   valueT newsize;
   /* turn alignment value into a mask */
   align--;