aboutsummaryrefslogtreecommitdiff
path: root/gas/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/read.c')
-rw-r--r--gas/read.c2744
1 files changed, 1479 insertions, 1265 deletions
diff --git a/gas/read.c b/gas/read.c
index 7d441f8..7f04ae4 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -1,22 +1,21 @@
/* read.c - read a source file -
+ Copyright (C) 1986, 1987, 1990, 1991 Free Software Foundation, Inc.
- Copyright (C) 1986, 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
-
- This file is part of GAS, the GNU Assembler.
-
- GAS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GAS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GAS; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
change this a bit. But then, GNU isn't
@@ -25,9 +24,9 @@
*/
#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
-/* This is the largest known floating point */
-/* format (for now). It will grow when we */
-/* do 4361 style flonums. */
+ /* This is the largest known floating point */
+ /* format (for now). It will grow when we */
+ /* do 4361 style flonums. */
/* Routines that read assembler source text to build spagetti in memory. */
@@ -36,36 +35,33 @@
#include "as.h"
#include "obstack.h"
-
+#include "listing.h"
char *input_line_pointer; /*->next char of source file to parse. */
-#ifndef NOP_OPCODE
-# define NOP_OPCODE 0x00
-#endif
#if BITS_PER_CHAR != 8
The following table is indexed by [ (char) ] and will break if
- a char does not have exactly 256 states (hopefully 0:255!) !
+a char does not have exactly 256 states (hopefully 0:255!) !
#endif
-
- const char /* used by is_... macros. our ctype[] */
- lex_type [256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
- 0, 0, 0, 0, 3, 0, 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, 0, /* 0123456789:;<=>? */
- 0, 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, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
- 0, 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, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
- 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
- };
+
+const char /* used by is_... macros. our ctype[] */
+lex_type [256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
+ 0, 0, 0, 0, 3, 0, 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, 0, /* 0123456789:;<=>? */
+ 0, 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, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
+ 0, 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, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
+ 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
+};
/*
@@ -75,26 +71,26 @@ The following table is indexed by [ (char) ] and will break if
#define _ (0)
char is_end_of_line [256] = {
#ifdef CR_EOL
- _, _, _, _, _, _, _, _, _, _,99, _, _, 99, _, _,/* @abcdefghijklmno */
+ _, _, _, _, _, _, _, _, _, _,99, _, _, 99, _, _,/* @abcdefghijklmno */
#else
- _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, _, /* @abcdefghijklmno */
+ _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, _, /* @abcdefghijklmno */
#endif
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, /* 0123456789:;<=>? */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ /* */
- };
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, /* 0123456789:;<=>? */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ /* */
+};
#undef _
-/* Functions private to this file. */
+ /* Functions private to this file. */
char line_comment_chars[1];
char line_separator_chars[1];
@@ -105,8 +101,8 @@ static char *buffer_limit; /*->1 + last char in buffer. */
static char *bignum_low; /* Lowest char of bignum. */
static char *bignum_limit; /* 1st illegal address of bignum. */
static char *bignum_high; /* Highest char of bignum. */
-/* May point to (bignum_start-1). */
-/* Never >= bignum_limit. */
+ /* May point to (bignum_start-1). */
+ /* Never >= bignum_limit. */
static char *old_buffer = 0; /* JF a hack */
static char *old_input;
static char *old_limit;
@@ -123,7 +119,7 @@ struct broken_word *broken_words;
int new_broken_words = 0;
#endif
-#if __STDC__ == 1
+#ifdef __STDC__
static char *demand_copy_string(int *lenP);
int is_it_end_of_statement(void);
@@ -131,7 +127,7 @@ unsigned int next_char_of_string(void);
static segT get_known_segmented_expression(expressionS *expP);
static void grow_bignum(void);
static void pobegin(void);
-void stringer(int append_zero);
+ void stringer(int append_zero);
#else /* __STDC__ */
@@ -141,138 +137,125 @@ unsigned int next_char_of_string();
static segT get_known_segmented_expression();
static void grow_bignum();
static void pobegin();
-void stringer();
+ void stringer();
-#endif /* not __STDC__ */
+#endif /* __STDC__ */
extern int listing;
void
- read_begin()
+read_begin()
{
- char *p;
-
- pobegin();
- obj_read_begin_hook();
-
- obstack_begin(&notes, 5000);
- obstack_begin(&cond_obstack, 960);
-
+ char *p;
+
+ pobegin();
+ obj_read_begin_hook();
+
+ obstack_begin(&notes, 5000);
+ obstack_begin(&cond_obstack, 960);
+
#define BIGNUM_BEGIN_SIZE (16)
- bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);
- bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
-
- /* Use machine dependent syntax */
- for (p = line_separator_chars; *p; p++)
- is_end_of_line[*p] = 1;
- /* Use more. FIXME-SOMEDAY. */
+ bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);
+ bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
+
+ /* Use machine dependent syntax */
+ for (p = line_separator_chars; *p; p++)
+ is_end_of_line[*p] = 1;
+ /* Use more. FIXME-SOMEDAY. */
}
/* set up pseudo-op tables */
struct hash_control *
- po_hash = NULL; /* use before set up: NULL->address error */
+po_hash = NULL; /* use before set up: NULL->address error */
+
+#ifdef DONTDEF
+void s_gdbline(), s_gdblinetab();
+void s_gdbbeg(), s_gdbblock(), s_gdbend(), s_gdbsym();
+#endif
static const pseudo_typeS
- potable[] =
+potable[] =
{
- { "abort", s_abort, 0 },
- { "align", s_align_ptwo, 0 },
- { "ascii", stringer, 0 },
- { "asciz", stringer, 1 },
- /* block */
- { "byte", cons, 1 },
- { "bss", s_bss, 0 },
- { "comm", s_comm, 0 },
- { "data", s_data, 0 },
- /* dim */
- { "double", float_cons, 'd' },
- /* dsect */
-#ifdef NO_LISTING
- { "eject", s_ignore, 0 }, /* Formfeed listing */
-#else
- { "eject", listing_eject, 0 }, /* Formfeed listing */
-#endif /* NO_LISTING */
- { "else", s_else, 0 },
- { "end", s_end, 0 },
- { "endif", s_endif, 0 },
- /* endef */
- { "equ", s_set, 0 },
- /* err */
- /* extend */
- { "extern", s_ignore, 0 }, /* We treat all undef as ext */
- { "app-file", s_app_file, 0 },
- { "file", s_app_file, 0 },
- { "fill", s_fill, 0 },
- { "float", float_cons, 'f' },
- { "global", s_globl, 0 },
- { "globl", s_globl, 0 },
- { "hword", cons, 2 },
- { "if", s_if, 0 },
- { "ifdef", s_ifdef, 0 },
- { "ifeqs", s_ifeqs, 0 },
- { "ifndef", s_ifdef, 1 },
- { "ifnes", s_ifeqs, 1 },
- { "ifnotdef", s_ifdef, 1 },
- { "include", s_include, 0 },
- { "int", cons, 4 },
- { "lcomm", s_lcomm, 0 },
-#ifdef NO_LISTING
- { "lflags", s_ignore, 0 }, /* Listing flags */
- { "list", s_ignore, 1 }, /* Turn listing on */
-#else
- { "lflags", listing_flags, 0 }, /* Listing flags */
- { "list", listing_list, 1 }, /* Turn listing on */
-#endif /* NO_LISTING */
- { "long", cons, 4 },
- { "lsym", s_lsym, 0 },
-#ifdef NO_LISTING
- { "nolist", s_ignore, 0 }, /* Turn listing off */
-#else
- { "nolist", listing_list, 0 }, /* Turn listing off */
-#endif /* NO_LISTING */
- { "octa", big_cons, 16 },
- { "org", s_org, 0 },
-#ifdef NO_LISTING
- { "psize", s_ignore, 0 }, /* set paper size */
-#else
- { "psize", listing_psize, 0 }, /* set paper size */
-#endif /* NO_LISTING */
- /* print */
- { "quad", big_cons, 8 },
-#ifdef NO_LISTING
- { "sbttl", s_ignore, 1 }, /* Subtitle of listing */
-#else
- { "sbttl", listing_title, 1 }, /* Subtitle of listing */
-#endif /* NO_LISTING */
- /* scl */
- /* sect */
- { "set", s_set, 0 },
- { "short", cons, 2 },
- { "single", float_cons, 'f' },
- /* size */
- { "space", s_space, 0 },
- /* tag */
- { "text", s_text, 0 },
-#ifdef NO_LISTING
- { "title", s_ignore, 0 }, /* Listing title */
-#else
- { "title", listing_title, 0 }, /* Listing title */
-#endif /* NO_LISTING */
- /* type */
- /* use */
- /* val */
- { "word", cons, 2 },
- { NULL} /* end sentinel */
+ { "abort", s_abort, 0 },
+ { "align", s_align_ptwo, 0 },
+ { "ascii", stringer, 0 },
+ { "asciz", stringer, 1 },
+/* block */
+ { "byte", cons, 1 },
+ { "comm", s_comm, 0 },
+ { "data", s_data, 0 },
+/* dim */
+ { "double", float_cons, 'd' },
+/* dsect */
+ { "eject", listing_eject, 0 }, /* Formfeed listing */
+ { "else", s_else, 0 },
+ { "end", s_end, 0 },
+ { "endif", s_endif, 0 },
+/* endef */
+ { "equ", s_set, 0 },
+/* err */
+/* extend */
+ { "extern", s_ignore, 0 }, /* We treat all undef as ext */
+ { "app-file", s_app_file, 0 },
+ { "file", s_app_file, 0 },
+ { "fill", s_fill, 0 },
+ { "float", float_cons, 'f' },
+#ifdef DONTDEF
+ { "gdbbeg", s_gdbbeg, 0 },
+ { "gdbblock", s_gdbblock, 0 },
+ { "gdbend", s_gdbend, 0 },
+ { "gdbsym", s_gdbsym, 0 },
+ { "gdbline", s_gdbline, 0 },
+ { "gdblinetab",s_gdblinetab, 0 },
+#endif
+ { "global", s_globl, 0 },
+ { "globl", s_globl, 0 },
+ { "hword", cons, 2 },
+ { "if", s_if, 0 },
+ { "ifdef", s_ifdef, 0 },
+ { "ifeqs", s_ifeqs, 0 },
+ { "ifndef", s_ifdef, 1 },
+ { "ifnes", s_ifeqs, 1 },
+ { "ifnotdef", s_ifdef, 1 },
+ { "include", s_include, 0 },
+ { "int", cons, 4 },
+ { "lcomm", s_lcomm, 0 },
+ { "lflags", listing_flags, 0 }, /* Listing flags */
+ { "list", listing_list, 1 }, /* Turn listing on */
+ { "long", cons, 4 },
+ { "lsym", s_lsym, 0 },
+ { "nolist", listing_list, 0 }, /* Turn listing off */
+ { "octa", big_cons, 16 },
+ { "org", s_org, 0 },
+ { "psize", listing_psize, 0 }, /* set paper size */
+/* print */
+ { "quad", big_cons, 8 },
+ { "sbttl", listing_title, 1 }, /* Subtitle of listing */
+/* scl */
+/* sect */
+ { "set", s_set, 0 },
+ { "short", cons, 2 },
+ { "single", float_cons, 'f' },
+/* size */
+ { "space", s_space, 0 },
+/* tag */
+ { "text", s_text, 0 },
+ { "title", listing_title, 0 }, /* Listing title */
+/* type */
+/* use */
+/* val */
+ { "word", cons, 2 },
+ { NULL} /* end sentinel */
};
static void pobegin() {
char *errtxt; /* error text */
const pseudo_typeS * pop;
-
+
po_hash = hash_new();
-
+
/* Do the target-specific pseudo ops. */
for (pop = md_pseudo_table; pop->poc_name; pop++) {
errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop);
@@ -280,7 +263,7 @@ static void pobegin() {
as_fatal("error constructing md pseudo-op table");
} /* on error */
} /* for each op */
-
+
/* Now object specific. Skip any that were in the target table. */
for (pop=obj_pseudo_table; pop->poc_name; pop++) {
errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
@@ -295,7 +278,7 @@ static void pobegin() {
} /* if overridden */
} /* on error */
} /* for each op */
-
+
/* Now portable ones. Skip any that we've seen already. */
for (pop=potable; pop->poc_name; pop++) {
errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
@@ -310,18 +293,18 @@ static void pobegin() {
} /* if overridden */
} /* on error */
} /* for each op */
-
+
return;
} /* pobegin() */
#define HANDLE_CONDITIONAL_ASSEMBLY() \
- if (ignore_input ()) \
-{ \
- while (! is_end_of_line[*input_line_pointer++]) \
- if (input_line_pointer == buffer_limit) \
- break; \
- continue; \
- }
+ if (ignore_input ()) \
+ { \
+ while (! is_end_of_line[*input_line_pointer++]) \
+ if (input_line_pointer == buffer_limit) \
+ break; \
+ continue; \
+ }
/* read_a_source_file()
@@ -332,264 +315,315 @@ static void pobegin() {
void read_a_source_file(name)
char *name;
{
- register char c;
- register char * s; /* string of symbol, '\0' appended */
- register int temp;
- /* register struct frag * fragP; JF unused */ /* a frag we just made */
- pseudo_typeS *pop;
-
- buffer = input_scrub_new_file(name);
-
- listing_file(name);
- listing_newline("");
-
- 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. */
- contin: /* JF this goto is my fault I admit it. Someone brave please re-write
- the whole input section here? Pleeze??? */
- while (input_line_pointer < buffer_limit) { /* We have more of this buffer to parse. */
-
- /*
- * 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.
- */
- if (input_line_pointer[-1] == '\n') {
- bump_line_counters();
- } /* just passed a newline */
-
-
+ register char c;
+ register char * s; /* string of symbol, '\0' appended */
+ register int temp;
+ /* register struct frag * fragP; JF unused */ /* a frag we just made */
+ pseudo_typeS *pop;
+#ifdef DONTDEF
+ void gdb_block_beg();
+ void gdb_block_position();
+ void gdb_block_end();
+ void gdb_symbols_fixup();
+#endif
+
+ buffer = input_scrub_new_file(name);
+
+ listing_file(name);
+ listing_newline("");
+
+ 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. */
+ contin: /* JF this goto is my fault I admit it. Someone brave please re-write
+ the whole input section here? Pleeze??? */
+ while (input_line_pointer < buffer_limit) { /* We have more of this buffer to parse. */
+
+ /*
+ * 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.
+ */
+ if (input_line_pointer[-1] == '\n') {
+ bump_line_counters();
+
+#ifdef MRI
+ /* Text at the start of a line must be a label, we run down and stick a colon in */
+ if (is_name_beginner(*input_line_pointer))
+ {
+ char *line_start = input_line_pointer;
+ char c = get_symbol_end();
+ colon(line_start);
+ *input_line_pointer = c;
+ if (c == ':')
+ input_line_pointer++;
+
+ }
+#endif
+ } /* just passed a newline */
+
+
+
+
- /*
- * We are at the begining of a line, or similar place.
- * We expect a well-formed assembler statement.
- * A "symbol-name:" is a statement.
- *
- * Depending on what compiler is used, the order of these tests
- * may vary to catch most common case 1st.
- * Each test is independent of all other tests at the (top) level.
- * PLEASE make a compiler that doesn't use this assembler.
- * It is crufty to waste a compiler's time encoding things for this
- * assembler, which then wastes more time decoding it.
- * (And communicating via (linear) files is silly!
- * If you must pass stuff, please pass a tree!)
- */
- if ((c = *input_line_pointer++) == '\t' || c == ' ' || c=='\f' || c == 0) {
- c = *input_line_pointer++;
- }
- know(c != ' '); /* No further leading whitespace. */
- LISTING_NEWLINE();
- /*
- * C is the 1st significant character.
- * Input_line_pointer points after that character.
- */
- if (is_name_beginner(c)) { /* want user-defined label or pseudo/opcode */
- HANDLE_CONDITIONAL_ASSEMBLY();
+ /*
+ * We are at the begining of a line, or similar place.
+ * We expect a well-formed assembler statement.
+ * A "symbol-name:" is a statement.
+ *
+ * Depending on what compiler is used, the order of these tests
+ * may vary to catch most common case 1st.
+ * Each test is independent of all other tests at the (top) level.
+ * PLEASE make a compiler that doesn't use this assembler.
+ * It is crufty to waste a compiler's time encoding things for this
+ * assembler, which then wastes more time decoding it.
+ * (And communicating via (linear) files is silly!
+ * If you must pass stuff, please pass a tree!)
+ */
+ if ((c = *input_line_pointer++) == '\t' || c == ' ' || c=='\f' || c == 0) {
+ c = *input_line_pointer++;
+ }
+ know(c != ' '); /* No further leading whitespace. */
+ LISTING_NEWLINE();
+ /*
+ * C is the 1st significant character.
+ * Input_line_pointer points after that character.
+ */
+ if (is_name_beginner(c)) { /* want user-defined label or pseudo/opcode */
+ HANDLE_CONDITIONAL_ASSEMBLY();
- s = --input_line_pointer;
- c = get_symbol_end(); /* name's delimiter */
- /*
- * C is character after symbol.
- * That character's place in the input line is now '\0'.
- * S points to the beginning of the symbol.
- * [In case of pseudo-op, s->'.'.]
- * Input_line_pointer->'\0' where c was.
- */
- if (c == ':') {
- colon(s); /* user-defined label */
- * input_line_pointer ++ = ':'; /* Put ':' back for error messages' sake. */
- /* Input_line_pointer->after ':'. */
- SKIP_WHITESPACE();
-
+ s = --input_line_pointer;
+ c = get_symbol_end(); /* name's delimiter */
+ /*
+ * C is character after symbol.
+ * That character's place in the input line is now '\0'.
+ * S points to the beginning of the symbol.
+ * [In case of pseudo-op, s->'.'.]
+ * Input_line_pointer->'\0' where c was.
+ */
+ if (c == ':') {
+ colon(s); /* user-defined label */
+ * input_line_pointer ++ = ':'; /* Put ':' back for error messages' sake. */
+ /* Input_line_pointer->after ':'. */
+ SKIP_WHITESPACE();
+
- } else if (c == '=' || input_line_pointer[1] == '=') { /* JF deal with FOO=BAR */
- equals(s);
- demand_empty_rest_of_line();
- } else { /* expect pseudo-op or machine instruction */
- if (*s == '.') {
- /*
- * PSEUDO - OP.
- *
- * WARNING: c has next char, which may be end-of-line.
- * We lookup the pseudo-op table with s+1 because we
- * already know that the pseudo-op begins with a '.'.
- */
+ } else if (c == '=' || input_line_pointer[1] == '=') { /* JF deal with FOO=BAR */
+ equals(s);
+ demand_empty_rest_of_line();
+ } else { /* expect pseudo-op or machine instruction */
+#ifdef MRI
+ if(!done_pseudo(s))
+
+#else
+ if (*s == '.') {
+ /*
+ * PSEUDO - OP.
+ *
+ * WARNING: c has next char, which may be end-of-line.
+ * We lookup the pseudo-op table with s+1 because we
+ * already know that the pseudo-op begins with a '.'.
+ */
- pop = (pseudo_typeS *) hash_find(po_hash, s+1);
+ pop = (pseudo_typeS *) hash_find(po_hash, s+1);
- /* Print the error msg now, while we still can */
- if (!pop) {
- as_bad("Unknown pseudo-op: `%s'",s);
- *input_line_pointer = c;
- s_ignore(0);
- break;
- }
+ /* Print the error msg now, while we still can */
+ if (!pop) {
+ as_bad("Unknown pseudo-op: `%s'",s);
+ *input_line_pointer = c;
+ s_ignore(0);
+ break;
+ }
- /* Put it back for error messages etc. */
- *input_line_pointer = c;
- /* The following skip of whitespace is compulsory. */
- /* A well shaped space is sometimes all that separates keyword from operands. */
- if (c == ' ' || c == '\t') {
- input_line_pointer++;
- } /* Skip seperator after keyword. */
- /*
- * Input_line is restored.
- * Input_line_pointer->1st non-blank char
- * after pseudo-operation.
- */
- if (!pop) {
- ignore_rest_of_line();
- break;
- } else {
- (*pop->poc_handler)(pop->poc_val);
- } /* if we have one */
- } else { /* machine instruction */
- /* WARNING: c has char, which may be end-of-line. */
- /* Also: input_line_pointer->`\0` where c was. */
- * input_line_pointer = c;
- while (!is_end_of_line[*input_line_pointer]) {
- input_line_pointer++;
- }
- c = *input_line_pointer;
- *input_line_pointer = '\0';
- md_assemble(s); /* Assemble 1 instruction. */
- *input_line_pointer++ = c;
- /* We resume loop AFTER the end-of-line from this instruction */
- } /* if (*s=='.') */
-
- } /* if c==':' */
- continue;
- } /* if (is_name_beginner(c) */
-
+ /* Put it back for error messages etc. */
+ *input_line_pointer = c;
+ /* The following skip of whitespace is compulsory. */
+ /* A well shaped space is sometimes all that separates keyword from operands. */
+ if (c == ' ' || c == '\t') {
+ input_line_pointer++;
+ } /* Skip seperator after keyword. */
+ /*
+ * Input_line is restored.
+ * Input_line_pointer->1st non-blank char
+ * after pseudo-operation.
+ */
+ if (!pop) {
+ ignore_rest_of_line();
+ break;
+ } else {
+ (*pop->poc_handler)(pop->poc_val);
+ } /* if we have one */
+ } else
+#endif
+ { /* machine instruction */
+ /* WARNING: c has char, which may be end-of-line. */
+ /* Also: input_line_pointer->`\0` where c was. */
+ * input_line_pointer = c;
+ while (!is_end_of_line[*input_line_pointer]) {
+ input_line_pointer++;
+ }
+
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ md_assemble(s); /* Assemble 1 instruction. */
+
+ *input_line_pointer++ = c;
+
+ /* We resume loop AFTER the end-of-line from this instruction */
+ } /* if (*s=='.') */
+
+ } /* if c==':' */
+ continue;
+ } /* if (is_name_beginner(c) */
- if (is_end_of_line [c]) {
- continue;
- } /* empty statement */
+ if (is_end_of_line [c]) {
+ continue;
+ } /* empty statement */
- if (isdigit(c)) { /* local label ("4:") */
- HANDLE_CONDITIONAL_ASSEMBLY ();
-
- temp = c - '0';
+
+#if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
+ if (isdigit(c)) { /* local label ("4:") */
+ char *backup = input_line_pointer;
+
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+ temp = c - '0';
+
+ while (isdigit(*input_line_pointer)) {
+ temp = (temp * 10) + *input_line_pointer - '0';
+ ++input_line_pointer;
+ } /* read the whole number */
+
#ifdef LOCAL_LABELS_DOLLAR
- if (*input_line_pointer=='$')
- input_line_pointer++;
-#endif
- if (* input_line_pointer ++ == ':')
- {
- local_colon (temp);
- }
- else
- {
- as_bad("Spurious digit %d.", temp);
- input_line_pointer -- ;
- ignore_rest_of_line();
- }
- continue;
- } /* local label ("4:") */
-
- if (c && strchr(line_comment_chars,c)) { /* Its a comment. Better say APP or NO_APP */
- char *ends;
- char *new_buf;
- char *new_tmp;
- int new_length;
- char *tmp_buf = 0;
- extern char *scrub_string,*scrub_last_string;
+ if (*input_line_pointer == '$'
+ && *(input_line_pointer + 1) == ':') {
+ input_line_pointer += 2;
+
+ if (dollar_label_defined(temp)) {
+ as_fatal("label \"%d$\" redefined", temp);
+ }
+
+ define_dollar_label(temp);
+ colon(dollar_label_name(temp, 0));
+ continue;
+ }
+#endif /* LOCAL_LABELS_DOLLAR */
+
+#ifdef LOCAL_LABELS_FB
+ if (*input_line_pointer++ == ':') {
+ fb_label_instance_inc(temp);
+ colon(fb_label_name(temp, 0));
+ continue;
+ }
+#endif /* LOCAL_LABELS_FB */
+
+ input_line_pointer = backup;
+ } /* local label ("4:") */
+#endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
+
+ if (c && strchr(line_comment_chars,c)) { /* Its a comment. Better say APP or NO_APP */
+ char *ends;
+ char *new_buf;
+ char *new_tmp;
+ int new_length;
+ char *tmp_buf = 0;
+ extern char *scrub_string,*scrub_last_string;
- bump_line_counters();
- s=input_line_pointer;
- if (strncmp(s,"APP\n",4))
- continue; /* We ignore it */
- s+=4;
+ bump_line_counters();
+ s=input_line_pointer;
+ if (strncmp(s,"APP\n",4))
+ continue; /* We ignore it */
+ s+=4;
- ends=strstr(s,"#NO_APP\n");
+ ends=strstr(s,"#NO_APP\n");
- if (!ends) {
- int tmp_len;
- int num;
+ if (!ends) {
+ int tmp_len;
+ int num;
- /* The end of the #APP wasn't in this buffer. We
- keep reading in buffers until we find the #NO_APP
- that goes with this #APP There is one. The specs
- guarentee it. . . */
- tmp_len=buffer_limit-s;
- tmp_buf=xmalloc(tmp_len);
- memcpy(tmp_buf, s, tmp_len);
- do {
- new_tmp = input_scrub_next_buffer(&buffer);
- if (!new_tmp)
- break;
- else
- buffer_limit = new_tmp;
- input_line_pointer = buffer;
- ends = strstr(buffer,"#NO_APP\n");
- if (ends)
- num=ends-buffer;
- else
- num=buffer_limit-buffer;
+ /* The end of the #APP wasn't in this buffer. We
+ keep reading in buffers until we find the #NO_APP
+ that goes with this #APP There is one. The specs
+ guarentee it. . . */
+ tmp_len=buffer_limit-s;
+ tmp_buf=xmalloc(tmp_len);
+ bcopy(s,tmp_buf,tmp_len);
+ do {
+ new_tmp = input_scrub_next_buffer(&buffer);
+ if (!new_tmp)
+ break;
+ else
+ buffer_limit = new_tmp;
+ input_line_pointer = buffer;
+ ends = strstr(buffer,"#NO_APP\n");
+ if (ends)
+ num=ends-buffer;
+ else
+ num=buffer_limit-buffer;
- tmp_buf = xrealloc(tmp_buf, tmp_len + num);
- memcpy(tmp_buf + tmp_len, buffer, num);
- tmp_len+=num;
- } while(!ends);
+ tmp_buf = xrealloc(tmp_buf, tmp_len + num);
+ bcopy(buffer,tmp_buf+tmp_len,num);
+ tmp_len+=num;
+ } while(!ends);
- input_line_pointer= ends ? ends+8 : NULL;
+ input_line_pointer= ends ? ends+8 : NULL;
- s=tmp_buf;
- ends=s+tmp_len;
+ s=tmp_buf;
+ ends=s+tmp_len;
- } else {
- input_line_pointer=ends+8;
- }
- new_buf=xmalloc(100);
- new_length=100;
- new_tmp=new_buf;
-
- scrub_string=s;
- scrub_last_string = ends;
- for(;;) {
- int ch;
-
- ch = do_scrub_next_char(scrub_from_string, scrub_to_string);
- if (ch==EOF) break;
- *new_tmp++=ch;
- if (new_tmp==new_buf+new_length) {
- new_buf=xrealloc(new_buf,new_length+100);
- new_tmp=new_buf+new_length;
- new_length+=100;
- }
- }
-
- if (tmp_buf)
- free(tmp_buf);
- old_buffer=buffer;
- old_input=input_line_pointer;
- old_limit=buffer_limit;
- buffer=new_buf;
- input_line_pointer=new_buf;
- buffer_limit=new_tmp;
- continue;
- }
-
- HANDLE_CONDITIONAL_ASSEMBLY();
-
- /* as_warn("Junk character %d.",c); Now done by ignore_rest */
- input_line_pointer--; /* Report unknown char as ignored. */
- ignore_rest_of_line();
- } /* while (input_line_pointer<buffer_limit) */
- if (old_buffer) {
- bump_line_counters();
- if (old_input != 0) {
- buffer=old_buffer;
- input_line_pointer=old_input;
- buffer_limit=old_limit;
- old_buffer = 0;
- goto contin;
- }
+ } else {
+ input_line_pointer=ends+8;
+ }
+ new_buf=xmalloc(100);
+ new_length=100;
+ new_tmp=new_buf;
+
+ scrub_string=s;
+ scrub_last_string = ends;
+ for(;;) {
+ int ch;
+
+ ch = do_scrub_next_char(scrub_from_string, scrub_to_string);
+ if (ch==EOF) break;
+ *new_tmp++=ch;
+ if (new_tmp==new_buf+new_length) {
+ new_buf=xrealloc(new_buf,new_length+100);
+ new_tmp=new_buf+new_length;
+ new_length+=100;
+ }
}
- } /* while (more buffers to scan) */
- input_scrub_close(); /* Close the input file */
-
+
+ if (tmp_buf)
+ free(tmp_buf);
+ old_buffer=buffer;
+ old_input=input_line_pointer;
+ old_limit=buffer_limit;
+ buffer=new_buf;
+ input_line_pointer=new_buf;
+ buffer_limit=new_tmp;
+ continue;
+ }
+
+ HANDLE_CONDITIONAL_ASSEMBLY();
+
+ /* as_warn("Junk character %d.",c); Now done by ignore_rest */
+ input_line_pointer--; /* Report unknown char as ignored. */
+ ignore_rest_of_line();
+ } /* while (input_line_pointer<buffer_limit) */
+ if (old_buffer) {
+ bump_line_counters();
+ if (old_input != 0) {
+ buffer=old_buffer;
+ input_line_pointer=old_input;
+ buffer_limit=old_limit;
+ old_buffer = 0;
+ goto contin;
+ }
+ }
+ } /* while (more buffers to scan) */
+ input_scrub_close(); /* Close the input file */
+
} /* read_a_source_file() */
void s_abort() {
@@ -600,43 +634,43 @@ void s_abort() {
void s_align_bytes(arg)
int arg;
{
- register unsigned int temp;
- register long temp_fill;
- unsigned int i = 0;
- unsigned long max_alignment = 1 << 15;
-
- if (is_end_of_line[*input_line_pointer])
- temp = arg; /* Default value from pseudo-op table */
- else
- temp = get_absolute_expression ();
-
- if (temp > max_alignment) {
- as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
- }
-
- /*
- * For the sparc, `.align (1<<n)' actually means `.align n'
- * so we have to convert it.
- */
- if (temp != 0) {
- for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
- ;
- }
- if (temp != 1)
- as_bad("Alignment not a power of 2");
-
- temp = i;
- if (*input_line_pointer == ',') {
- input_line_pointer ++;
- temp_fill = get_absolute_expression ();
- } else {
- temp_fill = NOP_OPCODE;
- }
- /* Only make a frag if we HAVE to. . . */
- if (temp && ! need_pass_2)
- frag_align(temp, (int)temp_fill);
-
- demand_empty_rest_of_line();
+ register unsigned int temp;
+ register long temp_fill;
+ unsigned int i = 0;
+ unsigned long max_alignment = 1 << 15;
+
+ if (is_end_of_line[*input_line_pointer])
+ temp = arg; /* Default value from pseudo-op table */
+ else
+ temp = get_absolute_expression ();
+
+ if (temp > max_alignment) {
+ as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
+ }
+
+ /*
+ * For the sparc, `.align (1<<n)' actually means `.align n'
+ * so we have to convert it.
+ */
+ if (temp != 0) {
+ for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
+ ;
+ }
+ if (temp != 1)
+ as_bad("Alignment not a power of 2");
+
+ temp = i;
+ if (*input_line_pointer == ',') {
+ input_line_pointer ++;
+ temp_fill = get_absolute_expression ();
+ } else {
+ temp_fill = 0;
+ }
+ /* Only make a frag if we HAVE to. . . */
+ if (temp && ! need_pass_2)
+ frag_align(temp, (int)temp_fill);
+
+ demand_empty_rest_of_line();
} /* s_align_bytes() */
/* For machines where ".align 4" means align to 2**4 boundary. */
@@ -644,10 +678,10 @@ void s_align_ptwo() {
register int temp;
register long temp_fill;
long max_alignment = 15;
-
+
temp = get_absolute_expression ();
if (temp > max_alignment)
- as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
+ as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
else if (temp < 0) {
as_bad("Alignment negative. 0 assumed.");
temp = 0;
@@ -656,34 +690,23 @@ void s_align_ptwo() {
input_line_pointer ++;
temp_fill = get_absolute_expression ();
} else
- temp_fill = NOP_OPCODE;
+ temp_fill = 0;
/* Only make a frag if we HAVE to. . . */
if (temp && ! need_pass_2)
- frag_align (temp, (int)temp_fill);
-
+ frag_align (temp, (int)temp_fill);
+
record_alignment(now_seg, temp);
-
+
demand_empty_rest_of_line();
} /* s_align_ptwo() */
-
-void s_bss()
-{
- register int temp;
-
- temp = get_absolute_expression ();
- subseg_new (SEG_BSS, (subsegT)temp);
- demand_empty_rest_of_line();
-}
-
-
void s_comm() {
register char *name;
register char c;
register char *p;
register int temp;
register symbolS * symbolP;
-
+
name = input_line_pointer;
c = get_symbol_end();
/* just after name is now '\0' */
@@ -711,34 +734,34 @@ void s_comm() {
}
if (S_GET_VALUE(symbolP)) {
if (S_GET_VALUE(symbolP) != temp)
- as_bad("Length of .comm \"%s\" is already %d. Not changed to %d.",
- S_GET_NAME(symbolP),
- S_GET_VALUE(symbolP),
- temp);
+ as_bad("Length of .comm \"%s\" is already %d. Not changed to %d.",
+ S_GET_NAME(symbolP),
+ S_GET_VALUE(symbolP),
+ temp);
} else {
S_SET_VALUE(symbolP, temp);
S_SET_EXTERNAL(symbolP);
}
#ifdef VMS
if (!temp)
- symbolP->sy_other = const_flag;
+ symbolP->sy_other = const_flag;
#endif
know(symbolP->sy_frag == &zero_address_frag);
demand_empty_rest_of_line();
} /* s_comm() */
void
- s_data()
+s_data()
{
register int temp;
-
+
temp = get_absolute_expression ();
#ifdef MANY_SEGMENTS
subseg_new (SEG_E1, (subsegT)temp);
#else
subseg_new (SEG_DATA, (subsegT)temp);
#endif
-
+
#ifdef VMS
const_flag = 0;
#endif
@@ -748,7 +771,7 @@ void
void s_app_file() {
register char *s;
int length;
-
+
/* Some assemblers tolerate immediately following '"' */
if ((s = demand_copy_string(&length)) != 0) {
new_logical_line(s, -1);
@@ -764,7 +787,7 @@ void s_fill() {
long temp_size;
register long temp_fill;
char *p;
-
+
if (get_absolute_expression_and_terminator(& temp_repeat) != ',') {
input_line_pointer --; /* Backup over what was not a ','. */
as_bad("Expect comma after rep-size in .fill:");
@@ -772,10 +795,10 @@ void s_fill() {
return;
}
if (get_absolute_expression_and_terminator(& temp_size) != ',') {
- input_line_pointer --; /* Backup over what was not a ','. */
- as_bad("Expected comma after size in .fill");
- ignore_rest_of_line();
- return;
+ input_line_pointer --; /* Backup over what was not a ','. */
+ as_bad("Expected comma after size in .fill");
+ ignore_rest_of_line();
+ return;
}
/*
* This is to be compatible with BSD 4.2 AS, not for any rational reason.
@@ -794,29 +817,141 @@ void s_fill() {
temp_fill = get_absolute_expression ();
if (temp_size && !need_pass_2) {
p = frag_var(rs_fill, (int)temp_size, (int)temp_size, (relax_substateT)0, (symbolS *)0, temp_repeat, (char *)0);
- memset(p, '\0', (int) temp_size);
- /*
- * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
- * The following bizzare behaviour is to be compatible with above.
- * I guess they tried to take up to 8 bytes from a 4-byte expression
- * and they forgot to sign extend. Un*x Sux.
- */
+ bzero (p, (int)temp_size);
+/*
+ * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
+ * The following bizzare behaviour is to be compatible with above.
+ * I guess they tried to take up to 8 bytes from a 4-byte expression
+ * and they forgot to sign extend. Un*x Sux.
+ */
#define BSD_FILL_SIZE_CROCK_4 (4)
md_number_to_chars (p, temp_fill, temp_size > BSD_FILL_SIZE_CROCK_4 ? BSD_FILL_SIZE_CROCK_4 : (int)temp_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 compiler.
- */
+/*
+ * 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 compiler.
+ */
+ }
+ demand_empty_rest_of_line();
+}
+
+#ifdef DONTDEF
+void
+s_gdbbeg()
+{
+ register int temp;
+
+ temp = get_absolute_expression ();
+ if (temp < 0)
+ as_warn("Block number <0. Ignored.");
+ else if (flagseen ['G'])
+ gdb_block_beg ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
+ demand_empty_rest_of_line ();
+}
+
+void
+s_gdbblock()
+{
+ register int position;
+ int temp;
+
+ if (get_absolute_expression_and_terminator (&temp) != ',') {
+ as_bad("expected comma before position in .gdbblock");
+ --input_line_pointer;
+ ignore_rest_of_line ();
+ return;
+ }
+ position = get_absolute_expression ();
+ if (flagseen ['G'])
+ gdb_block_position ((long) temp, (long) position);
+ demand_empty_rest_of_line ();
+}
+
+void
+s_gdbend()
+{
+ register int temp;
+
+ temp = get_absolute_expression ();
+ if (temp < 0)
+ as_warn("Block number <0. Ignored.");
+ else if (flagseen ['G'])
+ gdb_block_end ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
+ demand_empty_rest_of_line ();
+}
+
+void
+s_gdbsym()
+{
+ register char *name,
+ *p;
+ register char c;
+ register symbolS * symbolP;
+ register int temp;
+
+ name = input_line_pointer;
+ c = get_symbol_end();
+ p = input_line_pointer;
+ symbolP = symbol_find_or_make(name);
+ *p = c;
+ SKIP_WHITESPACE();
+ if (* input_line_pointer != ',') {
+ as_bad("Expected comma after name");
+ ignore_rest_of_line();
+ return;
}
+ input_line_pointer ++;
+ if ((temp = get_absolute_expression ()) < 0) {
+ as_bad("Bad GDB symbol file offset (%d.) <0! Ignored.", temp);
+ ignore_rest_of_line();
+ return;
+ }
+ if (flagseen ['G'])
+ gdb_symbols_fixup (symbolP, (long)temp);
+ demand_empty_rest_of_line ();
+}
+
+void
+s_gdbline()
+{
+ int file_number,
+ lineno;
+
+ if (get_absolute_expression_and_terminator(&file_number) != ',') {
+ as_bad("expected comman after filenum in .gdbline");
+ ignore_rest_of_line();
+ return;
+ }
+ lineno=get_absolute_expression();
+ if (flagseen['G'])
+ gdb_line(file_number,lineno);
demand_empty_rest_of_line();
}
+
+void
+s_gdblinetab()
+{
+ int file_number,
+ offset;
+
+ if (get_absolute_expression_and_terminator(&file_number) != ',') {
+ as_bad("expected comma after filenum in .gdblinetab");
+ ignore_rest_of_line();
+ return;
+ }
+ offset=get_absolute_expression();
+ if (flagseen['G'])
+ gdb_line_tab(file_number,offset);
+ demand_empty_rest_of_line();
+}
+#endif
+
void s_globl() {
register char *name;
register int c;
register symbolS * symbolP;
-
+
do {
name = input_line_pointer;
c = get_symbol_end();
@@ -828,7 +963,7 @@ void s_globl() {
input_line_pointer++;
SKIP_WHITESPACE();
if (*input_line_pointer=='\n')
- c='\n';
+ c='\n';
}
} while(c==',');
demand_empty_rest_of_line();
@@ -847,7 +982,7 @@ int needs_align; /* 1 if this was a ".bss" directive, which may require
register symbolS * symbolP;
const int max_alignment = 15;
int align = 0;
-
+
name = input_line_pointer;
c = get_symbol_end();
p = input_line_pointer;
@@ -858,20 +993,20 @@ int needs_align; /* 1 if this was a ".bss" directive, which may require
ignore_rest_of_line();
return;
}
-
+
++input_line_pointer;
-
+
if (*input_line_pointer == '\n') {
as_bad("Missing size expression");
return;
}
-
+
if ((temp = get_absolute_expression ()) < 0) {
as_warn("BSS length (%d.) <0! Ignored.", temp);
ignore_rest_of_line();
return;
}
-
+
if (needs_align) {
align = 0;
SKIP_WHITESPACE();
@@ -901,11 +1036,11 @@ int needs_align; /* 1 if this was a ".bss" directive, which may require
record_alignment(SEG_BSS, align);
#endif
} /* if needs align */
-
+
*p = 0;
symbolP = symbol_find_or_make(name);
*p = c;
-
+
if (
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
S_GET_OTHER(symbolP) == 0 &&
@@ -919,7 +1054,7 @@ int needs_align; /* 1 if this was a ".bss" directive, which may require
local_bss_counter =
(local_bss_counter + align) & (~align);
}
-
+
S_SET_VALUE(symbolP,local_bss_counter);
S_SET_SEGMENT(symbolP, SEG_BSS);
#ifdef OBJ_COFF
@@ -935,21 +1070,21 @@ int needs_align; /* 1 if this was a ".bss" directive, which may require
local_bss_counter += temp;
} else {
as_bad("Ignoring attempt to re-define symbol from %d. to %d.",
- S_GET_VALUE(symbolP), local_bss_counter);
+ S_GET_VALUE(symbolP), local_bss_counter);
}
demand_empty_rest_of_line();
-
+
return;
} /* s_lcomm() */
void
- s_long()
+s_long()
{
cons(4);
}
void
- s_int()
+s_int()
{
cons(4);
}
@@ -961,7 +1096,7 @@ void s_lsym() {
register segT segment;
expressionS exp;
register symbolS *symbolP;
-
+
/* we permit ANY defined expression: BSD4.2 demands constants */
name = input_line_pointer;
c = get_symbol_end();
@@ -979,20 +1114,20 @@ void s_lsym() {
segment = expression(& exp);
if (segment != SEG_ABSOLUTE
#ifdef MANY_SEGMENTS
- && ! ( segment >= SEG_E0 && segment <= SEG_UNKNOWN)
+ && ! ( segment >= SEG_E0 && segment <= SEG_UNKNOWN)
#else
- && segment != SEG_DATA
- && segment != SEG_TEXT
- && segment != SEG_BSS
+ && segment != SEG_DATA
+ && segment != SEG_TEXT
+ && segment != SEG_BSS
#endif
- && segment != SEG_REGISTER) {
+ && segment != SEG_REGISTER) {
as_bad("Bad expression: %s", segment_name(segment));
ignore_rest_of_line();
return;
}
*p = 0;
symbolP = symbol_find_or_make(name);
-
+
/* FIXME-SOON I pulled a (&& symbolP->sy_other == 0
&& symbolP->sy_desc == 0) out of this test
because coff doesn't have those fields, and I
@@ -1000,7 +1135,7 @@ void s_lsym() {
think I understand why they were here so I may
have introduced a bug. As recently as 1.37 didn't
have this test anyway. xoxorich. */
-
+
if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN
&& S_GET_VALUE(symbolP) == 0) {
/* The name might be an undefined .global symbol; be
@@ -1019,27 +1154,27 @@ void s_org() {
expressionS exp;
register long temp_fill;
register char *p;
- /*
- * 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 given a warning, then assumed to be segment-relative.
- * Any segmented origin expression ("foo+42") had better be in the right
- * segment or the .org is ignored.
- *
- * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
- * never know sub-segment sizes when we are reading code.
- * BSD will crash trying to emit -ve numbers of filler bytes in certain
- * .orgs. We don't crash, but see as-write for that code.
- */
- /*
- * Don't make frag if need_pass_2==1.
- */
+/*
+ * 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 given a warning, then assumed to be segment-relative.
+ * Any segmented origin expression ("foo+42") had better be in the right
+ * segment or the .org is ignored.
+ *
+ * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
+ * never know sub-segment sizes when we are reading code.
+ * BSD will crash trying to emit -ve numbers of filler bytes in certain
+ * .orgs. We don't crash, but see as-write for that code.
+ */
+/*
+ * Don't make frag if need_pass_2==1.
+ */
segment = get_known_segmented_expression(&exp);
if (*input_line_pointer == ',') {
input_line_pointer ++;
temp_fill = get_absolute_expression ();
} else
- temp_fill = 0;
+ temp_fill = 0;
if (! need_pass_2) {
if (segment != now_seg && segment != SEG_ABSOLUTE)
as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
@@ -1056,7 +1191,7 @@ void s_set() {
register char delim;
register char *end_name;
register symbolS *symbolP;
-
+
/*
* Especial apologies for the random logic:
* this just grew, and could be parsed much more simply!
@@ -1067,7 +1202,7 @@ void s_set() {
end_name = input_line_pointer;
*end_name = delim;
SKIP_WHITESPACE();
-
+
if (*input_line_pointer != ',') {
*end_name = 0;
as_bad("Expected comma after name \"%s\"", name);
@@ -1075,32 +1210,32 @@ void s_set() {
ignore_rest_of_line();
return;
}
-
+
input_line_pointer ++;
*end_name = 0;
-
+
if (name[0]=='.' && name[1]=='\0') {
/* Turn '. = mumble' into a .org mumble */
register segT segment;
expressionS exp;
register char *ptr;
-
+
segment = get_known_segmented_expression(& exp);
-
+
if (!need_pass_2) {
if (segment != now_seg && segment != SEG_ABSOLUTE)
as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
- segment_name(segment),
- segment_name (now_seg));
+ 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;
return;
}
-
+
if ((symbolP = symbol_find(name)) == NULL
&& (symbolP = md_undefined_symbol(name)) == NULL) {
symbolP = symbol_new(name,
@@ -1111,11 +1246,11 @@ void s_set() {
/* "set" symbols are local unless otherwise specified. */
SF_SET_LOCAL(symbolP);
#endif /* OBJ_COFF */
-
+
} /* make a new symbol */
-
+
symbol_table_insert(symbolP);
-
+
*end_name = delim;
pseudo_set(symbolP);
demand_empty_rest_of_line();
@@ -1125,7 +1260,7 @@ void s_space() {
long temp_repeat;
register long temp_fill;
register char *p;
-
+
/* Just like .fill, but temp_size = 1 */
if (get_absolute_expression_and_terminator(& temp_repeat) == ',') {
temp_fill = get_absolute_expression ();
@@ -1140,17 +1275,17 @@ void s_space() {
}
if (! need_pass_2) {
p = frag_var (rs_fill, 1, 1, (relax_substateT)0, (symbolS *)0,
- temp_repeat, (char *)0);
+ temp_repeat, (char *)0);
* p = temp_fill;
}
demand_empty_rest_of_line();
} /* s_space() */
void
- s_text()
+s_text()
{
register int temp;
-
+
temp = get_absolute_expression ();
#ifdef MANY_SEGMENTS
subseg_new (SEG_E0, (subsegT)temp);
@@ -1174,24 +1309,24 @@ void demand_empty_rest_of_line() {
} /* Return pointing just after end-of-line. */
void
- ignore_rest_of_line() /* For suspect lines: gives warning. */
+ignore_rest_of_line() /* For suspect lines: gives warning. */
{
- if (! is_end_of_line [* input_line_pointer])
- {
- if (isprint(*input_line_pointer))
- as_bad("Rest of line ignored. First ignored character is `%c'.",
- *input_line_pointer);
- else
- as_bad("Rest of line ignored. First ignored character valued 0x%x.",
- *input_line_pointer);
- while (input_line_pointer < buffer_limit
- && ! is_end_of_line [* input_line_pointer])
- {
- input_line_pointer ++;
- }
- }
- input_line_pointer ++; /* Return pointing just after end-of-line. */
- know(is_end_of_line [input_line_pointer [-1]]);
+ if (! is_end_of_line [* input_line_pointer])
+ {
+ if (isprint(*input_line_pointer))
+ as_bad("Rest of line ignored. First ignored character is `%c'.",
+ *input_line_pointer);
+ else
+ as_bad("Rest of line ignored. First ignored character valued 0x%x.",
+ *input_line_pointer);
+ while (input_line_pointer < buffer_limit
+ && ! is_end_of_line [* input_line_pointer])
+ {
+ input_line_pointer ++;
+ }
+ }
+ input_line_pointer ++; /* Return pointing just after end-of-line. */
+ know(is_end_of_line [input_line_pointer [-1]]);
}
/*
@@ -1206,113 +1341,120 @@ void
* May set need_pass_2 == 1.
*/
void
- pseudo_set (symbolP)
-symbolS * symbolP;
+pseudo_set (symbolP)
+ symbolS * symbolP;
{
- expressionS exp;
- register segT segment;
+ expressionS exp;
+ register segT segment;
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
- int ext;
+ int ext;
#endif /* OBJ_AOUT or OBJ_BOUT */
-
- know(symbolP); /* NULL pointer is logic error. */
+
+ know(symbolP); /* NULL pointer is logic error. */
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
- ext=S_IS_EXTERNAL(symbolP);
+ ext=S_IS_EXTERNAL(symbolP);
#endif /* OBJ_AOUT or OBJ_BOUT */
-
- if ((segment = expression(& exp)) == SEG_ABSENT)
- {
- as_bad("Missing expression: absolute 0 assumed");
- exp . X_seg = SEG_ABSOLUTE;
- exp . X_add_number = 0;
- }
-
- switch (segment)
- {
- case SEG_BIG:
- as_bad("%s number invalid. Absolute 0 assumed.",
- exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
- S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
+
+ if ((segment = expression(& exp)) == SEG_ABSENT)
+ {
+ as_bad("Missing expression: absolute 0 assumed");
+ exp . X_seg = SEG_ABSOLUTE;
+ exp . X_add_number = 0;
+ }
+
+ switch (segment)
+ {
+ case SEG_REGISTER:
+ S_SET_SEGMENT(symbolP, SEG_REGISTER);
+ S_SET_VALUE(symbolP, exp.X_add_number);
+ symbolP->sy_frag = & zero_address_frag;
+ break;
+
+ case SEG_BIG:
+ as_bad("%s number invalid. Absolute 0 assumed.",
+ exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
+ S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
- ext ? S_SET_EXTERNAL(symbolP) :
- S_CLEAR_EXTERNAL(symbolP);
+ ext ? S_SET_EXTERNAL(symbolP) :
+ S_CLEAR_EXTERNAL(symbolP);
#endif /* OBJ_AOUT or OBJ_BOUT */
- S_SET_VALUE(symbolP, 0);
- symbolP->sy_frag = & zero_address_frag;
- break;
-
- case SEG_ABSENT:
- as_warn("No expression: Using absolute 0");
- S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
+ S_SET_VALUE(symbolP, 0);
+ symbolP->sy_frag = & zero_address_frag;
+ break;
+
+ case SEG_ABSENT:
+ as_warn("No expression: Using absolute 0");
+ S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
- ext ? S_SET_EXTERNAL(symbolP) :
- S_CLEAR_EXTERNAL(symbolP);
+ ext ? S_SET_EXTERNAL(symbolP) :
+ S_CLEAR_EXTERNAL(symbolP);
#endif /* OBJ_AOUT or OBJ_BOUT */
- S_SET_VALUE(symbolP, 0);
- symbolP->sy_frag = & zero_address_frag;
- break;
-
- case SEG_DIFFERENCE:
- if (exp.X_add_symbol && exp.X_subtract_symbol
- && (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) {
- 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);
- } else
- as_bad("Complex expression. Absolute segment assumed.");
- case SEG_ABSOLUTE:
- S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
+ S_SET_VALUE(symbolP, 0);
+ symbolP->sy_frag = & zero_address_frag;
+ break;
+
+ case SEG_DIFFERENCE:
+ if (exp.X_add_symbol && exp.X_subtract_symbol
+ && (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) {
+ 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);
+ } else
+ as_bad("Complex expression. Absolute segment assumed.");
+ case SEG_ABSOLUTE:
+ S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
- ext ? S_SET_EXTERNAL(symbolP) :
- S_CLEAR_EXTERNAL(symbolP);
+ ext ? S_SET_EXTERNAL(symbolP) :
+ S_CLEAR_EXTERNAL(symbolP);
#endif /* OBJ_AOUT or OBJ_BOUT */
- S_SET_VALUE(symbolP, exp.X_add_number);
- symbolP->sy_frag = & zero_address_frag;
- break;
-
- default:
+ S_SET_VALUE(symbolP, exp.X_add_number);
+ symbolP->sy_frag = & zero_address_frag;
+ break;
+
+ default:
#ifdef MANY_SEGMENTS
- S_SET_SEGMENT(symbolP, segment);
+ S_SET_SEGMENT(symbolP, segment);
#else
- switch(segment) {
- case SEG_DATA: S_SET_SEGMENT(symbolP, SEG_DATA); break;
- case SEG_TEXT: S_SET_SEGMENT(symbolP, SEG_TEXT); break;
- case SEG_BSS: S_SET_SEGMENT(symbolP, SEG_BSS); break;
- default: as_fatal("failed sanity check.");
- } /* switch on segment */
+ switch(segment) {
+ case SEG_DATA: S_SET_SEGMENT(symbolP, SEG_DATA); break;
+ case SEG_TEXT: S_SET_SEGMENT(symbolP, SEG_TEXT); break;
+ case SEG_BSS: S_SET_SEGMENT(symbolP, SEG_BSS); break;
+
+ default: as_fatal("failed sanity check.");
+ } /* switch on segment */
#endif
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
- if (ext) {
- S_SET_EXTERNAL(symbolP);
- } else {
- S_CLEAR_EXTERNAL(symbolP);
- } /* if external */
+ if (ext) {
+ S_SET_EXTERNAL(symbolP);
+ } else {
+ S_CLEAR_EXTERNAL(symbolP);
+ } /* if external */
#endif /* OBJ_AOUT or OBJ_BOUT */
-
- S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol));
- symbolP->sy_frag = exp . X_add_symbol->sy_frag;
- break;
-
- case SEG_PASS1: /* Not an error. Just try another pass. */
- symbolP->sy_forward=exp.X_add_symbol;
- as_bad("Unknown expression");
- know(need_pass_2 == 1);
- break;
-
- case SEG_UNKNOWN:
- symbolP->sy_forward=exp.X_add_symbol;
- /* as_warn("unknown symbol"); */
- /* need_pass_2 = 1; */
- break;
-
-
-
- }
+
+ S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol));
+ symbolP->sy_frag = exp . X_add_symbol->sy_frag;
+ break;
+
+ case SEG_PASS1: /* Not an error. Just try another pass. */
+ symbolP->sy_forward=exp.X_add_symbol;
+ as_bad("Unknown expression");
+ know(need_pass_2 == 1);
+ break;
+
+ case SEG_UNKNOWN:
+ symbolP->sy_forward=exp.X_add_symbol;
+ /* as_warn("unknown symbol"); */
+ /* need_pass_2 = 1; */
+ break;
+
+
+
+ }
}
/*
@@ -1330,245 +1472,305 @@ symbolS * symbolP;
* in the case of a long. Not worth the crocks required to fix it.
*/
-/* worker to do .byte etc statements */
-/* clobbers input_line_pointer, checks */
-/* end-of-line. */
+ /* worker to do .byte etc statements */
+ /* clobbers input_line_pointer, checks */
+ /* end-of-line. */
void cons(nbytes)
register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
{
- register char c;
- register long mask; /* High-order bits we will left-truncate, */
- /* but includes sign bit also. */
- register long get; /* what we get */
- register long use; /* get after truncation. */
- register long unmask; /* what bits we will store */
- register char * p;
- register segT segment;
- expressionS exp;
-
- /*
- * Input_line_pointer->1st char after pseudo-op-code and could legally
- * be a end-of-line. (Or, less legally an eof - which we cope with.)
- */
- /* JF << of >= number of bits in the object is undefined. In particular
- SPARC (Sun 4) has problems */
-
- if (nbytes>=sizeof(long)) {
- mask = 0;
- } else {
- mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
- } /* bigger than a long */
-
- unmask = ~mask; /* Do store these bits. */
-
+ register char c;
+ register long mask; /* High-order bits we will left-truncate, */
+ /* but includes sign bit also. */
+ register long get; /* what we get */
+ register long use; /* get after truncation. */
+ register long unmask; /* what bits we will store */
+ register char * p;
+ register segT segment;
+ expressionS exp;
+
+ /*
+ * Input_line_pointer->1st char after pseudo-op-code and could legally
+ * be a end-of-line. (Or, less legally an eof - which we cope with.)
+ */
+ /* JF << of >= number of bits in the object is undefined. In particular
+ SPARC (Sun 4) has problems */
+
+ if (nbytes>=sizeof(long)) {
+ mask = 0;
+ } else {
+ mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
+ } /* bigger than a long */
+
+ unmask = ~mask; /* Do store these bits. */
+
#ifdef NEVER
- "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
- mask = ~ (unmask >> 1); /* Includes sign bit now. */
+ "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
+ mask = ~ (unmask >> 1); /* Includes sign bit now. */
#endif
-
- /*
- * The following awkward logic is to parse ZERO or more expressions,
- * comma seperated. Recall an expression includes its leading &
- * trailing blanks. We fake a leading ',' if there is (supposed to
- * be) a 1st expression, and keep demanding 1 expression for each ','.
- */
- if (is_it_end_of_statement()) {
- c = 0; /* Skip loop. */
- input_line_pointer++; /* Matches end-of-loop 'correction'. */
- } else {
- c = ',';
- } /* if the end else fake it */
-
- /* Do loop. */
- while (c == ',') {
+
+ /*
+ * The following awkward logic is to parse ZERO or more expressions,
+ * comma seperated. Recall an expression includes its leading &
+ * trailing blanks. We fake a leading ',' if there is (supposed to
+ * be) a 1st expression, and keep demanding 1 expression for each ','.
+ */
+ if (is_it_end_of_statement()) {
+ c = 0; /* Skip loop. */
+ input_line_pointer++; /* Matches end-of-loop 'correction'. */
+ } else {
+ c = ',';
+ } /* if the end else fake it */
+
+ /* Do loop. */
+ while (c == ',') {
#ifdef WANT_BITFIELDS
- unsigned int bits_available = BITS_PER_CHAR * nbytes;
- /* used for error messages and rescanning */
- char *hold = input_line_pointer;
+ unsigned int bits_available = BITS_PER_CHAR * nbytes;
+ /* used for error messages and rescanning */
+ char *hold = input_line_pointer;
#endif /* WANT_BITFIELDS */
-
- /* At least scan over the expression. */
- segment = expression(&exp);
-
+#ifdef MRI
+ if (*input_line_pointer == '\'')
+ {
+ /* An MRI style string, cut into as many bytes as will fit
+ into a nbyte chunk, left justify if necessary, and sepatate
+ with commas so we can try again later */
+ int scan = 0;
+ unsigned int result = 0;
+ input_line_pointer++;
+ for (scan = 0; scan < nbytes; scan++)
+ {
+ if (*input_line_pointer == '\'')
+ {
+ if (input_line_pointer[1] == '\'')
+ {
+ input_line_pointer++;
+ }
+ else
+ break;
+ }
+ result = (result << 8) | (*input_line_pointer++);
+ }
+
+ /* Left justify */
+ while (scan < nbytes)
+ {
+ result <<=8;
+ scan++;
+ }
+ /* Create correct expression */
+ exp.X_add_symbol = 0;
+ exp.X_add_number = result;
+ exp.X_seg = segment = SEG_ABSOLUTE;
+ /* Fake it so that we can read the next char too */
+ if (input_line_pointer[0] != '\'' ||
+ (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
+ {
+ input_line_pointer-=2;
+ input_line_pointer[0] = ',';
+ input_line_pointer[1] = '\'';
+ }
+ else
+ input_line_pointer++;
+
+ }
+ else
+#endif
+ /* At least scan over the expression. */
+ segment = expression(&exp);
+
#ifdef WANT_BITFIELDS
- /* Some other assemblers, (eg, asm960), allow
- bitfields after ".byte" as w:x,y:z, where w and
- y are bitwidths and x and y are values. They
- then pack them all together. We do a little
- better in that we allow them in words, longs,
- etc. and we'll pack them in target byte order
- for you.
-
- The rules are: pack least significat bit first,
- if a field doesn't entirely fit, put it in the
- next unit. Overflowing the bitfield is
- explicitly *not* even a warning. The bitwidth
- should be considered a "mask".
-
- FIXME-SOMEDAY: If this is considered generally
- useful, this logic should probably be reworked.
- xoxorich. */
-
- if (*input_line_pointer == ':') { /* bitfields */
- long value = 0;
-
- for (;;) {
- unsigned long width;
-
- if (*input_line_pointer != ':') {
- input_line_pointer = hold;
- break;
- } /* next piece is not a bitfield */
-
- /* In the general case, we can't allow
- full expressions with symbol
- differences and such. The relocation
- entries for symbols not defined in this
- assembly would require arbitrary field
- widths, positions, and masks which most
- of our current object formats don't
- support.
-
- In the specific case where a symbol
- *is* defined in this assembly, we
- *could* build fixups and track it, but
- this could lead to confusion for the
- backends. I'm lazy. I'll take any
- SEG_ABSOLUTE. I think that means that
- you can use a previous .set or
- .equ type symbol. xoxorich. */
-
- if (segment == SEG_ABSENT) {
- as_warn("Using a bit field width of zero.");
- exp.X_add_number = 0;
- segment = SEG_ABSOLUTE;
- } /* implied zero width bitfield */
-
- if (segment != SEG_ABSOLUTE) {
- *input_line_pointer = '\0';
- as_bad("Field width \"%s\" too complex for a bitfield.\n", hold);
- *input_line_pointer = ':';
- demand_empty_rest_of_line();
- return;
- } /* too complex */
-
- if ((width = exp.X_add_number) > (BITS_PER_CHAR * nbytes)) {
- as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
- width, nbytes, (BITS_PER_CHAR * nbytes));
- width = BITS_PER_CHAR * nbytes;
- } /* too big */
-
- if (width > bits_available) {
- /* FIXME-SOMEDAY: backing up and
- reparsing is wasteful */
- input_line_pointer = hold;
- exp.X_add_number = value;
- break;
- } /* won't fit */
-
- hold = ++input_line_pointer; /* skip ':' */
-
- if ((segment = expression(&exp)) != SEG_ABSOLUTE) {
- char cache = *input_line_pointer;
-
- *input_line_pointer = '\0';
- as_bad("Field value \"%s\" too complex for a bitfield.\n", hold);
- *input_line_pointer = cache;
- demand_empty_rest_of_line();
- return;
- } /* too complex */
-
- value |= (~(-1 << width) & exp.X_add_number)
- << ((BITS_PER_CHAR * nbytes) - bits_available);
-
- if ((bits_available -= width) == 0
- || is_it_end_of_statement()
- || *input_line_pointer != ',') {
- break;
- } /* all the bitfields we're gonna get */
-
- hold = ++input_line_pointer;
- segment = expression(&exp);
- } /* forever loop */
-
- exp.X_add_number = value;
- segment = SEG_ABSOLUTE;
- } /* if looks like a bitfield */
+ /* Some other assemblers, (eg, asm960), allow
+ bitfields after ".byte" as w:x,y:z, where w and
+ y are bitwidths and x and y are values. They
+ then pack them all together. We do a little
+ better in that we allow them in words, longs,
+ etc. and we'll pack them in target byte order
+ for you.
+
+ The rules are: pack least significat bit first,
+ if a field doesn't entirely fit, put it in the
+ next unit. Overflowing the bitfield is
+ explicitly *not* even a warning. The bitwidth
+ should be considered a "mask".
+
+ FIXME-SOMEDAY: If this is considered generally
+ useful, this logic should probably be reworked.
+ xoxorich. */
+
+ if (*input_line_pointer == ':') { /* bitfields */
+ long value = 0;
+
+ for (;;) {
+ unsigned long width;
+
+ if (*input_line_pointer != ':') {
+ input_line_pointer = hold;
+ break;
+ } /* next piece is not a bitfield */
+
+ /* In the general case, we can't allow
+ full expressions with symbol
+ differences and such. The relocation
+ entries for symbols not defined in this
+ assembly would require arbitrary field
+ widths, positions, and masks which most
+ of our current object formats don't
+ support.
+
+ In the specific case where a symbol
+ *is* defined in this assembly, we
+ *could* build fixups and track it, but
+ this could lead to confusion for the
+ backends. I'm lazy. I'll take any
+ SEG_ABSOLUTE. I think that means that
+ you can use a previous .set or
+ .equ type symbol. xoxorich. */
+
+ if (segment == SEG_ABSENT) {
+ as_warn("Using a bit field width of zero.");
+ exp.X_add_number = 0;
+ segment = SEG_ABSOLUTE;
+ } /* implied zero width bitfield */
+
+ if (segment != SEG_ABSOLUTE) {
+ *input_line_pointer = '\0';
+ as_bad("Field width \"%s\" too complex for a bitfield.\n", hold);
+ *input_line_pointer = ':';
+ demand_empty_rest_of_line();
+ return;
+ } /* too complex */
+
+ if ((width = exp.X_add_number) > (BITS_PER_CHAR * nbytes)) {
+ as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
+ width, nbytes, (BITS_PER_CHAR * nbytes));
+ width = BITS_PER_CHAR * nbytes;
+ } /* too big */
+
+ if (width > bits_available) {
+ /* FIXME-SOMEDAY: backing up and
+ reparsing is wasteful */
+ input_line_pointer = hold;
+ exp.X_add_number = value;
+ break;
+ } /* won't fit */
+
+ hold = ++input_line_pointer; /* skip ':' */
+
+ if ((segment = expression(&exp)) != SEG_ABSOLUTE) {
+ char cache = *input_line_pointer;
+
+ *input_line_pointer = '\0';
+ as_bad("Field value \"%s\" too complex for a bitfield.\n", hold);
+ *input_line_pointer = cache;
+ demand_empty_rest_of_line();
+ return;
+ } /* too complex */
+
+ value |= (~(-1 << width) & exp.X_add_number)
+ << ((BITS_PER_CHAR * nbytes) - bits_available);
+
+ if ((bits_available -= width) == 0
+ || is_it_end_of_statement()
+ || *input_line_pointer != ',') {
+ break;
+ } /* all the bitfields we're gonna get */
+
+ hold = ++input_line_pointer;
+ segment = expression(&exp);
+ } /* forever loop */
+
+ exp.X_add_number = value;
+ segment = SEG_ABSOLUTE;
+ } /* if looks like a bitfield */
#endif /* WANT_BITFIELDS */
-
- if (!need_pass_2) { /* Still worthwhile making frags. */
-
- /* Don't call this if we are going to junk this pass anyway! */
- know(segment != SEG_PASS1);
-
- if (segment == SEG_DIFFERENCE && exp.X_add_symbol == NULL) {
- as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
- S_GET_NAME(exp.X_subtract_symbol),
- segment_name(S_GET_SEGMENT(exp.X_subtract_symbol)));
- segment = SEG_ABSOLUTE;
- /* Leave exp . X_add_number alone. */
- }
- p = frag_more(nbytes);
- switch (segment) {
- case SEG_BIG:
- as_bad("%s number invalid. Absolute 0 assumed.",
- exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
- md_number_to_chars (p, (long)0, nbytes);
- break;
-
- case SEG_ABSENT:
- as_warn("0 assumed for missing expression");
- exp . X_add_number = 0;
- know(exp . X_add_symbol == NULL);
- /* fall into SEG_ABSOLUTE */
- case SEG_ABSOLUTE:
- get = exp . X_add_number;
- use = get & unmask;
- if ((get & mask) && (get & mask) != mask)
- { /* Leading bits contain both 0s & 1s. */
- as_warn("Value 0x%x truncated to 0x%x.", get, use);
- }
- md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
- break;
-
- case SEG_DIFFERENCE:
+
+ if (!need_pass_2) { /* Still worthwhile making frags. */
+
+ /* Don't call this if we are going to junk this pass anyway! */
+ know(segment != SEG_PASS1);
+
+ if (segment == SEG_DIFFERENCE && exp.X_add_symbol == NULL) {
+ as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
+ S_GET_NAME(exp.X_subtract_symbol),
+ segment_name(S_GET_SEGMENT(exp.X_subtract_symbol)));
+ segment = SEG_ABSOLUTE;
+ /* Leave exp . X_add_number alone. */
+ }
+ p = frag_more(nbytes);
+ switch (segment) {
+ case SEG_BIG:
+ as_bad("%s number invalid. Absolute 0 assumed.",
+ exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
+ md_number_to_chars (p, (long)0, nbytes);
+ break;
+
+ case SEG_ABSENT:
+ as_warn("0 assumed for missing expression");
+ exp . X_add_number = 0;
+ know(exp . X_add_symbol == NULL);
+ /* fall into SEG_ABSOLUTE */
+ case SEG_ABSOLUTE:
+ get = exp . X_add_number;
+ use = get & unmask;
+ if ((get & mask) && (get & mask) != mask)
+ { /* Leading bits contain both 0s & 1s. */
+ as_warn("Value 0x%x truncated to 0x%x.", get, use);
+ }
+ md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
+ break;
+
+ case SEG_DIFFERENCE:
#ifndef WORKING_DOT_WORD
- if (nbytes==2) {
- struct broken_word *x;
-
- x=(struct broken_word *)xmalloc(sizeof(struct broken_word));
- x->next_broken_word=broken_words;
- broken_words=x;
- x->frag=frag_now;
- x->word_goes_here=p;
- x->dispfrag=0;
- x->add=exp.X_add_symbol;
- x->sub=exp.X_subtract_symbol;
- x->addnum=exp.X_add_number;
- x->added=0;
- new_broken_words++;
- break;
- }
- /* Else Fall through into. . . */
+ if (nbytes==2) {
+ struct broken_word *x;
+
+ x=(struct broken_word *)xmalloc(sizeof(struct broken_word));
+ x->next_broken_word=broken_words;
+ broken_words=x;
+ x->frag=frag_now;
+ x->word_goes_here=p;
+ x->dispfrag=0;
+ x->add=exp.X_add_symbol;
+ x->sub=exp.X_subtract_symbol;
+ x->addnum=exp.X_add_number;
+ x->added=0;
+ new_broken_words++;
+ break;
+ }
+ /* Else Fall through into. . . */
#endif
- default:
- case SEG_UNKNOWN:
+ default:
+ case SEG_UNKNOWN:
#ifdef TC_NS32K
- fix_new_ns32k(frag_now, p - frag_now->fr_literal, nbytes,
- exp.X_add_symbol, exp.X_subtract_symbol,
- exp.X_add_number, 0, 0, 2, 0, 0);
+ fix_new_ns32k (frag_now, p - frag_now->fr_literal, nbytes,
+ exp . X_add_symbol, exp . X_subtract_symbol,
+ exp . X_add_number, 0, 0, 2, 0, 0);
#else
- fix_new(frag_now, p - frag_now->fr_literal, nbytes,
- exp.X_add_symbol, exp.X_subtract_symbol,
- exp.X_add_number, 0, RELOC_32);
+# if defined(TC_SPARC) || defined(TC_A29K)
+ fix_new (frag_now, p - frag_now->fr_literal, nbytes,
+ exp . X_add_symbol, exp . X_subtract_symbol,
+ exp . X_add_number, 0, RELOC_32);
+# else
+# if defined(TC_H8300)
+ fix_new (frag_now, p - frag_now->fr_literal, nbytes,
+ exp . X_add_symbol, exp . X_subtract_symbol,
+ exp . X_add_number, 0, R_RELWORD);
+
+# else
+ fix_new (frag_now, p - frag_now->fr_literal, nbytes,
+ exp . X_add_symbol, exp . X_subtract_symbol,
+ exp . X_add_number, 0, 0);
+
+# endif /* tc_h8300 */
+# endif /* tc_sparc|tc_a29k */
#endif /* TC_NS32K */
- break;
- } /* switch(segment) */
- } /* if (!need_pass_2) */
- c = *input_line_pointer++;
- } /* while(c==',') */
- input_line_pointer--; /* Put terminator back into stream. */
- demand_empty_rest_of_line();
+ break;
+ } /* switch(segment) */
+ } /* if (!need_pass_2) */
+ c = *input_line_pointer++;
+ } /* while(c==',') */
+ input_line_pointer--; /* Put terminator back into stream. */
+ demand_empty_rest_of_line();
} /* cons() */
/*
@@ -1597,124 +1799,124 @@ register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
/* 8=.quad 16=.octa ... */
void big_cons(nbytes)
-register int nbytes;
+ register int nbytes;
{
- register char c; /* input_line_pointer->c. */
- register int radix;
- register long length; /* Number of chars in an object. */
- register int digit; /* Value of 1 digit. */
- register int carry; /* For multi-precision arithmetic. */
- register int work; /* For multi-precision arithmetic. */
- register char * p; /* For multi-precision arithmetic. */
-
- extern char hex_value[]; /* In hex_value.c. */
-
- /*
- * The following awkward logic is to parse ZERO or more strings,
- * comma seperated. Recall an expression includes its leading &
- * trailing blanks. We fake a leading ',' if there is (supposed to
- * be) a 1st expression, and keep demanding 1 expression for each ','.
- */
- if (is_it_end_of_statement())
+ register char c; /* input_line_pointer->c. */
+ register int radix;
+ register long length; /* Number of chars in an object. */
+ register int digit; /* Value of 1 digit. */
+ register int carry; /* For multi-precision arithmetic. */
+ register int work; /* For multi-precision arithmetic. */
+ register char * p; /* For multi-precision arithmetic. */
+
+ extern char hex_value[]; /* In hex_value.c. */
+
+ /*
+ * The following awkward logic is to parse ZERO or more strings,
+ * comma seperated. Recall an expression includes its leading &
+ * trailing blanks. We fake a leading ',' if there is (supposed to
+ * be) a 1st expression, and keep demanding 1 expression for each ','.
+ */
+ if (is_it_end_of_statement())
+ {
+ c = 0; /* Skip loop. */
+ }
+ else
+ {
+ c = ','; /* Do loop. */
+ -- input_line_pointer;
+ }
+ while (c == ',')
+ {
+ ++ input_line_pointer;
+ SKIP_WHITESPACE();
+ c = * input_line_pointer;
+ /* C contains 1st non-blank character of what we hope is a number. */
+ if (c == '0')
+ {
+ c = * ++ input_line_pointer;
+ if (c == 'x' || c=='X')
{
- c = 0; /* Skip loop. */
+ c = * ++ input_line_pointer;
+ radix = 16;
}
- else
+ else
{
- c = ','; /* Do loop. */
- -- input_line_pointer;
+ radix = 8;
}
- while (c == ',')
+ }
+ else
+ {
+ radix = 10;
+ }
+ /*
+ * This feature (?) is here to stop people worrying about
+ * mysterious zero constants: which is what they get when
+ * they completely omit digits.
+ */
+ if (hex_value[c] >= radix) {
+ as_bad("Missing digits. 0 assumed.");
+ }
+ bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
+ for(; (digit = hex_value [c]) < radix; c = * ++ input_line_pointer)
+ {
+ /* Multiply existing number by radix, then add digit. */
+ carry = digit;
+ for (p=bignum_low; p <= bignum_high; p++)
{
- ++ input_line_pointer;
- SKIP_WHITESPACE();
- c = * input_line_pointer;
- /* C contains 1st non-blank character of what we hope is a number. */
- if (c == '0')
- {
- c = * ++ input_line_pointer;
- if (c == 'x' || c=='X')
- {
- c = * ++ input_line_pointer;
- radix = 16;
- }
- else
- {
- radix = 8;
- }
- }
- else
- {
- radix = 10;
- }
- /*
- * This feature (?) is here to stop people worrying about
- * mysterious zero constants: which is what they get when
- * they completely omit digits.
- */
- if (hex_value[c] >= radix) {
- as_bad("Missing digits. 0 assumed.");
- }
- bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
- for(; (digit = hex_value [c]) < radix; c = * ++ input_line_pointer)
- {
- /* Multiply existing number by radix, then add digit. */
- carry = digit;
- for (p=bignum_low; p <= bignum_high; p++)
- {
- work = (*p & MASK_CHAR) * radix + carry;
- *p = work & MASK_CHAR;
- carry = work >> BITS_PER_CHAR;
- }
- if (carry)
- {
- grow_bignum();
- * bignum_high = carry & MASK_CHAR;
- know((carry & ~ MASK_CHAR) == 0);
- }
- }
- length = bignum_high - bignum_low + 1;
- if (length > nbytes)
- {
- as_warn("Most significant bits truncated in integer constant.");
- }
- else
- {
- register long leading_zeroes;
-
- for(leading_zeroes = nbytes - length;
- leading_zeroes;
- leading_zeroes --)
- {
- grow_bignum();
- * bignum_high = 0;
- }
- }
- if (! need_pass_2)
- {
- p = frag_more (nbytes);
- memcpy(p, bignum_low, (int) nbytes);
- }
- /* C contains character after number. */
- SKIP_WHITESPACE();
- c = *input_line_pointer;
- /* C contains 1st non-blank character after number. */
+ work = (*p & MASK_CHAR) * radix + carry;
+ *p = work & MASK_CHAR;
+ carry = work >> BITS_PER_CHAR;
}
- demand_empty_rest_of_line();
-} /* big_cons() */
+ if (carry)
+ {
+ grow_bignum();
+ * bignum_high = carry & MASK_CHAR;
+ know((carry & ~ MASK_CHAR) == 0);
+ }
+ }
+ length = bignum_high - bignum_low + 1;
+ if (length > nbytes)
+ {
+ as_warn("Most significant bits truncated in integer constant.");
+ }
+ else
+ {
+ register long leading_zeroes;
-/* Extend bignum by 1 char. */
-static void grow_bignum() {
- register long length;
-
- bignum_high ++;
- if (bignum_high >= bignum_limit)
+ for(leading_zeroes = nbytes - length;
+ leading_zeroes;
+ leading_zeroes --)
{
- length = bignum_limit - bignum_low;
- bignum_low = xrealloc(bignum_low, length + length);
- bignum_high = bignum_low + length;
- bignum_limit = bignum_low + length + length;
+ grow_bignum();
+ * bignum_high = 0;
}
+ }
+ if (! need_pass_2)
+ {
+ p = frag_more (nbytes);
+ bcopy (bignum_low, p, (int)nbytes);
+ }
+ /* C contains character after number. */
+ SKIP_WHITESPACE();
+ c = * input_line_pointer;
+ /* C contains 1st non-blank character after number. */
+ }
+ demand_empty_rest_of_line();
+} /* big_cons() */
+
+ /* Extend bignum by 1 char. */
+static void grow_bignum() {
+ register long length;
+
+ bignum_high ++;
+ if (bignum_high >= bignum_limit)
+ {
+ length = bignum_limit - bignum_low;
+ bignum_low = xrealloc(bignum_low, length + length);
+ bignum_high = bignum_low + length;
+ bignum_limit = bignum_low + length + length;
+ }
} /* grow_bignum(); */
/*
@@ -1738,65 +1940,70 @@ static void grow_bignum() {
*/
void /* JF was static, but can't be if VAX.C is goning to use it */
- float_cons(float_type) /* Worker to do .float etc statements. */
-/* Clobbers input_line-pointer, checks end-of-line. */
-register int float_type; /* 'f':.ffloat ... 'F':.float ... */
+float_cons(float_type) /* Worker to do .float etc statements. */
+ /* Clobbers input_line-pointer, checks end-of-line. */
+ register int float_type; /* 'f':.ffloat ... 'F':.float ... */
{
- register char * p;
- register char c;
- int length; /* Number of chars in an object. */
- register char * err; /* Error from scanning floating literal. */
- char temp [MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
-
- /*
- * The following awkward logic is to parse ZERO or more strings,
- * comma seperated. Recall an expression includes its leading &
- * trailing blanks. We fake a leading ',' if there is (supposed to
- * be) a 1st expression, and keep demanding 1 expression for each ','.
- */
- if (is_it_end_of_statement())
- {
- c = 0; /* Skip loop. */
- ++ input_line_pointer; /*->past termintor. */
- }
- else
+ register char * p;
+ register char c;
+ int length; /* Number of chars in an object. */
+ register char * err; /* Error from scanning floating literal. */
+ char temp [MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
+
+ /*
+ * The following awkward logic is to parse ZERO or more strings,
+ * comma seperated. Recall an expression includes its leading &
+ * trailing blanks. We fake a leading ',' if there is (supposed to
+ * be) a 1st expression, and keep demanding 1 expression for each ','.
+ */
+ if (is_it_end_of_statement())
+ {
+ c = 0; /* Skip loop. */
+ ++ input_line_pointer; /*->past termintor. */
+ }
+ else
+ {
+ c = ','; /* Do loop. */
+ }
+ while (c == ',')
+ {
+ /* input_line_pointer->1st char of a flonum (we hope!). */
+ SKIP_WHITESPACE();
+ /* Skip any 0{letter} that may be present. Don't even check if the
+ * letter is legal. Someone may invent a "z" format and this routine
+ * has no use for such information. Lusers beware: you get
+ * diagnostics if your input is ill-conditioned.
+ */
+
+ if (input_line_pointer[0]=='0' && isalpha(input_line_pointer[1]))
+ input_line_pointer+=2;
+
+ err = md_atof (float_type, temp, &length);
+ know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+ know(length > 0);
+ if (* err)
+ {
+ as_bad("Bad floating literal: %s", err);
+ ignore_rest_of_line();
+ /* Input_line_pointer->just after end-of-line. */
+ c = 0; /* Break out of loop. */
+ }
+ else
+ {
+ if (! need_pass_2)
{
- c = ','; /* Do loop. */
+ p = frag_more (length);
+ bcopy (temp, p, length);
}
- while (c == ',') {
- /* input_line_pointer->1st char of a flonum (we hope!). */
- SKIP_WHITESPACE();
- /* Skip any 0{letter} that may be present. Don't even check if the
- * letter is legal. Someone may invent a "z" format and this routine
- * has no use for such information. Lusers beware: you get
- * diagnostics if your input is ill-conditioned.
- */
-
- if (input_line_pointer[0]=='0' && isalpha(input_line_pointer[1]))
- input_line_pointer+=2;
-
- err = md_atof (float_type, temp, &length);
- know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
- know(length > 0);
- if (* err) {
- as_bad("Bad floating literal: %s", err);
- ignore_rest_of_line();
- /* Input_line_pointer->just after end-of-line. */
- c = 0; /* Break out of loop. */
- } else {
- if (! need_pass_2) {
- p = frag_more (length);
- memcpy(p, temp, length);
- }
- SKIP_WHITESPACE();
- c = *input_line_pointer++;
- /* C contains 1st non-white character after number. */
- /* input_line_pointer->just after terminator (c). */
- }
+ SKIP_WHITESPACE();
+ c = * input_line_pointer ++;
+ /* C contains 1st non-white character after number. */
+ /* input_line_pointer->just after terminator (c). */
}
- --input_line_pointer; /*->terminator (is not ','). */
- demand_empty_rest_of_line();
-} /* float_cons() */
+ }
+ -- input_line_pointer; /*->terminator (is not ','). */
+ demand_empty_rest_of_line();
+} /* float_cons() */
/*
* stringer()
@@ -1808,65 +2015,72 @@ register int float_type; /* 'f':.ffloat ... 'F':.float ... */
void stringer(append_zero ) /* Worker to do .ascii etc statements. */
-/* Checks end-of-line. */
-register int append_zero; /* 0: don't append '\0', else 1 */
+ /* Checks end-of-line. */
+ register int append_zero; /* 0: don't append '\0', else 1 */
{
- unsigned int c;
-
- /*
- * The following awkward logic is to parse ZERO or more strings,
- * comma seperated. 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 (is_it_end_of_statement()) {
- c = 0; /* Skip loop. */
- ++ input_line_pointer; /* Compensate for end of loop. */
- } else {
- c = ','; /* Do loop. */
- }
-
- while (c == ',' || c == '<' || c == '"') {
- SKIP_WHITESPACE();
- switch (*input_line_pointer) {
- case '\"':
- ++input_line_pointer; /*->1st char of string. */
- while (is_a_char(c = next_char_of_string())) {
- FRAG_APPEND_1_CHAR(c);
- }
- if (append_zero) {
- FRAG_APPEND_1_CHAR(0);
- }
- know(input_line_pointer [-1] == '\"');
- break;
- case '<':
- input_line_pointer++;
- c =get_single_number();
- FRAG_APPEND_1_CHAR(c);
- if(*input_line_pointer != '>') {
- as_bad("Expected <nn>");
- }
- input_line_pointer++;
- break;
- case ',':
- input_line_pointer++;
- break;
- }
- SKIP_WHITESPACE();
- c = *input_line_pointer;
- }
-
- demand_empty_rest_of_line();
+ /* register char * p; JF unused */
+ /* register int length; JF unused */ /* Length of string we read, excluding */
+ /* trailing '\0' implied by closing quote. */
+ /* register char * where; JF unused */
+ /* register fragS * fragP; JF unused */
+ register unsigned int c;
+
+ /*
+ * The following awkward logic is to parse ZERO or more strings,
+ * comma seperated. 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 (is_it_end_of_statement())
+ {
+ c = 0; /* Skip loop. */
+ ++ input_line_pointer; /* Compensate for end of loop. */
+ }
+ else
+ {
+ c = ','; /* Do loop. */
+ }
+ while (c == ',' || c == '<' || c == '"' ) {
+ SKIP_WHITESPACE();
+ switch (*input_line_pointer) {
+ case '\"':
+ ++input_line_pointer; /*->1st char of string. */
+ while (is_a_char(c = next_char_of_string())) {
+ FRAG_APPEND_1_CHAR(c);
+ }
+ if (append_zero) {
+ FRAG_APPEND_1_CHAR(0);
+ }
+ know(input_line_pointer [-1] == '\"');
+ break;
+ case '<':
+ input_line_pointer++;
+ c =get_single_number();
+ FRAG_APPEND_1_CHAR(c);
+ if(*input_line_pointer != '>') {
+ as_bad("Expected <nn>");
+ }
+ input_line_pointer++;
+ break;
+ case ',':
+ input_line_pointer++;
+ break;
+ }
+ SKIP_WHITESPACE();
+ c = *input_line_pointer;
+ }
+
+ demand_empty_rest_of_line();
} /* stringer() */
-/* FIXME-SOMEDAY: I had trouble here on characters with the
- high bits set. We'll probably also have trouble with
- multibyte chars, wide chars, etc. Also be careful about
- returning values bigger than 1 byte. xoxorich. */
+ /* FIXME-SOMEDAY: I had trouble here on characters with the
+ high bits set. We'll probably also have trouble with
+ multibyte chars, wide chars, etc. Also be careful about
+ returning values bigger than 1 byte. xoxorich. */
-unsigned int next_char_of_string() {
+ unsigned int next_char_of_string() {
register unsigned int c;
c = *input_line_pointer++ & CHAR_MASK;
@@ -1951,80 +2165,80 @@ unsigned int next_char_of_string() {
} /* next_char_of_string() */
static segT
- get_segmented_expression (expP)
-register expressionS * expP;
+get_segmented_expression (expP)
+ register expressionS * expP;
{
- register segT retval;
-
- if ((retval = expression(expP)) == SEG_PASS1 || retval == SEG_ABSENT || retval == SEG_BIG)
- {
- as_bad("Expected address expression: absolute 0 assumed");
- retval = expP->X_seg = SEG_ABSOLUTE;
- expP->X_add_number = 0;
- expP->X_add_symbol = expP->X_subtract_symbol = 0;
- }
- return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
+ register segT retval;
+
+ if ((retval = expression(expP)) == SEG_PASS1 || retval == SEG_ABSENT || retval == SEG_BIG)
+ {
+ as_bad("Expected address expression: absolute 0 assumed");
+ retval = expP->X_seg = SEG_ABSOLUTE;
+ expP->X_add_number = 0;
+ expP->X_add_symbol = expP->X_subtract_symbol = 0;
+ }
+ return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
}
static segT get_known_segmented_expression(expP)
register expressionS *expP;
{
- register segT retval;
- register char * name1;
- register char * name2;
-
- if ((retval = get_segmented_expression (expP)) == SEG_UNKNOWN)
- {
- name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : "";
- name2 = expP->X_subtract_symbol ?
- S_GET_NAME(expP->X_subtract_symbol) :
- "";
- if (name1 && name2)
- {
- as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
- name1, name2);
- }
- else
- {
- as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
- name1 ? name1 : name2);
- }
- retval = expP->X_seg = SEG_ABSOLUTE;
- expP->X_add_number = 0;
- expP->X_add_symbol = expP->X_subtract_symbol = NULL;
- }
+ register segT retval;
+ register char * name1;
+ register char * name2;
+
+ if ((retval = get_segmented_expression (expP)) == SEG_UNKNOWN)
+ {
+ name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : "";
+ name2 = expP->X_subtract_symbol ?
+ S_GET_NAME(expP->X_subtract_symbol) :
+ "";
+ if (name1 && name2)
+ {
+ as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
+ name1, name2);
+ }
+ else
+ {
+ as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
+ name1 ? name1 : name2);
+ }
+ retval = expP->X_seg = SEG_ABSOLUTE;
+ expP->X_add_number = 0;
+ expP->X_add_symbol = expP->X_subtract_symbol = NULL;
+ }
#ifndef MANY_SEGMENTS
- know(retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE);
+ know(retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE);
#endif
- return (retval);
-
+ return (retval);
+
} /* get_known_segmented_expression() */
/* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
- get_absolute_expression ()
+get_absolute_expression ()
{
- expressionS exp;
- register segT s;
-
- if ((s = expression(& exp)) != SEG_ABSOLUTE)
- {
- if (s != SEG_ABSENT)
- {
- as_bad("Bad Absolute Expression, absolute 0 assumed.");
- }
- exp . X_add_number = 0;
- }
- return (exp . X_add_number);
+ expressionS exp;
+ register segT s;
+
+ if ((s = expression(& exp)) != SEG_ABSOLUTE)
+ {
+ if (s != SEG_ABSENT)
+ {
+ as_bad("Bad Absolute Expression, absolute 0 assumed.");
+ }
+ exp . X_add_number = 0;
+ }
+ return (exp . X_add_number);
}
char /* return terminator */
- get_absolute_expression_and_terminator(val_pointer)
-long * val_pointer; /* return value of expression */
+get_absolute_expression_and_terminator(val_pointer)
+ long * val_pointer; /* return value of expression */
{
- * val_pointer = get_absolute_expression ();
- return (* input_line_pointer ++);
+ * val_pointer = get_absolute_expression ();
+ return (* input_line_pointer ++);
}
/*
@@ -2034,29 +2248,29 @@ long * val_pointer; /* return value of expression */
* Give a warning if that happens.
*/
char *
- demand_copy_C_string (len_pointer)
-int * len_pointer;
+demand_copy_C_string (len_pointer)
+ int * len_pointer;
{
- register char * s;
-
- if ((s = demand_copy_string(len_pointer)) != 0)
+ register char * s;
+
+ if ((s = demand_copy_string(len_pointer)) != 0)
+ {
+ register int len;
+
+ for (len = * len_pointer;
+ len > 0;
+ len--)
+ {
+ if (* s == 0)
{
- register int len;
-
- for (len = * len_pointer;
- len > 0;
- len--)
- {
- if (* s == 0)
- {
- s = 0;
- len = 1;
- * len_pointer = 0;
- as_bad("This string may not contain \'\\0\'");
- }
- }
+ s = 0;
+ len = 1;
+ * len_pointer = 0;
+ as_bad("This string may not contain \'\\0\'");
}
- return (s);
+ }
+ }
+ return (s);
}
/*
@@ -2102,44 +2316,44 @@ int *lenP;
* Do: Skip input_line_pointer over all whitespace.
*
* Out: 1 if input_line_pointer->end-of-line.
- */
+*/
int is_it_end_of_statement() {
- SKIP_WHITESPACE();
- return (is_end_of_line [* input_line_pointer]);
+ SKIP_WHITESPACE();
+ return (is_end_of_line [* input_line_pointer]);
} /* is_it_end_of_statement() */
void equals(sym_name)
char *sym_name;
{
- register symbolS *symbolP; /* symbol we are working with */
-
- input_line_pointer++;
- if (*input_line_pointer=='=')
- input_line_pointer++;
-
- while(*input_line_pointer==' ' || *input_line_pointer=='\t')
- input_line_pointer++;
-
- if (sym_name[0]=='.' && sym_name[1]=='\0') {
- /* Turn '. = mumble' into a .org mumble */
- register segT segment;
- expressionS exp;
- register char *p;
-
- segment = get_known_segmented_expression(& exp);
- if (! need_pass_2) {
- if (segment != now_seg && segment != SEG_ABSOLUTE)
- 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 {
- symbolP=symbol_find_or_make(sym_name);
- pseudo_set(symbolP);
- }
+ register symbolS *symbolP; /* symbol we are working with */
+
+ input_line_pointer++;
+ if (*input_line_pointer=='=')
+ input_line_pointer++;
+
+ while(*input_line_pointer==' ' || *input_line_pointer=='\t')
+ input_line_pointer++;
+
+ if (sym_name[0]=='.' && sym_name[1]=='\0') {
+ /* Turn '. = mumble' into a .org mumble */
+ register segT segment;
+ expressionS exp;
+ register char *p;
+
+ segment = get_known_segmented_expression(& exp);
+ if (! need_pass_2) {
+ if (segment != now_seg && segment != SEG_ABSOLUTE)
+ 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 {
+ symbolP=symbol_find_or_make(sym_name);
+ pseudo_set(symbolP);
+ }
} /* equals() */
/* .include -- include a file at this point. */
@@ -2148,68 +2362,68 @@ char *sym_name;
void s_include(arg)
int arg;
{
- char *newbuf;
- char *filename;
- int i;
- FILE *try;
- char *path;
-
- filename = demand_copy_string(&i);
- demand_empty_rest_of_line();
- path = xmalloc(i + include_dir_maxlen + 5 /* slop */);
- for (i = 0; i < include_dir_count; i++) {
- strcpy(path, include_dirs[i]);
- strcat(path, "/");
- strcat(path, filename);
- if (0 != (try = fopen(path, "r")))
- {
- fclose (try);
- goto gotit;
- }
- }
- free(path);
- path = filename;
- gotit:
- /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
- newbuf = input_scrub_include_file (path, input_line_pointer);
- buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ char *newbuf;
+ char *filename;
+ int i;
+ FILE *try;
+ char *path;
+
+ filename = demand_copy_string(&i);
+ demand_empty_rest_of_line();
+ path = xmalloc(i + include_dir_maxlen + 5 /* slop */);
+ for (i = 0; i < include_dir_count; i++) {
+ strcpy(path, include_dirs[i]);
+ strcat(path, "/");
+ strcat(path, filename);
+ if (0 != (try = fopen(path, "r")))
+ {
+ fclose (try);
+ goto gotit;
+ }
+ }
+ free(path);
+ path = filename;
+gotit:
+ /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
+ newbuf = input_scrub_include_file (path, input_line_pointer);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
} /* s_include() */
void add_include_dir(path)
char *path;
{
- int i;
-
- if (include_dir_count == 0)
- {
- include_dirs = (char **)xmalloc (2 * sizeof (*include_dirs));
- include_dirs[0] = "."; /* Current dir */
- include_dir_count = 2;
- }
- else
- {
- include_dir_count++;
- include_dirs = (char **) realloc(include_dirs,
- include_dir_count*sizeof (*include_dirs));
- }
-
- include_dirs[include_dir_count-1] = path; /* New one */
-
- i = strlen (path);
- if (i > include_dir_maxlen)
- include_dir_maxlen = i;
+ int i;
+
+ if (include_dir_count == 0)
+ {
+ include_dirs = (char **)xmalloc (2 * sizeof (*include_dirs));
+ include_dirs[0] = "."; /* Current dir */
+ include_dir_count = 2;
+ }
+ else
+ {
+ include_dir_count++;
+ include_dirs = (char **) realloc(include_dirs,
+ include_dir_count*sizeof (*include_dirs));
+ }
+
+ include_dirs[include_dir_count-1] = path; /* New one */
+
+ i = strlen (path);
+ if (i > include_dir_maxlen)
+ include_dir_maxlen = i;
} /* add_include_dir() */
void s_ignore(arg)
int arg;
{
extern char is_end_of_line[];
-
+
while (!is_end_of_line[*input_line_pointer]) {
++input_line_pointer;
}
++input_line_pointer;
-
+
return;
} /* s_ignore() */