/* 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.
#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,
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));
{"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 */
};
* 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))
* 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;
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);
} /* 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
int arg;
{
register unsigned int temp;
- register long temp_fill;
+ char temp_fill;
unsigned int i = 0;
unsigned long max_alignment = 1 << 15;
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)
{
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
int ignore;
{
register int temp;
- register long temp_fill;
+ char temp_fill;
long max_alignment = 15;
temp = get_absolute_expression ();
{
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)
*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;
}
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 ();
register int temp;
temp = get_absolute_expression ();
- if (flagseen['R'])
+ if (flag_readonly_data_in_text)
{
section = text_section;
temp += 1000;
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);
}
#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)
{
}
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);
#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);
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. */
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. */
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)
{
}
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
c = NOT_A_CHAR;
break;
+#ifndef NO_STRING_ESCAPES
case '\\':
switch (c = *input_line_pointer++)
{
break;
} /* switch on escaped char */
break;
+#endif /* ! defined (NO_STRING_ESCAPES) */
default:
break;
* 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;
{
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;