aboutsummaryrefslogtreecommitdiff
path: root/gas/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/read.c')
-rw-r--r--gas/read.c367
1 files changed, 215 insertions, 152 deletions
diff --git a/gas/read.c b/gas/read.c
index 03c19ee..d604d95 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -76,6 +76,12 @@ bool input_from_string = false;
die horribly;
#endif
+#ifndef CR_EOL
+#define LEX_CR LEX_WHITE
+#else
+#define LEX_CR LEX_EOL
+#endif
+
#ifndef LEX_AT
#define LEX_AT 0
#endif
@@ -112,9 +118,9 @@ die horribly;
/* Used by is_... macros. our ctype[]. */
char lex_type[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
+ 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0x20, 0, 0, LEX_CR, 0, 0, /* @ABCDEFGHIJKLMNO */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
- 0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
+ 8, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
@@ -130,32 +136,6 @@ char lex_type[256] = {
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
-/* In: a character.
- Out: 1 if this character ends a line.
- 2 if this character is a line separator. */
-char is_end_of_line[256] = {
-#ifdef CR_EOL
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, /* @abcdefghijklmno */
-#else
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* @abcdefghijklmno */
-#endif
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* _!"#$%&'()*+,-./ */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* */
-};
-
#ifndef TC_CASE_SENSITIVE
char original_case_string[128];
#endif
@@ -254,9 +234,9 @@ static unsigned int bundle_lock_depth;
#endif
static void do_s_func (int end_p, const char *default_prefix);
-static void s_align (int, int);
static void s_altmacro (int);
static void s_bad_end (int);
+static void s_errwarn_if (int);
static void s_reloc (int);
static int hex_float (int, char *);
static segT get_known_segmented_expression (expressionS * expP);
@@ -284,8 +264,7 @@ read_begin (void)
#endif
/* Use machine dependent syntax. */
for (p = tc_line_separator_chars; *p; p++)
- is_end_of_line[(unsigned char) *p] = 2;
- /* Use more. FIXME-SOMEDAY. */
+ lex_type[(unsigned char) *p] = LEX_EOS;
if (flag_mri)
lex_type['?'] = LEX_BEGIN_NAME | LEX_NAME;
@@ -423,6 +402,7 @@ static const pseudo_typeS potable[] = {
{"equiv", s_set, 1},
{"eqv", s_set, -1},
{"err", s_err, 0},
+ {"errif", s_errwarn_if, 1},
{"error", s_errwarn, 1},
{"exitm", s_mexit, 0},
/* extend */
@@ -537,6 +517,7 @@ static const pseudo_typeS potable[] = {
{"xdef", s_globl, 0},
{"xref", s_ignore, 0},
{"xstabs", s_xstab, 's'},
+ {"warnif", s_errwarn_if, 0},
{"warning", s_errwarn, 0},
{"weakref", s_weakref, 0},
{"word", cons, 2},
@@ -689,23 +670,26 @@ start_bundle (void)
{
fragS *frag = frag_now;
- frag_align_code (0, 0);
+ frag_align_code (bundle_align_p2, 0);
while (frag->fr_type != rs_align_code)
frag = frag->fr_next;
gas_assert (frag != frag_now);
+ /* Set initial alignment to zero. */
+ frag->fr_offset = 0;
+
return frag;
}
/* Calculate the maximum size after relaxation of the region starting
at the given frag and extending through frag_now (which is unfinished). */
-static unsigned int
+static valueT
pending_bundle_size (fragS *frag)
{
- unsigned int offset = frag->fr_fix;
- unsigned int size = 0;
+ valueT offset = frag->fr_fix;
+ valueT size = 0;
gas_assert (frag != frag_now);
gas_assert (frag->fr_type == rs_align_code);
@@ -728,23 +712,23 @@ pending_bundle_size (fragS *frag)
if (frag->fr_type == rs_machine_dependent)
size += md_frag_max_var (frag);
- gas_assert (size >= offset);
+ gas_assert (size >= offset || now_seg == absolute_section);
return size - offset;
}
/* Finish off the frag created to ensure bundle alignment. */
static void
-finish_bundle (fragS *frag, unsigned int size)
+finish_bundle (fragS *frag, valueT size)
{
gas_assert (bundle_align_p2 > 0);
gas_assert (frag->fr_type == rs_align_code);
if (size > 1)
{
- /* If there is more than a single byte, then we need to set up the
- alignment frag. Otherwise we leave it at its initial state from
- calling frag_align_code (0, 0), so that it does nothing. */
+ /* If there is more than a single byte, then we need to set up
+ the alignment frag. Otherwise we leave it at its initial
+ state with zero alignment so that it does nothing. */
frag->fr_offset = bundle_align_p2;
frag->fr_subtype = size - 1;
}
@@ -779,20 +763,20 @@ assemble_one (char *line)
{
/* Make sure this hasn't pushed the locked sequence
past the bundle size. */
- unsigned int bundle_size = pending_bundle_size (bundle_lock_frag);
+ valueT bundle_size = pending_bundle_size (bundle_lock_frag);
if (bundle_size > 1U << bundle_align_p2)
- as_bad (_ (".bundle_lock sequence at %u bytes, "
+ as_bad (_ (".bundle_lock sequence at %" PRIu64 " bytes, "
"but .bundle_align_mode limit is %u bytes"),
- bundle_size, 1U << bundle_align_p2);
+ (uint64_t) bundle_size, 1U << bundle_align_p2);
}
else if (bundle_align_p2 > 0)
{
- unsigned int insn_size = pending_bundle_size (insn_start_frag);
+ valueT insn_size = pending_bundle_size (insn_start_frag);
if (insn_size > 1U << bundle_align_p2)
- as_bad (_("single instruction is %u bytes long, "
+ as_bad (_("single instruction is %" PRIu64 " bytes long, "
"but .bundle_align_mode limit is %u bytes"),
- insn_size, 1U << bundle_align_p2);
+ (uint64_t) insn_size, 1U << bundle_align_p2);
finish_bundle (insn_start_frag, insn_size);
}
@@ -938,7 +922,8 @@ read_a_source_file (const char *name)
/* We now have input_line_pointer->1st char of next line.
If input_line_pointer [-1] == '\n' then we just
scanned another line: so bump line counters. */
- was_new_line = is_end_of_line[(unsigned char) input_line_pointer[-1]];
+ was_new_line = lex_type[(unsigned char) input_line_pointer[-1]]
+ & (LEX_EOL | LEX_EOS);
if (was_new_line)
{
symbol_set_value_now (&dot_symbol);
@@ -987,7 +972,7 @@ read_a_source_file (const char *name)
#endif
next_char = *input_line_pointer;
- if (was_new_line == 1
+ if ((was_new_line & LEX_EOL)
&& (strchr (line_comment_chars, '#')
? next_char == '#'
: next_char && strchr (line_comment_chars, next_char)))
@@ -1068,11 +1053,11 @@ read_a_source_file (const char *name)
if (*rest == ':')
++rest;
- if (*rest == ' ' || *rest == '\t')
+ if (is_whitespace (*rest))
++rest;
if ((strncasecmp (rest, "EQU", 3) == 0
|| strncasecmp (rest, "SET", 3) == 0)
- && (rest[3] == ' ' || rest[3] == '\t'))
+ && is_whitespace (rest[3]))
{
input_line_pointer = rest + 3;
equals (line_start,
@@ -1080,9 +1065,8 @@ read_a_source_file (const char *name)
continue;
}
if (strncasecmp (rest, "MACRO", 5) == 0
- && (rest[5] == ' '
- || rest[5] == '\t'
- || is_end_of_line[(unsigned char) rest[5]]))
+ && (is_whitespace (rest[5])
+ || is_end_of_stmt (rest[5])))
mri_line_macro = 1;
}
@@ -1117,7 +1101,7 @@ read_a_source_file (const char *name)
level. */
do
nul_char = next_char = *input_line_pointer++;
- while (next_char == '\t' || next_char == ' ' || next_char == '\f');
+ while (is_whitespace (next_char) || next_char == '\f');
/* C is the 1st significant character.
Input_line_pointer points after that character. */
@@ -1146,12 +1130,12 @@ read_a_source_file (const char *name)
if (*rest == ':')
++rest;
- if (*rest == ' ' || *rest == '\t')
+ if (is_whitespace (*rest))
++rest;
if ((strncasecmp (rest, "EQU", 3) == 0
|| strncasecmp (rest, "SET", 3) == 0)
- && (rest[3] == ' ' || rest[3] == '\t'))
+ && is_whitespace (rest[3]))
{
input_line_pointer = rest + 3;
equals (s, 1);
@@ -1169,7 +1153,7 @@ read_a_source_file (const char *name)
SKIP_WHITESPACE ();
}
else if ((next_char == '=' && *rest == '=')
- || ((next_char == ' ' || next_char == '\t')
+ || (is_whitespace (next_char)
&& rest[0] == '='
&& rest[1] == '='))
{
@@ -1177,7 +1161,7 @@ read_a_source_file (const char *name)
demand_empty_rest_of_line ();
}
else if ((next_char == '='
- || ((next_char == ' ' || next_char == '\t')
+ || (is_whitespace (next_char)
&& *rest == '='))
#ifdef TC_EQUAL_IN_INSN
&& !TC_EQUAL_IN_INSN (next_char, s)
@@ -1251,7 +1235,7 @@ read_a_source_file (const char *name)
|| pop->poc_handler == s_globl
|| pop->poc_handler == s_ignore)))
{
- do_align (1, (char *) NULL, 0, 0);
+ do_align (1, NULL, 0, 0);
mri_pending_align = 0;
if (line_label != NULL)
@@ -1284,7 +1268,7 @@ read_a_source_file (const char *name)
/* The following skip of whitespace is compulsory.
A well shaped space is sometimes all that separates
keyword from operands. */
- if (next_char == ' ' || next_char == '\t')
+ if (is_whitespace (next_char))
input_line_pointer++;
/* Input_line is restored.
@@ -1312,7 +1296,7 @@ read_a_source_file (const char *name)
if (mri_pending_align)
{
- do_align (1, (char *) NULL, 0, 0);
+ do_align (1, NULL, 0, 0);
mri_pending_align = 0;
if (line_label != NULL)
{
@@ -1338,7 +1322,7 @@ read_a_source_file (const char *name)
}
/* Empty statement? */
- if (is_end_of_line[(unsigned char) next_char])
+ if (is_end_of_stmt (next_char))
continue;
if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && ISDIGIT (next_char))
@@ -1456,14 +1440,15 @@ read_a_source_file (const char *name)
#endif
}
-/* Convert O_constant expression EXP into the equivalent O_big representation.
- Take the sign of the number from SIGN rather than X_add_number. */
+/* Convert O_constant expression EXP into the equivalent O_big
+ representation. */
-static void
-convert_to_bignum (expressionS *exp, int sign)
+static bool
+convert_to_bignum (expressionS *exp)
{
valueT value;
unsigned int i;
+ bool sign = !exp->X_unsigned && exp->X_extrabit;
value = exp->X_add_number;
for (i = 0; i < sizeof (exp->X_add_number) / CHARS_PER_LITTLENUM; i++)
@@ -1477,6 +1462,9 @@ convert_to_bignum (expressionS *exp, int sign)
generic_bignum[i++] = sign ? LITTLENUM_MASK : 0;
exp->X_op = O_big;
exp->X_add_number = i;
+ exp->X_unsigned = !sign;
+
+ return sign;
}
/* For most MRI pseudo-ops, the line actually ends at the first
@@ -1497,7 +1485,7 @@ mri_comment_field (char *stopcp)
know (flag_m68k_mri);
for (s = input_line_pointer;
- ((!is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t')
+ ((!is_end_of_stmt (*s) && !is_whitespace (*s))
|| inquote);
s++)
{
@@ -1506,7 +1494,7 @@ mri_comment_field (char *stopcp)
}
#else
for (s = input_line_pointer;
- !is_end_of_line[(unsigned char) *s];
+ !is_end_of_stmt (*s);
s++)
;
#endif
@@ -1525,7 +1513,7 @@ mri_comment_end (char *stop, int stopc)
input_line_pointer = stop;
*stop = stopc;
- while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ while (!is_end_of_stmt (*input_line_pointer))
++input_line_pointer;
}
@@ -1535,13 +1523,14 @@ s_abort (int ignore ATTRIBUTE_UNUSED)
as_fatal (_(".abort detected. Abandoning ship."));
}
+#ifndef TC_ALIGN_LIMIT
+#define TC_ALIGN_LIMIT (stdoutput->arch_info->bits_per_address - 1)
+#endif
+
/* Handle the .align pseudo-op. A positive ARG is a default alignment
(in bytes). A negative ARG is the negative of the length of the
fill pattern. BYTES_P is non-zero if the alignment value should be
interpreted as the byte boundary, rather than the power of 2. */
-#ifndef TC_ALIGN_LIMIT
-#define TC_ALIGN_LIMIT (stdoutput->arch_info->bits_per_address - 1)
-#endif
static void
s_align (signed int arg, int bytes_p)
@@ -1557,7 +1546,7 @@ s_align (signed int arg, int bytes_p)
if (flag_mri)
stop = mri_comment_field (&stopc);
- if (is_end_of_line[(unsigned char) *input_line_pointer])
+ if (is_end_of_stmt (*input_line_pointer))
{
if (arg < 0)
align = 0;
@@ -1594,7 +1583,8 @@ s_align (signed int arg, int bytes_p)
if (align > align_limit)
{
align = align_limit;
- as_warn (_("alignment too large: %u assumed"), align_limit);
+ as_warn (_("alignment too large: %u assumed"),
+ bytes_p ? 1u << align_limit : align_limit);
}
if (*input_line_pointer != ',')
@@ -1619,7 +1609,13 @@ s_align (signed int arg, int bytes_p)
else
{
++input_line_pointer;
- max = get_absolute_expression ();
+ offsetT val = get_absolute_expression ();
+ max = val;
+ if (val < 0 || max != (valueT) val)
+ {
+ as_warn (_("ignoring out of range alignment maximum"));
+ max = 0;
+ }
}
}
@@ -1627,7 +1623,7 @@ s_align (signed int arg, int bytes_p)
{
if (arg < 0)
as_warn (_("expected fill pattern missing"));
- do_align (align, (char *) NULL, 0, max);
+ do_align (align, NULL, 0, max);
}
else
{
@@ -1860,7 +1856,7 @@ s_comm_internal (int param,
symbolP = (*comm_parse_extra) (param, symbolP, size);
else
{
- S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_VALUE (symbolP, size);
S_SET_EXTERNAL (symbolP);
S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
}
@@ -1997,7 +1993,7 @@ s_data (int ignore ATTRIBUTE_UNUSED)
else
section = data_section;
- subseg_set (section, (subsegT) temp);
+ subseg_set (section, temp);
demand_empty_rest_of_line ();
}
@@ -2033,7 +2029,7 @@ s_file (int ignore ATTRIBUTE_UNUSED)
backquote. */
if (flag_m68k_mri
&& *input_line_pointer == '\''
- && is_end_of_line[(unsigned char) input_line_pointer[1]])
+ && is_end_of_stmt (input_line_pointer[1]))
++input_line_pointer;
demand_empty_rest_of_line ();
@@ -2156,7 +2152,7 @@ s_linefile (int ignore ATTRIBUTE_UNUSED)
break;
}
- if (!is_end_of_line[(unsigned char)*input_line_pointer])
+ if (!is_end_of_stmt (*input_line_pointer))
file = NULL;
}
@@ -2191,7 +2187,7 @@ s_end (int ignore ATTRIBUTE_UNUSED)
/* 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]
+ if (!is_end_of_stmt (*input_line_pointer)
&& *input_line_pointer != '*'
&& *input_line_pointer != '!')
as_warn (_("start address not supported"));
@@ -2244,6 +2240,62 @@ s_errwarn (int err)
demand_empty_rest_of_line ();
}
+/* Handle the .errif and .warnif pseudo-ops. */
+
+static struct deferred_diag {
+ struct deferred_diag *next;
+ const char *file;
+ unsigned int lineno;
+ bool err;
+ expressionS exp;
+} *deferred_diags, *last_deferred_diag;
+
+static void
+s_errwarn_if (int err)
+{
+ struct deferred_diag *diag = XNEW (struct deferred_diag);
+ int errcnt = had_errors ();
+
+ deferred_expression (&diag->exp);
+ if (errcnt != had_errors ())
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+
+ diag->err = err;
+ diag->file = as_where (&diag->lineno);
+ diag->next = NULL;
+ if ( deferred_diags == NULL )
+ deferred_diags = diag;
+ else
+ last_deferred_diag->next = diag;
+ last_deferred_diag = diag;
+
+ demand_empty_rest_of_line ();
+}
+
+void
+evaluate_deferred_diags (void)
+{
+ struct deferred_diag *diag;
+
+ for (diag = deferred_diags; diag != NULL; diag = diag->next)
+ {
+ if (!resolve_expression (&diag->exp) || diag->exp.X_op != O_constant)
+ as_warn_where (diag->file, diag->lineno,
+ _("expression does not evaluate to a constant"));
+ else if (diag->exp.X_add_number == 0)
+ continue;
+ else if (diag->err)
+ as_bad_where (diag->file, diag->lineno,
+ _(".errif expression evaluates to true"));
+ else
+ as_warn_where (diag->file, diag->lineno,
+ _(".warnif expression evaluates to true"));
+ }
+}
+
/* Handle the MRI fail pseudo-op. */
void
@@ -2272,8 +2324,8 @@ void
s_fill (int ignore ATTRIBUTE_UNUSED)
{
expressionS rep_exp;
- long size = 1;
- long fill = 0;
+ offsetT size = 1;
+ valueT fill = 0;
char *p;
#ifdef md_flush_pending_output
@@ -2339,14 +2391,12 @@ s_fill (int ignore ATTRIBUTE_UNUSED)
if (size && !need_pass_2)
{
if (now_seg == absolute_section)
- abs_section_offset += rep_exp.X_add_number * size;
+ abs_section_offset += (valueT) rep_exp.X_add_number * size;
if (rep_exp.X_op == O_constant)
{
- p = frag_var (rs_fill, (int) size, (int) size,
- (relax_substateT) 0, (symbolS *) 0,
- (offsetT) rep_exp.X_add_number,
- (char *) 0);
+ p = frag_var (rs_fill, size, size, 0, NULL,
+ rep_exp.X_add_number, NULL);
}
else
{
@@ -2370,11 +2420,10 @@ s_fill (int ignore ATTRIBUTE_UNUSED)
rep_sym = make_expr_symbol (&rep_exp);
}
- p = frag_var (rs_space, (int) size, (int) size,
- (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0);
+ p = frag_var (rs_space, size, size, 0, rep_sym, 0, NULL);
}
- memset (p, 0, (unsigned int) size);
+ memset (p, 0, size);
/* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
flavoured AS. The following bizarre behaviour is to be
@@ -2382,10 +2431,10 @@ s_fill (int ignore ATTRIBUTE_UNUSED)
bytes from a 4-byte expression and they forgot to sign
extend. */
#define BSD_FILL_SIZE_CROCK_4 (4)
- md_number_to_chars (p, (valueT) fill,
+ md_number_to_chars (p, fill,
(size > BSD_FILL_SIZE_CROCK_4
? BSD_FILL_SIZE_CROCK_4
- : (int) size));
+ : size));
/* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
but emits no error message because it seems a legal thing to do.
It is a degenerate case of .fill but could be emitted by a
@@ -2420,7 +2469,7 @@ s_globl (int ignore ATTRIBUTE_UNUSED)
{
input_line_pointer++;
SKIP_WHITESPACE ();
- if (is_end_of_line[(unsigned char) *input_line_pointer])
+ if (is_end_of_stmt (*input_line_pointer))
c = '\n';
}
@@ -2480,7 +2529,7 @@ s_linkonce (int ignore ATTRIBUTE_UNUSED)
type = LINKONCE_DISCARD;
- if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ if (!is_end_of_stmt (*input_line_pointer))
{
char *s;
char c;
@@ -2711,7 +2760,7 @@ s_lsym (int ignore ATTRIBUTE_UNUSED)
(exp.X_op == O_constant
? absolute_section
: reg_section));
- S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
+ S_SET_VALUE (symbolP, exp.X_add_number);
}
else
{
@@ -2920,7 +2969,7 @@ do_org (segT segment, expressionS *exp, int fill)
off = 0;
}
- p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0);
+ p = frag_var (rs_org, 1, 1, 0, sym, off, NULL);
*p = fill;
}
}
@@ -3125,7 +3174,7 @@ s_rept (int expand_count)
{
size_t count;
- count = (size_t) get_absolute_expression ();
+ count = get_absolute_expression ();
do_repeat (count, "REPT", "ENDR", expand_count ? "" : NULL);
}
@@ -3291,7 +3340,6 @@ assign_symbol (char *name, int mode)
for this symbol. */
if (listing & LISTING_SYMBOLS)
{
- extern struct list_info_struct *listing_tail;
fragS *dummy_frag = notes_calloc (1, sizeof (*dummy_frag));
dummy_frag->line = listing_tail;
dummy_frag->fr_symbol = symbolP;
@@ -3318,6 +3366,7 @@ assign_symbol (char *name, int mode)
retain the value of the symbol at the point of use. */
else if (S_IS_VOLATILE (symbolP))
symbolP = symbol_clone (symbolP, 1);
+ S_CLEAR_WEAKREFR (symbolP);
}
if (mode == 0)
@@ -3433,7 +3482,7 @@ s_space (int mult)
}
else
{
- do_align (1, (char *) NULL, 0, 0);
+ do_align (1, NULL, 0, 0);
if (line_label != NULL)
{
symbol_set_frag (line_label, frag_now);
@@ -3539,8 +3588,7 @@ s_space (int mult)
}
if (!need_pass_2)
- p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
- (offsetT) total, (char *) 0);
+ p = frag_var (rs_fill, 1, 1, 0, NULL, total, NULL);
}
else
{
@@ -3557,8 +3605,7 @@ s_space (int mult)
}
if (!need_pass_2)
- p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
- make_expr_symbol (&exp), (offsetT) 0, (char *) 0);
+ p = frag_var (rs_space, 1, 1, 0, make_expr_symbol (&exp), 0, NULL);
}
if ((val.X_op != O_constant || val.X_add_number != 0) && in_bss ())
@@ -3632,6 +3679,13 @@ s_nop (int ignore ATTRIBUTE_UNUSED)
&& frag_off + frag_now_fix () < start_off + exp.X_add_number);
}
+/* Use this to specify the amount of memory allocated for representing
+ the nops. Needs to be large enough to hold any fixed size prologue
+ plus the replicating portion. */
+#ifndef MAX_MEM_FOR_RS_SPACE_NOP
+# define MAX_MEM_FOR_RS_SPACE_NOP 1
+#endif
+
void
s_nops (int ignore ATTRIBUTE_UNUSED)
{
@@ -3680,8 +3734,7 @@ s_nops (int ignore ATTRIBUTE_UNUSED)
/* Store the no-op instruction control byte in the first byte of frag. */
char *p;
symbolS *sym = make_expr_symbol (&exp);
- p = frag_var (rs_space_nop, 1, 1, (relax_substateT) 0,
- sym, (offsetT) 0, (char *) 0);
+ p = frag_var (rs_space_nop, MAX_MEM_FOR_RS_SPACE_NOP, 1, 0, sym, 0, NULL);
*p = val.X_add_number;
}
@@ -3842,7 +3895,7 @@ s_float_space (int float_type)
char *p;
p = frag_more (flen);
- memcpy (p, temp, (unsigned int) flen);
+ memcpy (p, temp, flen);
}
demand_empty_rest_of_line ();
@@ -3880,7 +3933,7 @@ s_text (int ignore ATTRIBUTE_UNUSED)
int temp;
temp = get_absolute_expression ();
- subseg_set (text_section, (subsegT) temp);
+ subseg_set (text_section, temp);
demand_empty_rest_of_line ();
}
@@ -4011,7 +4064,7 @@ demand_empty_rest_of_line (void)
SKIP_WHITESPACE ();
if (input_line_pointer > buffer_limit)
return;
- if (is_end_of_line[(unsigned char) *input_line_pointer])
+ if (is_end_of_stmt (*input_line_pointer))
input_line_pointer++;
else
{
@@ -4132,6 +4185,8 @@ pseudo_set (symbolS *symbolP)
case O_symbol:
seg = S_GET_SEGMENT (exp.X_add_symbol);
+ if (seg == expr_section)
+ goto expr;
/* For x=undef+const, create an expression symbol.
For x=x+const, just update x except when x is an undefined symbol
For x=defined+const, evaluate x. */
@@ -4163,6 +4218,7 @@ pseudo_set (symbolS *symbolP)
break;
default:
+ expr:
/* The value is some complex expression. */
S_SET_SEGMENT (symbolP, expr_section);
symbol_set_value_expression (symbolP, &exp);
@@ -4198,6 +4254,21 @@ static void
parse_mri_cons (expressionS *exp, unsigned int nbytes);
#endif
+/* This function is used by .cfi_* directive handling, and hence must not
+ invoke parse_repeat_cons(). */
+
+TC_PARSE_CONS_RETURN_TYPE
+do_parse_cons_expression (expressionS *exp,
+ int nbytes ATTRIBUTE_UNUSED)
+{
+#ifdef TC_PARSE_CONS_EXPRESSION
+ return TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+#else
+ expression (exp);
+ return TC_PARSE_CONS_RETURN_NONE;
+#endif
+}
+
#ifndef TC_PARSE_CONS_EXPRESSION
#ifdef REPEAT_CONS_EXPRESSIONS
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
@@ -4213,14 +4284,6 @@ parse_repeat_cons (expressionS *exp, unsigned int nbytes);
#endif
#endif
-void
-do_parse_cons_expression (expressionS *exp,
- int nbytes ATTRIBUTE_UNUSED)
-{
- (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes);
-}
-
-
/* Worker to do .byte etc statements.
Clobbers input_line_pointer and checks end-of-line. */
@@ -4268,7 +4331,7 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long. */
#ifdef TC_M68K
if (flag_m68k_mri)
- parse_mri_cons (&exp, (unsigned int) nbytes);
+ parse_mri_cons (&exp, nbytes);
else
#endif
{
@@ -4280,7 +4343,7 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long. */
return;
}
#endif
- ret = TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+ ret = TC_PARSE_CONS_EXPRESSION (&exp, nbytes);
}
if (rva)
@@ -4290,7 +4353,7 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long. */
else
as_fatal (_("rva without symbol"));
}
- emit_expr_with_reloc (&exp, (unsigned int) nbytes, ret);
+ emit_expr_with_reloc (&exp, nbytes, ret);
#ifdef TC_CONS_FIX_CHECK
TC_CONS_FIX_CHECK (&exp, nbytes, *cur_fix);
#endif
@@ -4496,7 +4559,7 @@ emit_expr_with_reloc (expressionS *exp,
&& nbytes == 2
&& exp->X_op == O_constant
&& (exp->X_add_number == -1 || exp->X_add_number == 0xffff))
- listing_source_line ((unsigned int) dwarf_line);
+ listing_source_line (dwarf_line);
else if (nbytes == 4
&& exp->X_op == O_constant
&& exp->X_add_number >= 0)
@@ -4573,7 +4636,7 @@ emit_expr_with_reloc (expressionS *exp,
/* We can ignore any carry out, because it will be handled by
extra_digit if it is needed. */
- extra_digit = (valueT) -1;
+ extra_digit = -1;
op = O_big;
}
@@ -4609,7 +4672,7 @@ emit_expr_with_reloc (expressionS *exp,
as_bad (_("attempt to store non-zero value in section `%s'"),
segment_name (now_seg));
- p = frag_more ((int) nbytes);
+ p = frag_more (nbytes);
if (reloc != TC_PARSE_CONS_RETURN_NONE)
{
@@ -4646,8 +4709,7 @@ emit_expr_with_reloc (expressionS *exp,
pass to md_number_to_chars, handle it as a bignum. */
if (op == O_constant && nbytes > sizeof (valueT))
{
- extra_digit = exp->X_unsigned ? 0 : -1;
- convert_to_bignum (exp, !exp->X_unsigned);
+ extra_digit = -convert_to_bignum (exp);
op = O_big;
}
@@ -4687,7 +4749,7 @@ emit_expr_with_reloc (expressionS *exp,
(uint64_t) get, (uint64_t) use);
}
/* Put bytes in right order. */
- md_number_to_chars (p, use, (int) nbytes);
+ md_number_to_chars (p, use, nbytes);
}
else if (op == O_big)
{
@@ -4736,7 +4798,7 @@ emit_expr_with_reloc (expressionS *exp,
if (nbytes == 1)
{
- md_number_to_chars (p, (valueT) generic_bignum[0], 1);
+ md_number_to_chars (p, generic_bignum[0], 1);
return;
}
know (nbytes % CHARS_PER_LITTLENUM == 0);
@@ -4754,7 +4816,7 @@ emit_expr_with_reloc (expressionS *exp,
while (size >= CHARS_PER_LITTLENUM)
{
--nums;
- md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
+ md_number_to_chars (p, *nums, CHARS_PER_LITTLENUM);
size -= CHARS_PER_LITTLENUM;
p += CHARS_PER_LITTLENUM;
}
@@ -4764,7 +4826,7 @@ emit_expr_with_reloc (expressionS *exp,
nums = generic_bignum;
while (size >= CHARS_PER_LITTLENUM)
{
- md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
+ md_number_to_chars (p, *nums, CHARS_PER_LITTLENUM);
++nums;
size -= CHARS_PER_LITTLENUM;
p += CHARS_PER_LITTLENUM;
@@ -5096,7 +5158,7 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line. */
while (--count >= 0)
{
p = frag_more (length);
- memcpy (p, temp, (unsigned int) length);
+ memcpy (p, temp, length);
}
}
SKIP_WHITESPACE ();
@@ -5166,7 +5228,7 @@ unsigned int
sizeof_leb128 (valueT value, int sign)
{
if (sign)
- return sizeof_sleb128 ((offsetT) value);
+ return sizeof_sleb128 (value);
else
return sizeof_uleb128 (value);
}
@@ -5225,7 +5287,7 @@ unsigned int
output_leb128 (char *p, valueT value, int sign)
{
if (sign)
- return output_sleb128 (p, (offsetT) value);
+ return output_sleb128 (p, value);
else
return output_uleb128 (p, value);
}
@@ -5366,12 +5428,14 @@ emit_leb128_expr (expressionS *exp, int sign)
}
else if (op == O_constant
&& sign
- && (exp->X_add_number < 0) == !exp->X_extrabit)
+ && (exp->X_unsigned
+ ? exp->X_add_number < 0
+ : (exp->X_add_number < 0) != exp->X_extrabit))
{
/* We're outputting a signed leb128 and the sign of X_add_number
doesn't reflect the sign of the original value. Convert EXP
to a correctly-extended bignum instead. */
- convert_to_bignum (exp, exp->X_extrabit);
+ convert_to_bignum (exp);
op = O_big;
}
@@ -5389,7 +5453,7 @@ emit_leb128_expr (expressionS *exp, int sign)
/* Let check_eh_frame know that data is being emitted. nbytes == -1 is
a signal that this is leb128 data. It shouldn't optimize this away. */
- nbytes = (unsigned int) -1;
+ nbytes = -1u;
if (check_eh_frame (exp, &nbytes))
abort ();
@@ -5437,7 +5501,7 @@ emit_leb128_expr (expressionS *exp, int sign)
resolve things later. */
frag_var (rs_leb128, sizeof_uleb128 (~(valueT) 0), 0, sign,
- make_expr_symbol (exp), 0, (char *) NULL);
+ make_expr_symbol (exp), 0, NULL);
}
}
@@ -5779,7 +5843,7 @@ s_base64 (int dummy ATTRIBUTE_UNUSED)
{
c = * input_line_pointer ++;
- if (c >= 256 || is_end_of_line [c])
+ if (c >= 256 || is_end_of_stmt (c))
{
as_bad (_("end of line encountered inside .base64 string"));
ignore_rest_of_line ();
@@ -6229,7 +6293,7 @@ char /* Return terminator. */
get_absolute_expression_and_terminator (long *val_pointer /* Return value of expression. */)
{
/* FIXME: val_pointer should probably be offsetT *. */
- *val_pointer = (long) get_absolute_expression ();
+ *val_pointer = get_absolute_expression ();
return (*input_line_pointer++);
}
@@ -6284,7 +6348,7 @@ demand_copy_string (int *lenP)
/* JF this next line is so demand_copy_C_string will return a
null terminated string. */
obstack_1grow (&notes, '\0');
- retval = (char *) obstack_finish (&notes);
+ retval = obstack_finish (&notes);
}
else
{
@@ -6293,7 +6357,7 @@ demand_copy_string (int *lenP)
ignore_rest_of_line ();
}
*lenP = len;
- return (retval);
+ return retval;
}
/* In: Input_line_pointer->next character.
@@ -6306,7 +6370,7 @@ int
is_it_end_of_statement (void)
{
SKIP_WHITESPACE ();
- return (is_end_of_line[(unsigned char) *input_line_pointer]);
+ return is_end_of_stmt (*input_line_pointer);
}
void
@@ -6321,7 +6385,7 @@ equals (char *sym_name, int reassign)
if (reassign < 0 && *input_line_pointer == '=')
input_line_pointer++;
- while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
+ while (is_whitespace (*input_line_pointer))
input_line_pointer++;
if (flag_mri)
@@ -6494,9 +6558,8 @@ s_include (int arg ATTRIBUTE_UNUSED)
{
SKIP_WHITESPACE ();
i = 0;
- while (!is_end_of_line[(unsigned char) *input_line_pointer]
- && *input_line_pointer != ' '
- && *input_line_pointer != '\t')
+ while (!is_end_of_stmt (*input_line_pointer)
+ && !is_whitespace (*input_line_pointer))
{
obstack_1grow (&notes, *input_line_pointer);
++input_line_pointer;
@@ -6504,8 +6567,8 @@ s_include (int arg ATTRIBUTE_UNUSED)
}
obstack_1grow (&notes, '\0');
- filename = (char *) obstack_finish (&notes);
- while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ filename = obstack_finish (&notes);
+ while (!is_end_of_stmt (*input_line_pointer))
++input_line_pointer;
}
@@ -6704,7 +6767,7 @@ s_bundle_lock (int arg ATTRIBUTE_UNUSED)
void
s_bundle_unlock (int arg ATTRIBUTE_UNUSED)
{
- unsigned int size;
+ valueT size;
demand_empty_rest_of_line ();
@@ -6723,9 +6786,9 @@ s_bundle_unlock (int arg ATTRIBUTE_UNUSED)
size = pending_bundle_size (bundle_lock_frag);
if (size > 1U << bundle_align_p2)
- as_bad (_(".bundle_lock sequence is %u bytes, "
+ as_bad (_(".bundle_lock sequence is %" PRIu64 " bytes, "
"but bundle size is only %u bytes"),
- size, 1u << bundle_align_p2);
+ (uint64_t) size, 1u << bundle_align_p2);
else
finish_bundle (bundle_lock_frag, size);
@@ -6791,7 +6854,7 @@ _find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED,
char inquote = '\0';
int inescape = 0;
- while (!is_end_of_line[(unsigned char) *s]
+ while (!is_end_of_stmt (*s)
|| (inquote && !ISCNTRL (*s))
|| (inquote == '\'' && flag_mri)
#ifdef TC_EOL_IN_INSN
@@ -6800,7 +6863,7 @@ _find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED,
/* PR 6926: When we are parsing the body of a macro the sequence
\@ is special - it refers to the invocation count. If the @
character happens to be registered as a line-separator character
- by the target, then the is_end_of_line[] test above will have
+ by the target, then the is_end_of_stmt() test above will have
returned true, but we need to ignore the line separating
semantics in this particular case. */
|| (in_macro && inescape && *s == '@')