* read.c (read_a_source_file): Call LISTING_NEWLINE before
authorIan Lance Taylor <ian@airs.com>
Thu, 13 Mar 1997 20:19:43 +0000 (20:19 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 13 Mar 1997 20:19:43 +0000 (20:19 +0000)
HANDLE_CONDITIONAL_ASSEMBLY when handling an MRI line label.
PR 11746.

gas/ChangeLog
gas/read.c

index b4679d63cbb735eec83471e7abcac00a2acfe8ae..6f099d13901f6c51bf4170faeb417185786311c0 100644 (file)
@@ -1,5 +1,8 @@
 Thu Mar 13 11:20:51 1997  Ian Lance Taylor  <ian@cygnus.com>
 
+       * read.c (read_a_source_file): Call LISTING_NEWLINE before
+       HANDLE_CONDITIONAL_ASSEMBLY when handling an MRI line label.
+
        * config/obj-elf.c (obj_elf_data): Call md_flush_pending_output
        and md_elf_section_change_hook if they are defined.
        (obj_elf_text, obj_elf_previous): Likewise.
index 990de7c2a23fd9c9514de2274e1814f289119fb4..bb6e6d2722f4b59549cb891e8a20146655d46e77 100644 (file)
@@ -159,17 +159,9 @@ char is_end_of_line[256] =
 static char *buffer;   /* 1st char of each buffer of lines is here. */
 static char *buffer_limit;     /*->1 + last char in buffer. */
 
-#ifdef TARGET_BYTES_BIG_ENDIAN
-/* Hack to deal with tc-*.h defining TARGET_BYTES_BIG_ENDIAN to empty
-   instead of to 0 or 1.  */
-#if 5 - TARGET_BYTES_BIG_ENDIAN - 5 == 10
-#undef  TARGET_BYTES_BIG_ENDIAN
-#define TARGET_BYTES_BIG_ENDIAN 1
-#endif
+/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1 in the
+   tc-<CPU>.h file.  See the "Porting GAS" section of the internals manual. */
 int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
-#else
-int target_big_endian /* = 0 */;
-#endif
 
 static char *old_buffer;       /* JF a hack */
 static char *old_input;
@@ -208,7 +200,8 @@ symbolS *mri_common_symbol;
 static int mri_pending_align;
 
 static int scrub_from_string PARAMS ((char **));
-static void do_align PARAMS ((int, char *, int));
+static void do_align PARAMS ((int, char *, int, int));
+static void s_align PARAMS ((int, int));
 static int hex_float PARAMS ((int, char *));
 static void do_org PARAMS ((segT, expressionS *, int));
 char *demand_copy_string PARAMS ((int *lenP));
@@ -534,6 +527,7 @@ read_a_source_file (name)
                      char c;
                      int mri_line_macro;
 
+                     LISTING_NEWLINE ();
                      HANDLE_CONDITIONAL_ASSEMBLY ();
 
                      c = get_symbol_end ();
@@ -554,7 +548,8 @@ read_a_source_file (name)
                              && (rest[3] == ' ' || rest[3] == '\t'))
                            {
                              input_line_pointer = rest + 3;
-                             equals (line_start);
+                             equals (line_start,
+                                     strncasecmp (rest, "SET", 3) == 0);
                              continue;
                            }
                          if (strncasecmp (rest, "MACRO", 5) == 0
@@ -640,7 +635,7 @@ read_a_source_file (name)
                          && (rest[3] == ' ' || rest[3] == '\t'))
                        {
                          input_line_pointer = rest + 3;
-                         equals (s);
+                         equals (s, 1);
                          continue;
                        }
                    }
@@ -660,7 +655,7 @@ read_a_source_file (name)
 #endif
                           ))
                {
-                 equals (s);
+                 equals (s, 1);
                  demand_empty_rest_of_line ();
                }
              else
