static segT get_known_segmented_expression PARAMS ((expressionS * expP));
static void pobegin PARAMS ((void));
static int get_line_sb PARAMS ((sb *));
+static void generate_file_debug PARAMS ((void));
+static void generate_lineno_debug PARAMS ((void));
\f
void
{"elsec", s_else, 0},
{"end", s_end, 0},
{"endc", s_endif, 0},
+ {"endfunc", s_func, 1},
{"endif", s_endif, 0},
/* endef */
{"equ", s_set, 0},
{"fill", s_fill, 0},
{"float", float_cons, 'f'},
{"format", s_ignore, 0},
+ {"func", s_func, 0},
{"global", s_globl, 0},
{"globl", s_globl, 0},
{"hword", cons, 2},
listing_newline (NULL);
register_dependency (name);
+ /* Generate debugging information before we've read anything in to denote
+ this file as the "main" source file and not a subordinate one
+ (e.g. N_SO vs N_SOL in stabs). */
+ generate_file_debug ();
+
while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
{ /* We have another line to parse. */
know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
c = *input_line_pointer;
*input_line_pointer = '\0';
- if (debug_type == DEBUG_STABS)
- stabs_generate_asm_lineno ();
-
-#ifdef OBJ_GENERATE_ASM_LINENO
-#ifdef ECOFF_DEBUGGING
- /* ECOFF assemblers automatically generate
- debugging information. FIXME: This should
- probably be handled elsewhere. */
- if (debug_type == DEBUG_NONE)
- {
- if (ecoff_no_current_file ())
- debug_type = DEBUG_ECOFF;
- }
-
- if (debug_type == DEBUG_ECOFF)
- {
- unsigned int lineno;
- char *s;
-
- as_where (&s, &lineno);
- OBJ_GENERATE_ASM_LINENO (s, lineno);
- }
-#endif
-#endif
+ generate_lineno_debug ();
if (macro_defined)
{
}
}
+ demand_empty_rest_of_line ();
+
if (flag_mri)
mri_comment_end (stop, stopc);
-
- demand_empty_rest_of_line ();
}
/* Handle the .align pseudo-op on machines where ".align 4" means
if (*input_line_pointer != ',')
{
as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+ ignore_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- ignore_rest_of_line ();
return;
}
input_line_pointer++; /* skip ',' */
if ((temp = get_absolute_expression ()) < 0)
{
as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
+ ignore_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- ignore_rest_of_line ();
return;
}
*p = 0;
{
as_bad (_("Ignoring attempt to re-define symbol `%s'."),
S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- ignore_rest_of_line ();
return;
}
if (S_GET_VALUE (symbolP))
#endif /* not OBJ_VMS */
know (symbolP->sy_frag == &zero_address_frag);
+ demand_empty_rest_of_line ();
+
if (flag_mri)
mri_comment_end (stop, stopc);
-
- demand_empty_rest_of_line ();
} /* s_comm() */
/* The MRI COMMON pseudo-op. We handle this by creating a common
if (S_IS_DEFINED (sym) && ! S_IS_COMMON (sym))
{
as_bad (_("attempt to re-define symbol `%s'"), S_GET_NAME (sym));
- mri_comment_end (stop, stopc);
ignore_rest_of_line ();
+ mri_comment_end (stop, stopc);
return;
}
if (*input_line_pointer == ',')
input_line_pointer += 2;
- mri_comment_end (stop, stopc);
-
demand_empty_rest_of_line ();
+
+ mri_comment_end (stop, stopc);
}
void
else
as_bad (_(".fail %ld encountered"), (long) temp);
+ demand_empty_rest_of_line ();
+
if (flag_mri)
mri_comment_end (stop, stopc);
-
- demand_empty_rest_of_line ();
}
void
}
while (c == ',');
+ demand_empty_rest_of_line ();
+
if (flag_mri)
mri_comment_end (stop, stopc);
-
- demand_empty_rest_of_line ();
}
/* Handle the MRI IRP and IRPC pseudo-ops. */
#ifdef TC_M68K
flag_m68k_mri = 1;
#endif
+ macro_mri_mode (1);
}
else
{
flag_mri = 0;
flag_m68k_mri = 0;
+ macro_mri_mode (0);
}
+ /* Operator precedence changes in m68k MRI mode, so we need to
+ update the operator rankings. */
+ expr_set_precedence ();
+
#ifdef MRI_MODE_CHANGE
if (on != old_flag)
MRI_MODE_CHANGE (on);
expressionS exp;
register long temp_fill;
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
/* The m68k MRI assembler has a different meaning for .org. It
means to create an absolute section at a given address. We can't
support that--use a linker script instead. */
if (listing & LISTING_SYMBOLS)
{
extern struct list_info_struct *listing_tail;
- fragS *dummy_frag = xmalloc (sizeof(fragS));
+ fragS *dummy_frag = (fragS *) xmalloc (sizeof(fragS));
memset (dummy_frag, 0, sizeof(fragS));
dummy_frag->fr_type = rs_fill;
dummy_frag->line = listing_tail;
if (flag_mri && (bytes & 1) != 0)
mri_pending_align = 1;
+ demand_empty_rest_of_line ();
+
if (flag_mri)
mri_comment_end (stop, stopc);
-
- demand_empty_rest_of_line ();
}
/* This is like s_space, but the value is a floating point number with
if (*input_line_pointer != ',')
{
as_bad (_("missing value"));
+ ignore_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- ignore_rest_of_line ();
return;
}
flen = hex_float (float_type, temp);
if (flen < 0)
{
+ ignore_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- ignore_rest_of_line ();
return;
}
}
if (err)
{
as_bad (_("Bad floating literal: %s"), err);
+ ignore_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- ignore_rest_of_line ();
return;
}
}
memcpy (p, temp, (unsigned int) flen);
}
+ demand_empty_rest_of_line ();
+
if (flag_mri)
mri_comment_end (stop, stopc);
-
- demand_empty_rest_of_line ();
}
/* Handle the .struct pseudo-op, as found in MIPS assemblers. */
stop = mri_comment_field (&stopc);
abs_section_offset = get_absolute_expression ();
subseg_set (absolute_section, 0);
+ demand_empty_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- demand_empty_rest_of_line ();
}
void
if (is_it_end_of_statement ())
{
+ demand_empty_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
- demand_empty_rest_of_line ();
return;
}
input_line_pointer--; /* Put terminator back into stream. */
+ demand_empty_rest_of_line ();
+
if (flag_mri)
mri_comment_end (stop, stopc);
-
- demand_empty_rest_of_line ();
}
x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
x->next_broken_word = broken_words;
broken_words = x;
+ x->seg = now_seg;
+ x->subseg = now_subseg;
x->frag = frag_now;
x->word_goes_here = p;
x->dispfrag = 0;
return size;
}
-inline int
+int
sizeof_leb128 (value, sign)
valueT value;
int sign;
/*
* The following awkward logic is to parse ZERO or more strings,
- * comma seperated. Recall a string expression includes spaces
+ * comma separated. Recall a string expression includes spaces
* before the opening '\"' and spaces after the closing '\"'.
* We fake a leading ',' if there is (supposed to be)
* a 1st, expression. We keep demanding expressions for each
}
if (flag_mri)
- mri_comment_end (stop, stopc);
+ {
+ ignore_rest_of_line (); /* check garbage after the expression */
+ mri_comment_end (stop, stopc);
+ }
} /* equals() */
/* .include -- include a file at this point. */
if (i > include_dir_maxlen)
include_dir_maxlen = i;
} /* add_include_dir() */
+\f
+/* Output debugging information to denote the source file. */
+
+static void
+generate_file_debug ()
+{
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_file ();
+}
+
+/* Output line number debugging information for the current source line. */
+
+static void
+generate_lineno_debug ()
+{
+#ifdef ECOFF_DEBUGGING
+ /* ECOFF assemblers automatically generate debugging information.
+ FIXME: This should probably be handled elsewhere. */
+ if (debug_type == DEBUG_UNSPECIFIED)
+ {
+ if (ECOFF_DEBUGGING && ecoff_no_current_file ())
+ debug_type = DEBUG_ECOFF;
+ else
+ debug_type = DEBUG_NONE;
+ }
+#endif
+
+ switch (debug_type)
+ {
+ case DEBUG_UNSPECIFIED:
+ case DEBUG_NONE:
+ break;
+ case DEBUG_STABS:
+ stabs_generate_asm_lineno ();
+ break;
+ case DEBUG_ECOFF:
+ ecoff_generate_asm_lineno ();
+ break;
+ }
+}
+
+/* Output debugging information to mark a function entry point or end point.
+ END_P is zero for .func, and non-zero for .endfunc. */
+
+void
+s_func (end_p)
+ int end_p;
+{
+ do_s_func (end_p, NULL);
+}
+
+/* Subroutine of s_func so targets can choose a different default prefix.
+ If DEFAULT_PREFIX is NULL, use the target's "leading char". */
+
+void
+do_s_func (end_p, default_prefix)
+ int end_p;
+ const char *default_prefix;
+{
+ /* Record the current function so that we can issue an error message for
+ misplaced .func,.endfunc, and also so that .endfunc needs no
+ arguments. */
+ static char *current_name;
+ static char *current_label;
+
+ if (end_p)
+ {
+ if (current_name == NULL)
+ {
+ as_bad (_("missing .func"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_endfunc (current_name, current_label);
+
+ current_name = current_label = NULL;
+ }
+ else /* ! end_p */
+ {
+ char *name,*label;
+ char delim1,delim2;
+
+ if (current_name != NULL)
+ {
+ as_bad (_(".endfunc missing for previous .func"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ delim1 = get_symbol_end ();
+ name = xstrdup (name);
+ *input_line_pointer = delim1;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ if (default_prefix)
+ asprintf (&label, "%s%s", default_prefix, name);
+ else
+ {
+ char leading_char = 0;
+#ifdef BFD_ASSEMBLER
+ leading_char = bfd_get_symbol_leading_char (stdoutput);
+#endif
+ /* Missing entry point, use function's name with the leading
+ char prepended. */
+ if (leading_char)
+ asprintf (&label, "%c%s", leading_char, name);
+ else
+ label = name;
+ }
+ }
+ else
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ label = input_line_pointer;
+ delim2 = get_symbol_end ();
+ label = xstrdup (label);
+ *input_line_pointer = delim2;
+ }
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_func (name, label);
+
+ current_name = name;
+ current_label = label;
+ }
+ demand_empty_rest_of_line ();
+}
+\f
void
s_ignore (arg)
int arg;