]> Git Repo - binutils.git/blobdiff - gas/read.c
handle target ppc-*-elf*, for zoo.
[binutils.git] / gas / read.c
index 3d3397df811ec7bc591aae857266e23765577030..2aaeae02f7543d397d2429226104327bb1fdd190 100644 (file)
@@ -1,5 +1,6 @@
 /* read.c - read a source file -
-   Copyright (C) 1986, 1987, 1990, 1991, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1987, 1990, 1991, 1993, 1994
+   Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
 
@@ -70,17 +71,27 @@ die horribly;
 #define LEX_AT 0
 #endif
 
+#ifndef LEX_BR
+/* The RS/6000 assembler uses {,},[,] as parts of symbol names.  */
+#define LEX_BR 0
+#endif
+
+#ifndef LEX_PCT
+/* The Delta 68k assembler permits % inside label names.  */
+#define LEX_PCT 0
+#endif
+
 /* used by is_... macros. our ctype[] */
 const char lex_type[256] =
 {
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* @ABCDEFGHIJKLMNO */
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* PQRSTUVWXYZ[\]^_ */
-  0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,      /* _!"#$%&'()*+,-./ */
+  0, 0, 0, 0, 3, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,        /* _!"#$%&'()*+,-./ */
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,      /* 0123456789:;<=>? */
   LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
-  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3,      /* PQRSTUVWXYZ[\]^_ */
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
   0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,      /* `abcdefghijklmno */
-  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,      /* pqrstuvwxyz{|}~. */
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 0, /* pqrstuvwxyz{|}~. */
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -146,7 +157,7 @@ struct broken_word *broken_words;
 int new_broken_words;
 #endif
 
-static char *demand_copy_string PARAMS ((int *lenP));
+char *demand_copy_string PARAMS ((int *lenP));
 int is_it_end_of_statement PARAMS ((void));
 static segT get_segmented_expression PARAMS ((expressionS *expP));
 static segT get_known_segmented_expression PARAMS ((expressionS * expP));
@@ -242,12 +253,24 @@ static const pseudo_typeS potable[] =
   {"string", stringer, 1},
 /* tag */
   {"text", s_text, 0},
+
+  /* This is for gcc to use.  It's only just been added (2/94), so gcc
+     won't be able to use it for a while -- probably a year or more.
+     But once this has been released, check with gcc maintainers
+     before deleting it or even changing the spelling.  */
+  {"this_GCC_requires_the_GNU_assembler", s_ignore, 0},
+  /* If we're folding case -- done for some targets, not necessarily
+     all -- the above string in an input file will be converted to
+     this one.  Match it either way...  */
+  {"this_gcc_requires_the_gnu_assembler", s_ignore, 0},
+
   {"title", listing_title, 0}, /* Listing title */
 /* type */
 /* use */
 /* val */
   {"xstabs", s_xstab, 's'},
   {"word", cons, 2},
+  {"zero", s_space, 0},
   {NULL}                       /* end sentinel */
 };
 
@@ -356,12 +379,12 @@ read_a_source_file (name)
           * If input_line_pointer [-1] == '\n' then we just
           * scanned another line: so bump line counters.
           */
-         if (is_end_of_line[input_line_pointer[-1]])
+         if (is_end_of_line[(unsigned char) input_line_pointer[-1]])
            {
              if (input_line_pointer[-1] == '\n')
                bump_line_counters ();
 
-#if defined (MRI) || defined (LABLES_WITHOUT_COLONS)
+#if defined (MRI) || defined (LABELS_WITHOUT_COLONS)
              /* Text at the start of a line must be a label, we run down
                 and stick a colon in.  */
              if (is_name_beginner (*input_line_pointer))
@@ -406,7 +429,8 @@ read_a_source_file (name)
           * Input_line_pointer points after that character.
           */
          if (is_name_beginner (c))
-           {                   /* want user-defined label or pseudo/opcode */
+           {
+             /* want user-defined label or pseudo/opcode */
              HANDLE_CONDITIONAL_ASSEMBLY ();
 
              s = --input_line_pointer;
@@ -626,7 +650,7 @@ read_a_source_file (name)
                        num = buffer_limit - buffer;
 
                      tmp_buf = xrealloc (tmp_buf, tmp_len + num);
-                     memcpy (tmp_buf, buffer + tmp_len, num);
+                     memcpy (tmp_buf + tmp_len, buffer, num);
                      tmp_len += num;
                    }
                  while (!ends);
@@ -695,14 +719,49 @@ read_a_source_file (name)
     }                          /* while (more buffers to scan) */
   input_scrub_close ();                /* Close the input file */
 
-}                              /* read_a_source_file() */
+}
 
 void 
 s_abort (ignore)
      int ignore;
 {
   as_fatal (".abort detected.  Abandoning ship.");
-}                              /* s_abort() */
+}
+
+/* Guts of .align directive.  */
+static void 
+do_align (n, fill)
+     int n;
+     char *fill;
+{
+#ifdef md_do_align
+  md_do_align (n, fill, just_record_alignment);
+#endif
+  if (!fill)
+    {
+      /* @@ Fix this right for BFD!  */
+      static char zero;
+      static char nop_opcode = NOP_OPCODE;
+
+      if (now_seg != data_section && now_seg != bss_section)
+       {
+         fill = &nop_opcode;
+       }
+      else
+       {
+         fill = &zero;
+       }
+    }
+  /* Only make a frag if we HAVE to. . . */
+  if (n && !need_pass_2)
+    frag_align (n, *fill);
+
+#ifdef md_do_align
+ just_record_alignment:
+#endif
+
+  record_alignment (now_seg, n);
+}
 
 /* For machines where ".align 4" means align to a 4 byte boundary. */
 void 
