/* 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.
*/
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;
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;
if (ch == '"')
{
(*unget) (ch);
- out_string = "\n.app-file ";
+ out_string = "\n.appfile ";
old_state = 7;
state = -1;
return *out_string++;
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) ();
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);
}
{
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
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
{
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;
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 == '*')
- {
- state = -2;
- return (do_scrub_next_char (get, unget));
- }
- else
+ /* 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 == '/')
{
- (*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) ();
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. */
state = 3;
return ch;
}
+ else if (state == 10)
+ {
+ state = 3;
+ return ch;
+ }
else
{
return ch; /* Opcode or operands already */
#endif
-/*
- * Local Variables:
- * comment-column: 0
- * fill-column: 131
- * End:
- */
-
/* end of app.c */
{
#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)
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)
{
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);
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;
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 == 0x7fffffff)
+ goto do_true;
+ imm_expr.X_add_number++;
+ /* FALLTHROUGH */
+
+ case M_BLT_I:
if (imm_expr.X_add_number == 0)
{
- macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
+ macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
return;
}
- if (imm_expr.X_add_number == -1)
+ if (imm_expr.X_add_number == 1)
{
- macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
+ macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
return;
}
- imm_expr.X_add_number++;
set_at (&icnt, sreg);
macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
break;
macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
return;
}
+ 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)
+ goto do_false;
+ if (imm_expr.X_add_number == 1)
{
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;
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:
- if (imm_expr.X_add_number == 0)
- {
- macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
- return;
- }
- if (imm_expr.X_add_number == 1)
+ if (sreg == 0)
{
- macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
+ macro_build (&icnt, &offset_expr, "bgtz", "s,p", treg);
return;
}
- set_at (&icnt, sreg);
+ 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)
{
- /* NOP */
- if (mips_noreorder)
- as_warn ("Instruction %s is a nop; deleted", ip->insn_mo->name);
+ 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_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;
- }
- if (imm_expr.X_add_number == 1)
- {
- macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
- return;
- }
- set_at_unsigned (&icnt, sreg);
- macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
- break;
-
case M_DIV_3:
case M_REM_3:
if (treg == 0)
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:
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;
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:
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;
}
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;
}
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) */
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:
}
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;
}
int line;
line = get_number ();
- s_app_file ();
+ s_app_file (0);
}
#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. */
#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
/* 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'},
* [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. */
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;
/* 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 ()
{
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 ();
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;
align = 0;
as_warn ("Alignment negative. 0 assumed.");
}
- record_alignment (bss_section, align);
+ record_alignment (bss_seg, align);
} /* if needs align */
*p = 0;
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;
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
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
&& (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)
{
/* 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,
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 ();