aboutsummaryrefslogtreecommitdiff
path: root/gas/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/read.c')
-rw-r--r--gas/read.c114
1 files changed, 86 insertions, 28 deletions
diff --git a/gas/read.c b/gas/read.c
index 2b450a6..78061ef 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define MASK_CHAR ((int)(unsigned char)-1)
#endif
+
/* This is the largest known floating point format (for now). It will
grow when we do 4361 style flonums. */
@@ -44,6 +45,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#endif
#include "obstack.h"
+#include "listing.h"
+
+
+#ifndef TC_START_LABEL
+#define TC_START_LABEL(x,y) (x==':')
+#endif
/* The NOP_OPCODE is for the alignment fill value.
* fill it a nop instruction so that the disassembler does not choke
@@ -195,7 +202,8 @@ static const pseudo_typeS potable[] =
/* err */
/* extend */
{"extern", s_ignore, 0}, /* We treat all undef as ext */
- {"appfile", s_app_file, 0},
+ {"appfile", s_app_file, 1},
+ {"appline", s_app_line, 0},
{"file", s_app_file, 0},
{"fill", s_fill, 0},
{"float", float_cons, 'f'},
@@ -405,7 +413,7 @@ read_a_source_file (name)
* [In case of pseudo-op, s->'.'.]
* Input_line_pointer->'\0' where c was.
*/
- if (c == ':')
+ if (TC_START_LABEL(c, input_line_pointer))
{
colon (s); /* user-defined label */
*input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
@@ -828,8 +836,16 @@ s_data ()
demand_empty_rest_of_line ();
}
+/* Handle the .appfile pseudo-op. This is automatically generated by
+ do_scrub_next_char when a preprocessor # line comment is seen with
+ a file name. This default definition may be overridden by the
+ object or CPU specific pseudo-ops. This function is also the
+ default definition for .file; the APPFILE argument is 1 for
+ .appfile, 0 for .file. */
+
void
-s_app_file ()
+s_app_file (appfile)
+ int appfile;
{
register char *s;
int length;
@@ -837,14 +853,41 @@ s_app_file ()
/* Some assemblers tolerate immediately following '"' */
if ((s = demand_copy_string (&length)) != 0)
{
- new_logical_line (s, -1);
+ /* If this is a fake .appfile, a fake newline was inserted into
+ the buffer. Passing -2 to new_logical_line tells it to
+ account for it. */
+ new_logical_line (s, appfile ? -2 : -1);
demand_empty_rest_of_line ();
+#ifdef LISTING
+ if (listing)
+ listing_source_file (s);
+#endif
}
#ifdef OBJ_COFF
c_dot_file_symbol (s);
#endif /* OBJ_COFF */
} /* s_app_file() */
+/* Handle the .appline pseudo-op. This is automatically generated by
+ do_scrub_next_char when a preprocessor # line comment is seen.
+ This default definition may be overridden by the object or CPU
+ specific pseudo-ops. */
+
+void
+s_app_line ()
+{
+ int l;
+
+ /* The given number is that of the next line. */
+ l = get_absolute_expression () - 1;
+ new_logical_line ((char *) NULL, l);
+#ifdef LISTING
+ if (listing)
+ listing_source_line (l);
+#endif
+ demand_empty_rest_of_line ();
+}
+
void
s_fill ()
{
@@ -943,8 +986,11 @@ s_lcomm (needs_align)
register char *p;
register int temp;
register symbolS *symbolP;
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
const int max_alignment = 15;
int align = 0;
+ segT bss_seg = bss_section;
name = input_line_pointer;
c = get_symbol_end ();
@@ -973,6 +1019,14 @@ s_lcomm (needs_align)
return;
}
+#ifdef TC_MIPS
+#ifdef OBJ_ECOFF
+ /* For MIPS ECOFF, small objects are put in .sbss. */
+ if (temp <= bfd_get_gp_size (stdoutput))
+ bss_seg = subseg_new (".sbss", 1);
+#endif
+#endif
+
if (needs_align)
{
align = 0;
@@ -1001,7 +1055,7 @@ s_lcomm (needs_align)
align = 0;
as_warn ("Alignment negative. 0 assumed.");
}
- record_alignment (bss_section, align);
+ record_alignment (bss_seg, align);
} /* if needs align */
*p = 0;
@@ -1013,23 +1067,21 @@ s_lcomm (needs_align)
S_GET_OTHER (symbolP) == 0 &&
S_GET_DESC (symbolP) == 0 &&
#endif /* OBJ_AOUT or OBJ_BOUT */
- (S_GET_SEGMENT (symbolP) == bss_section
+ (S_GET_SEGMENT (symbolP) == bss_seg
|| (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
{
char *p;
- segT current_seg = now_seg;
- subsegT current_subseg = now_subseg;
#ifdef BFD_ASSEMBLER
- subseg_set (bss_section, 1);
+ subseg_set (bss_seg, 1);
#else
- subseg_new (bss_section, 1);
+ subseg_new (bss_seg, 1);
#endif
if (align)
frag_align (align, 0);
/* detach from old frag */
- if (S_GET_SEGMENT (symbolP) == bss_section)
+ if (S_GET_SEGMENT (symbolP) == bss_seg)
symbolP->sy_frag->fr_symbol = NULL;
symbolP->sy_frag = frag_now;
@@ -1037,7 +1089,7 @@ s_lcomm (needs_align)
temp, (char *)0);
*p = 0;
- S_SET_SEGMENT (symbolP, bss_section);
+ S_SET_SEGMENT (symbolP, bss_seg);
#ifdef OBJ_COFF
/* The symbol may already have been created with a preceding
@@ -1048,19 +1100,19 @@ s_lcomm (needs_align)
S_SET_STORAGE_CLASS (symbolP, C_STAT);
}
#endif /* OBJ_COFF */
-#ifdef BFD_ASSEMBLER
- subseg_set (current_seg, current_subseg);
-#else
- subseg_new (current_seg, current_subseg);
-#endif
}
else
{
as_bad ("Ignoring attempt to re-define symbol %s.", name);
}
- demand_empty_rest_of_line ();
- return;
+#ifdef BFD_ASSEMBLER
+ subseg_set (current_seg, current_subseg);
+#else
+ subseg_new (current_seg, current_subseg);
+#endif
+
+ demand_empty_rest_of_line ();
} /* s_lcomm() */
void
@@ -1406,18 +1458,23 @@ pseudo_set (symbolP)
&& (S_GET_SEGMENT (exp.X_add_symbol) ==
S_GET_SEGMENT (exp.X_subtract_symbol)))
{
- if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag)
+ if (exp.X_add_symbol->sy_frag == exp.X_subtract_symbol->sy_frag)
{
- as_bad ("Unknown expression: symbols %s and %s are in different frags.",
- S_GET_NAME (exp.X_add_symbol), S_GET_NAME (exp.X_subtract_symbol));
- need_pass_2++;
+ exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) -
+ S_GET_VALUE (exp.X_subtract_symbol);
+ goto abs;
}
- exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) -
- S_GET_VALUE (exp.X_subtract_symbol);
+ as_bad ("Invalid expression: separation between symbols `%s'",
+ S_GET_NAME (exp.X_add_symbol));
+ as_bad (" and `%s' may not be constant",
+ S_GET_NAME (exp.X_subtract_symbol));
+ need_pass_2++;
}
else
- as_bad ("Complex expression. Absolute segment assumed.");
- goto abs;
+ {
+ as_bad ("Complex expression. Absolute segment assumed.");
+ goto abs;
+ }
}
else if (segment == absolute_section)
{
@@ -1785,6 +1842,7 @@ cons (nbytes)
/* undefined_section, others */
{
defalt:
+ md_number_to_chars (p, (long) 0, nbytes);
#ifdef BFD_ASSEMBLER
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
exp.X_add_symbol, exp.X_subtract_symbol,
@@ -2051,7 +2109,7 @@ float_cons (float_type) /* Worker to do .float etc statements. */
err = md_atof (float_type, temp, &length);
know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
know (length > 0);
- if (*err)
+ if (err && *err)
{
as_bad ("Bad floating literal: %s", err);
ignore_rest_of_line ();