@@ -710,7 +769,7 @@ s_align_bytes (arg)
      int arg;
 {
   register unsigned int temp;
-  register long temp_fill;
+  char temp_fill;
   unsigned int i = 0;
   unsigned long max_alignment = 1 << 15;
 
@@ -724,10 +783,8 @@ s_align_bytes (arg)
       as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
     }
 
-  /*
-     * For the sparc, `.align (1<<n)' actually means `.align n'
-     * so we have to convert it.
-     */
+  /* For the sparc, `.align (1<<n)' actually means `.align n' so we
+     have to convert it.  */
   if (temp != 0)
     {
       for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
@@ -741,19 +798,13 @@ s_align_bytes (arg)
     {
       input_line_pointer++;
       temp_fill = get_absolute_expression ();
+      do_align (temp, &temp_fill);
     }
-  else if (now_seg != data_section && now_seg != bss_section)
-    temp_fill = NOP_OPCODE;
   else
-    temp_fill = 0;
-  /* Only make a frag if we HAVE to. . . */
-  if (temp && !need_pass_2)
-    frag_align ((int) temp, (int) temp_fill);
-
-  record_alignment (now_seg, (int) temp);
+    do_align (temp, (char *) 0);
 
   demand_empty_rest_of_line ();
-}                              /* s_align_bytes() */
+}
 
 /* For machines where ".align 4" means align to 2**4 boundary. */
 void 
@@ -761,7 +812,7 @@ s_align_ptwo (ignore)
      int ignore;
 {
   register int temp;
-  register long temp_fill;
+  char temp_fill;
   long max_alignment = 15;
 
   temp = get_absolute_expression ();
@@ -776,20 +827,13 @@ s_align_ptwo (ignore)
     {
       input_line_pointer++;
       temp_fill = get_absolute_expression ();
+      do_align (temp, &temp_fill);
     }
-  /* @@ Fix this right for BFD!  */
-  else if (now_seg != data_section && now_seg != bss_section)
-    temp_fill = NOP_OPCODE;
   else
-    temp_fill = 0;
-  /* Only make a frag if we HAVE to. . . */
-  if (temp && !need_pass_2)
-    frag_align (temp, (int) temp_fill);
-
-  record_alignment (now_seg, temp);
+    do_align (temp, (char *) 0);
 
   demand_empty_rest_of_line ();
-}                              /* s_align_ptwo() */
+}
 
 void 
 s_comm (ignore)
@@ -825,7 +869,8 @@ s_comm (ignore)
   *p = c;
   if (S_IS_DEFINED (symbolP))
     {
-      as_bad ("Ignoring attempt to re-define symbol");
+      as_bad ("Ignoring attempt to re-define symbol `%s'.",
+             S_GET_NAME (symbolP));
       ignore_rest_of_line ();
       return;
     }
@@ -843,8 +888,11 @@ s_comm (ignore)
       S_SET_EXTERNAL (symbolP);
     }
 #ifdef OBJ_VMS
-  if ( (!temp) || !flagseen['1'])
-    S_GET_OTHER(symbolP) = const_flag;
+  {
+    extern int flag_one;
+    if ( (!temp) || !flag_one)
+      S_GET_OTHER(symbolP) = const_flag;
+  }
 #endif /* not OBJ_VMS */
   know (symbolP->sy_frag == &zero_address_frag);
   demand_empty_rest_of_line ();
@@ -858,7 +906,7 @@ s_data (ignore)
   register int temp;
 
   temp = get_absolute_expression ();
-  if (flagseen['R'])
+  if (flag_readonly_data_in_text)
     {
       section = text_section;
       temp += 1000;
@@ -1063,9 +1111,9 @@ s_lcomm (needs_align)
       return;
     }
 
