* read.c (read_a_source_file): Call LISTING_NEWLINE before

HANDLE_CONDITIONAL_ASSEMBLY when handling an MRI line label.
PR 11746.
This commit is contained in:
Ian Lance Taylor
1997-03-13 20:19:43 +00:00
parent 37897db02c
commit d428c89fdf
2 changed files with 175 additions and 143 deletions

View 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.

View 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;
{
#ifdef md_do_align
md_do_align (n, fill, len, just_record_alignment);
#endif
if (!fill)
{
/* @@ Fix this right for BFD! */
static char zero;
static char nop_opcode = NOP_OPCODE;
char default_fill;
#ifdef md_do_align
md_do_align (n, fill, len, max, just_record_alignment);
#endif
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,61 +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 (temp != 1)
if (align != 1)
as_bad ("Alignment not a power of 2");
align = i;
}
}
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
len = - arg;
if (len <= 1)
{
temp_fill = fillval;
do_align (temp, &temp_fill, len);
++input_line_pointer;
if (*input_line_pointer == ',')
fill_p = 0;
else
{
fill = get_absolute_expression ();
SKIP_WHITESPACE ();
fill_p = 1;
}
if (*input_line_pointer != ',')
max = 0;
else
{
++input_line_pointer;
max = get_absolute_expression ();
}
}
if (! fill_p)
{
if (arg < 0)
as_warn ("expected fill pattern missing");
do_align (align, (char *) NULL, 0, max);
}
else
{
int fill_len;
if (arg >= 0)
fill_len = 1;
else
fill_len = - arg;
if (fill_len <= 1)
{
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);
@ -1215,65 +1251,24 @@ s_align_bytes (arg)
demand_empty_rest_of_line ();
}
/* For machines where ".align 4" means align to 2**4 boundary. */
/* 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;
{
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 == ',')
{
offsetT fillval;
int len;
input_line_pointer++;
fillval = get_absolute_expression ();
if (arg >= 0)
len = 1;
else
len = - arg;
if (len <= 1)
{
temp_fill = fillval;
do_align (temp, &temp_fill, len);
}
else
{
char ab[16];
if (len > sizeof ab)
abort ();
md_number_to_chars (ab, fillval, len);
do_align (temp, ab, len);
}
}
else
{
if (arg < 0)
as_warn ("expected fill pattern missing");
do_align (temp, (char *) NULL, 0);
}
if (flag_mri)
mri_comment_end (stop, stopc);
demand_empty_rest_of_line ();
s_align (arg, 0);
}
void
@ -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])
/* 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
&& is_end_of_line[(unsigned char) *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);
}