* app.c (do_scrub_next_char): Added new state, 9, to avoid

dropping a space immediately following an identifier.
	* expr.c, write.c: Rewrote assert expressions to not use multiple
	lines; I don't think that can be done portably.
	* config/tc-mips.c (macro): Use $AT if target register is zero in
	load instruction, which it can be for a floating point load.

Also a bunch more changes to config/obj-ecoff.c, still in flux.
This commit is contained in:
Ian Lance Taylor 1993-03-18 00:52:37 +00:00
parent b17e0267c9
commit f6a91cc0f7
4 changed files with 188 additions and 101 deletions

View File

@ -1,3 +1,12 @@
Wed Mar 17 16:44:06 1993 Ian Lance Taylor (ian@cygnus.com)
* app.c (do_scrub_next_char): Added new state, 9, to avoid
dropping a space immediately following an identifier.
* expr.c, write.c: Rewrote assert expressions to not use multiple
lines; I don't think that can be done portably.
* config/tc-mips.c (macro): Use $AT if target register is zero in
load instruction, which it can be for a floating point load.
Mon Mar 15 12:17:28 1993 Ian Lance Taylor (ian@cygnus.com)
* write.c (write_contents): Compute the relocs before writing out

View File

@ -29,7 +29,6 @@
#include <stdio.h>
#include "as.h" /* For BAD_CASE() only */
#include "read.h"
#if (__STDC__ != 1) && !defined(const)
#define const /* Nothing */
@ -250,10 +249,18 @@ do_scrub_next_char (get, unget)
6: putting out \ escape in a "d string.
7: After putting out a .app-file, put out string.
8: After putting out a .app-file string, flush until newline.
9: After seeing symbol char in state 3 (keep 1white after symchar)
-1: output string in out_string and go to the state in old_state
-2: flush text until a '*' '/' is seen, then go to state old_state
*/
/* I added state 9 because the MIPS ECOFF assembler uses constructs
like ``.loc 1 20''. This was turning into ``.loc 120''. State 9
ensures that a space is never dropped immediately following a
character which could appear in a identifier. It is still
dropped following a comma, so this has no effect for most
assemblers. I hope. Ian Taylor, ian@cygnus.com. */
register int ch, ch2 = 0;
switch (state)
@ -399,7 +406,7 @@ do_scrub_next_char (get, unget)
return ch;
}
/* OK, we are somewhere in states 0 through 4 */
/* OK, we are somewhere in states 0 through 4 or 9 */
/* flushchar: */
ch = (*get) ();
@ -447,7 +454,8 @@ recycle:
case 1:
BAD_CASE (state); /* We can't get here */
case 2:
state++;
case 9:
state = 3;
(*unget) (ch);
return ' '; /* Sp after opco */
case 3:
@ -561,18 +569,22 @@ recycle:
goto de_fault;
/* FIXME-someday: The two character comment stuff was badly
thought out. On i386, we want '/' as line comment start
AND we want C style comments. hence this hack. The
whole lexical process should be reworked. xoxorich. */
thought out. On i386, we want '/' as line comment start AND
we want C style comments. hence this hack. The whole
lexical process should be reworked. xoxorich. */
if (ch == '/' && (ch2 = (*get) ()) == '*')
if (ch == '/')
{
state = -2;
return (do_scrub_next_char (get, unget));
}
else
{
(*unget) (ch2);
ch2 = (*get) ();
if (ch2 == '*')
{
state = -2;
return (do_scrub_next_char (get, unget));
}
else
{
(*unget) (ch2);
}
} /* bad hack */
do
@ -609,6 +621,10 @@ recycle:
state = 0;
return '\n';
case LEX_IS_SYMBOL_COMPONENT:
if (state == 3)
state = 9;
/* Fall through. */
default:
de_fault:
/* Some relatively `normal' character. */
@ -622,6 +638,12 @@ recycle:
state = 2; /* Ditto */
return ch;
}
else if (state == 9)
{
if (lex[ch] != LEX_IS_SYMBOL_COMPONENT)
state = 3;
return ch;
}
else
{
return ch; /* Opcode or operands already */

View File

@ -831,6 +831,7 @@ typedef struct scope {
information we generate. The gas symbol will be NULL if this is
only a debugging symbol. */
typedef struct localsym {
const char *name; /* symbol name */
symbolS *as_sym; /* symbol as seen by gas */
struct efdr *file_ptr; /* file pointer */
struct ecoff_proc *proc_ptr; /* proc pointer */
@ -1393,7 +1394,8 @@ static alloc_info_t alloc_counts[ (int)alloc_type_last ];
/* Various statics. */
static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */
static thead_t *cur_tag_head = (thead_t *)0; /* current tag head */
static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */
static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */
#ifdef ECOFF_DEBUG
static int debug = 0; /* trace functions */
#endif
@ -1561,6 +1563,11 @@ obj_read_begin_hook ()
tag_hash = hash_new ();
if (tag_hash == (struct hash_control *) NULL)
as_fatal ("Can't create hash table");
top_tag_head = allocate_thead ();
top_tag_head->first_tag = (tag_t *) NULL;
top_tag_head->free = (thead_t *) NULL;
top_tag_head->prev = cur_tag_head;
cur_tag_head = top_tag_head;
}
/* This function is called when a symbol is created. */
@ -1683,6 +1690,10 @@ add_ecoff_symbol (str, type, storage, sym_value, value, indx)
psym = &vp->last->datum->sym[ vp->objects_last_page++ ];
if (str == (const char *) NULL && sym_value != (symbolS *) NULL)
psym->name = S_GET_NAME (sym_value);
else
psym->name = str;
psym->as_sym = sym_value;
if (sym_value != (symbolS *) NULL)
sym_value->ecoff_symbol = 1;
@ -2194,7 +2205,7 @@ add_procedure (func)
new_proc_ptr->pdr.iline = -1;
/* Push the start of the function. */
new_proc_ptr->sym = add_ecoff_symbol (func, st_Proc, sc_Text,
new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text,
symbol_find_or_make (func),
(symint_t) 0, (symint_t) 0);
@ -2428,7 +2439,10 @@ obj_ecoff_begin (ignore)
*input_line_pointer = name_end;
demand_empty_rest_of_line ();
/* The line number follows, but we don't use it. */
while (! is_end_of_line[*input_line_pointer])
input_line_pointer++;
input_line_pointer++;
}
/* Parse .bend directives which have a label as the first argument
@ -2440,7 +2454,7 @@ obj_ecoff_bend (ignore)
{
char *name;
char name_end;
symbolS *begin;
symbolS *endsym;
if (cur_file_ptr == (efdr_t *) NULL)
{
@ -2460,21 +2474,21 @@ obj_ecoff_bend (ignore)
name_end = get_symbol_end ();
/* The value is the distance between the .bend directive and the
corresponding symbol. We create a fake symbol to hold the
current location, and put in the offset when we write out the
symbol. */
begin = symbol_find (name);
if (begin == (symbolS *) NULL)
corresponding symbol. We fill in the offset when we write out
the symbol. */
endsym = symbol_find (name);
if (endsym == (symbolS *) NULL)
as_warn (".bend directive names unknown symbol");
else
(void) add_ecoff_symbol (name, st_End, sc_Text,
symbol_new ("L0\001", now_seg,
frag_now_fix (), frag_now),
(void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
(symint_t) 0, (symint_t) 0);
*input_line_pointer = name_end;
demand_empty_rest_of_line ();
/* The line number follows, but we don't use it. */
while (! is_end_of_line[*input_line_pointer])
input_line_pointer++;
input_line_pointer++;
}
/* COFF debugging information is provided as a series of directives
@ -2601,15 +2615,8 @@ obj_ecoff_scl (ignore)
val = get_absolute_expression ();
/* If the symbol is a static or external, we have already gotten the
appropriate type and class, so make sure we don't override those
values. This is needed because there are some type and classes
that are not in COFF, such as short data, etc. */
if (coff_symbol_type == st_Nil)
{
coff_symbol_type = map_coff_sym_type[val];
coff_storage_class = map_coff_storage[val];
}
coff_symbol_type = map_coff_sym_type[val];
coff_storage_class = map_coff_storage[val];
demand_empty_rest_of_line ();
}
@ -2674,6 +2681,7 @@ obj_ecoff_type (ignore)
{
long val;
tq_t *tq_ptr;
tq_t *tq_shft;
if (coff_sym_name == (char *) NULL)
{
@ -2687,27 +2695,31 @@ obj_ecoff_type (ignore)
coff_type.orig_type = BTYPE (val);
coff_type.basic_type = map_coff_types[coff_type.orig_type];
tq_ptr = &coff_type.type_qualifiers[0];
tq_ptr = &coff_type.type_qualifiers[N_TQ];
while (val &~ N_BTMASK)
{
if (tq_ptr == &coff_type.type_qualifiers[N_TQ])
if (tq_ptr == &coff_type.type_qualifiers[0])
{
as_warn ("Too derived values in .type argument");
break;
}
if (ISPTR (val))
*tq_ptr++ = tq_Ptr;
*--tq_ptr = tq_Ptr;
else if (ISFCN (val))
*tq_ptr++ = tq_Proc;
*--tq_ptr = tq_Proc;
else if (ISARY (val))
*tq_ptr++ = tq_Array;
*--tq_ptr = tq_Array;
else
as_fatal ("Unrecognized .type argument");
val = DECREF (val);
}
if (tq_ptr != &coff_type.type_qualifiers[0] && tq_ptr[-1] == tq_Proc)
tq_shft = &coff_type.type_qualifiers[0];
while (tq_ptr != &coff_type.type_qualifiers[N_TQ])
*tq_shft++ = *tq_ptr++;
if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc)
{
/* If this is a function, ignore it, so that we don't get two
entries (one from the .ent, and one for the .def that
@ -2716,9 +2728,12 @@ obj_ecoff_type (ignore)
MIPS knows what reason, we must strip off the function type
at this point. */
coff_is_function = 1;
tq_ptr[-1] = tq_Nil;
tq_shft[-1] = tq_Nil;
}
while (tq_shft != &coff_type.type_qualifiers[N_TQ])
*tq_shft++ = tq_Nil;
demand_empty_rest_of_line ();
}
@ -2796,6 +2811,7 @@ static void
obj_ecoff_endef (ignore)
int ignore;
{
char *name;
symint_t indx;
localsym_t *sym;
@ -2807,6 +2823,19 @@ obj_ecoff_endef (ignore)
return;
}
name = coff_sym_name;
coff_sym_name = (char *) NULL;
/* If the symbol is a static or external, we have already gotten the
appropriate type and class, so make sure we don't override those
values. This is needed because there are some type and classes
that are not in COFF, such as short data, etc. */
if (coff_sym_value != (symbolS *) NULL)
{
coff_symbol_type = st_Nil;
coff_storage_class = sc_Nil;
}
coff_type.extra_sizes = coff_tag != (char *) NULL;
if (coff_type.num_dims > 0)
{
@ -2863,7 +2892,7 @@ obj_ecoff_endef (ignore)
{
if (coff_tag == (char *) NULL)
{
as_warn ("No tag specified for %s", coff_sym_name);
as_warn ("No tag specified for %s", name);
return;
}
@ -2908,8 +2937,8 @@ obj_ecoff_endef (ignore)
name which is always ".eos". This needs to be done last, so
that any error reporting above gives the correct name. */
case st_End:
free (coff_sym_name);
coff_sym_name = (char *) NULL;
free (name);
name = (char *) NULL;
coff_value = 0;
coff_inside_enumeration = 0;
break;
@ -2927,7 +2956,7 @@ obj_ecoff_endef (ignore)
}
/* Add the symbol. */
sym = add_ecoff_symbol (coff_sym_name,
sym = add_ecoff_symbol (name,
coff_symbol_type,
coff_storage_class,
coff_sym_value,
@ -2938,7 +2967,7 @@ obj_ecoff_endef (ignore)
if (coff_symbol_type == st_Block)
{
/* Create or update the tag information. */
tag_t *tag_ptr = get_tag (coff_sym_name,
tag_t *tag_ptr = get_tag (name,
sym,
coff_type.basic_type);
forward_t **pf;
@ -2998,7 +3027,7 @@ obj_ecoff_end (ignore)
if (ent == (symbolS *) NULL)
as_warn (".end directive names unknown symbol");
else
(void) add_ecoff_symbol (name, st_End, sc_Text,
(void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
symbol_new ("L0\001", now_seg,
frag_now_fix (), frag_now),
(symint_t) 0, (symint_t) 0);
@ -3189,18 +3218,10 @@ obj_ecoff_loc (ignore)
return;
}
/* FIXME: .loc directives look like ``.loc 1 4'' where the first
number is the file index and the second number is the line
number. Unfortunately, do_scrub_next_char removes the space,
producing ``.loc 14''. Urrrk. I'm afraid I'll break something
if I change do_scrub_next_char, so instead we do this gross hack.
Note that file_index is one less than the value in the .loc,
because we adjusted it by one in the call to add_file. This
actually won't work in the unfortunate circumstance of the same
file appearing twice with different indices with different
numbers of digits, which is possible. */
/* Skip the file number. */
SKIP_WHITESPACE ();
get_absolute_expression ();
SKIP_WHITESPACE ();
input_line_pointer += 1 + (cur_file_ptr->file_index + 1) / 10;
list = allocate_lineno_list ();
@ -3599,7 +3620,7 @@ ecoff_build_lineno (buf, bufend, offset, linecntptr)
}
else if (delta <= -7)
{
*bufptr++ = 0x0f + (9 << 4);
*bufptr++ = 0x0f + (-7 << 4);
delta += 7;
}
else
@ -3745,6 +3766,7 @@ ecoff_build_symbols (buf,
for (; sym_ptr < sym_end; sym_ptr++)
{
int local;
symbolS *as_sym;
forward_t *f;
know (sym_ptr->file_ptr == fil_ptr);
@ -3757,26 +3779,65 @@ ecoff_build_symbols (buf,
both if the local provides additional debugging
information for the external). */
local = 1;
if (sym_ptr->as_sym != (symbolS *) NULL)
as_sym = sym_ptr->as_sym;
if (as_sym != (symbolS *) NULL)
{
sym_ptr->ecoff_sym.value = S_GET_VALUE (sym_ptr->as_sym);
sym_ptr->ecoff_sym.value = S_GET_VALUE (as_sym);
/* Get the type and storage class based on where
the symbol actually wound up. */
if (sym_ptr->ecoff_sym.st == st_Nil
&& sym_ptr->ecoff_sym.sc == sc_Nil
&& ! MIPS_IS_STAB (&sym_ptr->ecoff_sym))
{
st_t st;
sc_t sc;
if (S_IS_EXTERNAL (as_sym)
|| ! S_IS_DEFINED (as_sym))
st = st_Global;
else if (S_GET_SEGMENT (as_sym) == text_section)
st = st_Label;
else
st = st_Static;
if (! S_IS_DEFINED (as_sym))
sc = sc_Undefined;
else if (S_IS_COMMON (as_sym))
sc = sc_Common;
else if (S_GET_SEGMENT (as_sym) == text_section)
sc = sc_Text;
else if (S_GET_SEGMENT (as_sym) == data_section)
sc = sc_Data;
else if (S_GET_SEGMENT (as_sym) == bss_section)
sc = sc_Bss;
else
abort ();
sym_ptr->ecoff_sym.st = (int) st;
sym_ptr->ecoff_sym.sc = (int) sc;
}
/* This is just an external symbol if it is
outside a procedure and it has a type. */
if ((S_IS_EXTERNAL (sym_ptr->as_sym)
|| ! S_IS_DEFINED (sym_ptr->as_sym))
outside a procedure and it has a type.
FIXME: g++ will generate symbols which have
different names in the debugging information
than the actual symbol. Should we handle
them here? */
if ((S_IS_EXTERNAL (as_sym)
|| ! S_IS_DEFINED (as_sym))
&& sym_ptr->proc_ptr == (proc_t *) NULL
&& sym_ptr->ecoff_sym.st != (int) st_Nil)
local = 0;
/* If an st_end symbol has an associated gas
symbol, then it is a fake created for a .bend
or .end directive. */
symbol, then it is a local label created for
a .bend or .end directive. */
if (local && sym_ptr->ecoff_sym.st != st_End)
sym_ptr->ecoff_sym.iss =
add_string (&fil_ptr->strings,
fil_ptr->str_hash,
S_GET_NAME (sym_ptr->as_sym),
sym_ptr->name,
(shash_t **) NULL);
}
@ -3817,12 +3878,13 @@ ecoff_build_symbols (buf,
/* The value of the symbol marking the end of a
procedure or block is the size of the
procedure or block. */
if (begin_type == st_Proc || begin_type == st_Block)
if ((begin_type == st_Proc || begin_type == st_Block)
&& sym_ptr->ecoff_sym.sc != (int) sc_Info)
{
know (sym_ptr->as_sym != (symbolS *) NULL);
know (as_sym != (symbolS *) NULL);
know (begin_ptr->as_sym != (symbolS *) NULL);
sym_ptr->ecoff_sym.value =
(S_GET_VALUE (sym_ptr->as_sym)
(S_GET_VALUE (as_sym)
- S_GET_VALUE (begin_ptr->as_sym));
}
}
@ -3855,9 +3917,9 @@ ecoff_build_symbols (buf,
}
/* If this is an external symbol, swap it out. */
if (sym_ptr->as_sym != (symbolS *) NULL
&& (S_IS_EXTERNAL (sym_ptr->as_sym)
|| ! S_IS_DEFINED (sym_ptr->as_sym)))
if (as_sym != (symbolS *) NULL
&& (S_IS_EXTERNAL (as_sym)
|| ! S_IS_DEFINED (as_sym)))
{
EXTR ext;
@ -3866,7 +3928,7 @@ ecoff_build_symbols (buf,
ext.ifd = fil_ptr->file_index;
ext.asym.iss = add_string (ext_strings,
ext_str_hash,
S_GET_NAME (sym_ptr->as_sym),
S_GET_NAME (as_sym),
(shash_t **) NULL);
if (*extbufend - (char *) ext_out
< sizeof (struct ext_ext))
@ -3875,7 +3937,7 @@ ecoff_build_symbols (buf,
(char *) ext_out,
sizeof (struct ext_ext)));
ecoff_swap_ext_out (stdoutput, &ext, ext_out);
ecoff_set_sym_index (sym_ptr->as_sym->bsym, iext);
ecoff_set_sym_index (as_sym->bsym, iext);
++ext_out;
++iext;
}
@ -4245,6 +4307,8 @@ ecoff_frob_symbol (sym)
void
ecoff_frob_file ()
{
tag_t *ptag;
tag_t *ptag_next;
efdr_t *fil_ptr;
efdr_t *hold_file_ptr;
proc_t * hold_proc_ptr;
@ -4261,6 +4325,21 @@ ecoff_frob_file ()
struct hash_control *ext_str_hash;
char *set;
/* Handle any top level tags. */
for (ptag = top_tag_head->first_tag;
ptag != (tag_t *) NULL;
ptag = ptag_next)
{
if (ptag->forward_ref != (forward_t *) NULL)
add_unknown_tag (ptag);
ptag_next = ptag->same_block;
ptag->hash_ptr->tag_ptr = ptag->same_name;
free_tag (ptag);
}
free_thead (top_tag_head);
/* Output an ending symbol for all the files. We have to do this
here for the last file, so we may as well do it for all of the
files. */
@ -4283,35 +4362,12 @@ ecoff_frob_file ()
cur_proc_ptr = (proc_t *) NULL;
for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
{
st_t st;
sc_t sc;
if (sym->ecoff_symbol
|| sym->ecoff_file == (efdr_t *) NULL)
continue;
if (S_IS_EXTERNAL (sym) || ! S_IS_DEFINED (sym))
st = st_Global;
else if (S_GET_SEGMENT (sym) == text_section)
st = st_Label;
else
st = st_Static;
if (! S_IS_DEFINED (sym))
sc = sc_Undefined;
else if (S_IS_COMMON (sym))
sc = sc_Common;
else if (S_GET_SEGMENT (sym) == text_section)
sc = sc_Text;
else if (S_GET_SEGMENT (sym) == data_section)
sc = sc_Data;
else if (S_GET_SEGMENT (sym) == bss_section)
sc = sc_Bss;
else
abort ();
cur_file_ptr = sym->ecoff_file;
add_ecoff_symbol (S_GET_NAME (sym), st, sc, sym,
add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym,
S_GET_VALUE (sym), indexNil);
}
cur_proc_ptr = hold_proc_ptr;

View File

@ -1096,7 +1096,7 @@ macro (ip)
case M_LWR_AB:
s = "lwr";
ld:
if (breg == treg) {
if (breg == treg || treg == 0) {
tempreg = AT;
used_at = 1;
} else {