-#ifdef TC_MIPS
+#if defined (TC_MIPS) || defined (TC_ALPHA)
 #if defined (OBJ_ECOFF) || defined (OBJ_ELF)
-  /* For MIPS ECOFF or ELF, small objects are put in .sbss.  */
+  /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss.  */
   if (temp <= bfd_get_gp_size (stdoutput))
     {
       bss_seg = subseg_new (".sbss", 1);
@@ -1073,6 +1121,20 @@ s_lcomm (needs_align)
     }
 #endif
 #endif
+   if (!needs_align)
+     {
+       /* FIXME. This needs to be machine independent. */
+       if (temp >= 8)
+        align = 3;
+       else if (temp >= 4)
+        align = 2;
+       else if (temp >= 2)
+        align = 1;
+       else
+        align = temp;
+
+       record_alignment(bss_seg, align);
+     }
 
   if (needs_align)
     {
@@ -1104,6 +1166,18 @@ s_lcomm (needs_align)
        }
       record_alignment (bss_seg, align);
     }                          /* if needs align */
+  else
+    {
+      /* Assume some objects may require alignment on some systems.  */
+#ifdef TC_ALPHA
+      if (temp > 1)
+       {
+         align = ffs (temp) - 1;
+         if (temp % (1 << align))
+           abort ();
+       }
+#endif
+    }
 
   *p = 0;
   symbolP = symbol_find_or_make (name);
@@ -1145,9 +1219,8 @@ s_lcomm (needs_align)
 #endif /* OBJ_COFF */
     }
   else
-    {
-      as_bad ("Ignoring attempt to re-define symbol %s.", name);
-    }
+    as_bad ("Ignoring attempt to re-define symbol `%s'.",
+           S_GET_NAME (symbolP));
 
   subseg_set (current_seg, current_subseg);
 
@@ -1585,7 +1658,7 @@ cons (nbytes)
 
   input_line_pointer--;                /* Put terminator back into stream. */
   demand_empty_rest_of_line ();
-}                              /* cons() */
+}
 
 /* Put the contents of expression EXP into the object file using
    NBYTES bytes.  If need_pass_2 is 1, this does nothing.  */
@@ -1702,17 +1775,17 @@ emit_expr (exp, nbytes)
 
   if (op == O_constant)
     {
-      register long get;
-      register long use;
-      register long mask;
-      register long unmask;
+      register valueT get;
+      register valueT use;
+      register valueT mask;
+      register valueT unmask;
 
       /* JF << of >= number of bits in the object is undefined.  In
         particular SPARC (Sun 4) has problems */
-      if (nbytes >= sizeof (long))
+      if (nbytes >= sizeof (valueT))
        mask = 0;
       else
-       mask = ~0 << (BITS_PER_CHAR * nbytes);  /* Don't store these bits. */
+       mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
 
       unmask = ~mask;          /* Do store these bits. */
 
@@ -1728,7 +1801,7 @@ emit_expr (exp, nbytes)
          as_warn ("Value 0x%lx truncated to 0x%lx.", get, use);
        }
       /* put bytes in right order. */
-      md_number_to_chars (p, (valueT) use, (int) nbytes);
+      md_number_to_chars (p, use, (int) nbytes);
     }
   else if (op == O_big)
     {
@@ -1784,7 +1857,7 @@ emit_expr (exp, nbytes)
     }
   else
     {
-      md_number_to_chars (p, (valueT) 0, (int) nbytes);
+      memset (p, 0, nbytes);
 
       /* Now we need to generate a fixS to record the symbol value.
         This is easy for BFD.  For other targets it can be more
@@ -2231,6 +2304,7 @@ next_char_of_string ()
       c = NOT_A_CHAR;
       break;
 
+#ifndef NO_STRING_ESCAPES
     case '\\':
       switch (c = *input_line_pointer++)
        {
@@ -2325,6 +2399,7 @@ next_char_of_string ()
          break;
        }                       /* switch on escaped char */
       break;
+#endif /* ! defined (NO_STRING_ESCAPES) */
 
     default:
       break;
@@ -2437,7 +2512,7 @@ demand_copy_C_string (len_pointer)
  * Demand string, but return a safe (=private) copy of the string.
  * Return NULL if we can't read a string here.
  */
-static char *
+char *
 demand_copy_string (lenP)
      int *lenP;
 {
@@ -2547,7 +2622,7 @@ s_include (arg)
       strcpy (path, include_dirs[i]);
       strcat (path, "/");
       strcat (path, filename);
-      if (0 != (try = fopen (path, "r")))
+      if (0 != (try = fopen (path, FOPEN_RT)))
        {
          fclose (try);
          goto gotit;
This page took 0.037343 seconds and 4 git commands to generate.