mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
* read.c (abs_section_offset): New global variable.
(potable): Add offset, struct. (do_org): New static function; handle changing the origin in the absolute section. (s_org): Use do_org. (s_set): Likewise. (equals): Likewise. (s_space): In absolute_section, just increase abs_section_offset. (s_struct): New function. (emit_expr): Handle absolute_section specially. * read.h (abs_section_offset): Declare. (s_struct): Declare. * read.c (potable): Add ifeq, ifge, ifgt, ifle, iflt, ifne. Change if to pass O_ne to s_if. (read_a_source_file): Don't define an label without a colon if ignore_input returns true. * read.c (potable): Add dcb, dcb.b, dcb.d, dcb.l, dcb.s, dcb.w, dcb.x, ds.d, ds.p, ds.s, ds.x, elsec, endc, fail, format, llen, noformat. (read_a_source_file): If pseudo-op handler is s_end, quit immediately. (s_end): New function. (s_fail): New function. (s_float_space): New function. (hex_float): New static function. (float_cons): Use hex_float. * read.h (s_fail): Declare. (s_float_space): Declare.
This commit is contained in:
@ -1,5 +1,63 @@
|
|||||||
Wed Aug 9 10:51:48 1995 Ian Lance Taylor <ian@cygnus.com>
|
Wed Aug 9 10:51:48 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
|
* write.c (adjust_reloc_syms): Check that symbol is not NULL
|
||||||
|
before checking sy_mri_common.
|
||||||
|
(fixup_segment): Likewise.
|
||||||
|
* config/obj-coff.c (fixup_segment): Likewise.
|
||||||
|
|
||||||
|
* read.c (abs_section_offset): New global variable.
|
||||||
|
(potable): Add offset, struct.
|
||||||
|
(do_org): New static function; handle changing the origin in the
|
||||||
|
absolute section.
|
||||||
|
(s_org): Use do_org.
|
||||||
|
(s_set): Likewise.
|
||||||
|
(equals): Likewise.
|
||||||
|
(s_space): In absolute_section, just increase abs_section_offset.
|
||||||
|
(s_struct): New function.
|
||||||
|
(emit_expr): Handle absolute_section specially.
|
||||||
|
* read.h (abs_section_offset): Declare.
|
||||||
|
(s_struct): Declare.
|
||||||
|
* frags.c (frag_more): Warn if in absolute_section.
|
||||||
|
(frag_now_fix): In absolute_section, return abs_section_offset.
|
||||||
|
* subsegs.c (subseg_change): If switching to absolute_section,
|
||||||
|
just set now_seg and now_subseg.
|
||||||
|
(subseg_set_rest): Special handling when switching to or from
|
||||||
|
absolute_section.
|
||||||
|
|
||||||
|
* config/tc-m68k.c (m68k_float_copnum): New static variable.
|
||||||
|
(md_pseudo_table): Add fopt and mask2.
|
||||||
|
(m68k_ip): Use m68k_float_copnum, not COPNUM, when setting
|
||||||
|
coprocessor register to use. In case 'I' when checking operands,
|
||||||
|
correct coprocessor register numbers. In case 'I' when setting
|
||||||
|
operands, don't add 1.
|
||||||
|
(s_fopt): New static function.
|
||||||
|
* config/m68k-parse.h (COPNUM): Don't define.
|
||||||
|
|
||||||
|
* read.c (potable): Add ifeq, ifge, ifgt, ifle, iflt, ifne.
|
||||||
|
Change if to pass O_ne to s_if.
|
||||||
|
(read_a_source_file): Don't define an label without a colon if
|
||||||
|
ignore_input returns true.
|
||||||
|
* cond.c (s_if): Treat argument as an operatorT describing how to
|
||||||
|
compare the argument against zero.
|
||||||
|
(ignore_input): Don't require an initial dot in MRI mode, or if
|
||||||
|
NO_PSEUDO_DOT is defined.
|
||||||
|
|
||||||
|
* read.c (potable): Add dcb, dcb.b, dcb.d, dcb.l, dcb.s, dcb.w,
|
||||||
|
dcb.x, ds.d, ds.p, ds.s, ds.x, elsec, endc, fail, format, llen,
|
||||||
|
noformat.
|
||||||
|
(read_a_source_file): If pseudo-op handler is s_end, quit
|
||||||
|
immediately.
|
||||||
|
(s_end): New function.
|
||||||
|
(s_fail): New function.
|
||||||
|
(s_float_space): New function.
|
||||||
|
(hex_float): New static function.
|
||||||
|
(float_cons): Use hex_float.
|
||||||
|
* read.h (s_fail): Declare.
|
||||||
|
(s_float_space): Declare.
|
||||||
|
* cond.c (s_end): Remove.
|
||||||
|
* listing.c (listing_psize): Treat argument as indicating whether
|
||||||
|
a height is expected.
|
||||||
|
|
||||||
* read.c (mri_pending_align): New static variable.
|
* read.c (mri_pending_align): New static variable.
|
||||||
(read_a_source_file): Handle mri_pending_align.
|
(read_a_source_file): Handle mri_pending_align.
|
||||||
(cons): Set mri_pending_align if appropriate.
|
(cons): Set mri_pending_align if appropriate.
|
||||||
|
421
gas/read.c
421
gas/read.c
@ -169,6 +169,11 @@ struct broken_word *broken_words;
|
|||||||
int new_broken_words;
|
int new_broken_words;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The current offset into the absolute section. We don't try to
|
||||||
|
build frags in the absolute section, since no data can be stored
|
||||||
|
there. We just keep track of the current offset. */
|
||||||
|
addressT abs_section_offset;
|
||||||
|
|
||||||
/* If this line had an MRI style label, it is stored in this variable.
|
/* If this line had an MRI style label, it is stored in this variable.
|
||||||
This is used by some of the MRI pseudo-ops. */
|
This is used by some of the MRI pseudo-ops. */
|
||||||
static symbolS *mri_line_label;
|
static symbolS *mri_line_label;
|
||||||
@ -185,6 +190,8 @@ symbolS *mri_common_symbol;
|
|||||||
static int mri_pending_align;
|
static int mri_pending_align;
|
||||||
|
|
||||||
static void do_align PARAMS ((int, char *));
|
static void do_align PARAMS ((int, char *));
|
||||||
|
static int hex_float PARAMS ((int, char *));
|
||||||
|
static void do_org PARAMS ((segT, expressionS *, int));
|
||||||
char *demand_copy_string PARAMS ((int *lenP));
|
char *demand_copy_string PARAMS ((int *lenP));
|
||||||
int is_it_end_of_statement PARAMS ((void));
|
int is_it_end_of_statement PARAMS ((void));
|
||||||
static segT get_segmented_expression PARAMS ((expressionS *expP));
|
static segT get_segmented_expression PARAMS ((expressionS *expP));
|
||||||
@ -238,10 +245,21 @@ static const pseudo_typeS potable[] =
|
|||||||
{"dc.s", float_cons, 'f'},
|
{"dc.s", float_cons, 'f'},
|
||||||
{"dc.w", cons, 2},
|
{"dc.w", cons, 2},
|
||||||
{"dc.x", float_cons, 'x'},
|
{"dc.x", float_cons, 'x'},
|
||||||
|
{"dcb", s_space, 2},
|
||||||
|
{"dcb.b", s_space, 1},
|
||||||
|
{"dcb.d", s_float_space, 'd'},
|
||||||
|
{"dcb.l", s_space, 4},
|
||||||
|
{"dcb.s", s_float_space, 'f'},
|
||||||
|
{"dcb.w", s_space, 2},
|
||||||
|
{"dcb.x", s_float_space, 'x'},
|
||||||
{"ds", s_space, 2},
|
{"ds", s_space, 2},
|
||||||
{"ds.b", s_space, 1},
|
{"ds.b", s_space, 1},
|
||||||
|
{"ds.d", s_space, 8},
|
||||||
{"ds.l", s_space, 4},
|
{"ds.l", s_space, 4},
|
||||||
|
{"ds.p", s_space, 12},
|
||||||
|
{"ds.s", s_space, 4},
|
||||||
{"ds.w", s_space, 2},
|
{"ds.w", s_space, 2},
|
||||||
|
{"ds.x", s_space, 12},
|
||||||
#ifdef S_SET_DESC
|
#ifdef S_SET_DESC
|
||||||
{"desc", s_desc, 0},
|
{"desc", s_desc, 0},
|
||||||
#endif
|
#endif
|
||||||
@ -250,7 +268,9 @@ static const pseudo_typeS potable[] =
|
|||||||
/* dsect */
|
/* dsect */
|
||||||
{"eject", listing_eject, 0}, /* Formfeed listing */
|
{"eject", listing_eject, 0}, /* Formfeed listing */
|
||||||
{"else", s_else, 0},
|
{"else", s_else, 0},
|
||||||
|
{"elsec", s_else, 0},
|
||||||
{"end", s_end, 0},
|
{"end", s_end, 0},
|
||||||
|
{"endc", s_endif, 0},
|
||||||
{"endif", s_endif, 0},
|
{"endif", s_endif, 0},
|
||||||
/* endef */
|
/* endef */
|
||||||
{"equ", s_set, 0},
|
{"equ", s_set, 0},
|
||||||
@ -259,16 +279,24 @@ static const pseudo_typeS potable[] =
|
|||||||
{"extern", s_ignore, 0}, /* We treat all undef as ext */
|
{"extern", s_ignore, 0}, /* We treat all undef as ext */
|
||||||
{"appfile", s_app_file, 1},
|
{"appfile", s_app_file, 1},
|
||||||
{"appline", s_app_line, 0},
|
{"appline", s_app_line, 0},
|
||||||
|
{"fail", s_fail, 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'},
|
||||||
|
{"format", s_ignore, 0},
|
||||||
{"global", s_globl, 0},
|
{"global", s_globl, 0},
|
||||||
{"globl", s_globl, 0},
|
{"globl", s_globl, 0},
|
||||||
{"hword", cons, 2},
|
{"hword", cons, 2},
|
||||||
{"if", s_if, 0},
|
{"if", s_if, (int) O_ne},
|
||||||
{"ifdef", s_ifdef, 0},
|
{"ifdef", s_ifdef, 0},
|
||||||
|
{"ifeq", s_if, (int) O_eq},
|
||||||
{"ifeqs", s_ifeqs, 0},
|
{"ifeqs", s_ifeqs, 0},
|
||||||
|
{"ifge", s_if, (int) O_ge},
|
||||||
|
{"ifgt", s_if, (int) O_gt},
|
||||||
|
{"ifle", s_if, (int) O_le},
|
||||||
|
{"iflt", s_if, (int) O_lt},
|
||||||
{"ifndef", s_ifdef, 1},
|
{"ifndef", s_ifdef, 1},
|
||||||
|
{"ifne", s_if, (int) O_ne},
|
||||||
{"ifnes", s_ifeqs, 1},
|
{"ifnes", s_ifeqs, 1},
|
||||||
{"ifnotdef", s_ifdef, 1},
|
{"ifnotdef", s_ifdef, 1},
|
||||||
{"include", s_include, 0},
|
{"include", s_include, 0},
|
||||||
@ -276,10 +304,13 @@ static const pseudo_typeS potable[] =
|
|||||||
{"lcomm", s_lcomm, 0},
|
{"lcomm", s_lcomm, 0},
|
||||||
{"lflags", listing_flags, 0}, /* Listing flags */
|
{"lflags", listing_flags, 0}, /* Listing flags */
|
||||||
{"list", listing_list, 1}, /* Turn listing on */
|
{"list", listing_list, 1}, /* Turn listing on */
|
||||||
|
{"llen", listing_psize, 1},
|
||||||
{"long", cons, 4},
|
{"long", cons, 4},
|
||||||
{"lsym", s_lsym, 0},
|
{"lsym", s_lsym, 0},
|
||||||
|
{"noformat", s_ignore, 0},
|
||||||
{"nolist", listing_list, 0}, /* Turn listing off */
|
{"nolist", listing_list, 0}, /* Turn listing off */
|
||||||
{"octa", cons, 16},
|
{"octa", cons, 16},
|
||||||
|
{"offset", s_struct, 0},
|
||||||
{"org", s_org, 0},
|
{"org", s_org, 0},
|
||||||
{"p2align", s_align_ptwo, 0},
|
{"p2align", s_align_ptwo, 0},
|
||||||
{"psize", listing_psize, 0}, /* set paper size */
|
{"psize", listing_psize, 0}, /* set paper size */
|
||||||
@ -297,6 +328,7 @@ static const pseudo_typeS potable[] =
|
|||||||
{"stabn", s_stab, 'n'},
|
{"stabn", s_stab, 'n'},
|
||||||
{"stabs", s_stab, 's'},
|
{"stabs", s_stab, 's'},
|
||||||
{"string", stringer, 1},
|
{"string", stringer, 1},
|
||||||
|
{"struct", s_struct, 0},
|
||||||
/* tag */
|
/* tag */
|
||||||
{"text", s_text, 0},
|
{"text", s_text, 0},
|
||||||
|
|
||||||
@ -433,22 +465,28 @@ read_a_source_file (name)
|
|||||||
char *line_start = input_line_pointer;
|
char *line_start = input_line_pointer;
|
||||||
char c = get_symbol_end ();
|
char c = get_symbol_end ();
|
||||||
|
|
||||||
/* In MRI mode, the EQU pseudoop must be handled
|
if (! ignore_input ())
|
||||||
specially. */
|
|
||||||
if (flag_mri)
|
|
||||||
{
|
{
|
||||||
if ((strncasecmp (input_line_pointer + 1, "EQU", 3)
|
/* In MRI mode, the EQU pseudoop must be
|
||||||
== 0)
|
handled specially. */
|
||||||
&& (input_line_pointer[4] == ' '
|
if (flag_mri)
|
||||||
|| input_line_pointer[4] == '\t'))
|
|
||||||
{
|
{
|
||||||
input_line_pointer += 4;
|
if (((strncasecmp (input_line_pointer + 1,
|
||||||
equals (line_start);
|
"EQU", 3) == 0)
|
||||||
continue;
|
|| (strncasecmp (input_line_pointer + 1,
|
||||||
|
"SET", 3) == 0))
|
||||||
|
&& (input_line_pointer[4] == ' '
|
||||||
|
|| input_line_pointer[4] == '\t'))
|
||||||
|
{
|
||||||
|
input_line_pointer += 4;
|
||||||
|
equals (line_start);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mri_line_label = colon (line_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
mri_line_label = colon (line_start);
|
|
||||||
*input_line_pointer = c;
|
*input_line_pointer = c;
|
||||||
if (c == ':')
|
if (c == ':')
|
||||||
input_line_pointer++;
|
input_line_pointer++;
|
||||||
@ -595,6 +633,10 @@ read_a_source_file (name)
|
|||||||
* after pseudo-operation.
|
* after pseudo-operation.
|
||||||
*/
|
*/
|
||||||
(*pop->poc_handler) (pop->poc_val);
|
(*pop->poc_handler) (pop->poc_val);
|
||||||
|
|
||||||
|
/* If that was .end, just get out now. */
|
||||||
|
if (pop->poc_handler == s_end)
|
||||||
|
goto quit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* machine instruction */
|
{ /* machine instruction */
|
||||||
@ -810,8 +852,9 @@ read_a_source_file (name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* while (more buffers to scan) */
|
} /* while (more buffers to scan) */
|
||||||
input_scrub_close (); /* Close the input file */
|
|
||||||
|
|
||||||
|
quit:
|
||||||
|
input_scrub_close (); /* Close the input file */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1173,6 +1216,39 @@ s_app_line (ignore)
|
|||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle the .end pseudo-op. Actually, the real work is done in
|
||||||
|
read_a_source_file. */
|
||||||
|
|
||||||
|
void
|
||||||
|
s_end (ignore)
|
||||||
|
int ignore;
|
||||||
|
{
|
||||||
|
if (flag_mri)
|
||||||
|
{
|
||||||
|
/* The MRI assembler permits the start symbol to follow .end,
|
||||||
|
but we don't support that. */
|
||||||
|
SKIP_WHITESPACE ();
|
||||||
|
if (! is_end_of_line[(unsigned char) *input_line_pointer])
|
||||||
|
as_warn ("start address not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the MRI fail pseudo-op. */
|
||||||
|
|
||||||
|
void
|
||||||
|
s_fail (ignore)
|
||||||
|
int ignore;
|
||||||
|
{
|
||||||
|
offsetT temp;
|
||||||
|
|
||||||
|
temp = get_absolute_expression ();
|
||||||
|
if (temp >= 500)
|
||||||
|
as_warn (".fail %ld encountered", (long) temp);
|
||||||
|
else
|
||||||
|
as_bad (".fail %ld encountered", (long) temp);
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
s_fill (ignore)
|
s_fill (ignore)
|
||||||
int ignore;
|
int ignore;
|
||||||
@ -1486,6 +1562,39 @@ s_lsym (ignore)
|
|||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
} /* s_lsym() */
|
} /* s_lsym() */
|
||||||
|
|
||||||
|
/* Handle changing the location counter. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_org (segment, exp, fill)
|
||||||
|
segT segment;
|
||||||
|
expressionS *exp;
|
||||||
|
int fill;
|
||||||
|
{
|
||||||
|
if (segment != now_seg && segment != absolute_section)
|
||||||
|
as_bad ("invalid segment \"%s\"; segment \"%s\" assumed",
|
||||||
|
segment_name (segment), segment_name (now_seg));
|
||||||
|
|
||||||
|
if (now_seg == absolute_section)
|
||||||
|
{
|
||||||
|
if (fill != 0)
|
||||||
|
as_warn ("ignoring fill value in absolute section");
|
||||||
|
if (exp->X_op != O_constant)
|
||||||
|
{
|
||||||
|
as_bad ("only constant offsets supported in absolute section");
|
||||||
|
exp->X_add_number = 0;
|
||||||
|
}
|
||||||
|
abs_section_offset = exp->X_add_number;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol,
|
||||||
|
exp->X_add_number, (char *) NULL);
|
||||||
|
*p = fill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
s_org (ignore)
|
s_org (ignore)
|
||||||
int ignore;
|
int ignore;
|
||||||
@ -1493,7 +1602,7 @@ s_org (ignore)
|
|||||||
register segT segment;
|
register segT segment;
|
||||||
expressionS exp;
|
expressionS exp;
|
||||||
register long temp_fill;
|
register long temp_fill;
|
||||||
register char *p;
|
|
||||||
/* Don't believe the documentation of BSD 4.2 AS. There is no such
|
/* Don't believe the documentation of BSD 4.2 AS. There is no such
|
||||||
thing as a sub-segment-relative origin. Any absolute origin is
|
thing as a sub-segment-relative origin. Any absolute origin is
|
||||||
given a warning, then assumed to be segment-relative. Any
|
given a warning, then assumed to be segment-relative. Any
|
||||||
@ -1514,15 +1623,10 @@ s_org (ignore)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
temp_fill = 0;
|
temp_fill = 0;
|
||||||
|
|
||||||
if (!need_pass_2)
|
if (!need_pass_2)
|
||||||
{
|
do_org (segment, &exp, temp_fill);
|
||||||
if (segment != now_seg && segment != absolute_section)
|
|
||||||
as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
|
|
||||||
segment_name (segment), segment_name (now_seg));
|
|
||||||
p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
|
|
||||||
exp.X_add_number, (char *) 0);
|
|
||||||
*p = temp_fill;
|
|
||||||
} /* if (ok to make frag) */
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
} /* s_org() */
|
} /* s_org() */
|
||||||
|
|
||||||
@ -1568,15 +1672,7 @@ s_set (ignore)
|
|||||||
segment = get_known_segmented_expression (&exp);
|
segment = get_known_segmented_expression (&exp);
|
||||||
|
|
||||||
if (!need_pass_2)
|
if (!need_pass_2)
|
||||||
{
|
do_org (segment, &exp, 0);
|
||||||
if (segment != now_seg && segment != absolute_section)
|
|
||||||
as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
|
|
||||||
segment_name (segment),
|
|
||||||
segment_name (now_seg));
|
|
||||||
ptr = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
|
|
||||||
exp.X_add_number, (char *) 0);
|
|
||||||
*ptr = 0;
|
|
||||||
} /* if (ok to make frag) */
|
|
||||||
|
|
||||||
*end_name = delim;
|
*end_name = delim;
|
||||||
return;
|
return;
|
||||||
@ -1629,6 +1725,14 @@ s_space (mult)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we are in the absolute section, just bump the offset. */
|
||||||
|
if (now_seg == absolute_section)
|
||||||
|
{
|
||||||
|
abs_section_offset += repeat;
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we are secretly in an MRI common section, then creating
|
/* If we are secretly in an MRI common section, then creating
|
||||||
space just increases the size of the common symbol. */
|
space just increases the size of the common symbol. */
|
||||||
if (mri_common_symbol != NULL)
|
if (mri_common_symbol != NULL)
|
||||||
@ -1645,6 +1749,11 @@ s_space (mult)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (now_seg == absolute_section)
|
||||||
|
{
|
||||||
|
as_bad ("space allocation too complex in absolute section");
|
||||||
|
subseg_set (text_section, 0);
|
||||||
|
}
|
||||||
if (mri_common_symbol != NULL)
|
if (mri_common_symbol != NULL)
|
||||||
{
|
{
|
||||||
as_bad ("space allocation too complex in common section");
|
as_bad ("space allocation too complex in common section");
|
||||||
@ -1671,6 +1780,85 @@ s_space (mult)
|
|||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is like s_space, but the value is a floating point number with
|
||||||
|
the given precision. This is for the MRI dcb.s pseudo-op and
|
||||||
|
friends. */
|
||||||
|
|
||||||
|
void
|
||||||
|
s_float_space (float_type)
|
||||||
|
int float_type;
|
||||||
|
{
|
||||||
|
offsetT count;
|
||||||
|
int flen;
|
||||||
|
char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
|
||||||
|
|
||||||
|
count = get_absolute_expression ();
|
||||||
|
|
||||||
|
SKIP_WHITESPACE ();
|
||||||
|
if (*input_line_pointer != ',')
|
||||||
|
{
|
||||||
|
as_bad ("missing value");
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++input_line_pointer;
|
||||||
|
|
||||||
|
SKIP_WHITESPACE ();
|
||||||
|
|
||||||
|
/* Skip any 0{letter} that may be present. Don't even check if the
|
||||||
|
* letter is legal. */
|
||||||
|
if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
|
||||||
|
input_line_pointer += 2;
|
||||||
|
|
||||||
|
/* Accept :xxxx, where the x's are hex digits, for a floating point
|
||||||
|
with the exact digits specified. */
|
||||||
|
if (input_line_pointer[0] == ':')
|
||||||
|
{
|
||||||
|
flen = hex_float (float_type, temp);
|
||||||
|
if (flen < 0)
|
||||||
|
{
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *err;
|
||||||
|
|
||||||
|
err = md_atof (float_type, temp, &flen);
|
||||||
|
know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
|
||||||
|
know (flen > 0);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
as_bad ("Bad floating literal: %s", err);
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (--count >= 0)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = frag_more (flen);
|
||||||
|
memcpy (p, temp, (unsigned int) flen);
|
||||||
|
}
|
||||||
|
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the .struct pseudo-op, as found in MIPS assemblers. */
|
||||||
|
|
||||||
|
void
|
||||||
|
s_struct (ignore)
|
||||||
|
int ignore;
|
||||||
|
{
|
||||||
|
abs_section_offset = get_absolute_expression ();
|
||||||
|
subseg_set (absolute_section, 0);
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
s_text (ignore)
|
s_text (ignore)
|
||||||
int ignore;
|
int ignore;
|
||||||
@ -1927,6 +2115,15 @@ emit_expr (exp, nbytes)
|
|||||||
|
|
||||||
op = exp->X_op;
|
op = exp->X_op;
|
||||||
|
|
||||||
|
/* Allow `.word 0' in the absolute section. */
|
||||||
|
if (now_seg == absolute_section)
|
||||||
|
{
|
||||||
|
if (op != O_constant || exp->X_add_number != 0)
|
||||||
|
as_bad ("attempt to store value in absolute section");
|
||||||
|
abs_section_offset += nbytes;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle a negative bignum. */
|
/* Handle a negative bignum. */
|
||||||
if (op == O_uminus
|
if (op == O_uminus
|
||||||
&& exp->X_add_number == 0
|
&& exp->X_add_number == 0
|
||||||
@ -2379,6 +2576,88 @@ parse_repeat_cons (exp, nbytes)
|
|||||||
|
|
||||||
#endif /* REPEAT_CONS_EXPRESSIONS */
|
#endif /* REPEAT_CONS_EXPRESSIONS */
|
||||||
|
|
||||||
|
/* Parse a floating point number represented as a hex constant. This
|
||||||
|
permits users to specify the exact bits they want in the floating
|
||||||
|
point number. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
hex_float (float_type, bytes)
|
||||||
|
int float_type;
|
||||||
|
char *bytes;
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (float_type)
|
||||||
|
{
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
length = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
length = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
length = 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
case 'P':
|
||||||
|
length = 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
as_bad ("Unknown floating type type '%c'", float_type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It would be nice if we could go through expression to parse the
|
||||||
|
hex constant, but if we get a bignum it's a pain to sort it into
|
||||||
|
the buffer correctly. */
|
||||||
|
i = 0;
|
||||||
|
while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
|
||||||
|
{
|
||||||
|
int d;
|
||||||
|
|
||||||
|
/* The MRI assembler accepts arbitrary underscores strewn about
|
||||||
|
through the hex constant, so we ignore them as well. */
|
||||||
|
if (*input_line_pointer == '_')
|
||||||
|
{
|
||||||
|
++input_line_pointer;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= length)
|
||||||
|
{
|
||||||
|
as_warn ("Floating point constant too large");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
d = hex_value (*input_line_pointer) << 4;
|
||||||
|
++input_line_pointer;
|
||||||
|
while (*input_line_pointer == '_')
|
||||||
|
++input_line_pointer;
|
||||||
|
if (hex_p (*input_line_pointer))
|
||||||
|
{
|
||||||
|
d += hex_value (*input_line_pointer);
|
||||||
|
++input_line_pointer;
|
||||||
|
}
|
||||||
|
bytes[i++] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < length)
|
||||||
|
memset (bytes + i, 0, length - i);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* float_cons()
|
* float_cons()
|
||||||
*
|
*
|
||||||
@ -2432,77 +2711,13 @@ float_cons (float_type)
|
|||||||
point with the exact digits specified. */
|
point with the exact digits specified. */
|
||||||
if (input_line_pointer[0] == ':')
|
if (input_line_pointer[0] == ':')
|
||||||
{
|
{
|
||||||
int i;
|
++input_line_pointer;
|
||||||
|
length = hex_float (float_type, temp);
|
||||||
switch (float_type)
|
if (length < 0)
|
||||||
{
|
{
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
case 's':
|
|
||||||
case 'S':
|
|
||||||
length = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
case 'r':
|
|
||||||
case 'R':
|
|
||||||
length = 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
length = 12;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'p':
|
|
||||||
case 'P':
|
|
||||||
length = 12;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
as_bad ("Unknown floating type type '%c'", float_type);
|
|
||||||
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It would be nice if we could go through expression to
|
|
||||||
parse the hex constant, but if we get a bignum it's a
|
|
||||||
pain to sort it into the buffer correctly. */
|
|
||||||
i = 0;
|
|
||||||
++input_line_pointer;
|
|
||||||
while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
|
|
||||||
{
|
|
||||||
int d;
|
|
||||||
|
|
||||||
/* The MRI assembler accepts arbitrary underscores
|
|
||||||
strewn about through the hex constant, so we ignore
|
|
||||||
them as well. */
|
|
||||||
if (*input_line_pointer == '_')
|
|
||||||
{
|
|
||||||
++input_line_pointer;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i >= length)
|
|
||||||
{
|
|
||||||
as_warn ("Floating point constant too large");
|
|
||||||
ignore_rest_of_line ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
d = hex_value (*input_line_pointer) << 4;
|
|
||||||
++input_line_pointer;
|
|
||||||
while (*input_line_pointer == '_')
|
|
||||||
++input_line_pointer;
|
|
||||||
if (hex_p (*input_line_pointer))
|
|
||||||
{
|
|
||||||
d += hex_value (*input_line_pointer);
|
|
||||||
++input_line_pointer;
|
|
||||||
}
|
|
||||||
temp[i++] = d;
|
|
||||||
}
|
|
||||||
if (i < length)
|
|
||||||
memset (temp + i, 0, length - i);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2924,15 +3139,7 @@ equals (sym_name)
|
|||||||
|
|
||||||
segment = get_known_segmented_expression (&exp);
|
segment = get_known_segmented_expression (&exp);
|
||||||
if (!need_pass_2)
|
if (!need_pass_2)
|
||||||
{
|
do_org (segment, &exp, 0);
|
||||||
if (segment != now_seg && segment != absolute_section)
|
|
||||||
as_warn ("Illegal segment \"%s\". Segment \"%s\" assumed.",
|
|
||||||
segment_name (segment),
|
|
||||||
segment_name (now_seg));
|
|
||||||
p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
|
|
||||||
exp.X_add_number, (char *) 0);
|
|
||||||
*p = 0;
|
|
||||||
} /* if (ok to make frag) */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -60,6 +60,9 @@ extern const char line_separator_chars[];
|
|||||||
/* This flag whether to generate line info for asm file */
|
/* This flag whether to generate line info for asm file */
|
||||||
extern int generate_asm_lineno;
|
extern int generate_asm_lineno;
|
||||||
|
|
||||||
|
/* The offset in the absolute section. */
|
||||||
|
extern addressT abs_section_offset;
|
||||||
|
|
||||||
/* This is used to support MRI common sections. */
|
/* This is used to support MRI common sections. */
|
||||||
extern symbolS *mri_common_symbol;
|
extern symbolS *mri_common_symbol;
|
||||||
|
|
||||||
@ -86,13 +89,14 @@ void s_align_ptwo PARAMS ((int));
|
|||||||
void s_app_file PARAMS ((int));
|
void s_app_file PARAMS ((int));
|
||||||
void s_app_line PARAMS ((int));
|
void s_app_line PARAMS ((int));
|
||||||
void s_comm PARAMS ((int));
|
void s_comm PARAMS ((int));
|
||||||
void s_mri_common PARAMS ((int));
|
|
||||||
void s_data PARAMS ((int));
|
void s_data PARAMS ((int));
|
||||||
void s_desc PARAMS ((int));
|
void s_desc PARAMS ((int));
|
||||||
void s_else PARAMS ((int arg));
|
void s_else PARAMS ((int arg));
|
||||||
void s_end PARAMS ((int arg));
|
void s_end PARAMS ((int arg));
|
||||||
void s_endif PARAMS ((int arg));
|
void s_endif PARAMS ((int arg));
|
||||||
|
void s_fail PARAMS ((int));
|
||||||
void s_fill PARAMS ((int));
|
void s_fill PARAMS ((int));
|
||||||
|
void s_float_space PARAMS ((int mult));
|
||||||
void s_globl PARAMS ((int arg));
|
void s_globl PARAMS ((int arg));
|
||||||
void s_if PARAMS ((int arg));
|
void s_if PARAMS ((int arg));
|
||||||
void s_ifdef PARAMS ((int arg));
|
void s_ifdef PARAMS ((int arg));
|
||||||
@ -101,10 +105,12 @@ void s_ignore PARAMS ((int arg));
|
|||||||
void s_include PARAMS ((int arg));
|
void s_include PARAMS ((int arg));
|
||||||
void s_lcomm PARAMS ((int needs_align));
|
void s_lcomm PARAMS ((int needs_align));
|
||||||
void s_lsym PARAMS ((int));
|
void s_lsym PARAMS ((int));
|
||||||
|
void s_mri_common PARAMS ((int));
|
||||||
void s_org PARAMS ((int));
|
void s_org PARAMS ((int));
|
||||||
void s_set PARAMS ((int));
|
void s_set PARAMS ((int));
|
||||||
void s_space PARAMS ((int mult));
|
void s_space PARAMS ((int mult));
|
||||||
void s_stab PARAMS ((int what));
|
void s_stab PARAMS ((int what));
|
||||||
|
void s_struct PARAMS ((int));
|
||||||
void s_text PARAMS ((int));
|
void s_text PARAMS ((int));
|
||||||
void stringer PARAMS ((int append_zero));
|
void stringer PARAMS ((int append_zero));
|
||||||
void s_xstab PARAMS ((int what));
|
void s_xstab PARAMS ((int what));
|
||||||
|
Reference in New Issue
Block a user