* app.c (do_scrub_begin): Let line_comment_chars override
comment_chars. (do_scrub_next_char): If a line comment character is not at the start of a line, treat it as a comment character if it is one. For a CPP line comment use pseudo-op .appline rather than .line. * input-scrub.c (logical_input_line): Make int rather than unsigned. (input_scrub_push, input_scrub_begin): Initialize logical_input_line to -1 rather than 0. (bump_line_counters): Increment logical_input_line. (new_logical_line): If line_number is -2, decrement logical_input_line. (as_where): Use logical_input_line even if it is 0. * read.h (s_app_file prototype): Now takes an int argument. * read.c (potable): Make .appfile call s_app_file with 1. New .appline pseudo-op calls s_app_line. (s_app_file): If .appfile, call new_logical_line with -2 to account for newline inserted by do_scrub_next_char. If listing, call listing_source_file. (s_app_line): New function to handle fake pseudo-op .appline. * config/obj-coff.c (obj_pseudo_table): Make .appline call obj_coff_ln. (obj_coff_ln): Added argument to indicate whether .appline. * config/obj-coffbfd.c (obj_pseudo_table): Make .appline call obj_coff_ln. (obj_coff_ln): Added argument to indicate whether .appline. * config/tc-mips.c (s_file): Pass argument to s_app_file.
This commit is contained in:
parent
d34094e8e0
commit
9a7d824a26
5 changed files with 360 additions and 199 deletions
|
@ -1,3 +1,33 @@
|
||||||
|
Thu May 27 11:07:50 1993 Ian Lance Taylor (ian@cygnus.com)
|
||||||
|
|
||||||
|
* app.c (do_scrub_begin): Let line_comment_chars override
|
||||||
|
comment_chars.
|
||||||
|
(do_scrub_next_char): If a line comment character is not at the
|
||||||
|
start of a line, treat it as a comment character if it is one.
|
||||||
|
For a CPP line comment use pseudo-op .appline rather than .line.
|
||||||
|
* input-scrub.c (logical_input_line): Make int rather than
|
||||||
|
unsigned.
|
||||||
|
(input_scrub_push, input_scrub_begin): Initialize
|
||||||
|
logical_input_line to -1 rather than 0.
|
||||||
|
(bump_line_counters): Increment logical_input_line.
|
||||||
|
(new_logical_line): If line_number is -2, decrement
|
||||||
|
logical_input_line.
|
||||||
|
(as_where): Use logical_input_line even if it is 0.
|
||||||
|
* read.h (s_app_file prototype): Now takes an int argument.
|
||||||
|
* read.c (potable): Make .appfile call s_app_file with 1. New
|
||||||
|
.appline pseudo-op calls s_app_line.
|
||||||
|
(s_app_file): If .appfile, call new_logical_line with -2 to
|
||||||
|
account for newline inserted by do_scrub_next_char. If listing,
|
||||||
|
call listing_source_file.
|
||||||
|
(s_app_line): New function to handle fake pseudo-op .appline.
|
||||||
|
* config/obj-coff.c (obj_pseudo_table): Make .appline call
|
||||||
|
obj_coff_ln.
|
||||||
|
(obj_coff_ln): Added argument to indicate whether .appline.
|
||||||
|
* config/obj-coffbfd.c (obj_pseudo_table): Make .appline call
|
||||||
|
obj_coff_ln.
|
||||||
|
(obj_coff_ln): Added argument to indicate whether .appline.
|
||||||
|
* config/tc-mips.c (s_file): Pass argument to s_app_file.
|
||||||
|
|
||||||
Tue May 25 11:59:07 1993 Ian Lance Taylor (ian@cygnus.com)
|
Tue May 25 11:59:07 1993 Ian Lance Taylor (ian@cygnus.com)
|
||||||
|
|
||||||
* config/obj-bout.h (S_GET_VALUE): Removed unnecessary cast.
|
* config/obj-bout.h (S_GET_VALUE): Removed unnecessary cast.
|
||||||
|
|
162
gas/app.c
162
gas/app.c
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/* App, the assembler pre-processor. This pre-processor strips out excess
|
/* App, the assembler pre-processor. This pre-processor strips out excess
|
||||||
spaces, turns single-quoted characters into a decimal constant, and turns
|
spaces, turns single-quoted characters into a decimal constant, and turns
|
||||||
# <number> <filename> <garbage> into a .line <number>\n.app-file <filename>
|
# <number> <filename> <garbage> into a .line <number>\n.file <filename>
|
||||||
pair. This needs better error-handling.
|
pair. This needs better error-handling.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -87,16 +87,16 @@ do_scrub_begin ()
|
||||||
lex[*p] = LEX_IS_SYMBOL_COMPONENT;
|
lex[*p] = LEX_IS_SYMBOL_COMPONENT;
|
||||||
} /* declare symbol characters */
|
} /* declare symbol characters */
|
||||||
|
|
||||||
for (p = line_comment_chars; *p; p++)
|
|
||||||
{
|
|
||||||
lex[*p] = LEX_IS_LINE_COMMENT_START;
|
|
||||||
} /* declare line comment chars */
|
|
||||||
|
|
||||||
for (p = comment_chars; *p; p++)
|
for (p = comment_chars; *p; p++)
|
||||||
{
|
{
|
||||||
lex[*p] = LEX_IS_COMMENT_START;
|
lex[*p] = LEX_IS_COMMENT_START;
|
||||||
} /* declare comment chars */
|
} /* declare comment chars */
|
||||||
|
|
||||||
|
for (p = line_comment_chars; *p; p++)
|
||||||
|
{
|
||||||
|
lex[*p] = LEX_IS_LINE_COMMENT_START;
|
||||||
|
} /* declare line comment chars */
|
||||||
|
|
||||||
for (p = line_separator_chars; *p; p++)
|
for (p = line_separator_chars; *p; p++)
|
||||||
{
|
{
|
||||||
lex[*p] = LEX_IS_LINE_SEPARATOR;
|
lex[*p] = LEX_IS_LINE_SEPARATOR;
|
||||||
|
@ -247,19 +247,19 @@ do_scrub_next_char (get, unget)
|
||||||
4: after putting out a .line, put out digits
|
4: after putting out a .line, put out digits
|
||||||
5: parsing a string, then go to old-state
|
5: parsing a string, then go to old-state
|
||||||
6: putting out \ escape in a "d string.
|
6: putting out \ escape in a "d string.
|
||||||
7: After putting out a .app-file, put out string.
|
7: After putting out a .appfile, put out string.
|
||||||
8: After putting out a .app-file string, flush until newline.
|
8: After putting out a .appfile string, flush until newline.
|
||||||
9: After seeing symbol char in state 3 (keep 1white after symchar)
|
9: After seeing symbol char in state 3 (keep 1white after symchar)
|
||||||
|
10: After seeing whitespace in state 9 (keep white before symchar)
|
||||||
-1: output string in out_string and go to the state in old_state
|
-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
|
-2: flush text until a '*' '/' is seen, then go to state old_state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* I added state 9 because the MIPS ECOFF assembler uses constructs
|
/* I added states 9 and 10 because the MIPS ECOFF assembler uses
|
||||||
like ``.loc 1 20''. This was turning into ``.loc 120''. State 9
|
constructs like ``.loc 1 20''. This was turning into ``.loc
|
||||||
ensures that a space is never dropped immediately following a
|
120''. States 9 and 10 ensure that a space is never dropped in
|
||||||
character which could appear in a identifier. It is still
|
between characters which could appear in a identifier. Ian
|
||||||
dropped following a comma, so this has no effect for most
|
Taylor, ian@cygnus.com. */
|
||||||
assemblers. I hope. Ian Taylor, ian@cygnus.com. */
|
|
||||||
|
|
||||||
register int ch, ch2 = 0;
|
register int ch, ch2 = 0;
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ do_scrub_next_char (get, unget)
|
||||||
if (ch == '"')
|
if (ch == '"')
|
||||||
{
|
{
|
||||||
(*unget) (ch);
|
(*unget) (ch);
|
||||||
out_string = "\n.app-file ";
|
out_string = "\n.appfile ";
|
||||||
old_state = 7;
|
old_state = 7;
|
||||||
state = -1;
|
state = -1;
|
||||||
return *out_string++;
|
return *out_string++;
|
||||||
|
@ -406,7 +406,7 @@ do_scrub_next_char (get, unget)
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK, we are somewhere in states 0 through 4 or 9 */
|
/* OK, we are somewhere in states 0 through 4 or 9 through 10 */
|
||||||
|
|
||||||
/* flushchar: */
|
/* flushchar: */
|
||||||
ch = (*get) ();
|
ch = (*get) ();
|
||||||
|
@ -454,12 +454,15 @@ recycle:
|
||||||
case 1:
|
case 1:
|
||||||
BAD_CASE (state); /* We can't get here */
|
BAD_CASE (state); /* We can't get here */
|
||||||
case 2:
|
case 2:
|
||||||
case 9:
|
|
||||||
state = 3;
|
state = 3;
|
||||||
(*unget) (ch);
|
(*unget) (ch);
|
||||||
return ' '; /* Sp after opco */
|
return ' '; /* Sp after opco */
|
||||||
case 3:
|
case 3:
|
||||||
goto recycle; /* Sp in operands */
|
goto recycle; /* Sp in operands */
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
state = 10; /* Sp after symbol char */
|
||||||
|
goto recycle;
|
||||||
default:
|
default:
|
||||||
BAD_CASE (state);
|
BAD_CASE (state);
|
||||||
}
|
}
|
||||||
|
@ -501,12 +504,17 @@ recycle:
|
||||||
{
|
{
|
||||||
if (ch2 != EOF)
|
if (ch2 != EOF)
|
||||||
(*unget) (ch2);
|
(*unget) (ch2);
|
||||||
|
if (state == 9 || state == 10)
|
||||||
|
state = 3;
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LEX_IS_STRINGQUOTE:
|
case LEX_IS_STRINGQUOTE:
|
||||||
old_state = state;
|
if (state == 9 || state == 10)
|
||||||
|
old_state = 3;
|
||||||
|
else
|
||||||
|
old_state = state;
|
||||||
state = 5;
|
state = 5;
|
||||||
return ch;
|
return ch;
|
||||||
#ifndef MRI
|
#ifndef MRI
|
||||||
|
@ -526,8 +534,7 @@ recycle:
|
||||||
sprintf (out_buf, "%d", (int) (unsigned char) ch);
|
sprintf (out_buf, "%d", (int) (unsigned char) ch);
|
||||||
|
|
||||||
|
|
||||||
/* None of these 'x constants for us. We want 'x'.
|
/* None of these 'x constants for us. We want 'x'. */
|
||||||
*/
|
|
||||||
if ((ch = (*get) ()) != '\'')
|
if ((ch = (*get) ()) != '\'')
|
||||||
{
|
{
|
||||||
#ifdef REQUIRE_CHAR_CLOSE_QUOTE
|
#ifdef REQUIRE_CHAR_CLOSE_QUOTE
|
||||||
|
@ -540,14 +547,19 @@ recycle:
|
||||||
{
|
{
|
||||||
return out_buf[0];
|
return out_buf[0];
|
||||||
}
|
}
|
||||||
old_state = state;
|
if (state == 9 || state == 10)
|
||||||
|
old_state = 3;
|
||||||
|
else
|
||||||
|
old_state = state;
|
||||||
state = -1;
|
state = -1;
|
||||||
out_string = out_buf;
|
out_string = out_buf;
|
||||||
return *out_string++;
|
return *out_string++;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case LEX_IS_COLON:
|
case LEX_IS_COLON:
|
||||||
if (state != 3)
|
if (state == 9 || state == 10)
|
||||||
|
state = 3;
|
||||||
|
else if (state != 3)
|
||||||
state = 0;
|
state = 0;
|
||||||
return ch;
|
return ch;
|
||||||
|
|
||||||
|
@ -565,53 +577,58 @@ recycle:
|
||||||
return ch;
|
return ch;
|
||||||
|
|
||||||
case LEX_IS_LINE_COMMENT_START:
|
case LEX_IS_LINE_COMMENT_START:
|
||||||
if (state != 0) /* Not at start of line, act normal */
|
if (state == 0) /* Only comment at start of line. */
|
||||||
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. */
|
|
||||||
|
|
||||||
if (ch == '/')
|
|
||||||
{
|
{
|
||||||
ch2 = (*get) ();
|
/* FIXME-someday: The two character comment stuff was badly
|
||||||
if (ch2 == '*')
|
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 == '/')
|
||||||
{
|
{
|
||||||
state = -2;
|
ch2 = (*get) ();
|
||||||
return (do_scrub_next_char (get, unget));
|
if (ch2 == '*')
|
||||||
}
|
{
|
||||||
else
|
state = -2;
|
||||||
{
|
return (do_scrub_next_char (get, unget));
|
||||||
(*unget) (ch2);
|
}
|
||||||
}
|
else
|
||||||
} /* bad hack */
|
{
|
||||||
|
(*unget) (ch2);
|
||||||
|
}
|
||||||
|
} /* bad hack */
|
||||||
|
|
||||||
do
|
do
|
||||||
ch = (*get) ();
|
|
||||||
while (ch != EOF && IS_WHITESPACE (ch));
|
|
||||||
if (ch == EOF)
|
|
||||||
{
|
|
||||||
as_warn ("EOF in comment: Newline inserted");
|
|
||||||
return '\n';
|
|
||||||
}
|
|
||||||
if (ch < '0' || ch > '9')
|
|
||||||
{
|
|
||||||
/* Non-numerics: Eat whole comment line */
|
|
||||||
while (ch != EOF && !IS_NEWLINE (ch))
|
|
||||||
ch = (*get) ();
|
ch = (*get) ();
|
||||||
|
while (ch != EOF && IS_WHITESPACE (ch));
|
||||||
if (ch == EOF)
|
if (ch == EOF)
|
||||||
as_warn ("EOF in Comment: Newline inserted");
|
{
|
||||||
state = 0;
|
as_warn ("EOF in comment: Newline inserted");
|
||||||
return '\n';
|
return '\n';
|
||||||
|
}
|
||||||
|
if (ch < '0' || ch > '9')
|
||||||
|
{
|
||||||
|
/* Non-numerics: Eat whole comment line */
|
||||||
|
while (ch != EOF && !IS_NEWLINE (ch))
|
||||||
|
ch = (*get) ();
|
||||||
|
if (ch == EOF)
|
||||||
|
as_warn ("EOF in Comment: Newline inserted");
|
||||||
|
state = 0;
|
||||||
|
return '\n';
|
||||||
|
}
|
||||||
|
/* Numerics begin comment. Perhaps CPP `# 123 "filename"' */
|
||||||
|
(*unget) (ch);
|
||||||
|
old_state = 4;
|
||||||
|
state = -1;
|
||||||
|
out_string = ".appline ";
|
||||||
|
return *out_string++;
|
||||||
}
|
}
|
||||||
/* Numerics begin comment. Perhaps CPP `# 123 "filename"' */
|
|
||||||
(*unget) (ch);
|
|
||||||
old_state = 4;
|
|
||||||
state = -1;
|
|
||||||
out_string = ".line ";
|
|
||||||
return *out_string++;
|
|
||||||
|
|
||||||
|
/* We have a line comment character which is not at the start of
|
||||||
|
a line. If this is also a normal comment character, fall
|
||||||
|
through. Otherwise treat it as a default character. */
|
||||||
|
if (strchr (comment_chars, ch) == NULL)
|
||||||
|
goto de_fault;
|
||||||
|
/* Fall through. */
|
||||||
case LEX_IS_COMMENT_START:
|
case LEX_IS_COMMENT_START:
|
||||||
do
|
do
|
||||||
ch = (*get) ();
|
ch = (*get) ();
|
||||||
|
@ -622,6 +639,15 @@ recycle:
|
||||||
return '\n';
|
return '\n';
|
||||||
|
|
||||||
case LEX_IS_SYMBOL_COMPONENT:
|
case LEX_IS_SYMBOL_COMPONENT:
|
||||||
|
if (state == 10)
|
||||||
|
{
|
||||||
|
/* This is a symbol character following another symbol
|
||||||
|
character, with whitespace in between. We skipped the
|
||||||
|
whitespace earlier, so output it now. */
|
||||||
|
(*unget) (ch);
|
||||||
|
state = 3;
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
if (state == 3)
|
if (state == 3)
|
||||||
state = 9;
|
state = 9;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
|
@ -644,6 +670,11 @@ recycle:
|
||||||
state = 3;
|
state = 3;
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
else if (state == 10)
|
||||||
|
{
|
||||||
|
state = 3;
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ch; /* Opcode or operands already */
|
return ch; /* Opcode or operands already */
|
||||||
|
@ -675,11 +706,4 @@ as_warn (str)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Local Variables:
|
|
||||||
* comment-column: 0
|
|
||||||
* fill-column: 131
|
|
||||||
* End:
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* end of app.c */
|
/* end of app.c */
|
||||||
|
|
|
@ -142,7 +142,7 @@ static void EXFUN( obj_coff_bss,(void));
|
||||||
static void EXFUN( obj_coff_ident,(void));
|
static void EXFUN( obj_coff_ident,(void));
|
||||||
static void EXFUN (obj_coff_endef, (void));
|
static void EXFUN (obj_coff_endef, (void));
|
||||||
static void EXFUN (obj_coff_line, (void));
|
static void EXFUN (obj_coff_line, (void));
|
||||||
static void EXFUN (obj_coff_ln, (void));
|
static void EXFUN (obj_coff_ln, (int));
|
||||||
static void EXFUN (obj_coff_scl, (void));
|
static void EXFUN (obj_coff_scl, (void));
|
||||||
static void EXFUN (obj_coff_size, (void));
|
static void EXFUN (obj_coff_size, (void));
|
||||||
static void EXFUN (obj_coff_tag, (void));
|
static void EXFUN (obj_coff_tag, (void));
|
||||||
|
@ -163,6 +163,7 @@ const pseudo_typeS obj_pseudo_table[] =
|
||||||
{"endef", obj_coff_endef, 0},
|
{"endef", obj_coff_endef, 0},
|
||||||
{"line", obj_coff_line, 0},
|
{"line", obj_coff_line, 0},
|
||||||
{"ln", obj_coff_ln, 0},
|
{"ln", obj_coff_ln, 0},
|
||||||
|
{"appline", obj_coff_ln, 1},
|
||||||
{"scl", obj_coff_scl, 0},
|
{"scl", obj_coff_scl, 0},
|
||||||
{"size", obj_coff_size, 0},
|
{"size", obj_coff_size, 0},
|
||||||
{"tag", obj_coff_tag, 0},
|
{"tag", obj_coff_tag, 0},
|
||||||
|
@ -776,11 +777,12 @@ stack_top (st)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
obj_coff_ln ()
|
obj_coff_ln (appline)
|
||||||
|
int appline;
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
if (def_symbol_in_progress != NULL)
|
if (! appline && def_symbol_in_progress != NULL)
|
||||||
{
|
{
|
||||||
as_warn (".ln pseudo-op inside .def/.endef: ignored.");
|
as_warn (".ln pseudo-op inside .def/.endef: ignored.");
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
|
@ -797,7 +799,9 @@ obj_coff_ln ()
|
||||||
|
|
||||||
if (listing)
|
if (listing)
|
||||||
{
|
{
|
||||||
listing_source_line (l + line_base - 1);
|
if (! appline)
|
||||||
|
l += line_base - 1;
|
||||||
|
listing_source_line (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1095,7 +1099,7 @@ obj_coff_line ()
|
||||||
|
|
||||||
if (def_symbol_in_progress == NULL)
|
if (def_symbol_in_progress == NULL)
|
||||||
{
|
{
|
||||||
obj_coff_ln ();
|
obj_coff_ln (0);
|
||||||
return;
|
return;
|
||||||
} /* if it looks like a stabs style line */
|
} /* if it looks like a stabs style line */
|
||||||
|
|
||||||
|
|
|
@ -405,12 +405,27 @@ gp_reference (ep)
|
||||||
{
|
{
|
||||||
#ifdef OBJ_ECOFF
|
#ifdef OBJ_ECOFF
|
||||||
symbolS *sym;
|
symbolS *sym;
|
||||||
|
const char *symname;
|
||||||
const char *segname;
|
const char *segname;
|
||||||
|
|
||||||
sym = ep->X_add_symbol;
|
sym = ep->X_add_symbol;
|
||||||
if (sym == (symbolS *) NULL
|
if (sym == (symbolS *) NULL
|
||||||
|| ep->X_subtract_symbol != (symbolS *) NULL)
|
|| ep->X_subtract_symbol != (symbolS *) NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Certain symbols can not be referenced off the GP, although it
|
||||||
|
appears as though they can. */
|
||||||
|
symname = S_GET_NAME (sym);
|
||||||
|
if (symname != (const char *) NULL
|
||||||
|
&& (strcmp (symname, "eprol") == 0
|
||||||
|
|| strcmp (symname, "etext") == 0
|
||||||
|
|| strcmp (symname, "_gp") == 0
|
||||||
|
|| strcmp (symname, "edata") == 0
|
||||||
|
|| strcmp (symname, "_fbss") == 0
|
||||||
|
|| strcmp (symname, "_fdata") == 0
|
||||||
|
|| strcmp (symname, "_ftext") == 0
|
||||||
|
|| strcmp (symname, "end") == 0))
|
||||||
|
return 0;
|
||||||
if (! S_IS_DEFINED (sym)
|
if (! S_IS_DEFINED (sym)
|
||||||
&& S_GET_VALUE (sym) != 0
|
&& S_GET_VALUE (sym) != 0
|
||||||
&& S_GET_VALUE (sym) <= g_switch_value)
|
&& S_GET_VALUE (sym) <= g_switch_value)
|
||||||
|
@ -883,13 +898,28 @@ macro (ip)
|
||||||
macro_build (&icnt, &offset_expr, "bgez", "s,p", sreg);
|
macro_build (&icnt, &offset_expr, "bgez", "s,p", sreg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sreg == 0)
|
||||||
|
{
|
||||||
|
macro_build (&icnt, &offset_expr, "blez", "s,p", treg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
|
macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_BGT_I:
|
case M_BGT_I:
|
||||||
|
/* check for > max integer */
|
||||||
|
if (imm_expr.X_add_number == 0x7fffffff)
|
||||||
|
{
|
||||||
|
do_false:
|
||||||
|
/* result is always false */
|
||||||
|
as_warn ("Branch %s is always false (nop)", ip->insn_mo->name);
|
||||||
|
macro_build (&icnt, NULL, "nop", "", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
imm_expr.X_add_number++;
|
imm_expr.X_add_number++;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case M_BGE_I:
|
case M_BGE_I:
|
||||||
if (imm_expr.X_add_number == 0)
|
if (imm_expr.X_add_number == 0)
|
||||||
{
|
{
|
||||||
|
@ -901,26 +931,39 @@ macro (ip)
|
||||||
macro_build (&icnt, &offset_expr, "bgtz", "s,p", sreg);
|
macro_build (&icnt, &offset_expr, "bgtz", "s,p", sreg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (imm_expr.X_add_number == 0x80000000)
|
||||||
|
{
|
||||||
|
do_true:
|
||||||
|
/* result is always true */
|
||||||
|
as_warn ("Branch %s is always true", ip->insn_mo->name);
|
||||||
|
macro_build (&icnt, &offset_expr, "b", "p");
|
||||||
|
return;
|
||||||
|
}
|
||||||
set_at (&icnt, sreg);
|
set_at (&icnt, sreg);
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_BGEU:
|
case M_BGEU:
|
||||||
if (treg == 0)
|
if (treg == 0)
|
||||||
|
goto do_true;
|
||||||
|
if (sreg == 0)
|
||||||
{
|
{
|
||||||
macro_build (&icnt, &offset_expr, "b", "p");
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", 0, treg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
|
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case M_BGTU_I:
|
||||||
|
if (sreg == 0 || imm_expr.X_add_number == 0xffffffff)
|
||||||
|
goto do_false;
|
||||||
|
imm_expr.X_add_number++;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case M_BGEU_I:
|
case M_BGEU_I:
|
||||||
if (imm_expr.X_add_number == 0)
|
if (imm_expr.X_add_number == 0)
|
||||||
{
|
goto do_true;
|
||||||
macro_build (&icnt, &offset_expr, "b", "p");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (imm_expr.X_add_number == 1)
|
if (imm_expr.X_add_number == 1)
|
||||||
{
|
{
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
|
||||||
|
@ -936,6 +979,11 @@ macro (ip)
|
||||||
macro_build (&icnt, &offset_expr, "bgtz", "s,p", sreg);
|
macro_build (&icnt, &offset_expr, "bgtz", "s,p", sreg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sreg == 0)
|
||||||
|
{
|
||||||
|
macro_build (&icnt, &offset_expr, "bltz", "s,p", treg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
|
macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -946,89 +994,32 @@ macro (ip)
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sreg == 0)
|
||||||
|
goto do_false;
|
||||||
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
|
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_BGTU_I:
|
|
||||||
if (imm_expr.X_add_number == 0)
|
|
||||||
{
|
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (imm_expr.X_add_number == -1)
|
|
||||||
{
|
|
||||||
/* NOP */
|
|
||||||
if (mips_noreorder)
|
|
||||||
as_warn ("Instruction %s is a nop; deleted", ip->insn_mo->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
imm_expr.X_add_number++;
|
|
||||||
set_at_unsigned (&icnt, sreg);
|
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case M_BLE:
|
case M_BLE:
|
||||||
if (treg == 0)
|
if (treg == 0)
|
||||||
{
|
{
|
||||||
macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
|
macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sreg == 0)
|
||||||
|
{
|
||||||
|
macro_build (&icnt, &offset_expr, "bgez", "s,p", treg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
|
macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_BLE_I:
|
case M_BLE_I:
|
||||||
if (imm_expr.X_add_number == 0)
|
if (imm_expr.X_add_number == 0x7fffffff)
|
||||||
{
|
goto do_true;
|
||||||
macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (imm_expr.X_add_number == -1)
|
|
||||||
{
|
|
||||||
macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
imm_expr.X_add_number++;
|
imm_expr.X_add_number++;
|
||||||
set_at (&icnt, sreg);
|
/* FALLTHROUGH */
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case M_BLEU:
|
|
||||||
if (treg == 0)
|
|
||||||
{
|
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
|
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case M_BLEU_I:
|
|
||||||
if (imm_expr.X_add_number == 0)
|
|
||||||
{
|
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (imm_expr.X_add_number == -1)
|
|
||||||
{
|
|
||||||
macro_build (&icnt, &offset_expr, "b", "p");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
imm_expr.X_add_number++;
|
|
||||||
set_at_unsigned (&icnt, sreg);
|
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case M_BLT:
|
|
||||||
if (treg == 0)
|
|
||||||
{
|
|
||||||
macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
|
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case M_BLT_I:
|
case M_BLT_I:
|
||||||
if (imm_expr.X_add_number == 0)
|
if (imm_expr.X_add_number == 0)
|
||||||
|
@ -1045,26 +1036,27 @@ macro (ip)
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_BLTU:
|
case M_BLEU:
|
||||||
if (treg == 0)
|
if (treg == 0)
|
||||||
{
|
{
|
||||||
/* NOP */
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
|
||||||
if (mips_noreorder)
|
|
||||||
as_warn ("Instruction %s is a nop; deleted", ip->insn_mo->name);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
|
if (sreg == 0)
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
goto do_true;
|
||||||
|
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
|
||||||
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case M_BLEU_I:
|
||||||
|
if (sreg == 0 || imm_expr.X_add_number == 0xffffffff)
|
||||||
|
goto do_true;
|
||||||
|
imm_expr.X_add_number++;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case M_BLTU_I:
|
case M_BLTU_I:
|
||||||
if (imm_expr.X_add_number == 0)
|
if (imm_expr.X_add_number == 0)
|
||||||
{
|
goto do_false;
|
||||||
/* NOP */
|
|
||||||
if (mips_noreorder)
|
|
||||||
as_warn ("Instruction %s is a nop; deleted", ip->insn_mo->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (imm_expr.X_add_number == 1)
|
if (imm_expr.X_add_number == 1)
|
||||||
{
|
{
|
||||||
macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
|
macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
|
||||||
|
@ -1074,6 +1066,33 @@ macro (ip)
|
||||||
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case M_BLT:
|
||||||
|
if (treg == 0)
|
||||||
|
{
|
||||||
|
macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sreg == 0)
|
||||||
|
{
|
||||||
|
macro_build (&icnt, &offset_expr, "bgtz", "s,p", treg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
|
||||||
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_BLTU:
|
||||||
|
if (treg == 0)
|
||||||
|
goto do_false;
|
||||||
|
if (sreg == 0)
|
||||||
|
{
|
||||||
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", 0, treg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
|
||||||
|
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case M_DIV_3:
|
case M_DIV_3:
|
||||||
case M_REM_3:
|
case M_REM_3:
|
||||||
if (treg == 0)
|
if (treg == 0)
|
||||||
|
@ -1318,13 +1337,19 @@ macro (ip)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_L_DOB:
|
case M_L_DOB:
|
||||||
|
/* Even on a big endian machine $fn comes before $fn+1. We have
|
||||||
|
to adjust when loading from memory. */
|
||||||
save_reorder_condition = mips_noreorder;
|
save_reorder_condition = mips_noreorder;
|
||||||
mips_noreorder = 1;
|
mips_noreorder = 1;
|
||||||
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg, breg);
|
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg : treg + 1,
|
||||||
|
breg);
|
||||||
/* unecessary implicit nop */
|
/* unecessary implicit nop */
|
||||||
mips_noreorder = save_reorder_condition;
|
mips_noreorder = save_reorder_condition;
|
||||||
offset_expr.X_add_number += 4;
|
offset_expr.X_add_number += 4;
|
||||||
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg + 1, breg);
|
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
|
||||||
|
breg);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case M_L_DAB:
|
case M_L_DAB:
|
||||||
|
@ -1356,13 +1381,19 @@ macro (ip)
|
||||||
macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
|
macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
|
||||||
tempreg = AT;
|
tempreg = AT;
|
||||||
}
|
}
|
||||||
|
/* Even on a big endian machine $fn comes before $fn+1. We have
|
||||||
|
to adjust when loading from memory. */
|
||||||
save_reorder_condition = mips_noreorder;
|
save_reorder_condition = mips_noreorder;
|
||||||
mips_noreorder = 1;
|
mips_noreorder = 1;
|
||||||
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg, tempreg);
|
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg : treg + 1,
|
||||||
|
tempreg);
|
||||||
/* unecessary implicit nop */
|
/* unecessary implicit nop */
|
||||||
mips_noreorder = save_reorder_condition;
|
mips_noreorder = save_reorder_condition;
|
||||||
offset_expr.X_add_number += 4;
|
offset_expr.X_add_number += 4;
|
||||||
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg + 1, tempreg);
|
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
|
||||||
|
tempreg);
|
||||||
if (tempreg == AT)
|
if (tempreg == AT)
|
||||||
break;
|
break;
|
||||||
return;
|
return;
|
||||||
|
@ -1469,9 +1500,15 @@ macro (ip)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_S_DOB:
|
case M_S_DOB:
|
||||||
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)", treg, breg);
|
/* Even on a big endian machine $fn comes before $fn+1. We have
|
||||||
|
to adjust when storing to memory. */
|
||||||
|
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg : treg + 1,
|
||||||
|
breg);
|
||||||
offset_expr.X_add_number += 4;
|
offset_expr.X_add_number += 4;
|
||||||
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)", treg + 1, breg);
|
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
|
||||||
|
breg);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case M_S_DAB:
|
case M_S_DAB:
|
||||||
|
@ -1493,9 +1530,15 @@ macro (ip)
|
||||||
macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
|
macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
|
||||||
tempreg = AT;
|
tempreg = AT;
|
||||||
}
|
}
|
||||||
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)", treg, tempreg);
|
/* Even on a big endian machine $fn comes before $fn+1. We have
|
||||||
|
to adjust when storing to memory. */
|
||||||
|
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg : treg + 1,
|
||||||
|
tempreg);
|
||||||
offset_expr.X_add_number += 4;
|
offset_expr.X_add_number += 4;
|
||||||
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)", treg + 1, tempreg);
|
macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
|
||||||
|
byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
|
||||||
|
tempreg);
|
||||||
if (tempreg == AT)
|
if (tempreg == AT)
|
||||||
break;
|
break;
|
||||||
return;
|
return;
|
||||||
|
@ -1520,7 +1563,8 @@ macro (ip)
|
||||||
}
|
}
|
||||||
if (sreg == 0)
|
if (sreg == 0)
|
||||||
{
|
{
|
||||||
/* result is always false */
|
as_warn ("Instruction %s: result is always false",
|
||||||
|
ip->insn_mo->name);
|
||||||
macro_build (&icnt, NULL, "move", "d,s", dreg, 0);
|
macro_build (&icnt, NULL, "move", "d,s", dreg, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1610,7 +1654,7 @@ macro (ip)
|
||||||
s = "sltu";
|
s = "sltu";
|
||||||
sle:
|
sle:
|
||||||
macro_build (&icnt, NULL, s, "d,v,t", dreg, treg, sreg);
|
macro_build (&icnt, NULL, s, "d,v,t", dreg, treg, sreg);
|
||||||
macro_build (&icnt, &imm_expr, "xori", "t,r,i", dreg, dreg);
|
macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
|
case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
|
||||||
|
@ -1621,7 +1665,7 @@ macro (ip)
|
||||||
slei:
|
slei:
|
||||||
load_register (&icnt, ip, AT, &imm_expr);
|
load_register (&icnt, ip, AT, &imm_expr);
|
||||||
macro_build (&icnt, NULL, s, "d,v,t", dreg, AT, sreg);
|
macro_build (&icnt, NULL, s, "d,v,t", dreg, AT, sreg);
|
||||||
macro_build (&icnt, &offset_expr, "xori", "t,r,i", dreg, dreg);
|
macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_SLT_I:
|
case M_SLT_I:
|
||||||
|
@ -1664,7 +1708,8 @@ macro (ip)
|
||||||
}
|
}
|
||||||
if (sreg == 0)
|
if (sreg == 0)
|
||||||
{
|
{
|
||||||
/* result is always true */
|
as_warn ("Instruction %s: result is always true",
|
||||||
|
ip->insn_mo->name);
|
||||||
macro_build (&icnt, &expr1, "addiu", "t,r,j", dreg, 0);
|
macro_build (&icnt, &expr1, "addiu", "t,r,j", dreg, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3163,7 +3208,7 @@ s_file (x)
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
line = get_number ();
|
line = get_number ();
|
||||||
s_app_file ();
|
s_app_file (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
114
gas/read.c
114
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)
|
#define MASK_CHAR ((int)(unsigned char)-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* This is the largest known floating point format (for now). It will
|
/* This is the largest known floating point format (for now). It will
|
||||||
grow when we do 4361 style flonums. */
|
grow when we do 4361 style flonums. */
|
||||||
|
|
||||||
|
@ -44,6 +45,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "obstack.h"
|
#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.
|
/* The NOP_OPCODE is for the alignment fill value.
|
||||||
* fill it a nop instruction so that the disassembler does not choke
|
* fill it a nop instruction so that the disassembler does not choke
|
||||||
|
@ -195,7 +202,8 @@ static const pseudo_typeS potable[] =
|
||||||
/* err */
|
/* err */
|
||||||
/* extend */
|
/* extend */
|
||||||
{"extern", s_ignore, 0}, /* We treat all undef as ext */
|
{"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},
|
{"file", s_app_file, 0},
|
||||||
{"fill", s_fill, 0},
|
{"fill", s_fill, 0},
|
||||||
{"float", float_cons, 'f'},
|
{"float", float_cons, 'f'},
|
||||||
|
@ -405,7 +413,7 @@ read_a_source_file (name)
|
||||||
* [In case of pseudo-op, s->'.'.]
|
* [In case of pseudo-op, s->'.'.]
|
||||||
* Input_line_pointer->'\0' where c was.
|
* Input_line_pointer->'\0' where c was.
|
||||||
*/
|
*/
|
||||||
if (c == ':')
|
if (TC_START_LABEL(c, input_line_pointer))
|
||||||
{
|
{
|
||||||
colon (s); /* user-defined label */
|
colon (s); /* user-defined label */
|
||||||
*input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
|
*input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
|
||||||
|
@ -828,8 +836,16 @@ s_data ()
|
||||||
demand_empty_rest_of_line ();
|
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
|
void
|
||||||
s_app_file ()
|
s_app_file (appfile)
|
||||||
|
int appfile;
|
||||||
{
|
{
|
||||||
register char *s;
|
register char *s;
|
||||||
int length;
|
int length;
|
||||||
|
@ -837,14 +853,41 @@ s_app_file ()
|
||||||
/* Some assemblers tolerate immediately following '"' */
|
/* Some assemblers tolerate immediately following '"' */
|
||||||
if ((s = demand_copy_string (&length)) != 0)
|
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 ();
|
demand_empty_rest_of_line ();
|
||||||
|
#ifdef LISTING
|
||||||
|
if (listing)
|
||||||
|
listing_source_file (s);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef OBJ_COFF
|
#ifdef OBJ_COFF
|
||||||
c_dot_file_symbol (s);
|
c_dot_file_symbol (s);
|
||||||
#endif /* OBJ_COFF */
|
#endif /* OBJ_COFF */
|
||||||
} /* s_app_file() */
|
} /* 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
|
void
|
||||||
s_fill ()
|
s_fill ()
|
||||||
{
|
{
|
||||||
|
@ -943,8 +986,11 @@ s_lcomm (needs_align)
|
||||||
register char *p;
|
register char *p;
|
||||||
register int temp;
|
register int temp;
|
||||||
register symbolS *symbolP;
|
register symbolS *symbolP;
|
||||||
|
segT current_seg = now_seg;
|
||||||
|
subsegT current_subseg = now_subseg;
|
||||||
const int max_alignment = 15;
|
const int max_alignment = 15;
|
||||||
int align = 0;
|
int align = 0;
|
||||||
|
segT bss_seg = bss_section;
|
||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
c = get_symbol_end ();
|
c = get_symbol_end ();
|
||||||
|
@ -973,6 +1019,14 @@ s_lcomm (needs_align)
|
||||||
return;
|
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)
|
if (needs_align)
|
||||||
{
|
{
|
||||||
align = 0;
|
align = 0;
|
||||||
|
@ -1001,7 +1055,7 @@ s_lcomm (needs_align)
|
||||||
align = 0;
|
align = 0;
|
||||||
as_warn ("Alignment negative. 0 assumed.");
|
as_warn ("Alignment negative. 0 assumed.");
|
||||||
}
|
}
|
||||||
record_alignment (bss_section, align);
|
record_alignment (bss_seg, align);
|
||||||
} /* if needs align */
|
} /* if needs align */
|
||||||
|
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
@ -1013,23 +1067,21 @@ s_lcomm (needs_align)
|
||||||
S_GET_OTHER (symbolP) == 0 &&
|
S_GET_OTHER (symbolP) == 0 &&
|
||||||
S_GET_DESC (symbolP) == 0 &&
|
S_GET_DESC (symbolP) == 0 &&
|
||||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
#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)))
|
|| (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
segT current_seg = now_seg;
|
|
||||||
subsegT current_subseg = now_subseg;
|
|
||||||
|
|
||||||
#ifdef BFD_ASSEMBLER
|
#ifdef BFD_ASSEMBLER
|
||||||
subseg_set (bss_section, 1);
|
subseg_set (bss_seg, 1);
|
||||||
#else
|
#else
|
||||||
subseg_new (bss_section, 1);
|
subseg_new (bss_seg, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (align)
|
if (align)
|
||||||
frag_align (align, 0);
|
frag_align (align, 0);
|
||||||
/* detach from old frag */
|
/* 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->fr_symbol = NULL;
|
||||||
|
|
||||||
symbolP->sy_frag = frag_now;
|
symbolP->sy_frag = frag_now;
|
||||||
|
@ -1037,7 +1089,7 @@ s_lcomm (needs_align)
|
||||||
temp, (char *)0);
|
temp, (char *)0);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
S_SET_SEGMENT (symbolP, bss_section);
|
S_SET_SEGMENT (symbolP, bss_seg);
|
||||||
|
|
||||||
#ifdef OBJ_COFF
|
#ifdef OBJ_COFF
|
||||||
/* The symbol may already have been created with a preceding
|
/* 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);
|
S_SET_STORAGE_CLASS (symbolP, C_STAT);
|
||||||
}
|
}
|
||||||
#endif /* OBJ_COFF */
|
#endif /* OBJ_COFF */
|
||||||
#ifdef BFD_ASSEMBLER
|
|
||||||
subseg_set (current_seg, current_subseg);
|
|
||||||
#else
|
|
||||||
subseg_new (current_seg, current_subseg);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
as_bad ("Ignoring attempt to re-define symbol %s.", name);
|
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() */
|
} /* s_lcomm() */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1406,18 +1458,23 @@ pseudo_set (symbolP)
|
||||||
&& (S_GET_SEGMENT (exp.X_add_symbol) ==
|
&& (S_GET_SEGMENT (exp.X_add_symbol) ==
|
||||||
S_GET_SEGMENT (exp.X_subtract_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.",
|
exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) -
|
||||||
S_GET_NAME (exp.X_add_symbol), S_GET_NAME (exp.X_subtract_symbol));
|
S_GET_VALUE (exp.X_subtract_symbol);
|
||||||
need_pass_2++;
|
goto abs;
|
||||||
}
|
}
|
||||||
exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) -
|
as_bad ("Invalid expression: separation between symbols `%s'",
|
||||||
S_GET_VALUE (exp.X_subtract_symbol);
|
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
|
else
|
||||||
as_bad ("Complex expression. Absolute segment assumed.");
|
{
|
||||||
goto abs;
|
as_bad ("Complex expression. Absolute segment assumed.");
|
||||||
|
goto abs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (segment == absolute_section)
|
else if (segment == absolute_section)
|
||||||
{
|
{
|
||||||
|
@ -1785,6 +1842,7 @@ cons (nbytes)
|
||||||
/* undefined_section, others */
|
/* undefined_section, others */
|
||||||
{
|
{
|
||||||
defalt:
|
defalt:
|
||||||
|
md_number_to_chars (p, (long) 0, nbytes);
|
||||||
#ifdef BFD_ASSEMBLER
|
#ifdef BFD_ASSEMBLER
|
||||||
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
|
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
|
||||||
exp.X_add_symbol, exp.X_subtract_symbol,
|
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);
|
err = md_atof (float_type, temp, &length);
|
||||||
know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
|
know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
|
||||||
know (length > 0);
|
know (length > 0);
|
||||||
if (*err)
|
if (err && *err)
|
||||||
{
|
{
|
||||||
as_bad ("Bad floating literal: %s", err);
|
as_bad ("Bad floating literal: %s", err);
|
||||||
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
||||||
|
|
Loading…
Reference in a new issue