* 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:
Ian Lance Taylor 1993-05-27 19:29:38 +00:00
parent d34094e8e0
commit 9a7d824a26
5 changed files with 360 additions and 199 deletions

View File

@ -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)
* config/obj-bout.h (S_GET_VALUE): Removed unnecessary cast.

162
gas/app.c
View File

@ -23,7 +23,7 @@
/* App, the assembler pre-processor. This pre-processor strips out excess
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.
*/
@ -87,16 +87,16 @@ do_scrub_begin ()
lex[*p] = LEX_IS_SYMBOL_COMPONENT;
} /* 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++)
{
lex[*p] = LEX_IS_COMMENT_START;
} /* 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++)
{
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
5: parsing a string, then go to old-state
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.
7: After putting out a .appfile, put out string.
8: After putting out a .appfile string, flush until newline.
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
-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. */
/* I added states 9 and 10 because the MIPS ECOFF assembler uses
constructs like ``.loc 1 20''. This was turning into ``.loc
120''. States 9 and 10 ensure that a space is never dropped in
between characters which could appear in a identifier. Ian
Taylor, ian@cygnus.com. */
register int ch, ch2 = 0;
@ -308,7 +308,7 @@ do_scrub_next_char (get, unget)
if (ch == '"')
{
(*unget) (ch);
out_string = "\n.app-file ";
out_string = "\n.appfile ";
old_state = 7;
state = -1;
return *out_string++;
@ -406,7 +406,7 @@ do_scrub_next_char (get, unget)
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: */
ch = (*get) ();
@ -454,12 +454,15 @@ recycle:
case 1:
BAD_CASE (state); /* We can't get here */
case 2:
case 9:
state = 3;
(*unget) (ch);
return ' '; /* Sp after opco */
case 3:
goto recycle; /* Sp in operands */
case 9:
case 10:
state = 10; /* Sp after symbol char */
goto recycle;
default:
BAD_CASE (state);
}
@ -501,12 +504,17 @@ recycle:
{
if (ch2 != EOF)
(*unget) (ch2);
if (state == 9 || state == 10)
state = 3;
return ch;
}
break;
case LEX_IS_STRINGQUOTE:
old_state = state;
if (state == 9 || state == 10)
old_state = 3;
else
old_state = state;
state = 5;
return ch;
#ifndef MRI
@ -526,8 +534,7 @@ recycle:
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) ()) != '\'')
{
#ifdef REQUIRE_CHAR_CLOSE_QUOTE
@ -540,14 +547,19 @@ recycle:
{
return out_buf[0];
}
old_state = state;
if (state == 9 || state == 10)
old_state = 3;
else
old_state = state;
state = -1;
out_string = out_buf;
return *out_string++;
#endif
#endif
case LEX_IS_COLON:
if (state != 3)
if (state == 9 || state == 10)
state = 3;
else if (state != 3)
state = 0;
return ch;
@ -565,53 +577,58 @@ recycle:
return ch;
case LEX_IS_LINE_COMMENT_START:
if (state != 0) /* Not at start of line, act normal */
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 == '/')
if (state == 0) /* Only comment at start of line. */
{
ch2 = (*get) ();
if (ch2 == '*')
/* 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 == '/')
{
state = -2;
return (do_scrub_next_char (get, unget));
}
else
{
(*unget) (ch2);
}
} /* bad hack */
ch2 = (*get) ();
if (ch2 == '*')
{
state = -2;
return (do_scrub_next_char (get, unget));
}
else
{
(*unget) (ch2);
}
} /* bad hack */
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))
do
ch = (*get) ();
while (ch != EOF && IS_WHITESPACE (ch));
if (ch == EOF)
as_warn ("EOF in Comment: Newline inserted");
state = 0;
return '\n';
{
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) ();
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:
do
ch = (*get) ();
@ -622,6 +639,15 @@ recycle:
return '\n';
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)
state = 9;
/* Fall through. */
@ -644,6 +670,11 @@ recycle:
state = 3;
return ch;
}
else if (state == 10)
{
state = 3;
return ch;
}
else
{
return ch; /* Opcode or operands already */
@ -675,11 +706,4 @@ as_warn (str)
#endif
/*
* Local Variables:
* comment-column: 0
* fill-column: 131
* End:
*/
/* end of app.c */

View File

@ -142,7 +142,7 @@ static void EXFUN( obj_coff_bss,(void));
static void EXFUN( obj_coff_ident,(void));
static void EXFUN (obj_coff_endef, (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_size, (void));
static void EXFUN (obj_coff_tag, (void));
@ -163,6 +163,7 @@ const pseudo_typeS obj_pseudo_table[] =
{"endef", obj_coff_endef, 0},
{"line", obj_coff_line, 0},
{"ln", obj_coff_ln, 0},
{"appline", obj_coff_ln, 1},
{"scl", obj_coff_scl, 0},
{"size", obj_coff_size, 0},
{"tag", obj_coff_tag, 0},
@ -776,11 +777,12 @@ stack_top (st)
*/
static void
obj_coff_ln ()
obj_coff_ln (appline)
int appline;
{
int l;
if (def_symbol_in_progress != NULL)
if (! appline && def_symbol_in_progress != NULL)
{
as_warn (".ln pseudo-op inside .def/.endef: ignored.");
demand_empty_rest_of_line ();
@ -797,7 +799,9 @@ obj_coff_ln ()
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)
{
obj_coff_ln ();
obj_coff_ln (0);
return;
} /* if it looks like a stabs style line */

View File

@ -405,12 +405,27 @@ gp_reference (ep)
{
#ifdef OBJ_ECOFF
symbolS *sym;
const char *symname;
const char *segname;
sym = ep->X_add_symbol;
if (sym == (symbolS *) NULL
|| ep->X_subtract_symbol != (symbolS *) NULL)
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)
&& S_GET_VALUE (sym) != 0
&& S_GET_VALUE (sym) <= g_switch_value)
@ -883,13 +898,28 @@ macro (ip)
macro_build (&icnt, &offset_expr, "bgez", "s,p", sreg);
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, &offset_expr, "beq", "s,t,p", AT, 0);
break;
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++;
/* FALLTHROUGH */
case M_BGE_I:
if (imm_expr.X_add_number == 0)
{
@ -901,26 +931,39 @@ macro (ip)
macro_build (&icnt, &offset_expr, "bgtz", "s,p", sreg);
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);
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
break;
case M_BGEU:
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;
}
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
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:
if (imm_expr.X_add_number == 0)
{
macro_build (&icnt, &offset_expr, "b", "p");
return;
}
goto do_true;
if (imm_expr.X_add_number == 1)
{
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);
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, &offset_expr, "bne", "s,t,p", AT, 0);
break;
@ -946,89 +994,32 @@ macro (ip)
macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
return;
}
if (sreg == 0)
goto do_false;
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
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:
if (treg == 0)
{
macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
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, &offset_expr, "beq", "s,t,p", AT, 0);
break;
case M_BLE_I:
if (imm_expr.X_add_number == 0)
{
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;
}
if (imm_expr.X_add_number == 0x7fffffff)
goto do_true;
imm_expr.X_add_number++;
set_at (&icnt, sreg);
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;
/* FALLTHROUGH */
case M_BLT_I:
if (imm_expr.X_add_number == 0)
@ -1045,26 +1036,27 @@ macro (ip)
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
break;
case M_BLTU:
case M_BLEU:
if (treg == 0)
{
/* NOP */
if (mips_noreorder)
as_warn ("Instruction %s is a nop; deleted", ip->insn_mo->name);
macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
return;
}
macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
if (sreg == 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;
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:
if (imm_expr.X_add_number == 0)
{
/* NOP */
if (mips_noreorder)
as_warn ("Instruction %s is a nop; deleted", ip->insn_mo->name);
return;
}
goto do_false;
if (imm_expr.X_add_number == 1)
{
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);
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_REM_3:
if (treg == 0)
@ -1318,13 +1337,19 @@ macro (ip)
break;
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;
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 */
mips_noreorder = save_reorder_condition;
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;
case M_L_DAB:
@ -1356,13 +1381,19 @@ macro (ip)
macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
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;
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 */
mips_noreorder = save_reorder_condition;
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)
break;
return;
@ -1469,9 +1500,15 @@ macro (ip)
break;
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;
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;
case M_S_DAB:
@ -1493,9 +1530,15 @@ macro (ip)
macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
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;
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)
break;
return;
@ -1520,7 +1563,8 @@ macro (ip)
}
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);
return;
}
@ -1610,7 +1654,7 @@ macro (ip)
s = "sltu";
sle:
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;
case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
@ -1621,7 +1665,7 @@ macro (ip)
slei:
load_register (&icnt, ip, AT, &imm_expr);
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;
case M_SLT_I:
@ -1664,7 +1708,8 @@ macro (ip)
}
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);
return;
}
@ -3163,7 +3208,7 @@ s_file (x)
int line;
line = get_number ();
s_app_file ();
s_app_file (0);
}

View File

@ -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 ();