@@ -728,7 +723,7 @@ read_a_source_file (name)
                                    || pop->poc_handler == s_globl
                                    || pop->poc_handler == s_ignore)))
                        {
-                         do_align (1, (char *) NULL, 0);
+                         do_align (1, (char *) NULL, 0, 0);
                          mri_pending_align = 0;
                          if (line_label != NULL)
                            {
@@ -823,7 +818,7 @@ read_a_source_file (name)
 
                      if (mri_pending_align)
                        {
-                         do_align (1, (char *) NULL, 0);
+                         do_align (1, (char *) NULL, 0, 0);
                          mri_pending_align = 0;
                          if (line_label != NULL)
                            {
@@ -1092,40 +1087,43 @@ s_abort (ignore)
   as_fatal (".abort detected.  Abandoning ship.");
 }
 
-/* Guts of .align directive.  */
+/* Guts of .align directive.  N is the power of two to which to align.
+   FILL may be NULL, or it may point to the bytes of the fill pattern.
+   LEN is the length of whatever FILL points to, if anything.  MAX is
+   the maximum number of characters to skip when doing the alignment,
+   or 0 if there is no maximum.  */
+
 static void 
-do_align (n, fill, len)
+do_align (n, fill, len, max)
      int n;
      char *fill;
      int len;
+     int max;
 {
+  char default_fill;
+
 #ifdef md_do_align
-  md_do_align (n, fill, len, just_record_alignment);
+  md_do_align (n, fill, len, max, just_record_alignment);
 #endif
-  if (!fill)
-    {
-      /* @@ Fix this right for BFD!  */
-      static char zero;
-      static char nop_opcode = NOP_OPCODE;
 
+  if (fill == NULL)
+    {
+      /* FIXME: Fix this right for BFD!  */
       if (now_seg != data_section && now_seg != bss_section)
-       {
-         fill = &nop_opcode;
-       }
+       default_fill = NOP_OPCODE;
       else
-       {
-         fill = &zero;
-       }
+       default_fill = 0;
+      fill = &default_fill;
       len = 1;
     }
 
   /* Only make a frag if we HAVE to. . . */
-  if (n && !need_pass_2)
+  if (n != 0 && !need_pass_2)
     {
       if (len <= 1)
-       frag_align (n, *fill);
+       frag_align (n, *fill, max);
       else
-       frag_align_pattern (n, fill, len);
+       frag_align_pattern (n, fill, len, max);
     }
 
 #ifdef md_do_align
@@ -1135,17 +1133,22 @@ do_align (n, fill, len)
   record_alignment (now_seg, n);
 }
 
-/* For machines where ".align 4" means align to a 4 byte boundary. */
-void 
-s_align_bytes (arg)
+/* Handle the .align pseudo-op.  A positive ARG is a default alignment
+   (in bytes).  A negative ARG is the negative of the length of the
+   fill pattern.  BYTES_P is non-zero if the alignment value should be
+   interpreted as the byte boundary, rather than the power of 2.  */
+
+static void
+s_align (arg, bytes_p)
      int arg;
+     int bytes_p;
 {
-  register unsigned int temp;
-  char temp_fill;
-  unsigned int i = 0;
-  unsigned long max_alignment = 1 << 15;
+  register unsigned int align;
   char *stop = NULL;
   char stopc;
+  offsetT fill = 0;
+  int max;
+  int fill_p;
 
   if (flag_mri)
     stop = mri_comment_field (&stopc);
@@ -1153,122 +1156,94 @@ s_align_bytes (arg)
   if (is_end_of_line[(unsigned char) *input_line_pointer])
     {
       if (arg < 0)
-       temp = 0;
+       align = 0;
       else
-       temp = arg;     /* Default value from pseudo-op table */
+       align = arg;    /* Default value from pseudo-op table */
     }
   else
-    temp = get_absolute_expression ();
-
-  if (temp > max_alignment)
     {
-      as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
+      align = get_absolute_expression ();
+      SKIP_WHITESPACE ();
     }
 
-  /* For the sparc, `.align (1<<n)' actually means `.align n' so we
-     have to convert it.  */
-  if (temp != 0)
+  if (bytes_p)
     {
-      for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
-       ;
+      /* Convert to a power of 2.  */
+      if (align != 0)
+       {
+         unsigned int i;
+
+         for (i = 0; (align & 1) == 0; align >>= 1, ++i)
+           ;
+         if (align != 1)
+           as_bad ("Alignment not a power of 2");
+         align = i;
+       }
     }
-  if (temp != 1)
-    as_bad ("Alignment not a power of 2");
 
-  temp = i;
-  if (*input_line_pointer == ',')
+  if (align > 15)
     {
-      offsetT fillval;
-      int len;
+      align = 15;
+      as_bad ("Alignment too large: %u assumed", align);
+    }
 
-      input_line_pointer++;
-      fillval = get_absolute_expression ();
-      if (arg >= 0)
-       len = 1;
+  if (*input_line_pointer != ',')
+    {
+      fill_p = 0;
+      max = 0;
+    }
+  else
+    {
+      ++input_line_pointer;
+      if (*input_line_pointer == ',')
+       fill_p = 0;
       else
-       len = - arg;
-      if (len <= 1)
        {
-         temp_fill = fillval;
-         do_align (temp, &temp_fill, len);
+         fill = get_absolute_expression ();
+         SKIP_WHITESPACE ();
+         fill_p = 1;
        }
+
+      if (*input_line_pointer != ',')
+       max = 0;
       else
        {
-         char ab[16];
-
-         if (len > sizeof ab)
-           abort ();
-         md_number_to_chars (ab, fillval, len);
-         do_align (temp, ab, len);
+         ++input_line_pointer;
+         max = get_absolute_expression ();
        }
     }
-  else
+
+  if (! fill_p)
     {
       if (arg < 0)
        as_warn ("expected fill pattern missing");
-      do_align (temp, (char *) NULL, 0);
+      do_align (align, (char *) NULL, 0, max);
     }
-
-  if (flag_mri)
-    mri_comment_end (stop, stopc);
-
-  demand_empty_rest_of_line ();
-}
-
-/* For machines where ".align 4" means align to 2**4 boundary. */
-void 
-s_align_ptwo (arg)
-     int arg;
-{
-  register int temp;
-  char temp_fill;
-  long max_alignment = 15;
-  char *stop = NULL;
-  char stopc;
-
-  if (flag_mri)
-    stop = mri_comment_field (&stopc);
-
-  temp = get_absolute_expression ();
-  if (temp > max_alignment)
-    as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
-  else if (temp < 0)
-    {
-      as_bad ("Alignment negative. 0 assumed.");
-      temp = 0;
-    }
-  if (*input_line_pointer == ',')
+  else
     {
-      offsetT fillval;
-      int len;
+      int fill_len;
 
-      input_line_pointer++;
-      fillval = get_absolute_expression ();
       if (arg >= 0)
-       len = 1;
+       fill_len = 1;
       else
-       len = - arg;
-      if (len <= 1)
+       fill_len = - arg;
+      if (fill_len <= 1)
        {
-         temp_fill = fillval;
-         do_align (temp, &temp_fill, len);
+         char fill_char;
+
+         fill_char = fill;
+         do_align (align, &fill_char, fill_len, max);
        }
       else
        {
          char ab[16];
 
-         if (len > sizeof ab)
+         if (fill_len > sizeof ab)
            abort ();
-         md_number_to_chars (ab, fillval, len);
-         do_align (temp, ab, len);
+         md_number_to_chars (ab, fill, fill_len);
+         do_align (align, ab, fill_len, max);
        }
     }
-  else
-    {
-      if (arg < 0)
-       as_warn ("expected fill pattern missing");
-      do_align (temp, (char *) NULL, 0);
-    }
 
   if (flag_mri)
     mri_comment_end (stop, stopc);
@@ -1276,6 +1251,26 @@ s_align_ptwo (arg)
   demand_empty_rest_of_line ();
 }
 
+/* Handle the .align pseudo-op on machines where ".align 4" means
+   align to a 4 byte boundary.  */
+
+void 
+s_align_bytes (arg)
+     int arg;
+{
+  s_align (arg, 1);
+}
+
+/* Handle the .align pseud-op on machines where ".align 4" means align
+   to a 2**4 boundary.  */
+
+void 
+s_align_ptwo (arg)
+     int arg;
+{
+  s_align (arg, 0);
+}
+
 void 
 s_comm (ignore)
      int ignore;
@@ -1957,7 +1952,7 @@ s_lcomm (needs_align)
       subseg_set (bss_seg, 1);
 
       if (align)
-       frag_align (align, 0);
+       frag_align (align, 0, 0);
                                        /* detach from old frag */
       if (S_GET_SEGMENT (symbolP) == bss_seg)
        symbolP->sy_frag->fr_symbol = NULL;
@@ -2060,6 +2055,8 @@ static int
 get_line_sb (line)
      sb *line;
 {
+  char quote1, quote2, inquote;
+
   if (input_line_pointer[-1] == '\n')
     bump_line_counters ();
 
@@ -2070,10 +2067,36 @@ get_line_sb (line)
        return 0;
     }
 
-  while (! is_end_of_line[(unsigned char) *input_line_pointer])
-    sb_add_char (line, *input_line_pointer++);
-  while (input_line_pointer < buffer_limit
-        && is_end_of_line[(unsigned char) *input_line_pointer])
+  /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this
+     code needs to be changed.  */
+  if (! flag_m68k_mri)
+    quote1 = '"';
+  else
+    quote1 = '\0';
+
+  quote2 = '\0';
+  if (flag_m68k_mri)
+    quote2 = '\'';
+#ifdef LEX_IS_STRINGQUOTE
+  quote2 = '\'';
+#endif
+
+  inquote = '\0';
+  while (! is_end_of_line[(unsigned char) *input_line_pointer]
+        || (inquote != '\0' && *input_line_pointer != '\n'))
+    {
+      if (inquote == *input_line_pointer)
+       inquote = '\0';
+      else if (inquote == '\0')
+       {
+         if (*input_line_pointer == quote1)
+           inquote = quote1;
+         else if (*input_line_pointer == quote2)
+           inquote = quote2;
+       }
+      sb_add_char (line, *input_line_pointer++);
+    }
+  while (input_line_pointer < buffer_limit && *input_line_pointer == '\n')
     {
       if (input_line_pointer[-1] == '\n')
        bump_line_counters ();
@@ -2606,7 +2629,7 @@ s_space (mult)
        }
       else
        {
-         do_align (1, (char *) NULL, 0);
+         do_align (1, (char *) NULL, 0, 0);
          if (line_label != NULL)
            {
              line_label->sy_frag = frag_now;
@@ -4173,8 +4196,9 @@ is_it_end_of_statement ()
 }                              /* is_it_end_of_statement() */
 
 void 
-equals (sym_name)
+equals (sym_name, reassign)
      char *sym_name;
+     int reassign;
 {
   register symbolS *symbolP;   /* symbol we are working with */
   char *stop;
@@ -4203,6 +4227,11 @@ equals (sym_name)
   else
     {
       symbolP = symbol_find_or_make (sym_name);
+      /* Permit register names to be redefined.  */
+      if (! reassign
+         && S_IS_DEFINED (symbolP)
+         && S_GET_SEGMENT (symbolP) != reg_section)
+       as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP));
       pseudo_set (symbolP);
     }