diff options
author | K. Richard Pixley <rich@cygnus> | 1992-02-13 08:33:54 +0000 |
---|---|---|
committer | K. Richard Pixley <rich@cygnus> | 1992-02-13 08:33:54 +0000 |
commit | a39116f1c91d3642c068d9df871338cca9006be2 (patch) | |
tree | dbd53d94ef859ca6425ef5370573030d4766161b /gas/read.c | |
parent | 77806c3e79cc6ebd5ab62ce46f7cdeecad50ca52 (diff) | |
download | gdb-a39116f1c91d3642c068d9df871338cca9006be2.zip gdb-a39116f1c91d3642c068d9df871338cca9006be2.tar.gz gdb-a39116f1c91d3642c068d9df871338cca9006be2.tar.bz2 |
White space and comments only. The devo tree prior to this delta is
tagged as "vanilla" for your convenience.
There are also some comment changes.
Diffstat (limited to 'gas/read.c')
-rw-r--r-- | gas/read.c | 2056 |
1 files changed, 1050 insertions, 1006 deletions
@@ -1,23 +1,21 @@ /* read.c - read a source file - Copyright (C) 1986, 1987, 1990, 1991 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 1, 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. */ - -/* static const char rcsid[] = "$Id$"; */ + + 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 @@ -26,9 +24,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ */ #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. */ @@ -37,33 +35,33 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "as.h" #include "obstack.h" - +#include "listing.h" char *input_line_pointer; /*->next char of source file to parse. */ #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 + }; /* @@ -73,26 +71,26 @@ lex_type [256] = { #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]; @@ -103,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; @@ -124,55 +122,53 @@ int new_broken_words = 0; #ifdef __STDC__ static char *demand_copy_string(int *lenP); -static int is_it_end_of_statement(void); -static unsigned int next_char_of_string(void); +int is_it_end_of_statement(void); +unsigned int next_char_of_string(void); static segT get_known_segmented_expression(expressionS *expP); static void grow_bignum(void); static void pobegin(void); -static void stringer(int append_zero); +void stringer(int append_zero); #else /* __STDC__ */ static char *demand_copy_string(); -static int is_it_end_of_statement(); -static unsigned int next_char_of_string(); +int is_it_end_of_statement(); +unsigned int next_char_of_string(); static segT get_known_segmented_expression(); static void grow_bignum(); static void pobegin(); -static void stringer(); +void stringer(); #endif /* __STDC__ */ +extern int listing; + void -read_begin() + read_begin() { - char *p; - - pobegin(); - obj_read_begin_hook(); - - obstack_begin(¬es, 5000); - /* Start off assuming that we won't need more than 20 levels - of .if/.endif; if we need more, we can always get it. */ - obstack_begin (&cond_obstack, 20); - /* We start life accepting input. */ - obstack_1grow (&cond_obstack, 1); - + char *p; + + pobegin(); + obj_read_begin_hook(); + + obstack_begin(¬es, 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(); @@ -180,93 +176,94 @@ 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 }, - { "comm", s_comm, 0 }, - { "data", s_data, 0 }, -/* dim */ - { "double", float_cons, 'd' }, -/* dsect */ - { "eject", s_ignore, 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' }, + { "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 }, + { "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", s_ignore, 0 }, /* Listing flags */ - { "list", s_ignore, 0 }, /* Turn listing on */ - { "long", cons, 4 }, - { "lsym", s_lsym, 0 }, - { "nolist", s_ignore, 0 }, /* Turn listing off */ - { "octa", big_cons, 16 }, - { "org", s_org, 0 }, -/* print */ - { "quad", big_cons, 8 }, - { "sbttl", s_ignore, 0 }, /* 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", s_ignore, 0 }, /* Listing title */ -/* type */ -/* use */ -/* val */ - { "word", cons, 2 }, - { NULL} /* end sentinel */ + { "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 */ + 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); + for (pop = md_pseudo_table; pop->poc_name; pop++) { + errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop); if (errtxt && *errtxt) { 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); @@ -281,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); @@ -296,18 +293,19 @@ 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() * @@ -328,14 +326,18 @@ char *name; 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 @@ -344,6 +346,9 @@ char *name; if (input_line_pointer[-1] == '\n') { bump_line_counters(); } /* just passed a newline */ + + + /* * We are at the begining of a line, or similar place. * We expect a well-formed assembler statement. @@ -358,10 +363,11 @@ char *name; * (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') { + 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. @@ -383,6 +389,8 @@ char *name; * 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(); @@ -437,6 +445,7 @@ char *name; *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) */ @@ -446,6 +455,7 @@ char *name; continue; } /* empty statement */ + if (isdigit(c)) { /* local label ("4:") */ HANDLE_CONDITIONAL_ASSEMBLY (); @@ -466,7 +476,7 @@ char *name; } 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; @@ -523,12 +533,12 @@ char *name; 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; @@ -538,7 +548,7 @@ char *name; new_length+=100; } } - + if (tmp_buf) free(tmp_buf); old_buffer=buffer; @@ -549,9 +559,9 @@ char *name; 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(); @@ -568,6 +578,7 @@ char *name; } } /* while (more buffers to scan) */ input_scrub_close(); /* Close the input file */ + } /* read_a_source_file() */ void s_abort() { @@ -578,43 +589,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 = 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(); + 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. */ @@ -622,10 +633,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; @@ -634,13 +645,13 @@ void s_align_ptwo() { input_line_pointer ++; temp_fill = get_absolute_expression (); } else - temp_fill = 0; + 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() */ @@ -650,7 +661,7 @@ void s_comm() { register char *p; register int temp; register symbolS * symbolP; - + name = input_line_pointer; c = get_symbol_end(); /* just after name is now '\0' */ @@ -678,29 +689,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 @@ -710,7 +726,7 @@ s_data() 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); @@ -726,7 +742,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:"); @@ -734,10 +750,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. @@ -757,43 +773,43 @@ void s_fill() { 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); 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. - */ + /* + * 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() + s_gdbbeg() { register int temp; - + temp = get_absolute_expression (); if (temp < 0) - as_warn("Block number <0. Ignored."); + 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)); + gdb_block_beg ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal)); demand_empty_rest_of_line (); } void -s_gdbblock() + 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; @@ -802,32 +818,32 @@ s_gdbblock() } position = get_absolute_expression (); if (flagseen ['G']) - gdb_block_position ((long) temp, (long) position); + gdb_block_position ((long) temp, (long) position); demand_empty_rest_of_line (); } void -s_gdbend() + s_gdbend() { register int temp; - + temp = get_absolute_expression (); if (temp < 0) - as_warn("Block number <0. Ignored."); + 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)); + gdb_block_end ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal)); demand_empty_rest_of_line (); } void -s_gdbsym() + s_gdbsym() { register char *name, - *p; + *p; register char c; register symbolS * symbolP; register int temp; - + name = input_line_pointer; c = get_symbol_end(); p = input_line_pointer; @@ -846,16 +862,16 @@ s_gdbsym() return; } if (flagseen ['G']) - gdb_symbols_fixup (symbolP, (long)temp); + gdb_symbols_fixup (symbolP, (long)temp); demand_empty_rest_of_line (); } void -s_gdbline() + s_gdbline() { int file_number, - lineno; - + lineno; + if (get_absolute_expression_and_terminator(&file_number) != ',') { as_bad("expected comman after filenum in .gdbline"); ignore_rest_of_line(); @@ -863,17 +879,17 @@ s_gdbline() } lineno=get_absolute_expression(); if (flagseen['G']) - gdb_line(file_number,lineno); + gdb_line(file_number,lineno); demand_empty_rest_of_line(); } void -s_gdblinetab() + s_gdblinetab() { int file_number, - offset; - + offset; + if (get_absolute_expression_and_terminator(&file_number) != ',') { as_bad("expected comma after filenum in .gdblinetab"); ignore_rest_of_line(); @@ -881,7 +897,7 @@ s_gdblinetab() } offset=get_absolute_expression(); if (flagseen['G']) - gdb_line_tab(file_number,offset); + gdb_line_tab(file_number,offset); demand_empty_rest_of_line(); } #endif @@ -890,7 +906,7 @@ void s_globl() { register char *name; register int c; register symbolS * symbolP; - + do { name = input_line_pointer; c = get_symbol_end(); @@ -902,7 +918,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(); @@ -920,31 +936,32 @@ int needs_align; /* 1 if this was a ".bss" directive, which may require register int temp; register symbolS * symbolP; const int max_alignment = 15; - int align; - + int align = 0; + name = input_line_pointer; c = get_symbol_end(); p = input_line_pointer; *p = c; SKIP_WHITESPACE(); - if (* input_line_pointer != ',') { + if (*input_line_pointer != ',') { as_bad("Expected comma after name"); ignore_rest_of_line(); return; } - input_line_pointer ++; - + + ++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(); @@ -967,13 +984,18 @@ int needs_align; /* 1 if this was a ".bss" directive, which may require align = 0; as_warn("Alignment negative. 0 assumed."); } - +#ifdef MANY_SEGMENTS +#define SEG_BSS SEG_E2 + record_alignment(SEG_E2, align); +#else 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 && @@ -987,7 +1009,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 @@ -1003,21 +1025,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); } @@ -1029,7 +1051,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(); @@ -1046,17 +1068,21 @@ void s_lsym() { input_line_pointer ++; segment = expression(& exp); if (segment != SEG_ABSOLUTE - && segment != SEG_DATA - && segment != SEG_TEXT - && segment != SEG_BSS - && segment != SEG_REGISTER) { +#ifdef MANY_SEGMENTS + && ! ( segment >= SEG_E0 && segment <= SEG_UNKNOWN) +#else + && segment != SEG_DATA + && segment != SEG_TEXT + && segment != SEG_BSS +#endif + && 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 @@ -1064,7 +1090,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 @@ -1083,27 +1109,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.", @@ -1120,7 +1146,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! @@ -1131,7 +1157,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); @@ -1139,32 +1165,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, @@ -1175,11 +1201,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(); @@ -1189,7 +1215,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 (); @@ -1204,19 +1230,23 @@ 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); +#else subseg_new (SEG_TEXT, (subsegT)temp); +#endif demand_empty_rest_of_line(); } /* s_text() */ @@ -1234,24 +1264,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]]); } /* @@ -1266,113 +1296,113 @@ ignore_rest_of_line() /* For suspect lines: gives warning. */ * 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_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; - - case SEG_DATA: - case SEG_TEXT: - case SEG_BSS: - 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: abort(); - } /* switch on segment */ - + S_SET_VALUE(symbolP, exp.X_add_number); + symbolP->sy_frag = & zero_address_frag; + break; + + default: +#ifdef MANY_SEGMENTS + 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 */ +#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; - - default: - BAD_CASE(segment); - 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; + + + + } } /* @@ -1390,249 +1420,245 @@ pseudo_set (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 == ',') { - unsigned int bits_available = BITS_PER_CHAR * nbytes; - /* used for error messages and rescanning */ - char *hold = input_line_pointer; - - /* At least scan over the expression. */ - segment = expression(&exp); - + + /* + * 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 - /* 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 */ + unsigned int bits_available = BITS_PER_CHAR * nbytes; + /* used for error messages and rescanning */ + char *hold = input_line_pointer; #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 x%x truncated to x%x.", get, use); - } - md_number_to_chars (p, use, nbytes); /* put bytes in right order. */ - break; - - case SEG_DIFFERENCE: + + /* 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 */ +#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: #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 - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_TEXT: - case SEG_DATA: + 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); + 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); #endif /* TC_NS32K */ - break; - - default: - BAD_CASE(segment); - 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() */ /* @@ -1661,124 +1687,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()) - { - 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 = * ++ 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++) + 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()) { - work = (*p & MASK_CHAR) * radix + carry; - *p = work & MASK_CHAR; - carry = work >> BITS_PER_CHAR; + c = 0; /* Skip loop. */ } - if (carry) + else { - grow_bignum(); - * bignum_high = carry & MASK_CHAR; - know((carry & ~ MASK_CHAR) == 0); + c = ','; /* Do loop. */ + -- input_line_pointer; } - } - 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 --) + while (c == ',') { - grow_bignum(); - * bignum_high = 0; + ++ 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); + 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. */ } - } - 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(); + demand_empty_rest_of_line(); } /* big_cons() */ - /* Extend bignum by 1 char. */ +/* 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; - } + 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(); */ /* @@ -1802,69 +1828,69 @@ 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 - { - 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) + 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()) { - p = frag_more (length); - bcopy (temp, p, length); + c = 0; /* Skip loop. */ + ++ input_line_pointer; /*->past termintor. */ } - 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(); + 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) + { + p = frag_more (length); + bcopy (temp, p, length); + } + 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() */ /* @@ -1874,9 +1900,11 @@ float_cons(float_type) /* Worker to do .float etc statements. */ * * Caller should have checked need_pass_2 is FALSE because we don't check it. */ -static 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 */ + + +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 */ { /* register char * p; JF unused */ /* register int length; JF unused */ /* Length of string we read, excluding */ @@ -1895,16 +1923,17 @@ static void stringer(append_zero) /* Worker to do .ascii etc statements. */ */ if (is_it_end_of_statement()) { - c = 0; /* Skip loop. */ - ++ input_line_pointer; /* Compensate for end of loop. */ + c = 0; /* Skip loop. */ + ++ input_line_pointer; /* Compensate for end of loop. */ } else { - c = ','; /* Do loop. */ + c = ','; /* Do loop. */ } - for (; c == ','; c = *input_line_pointer++) { + while (c == ',' || c == '<' || c == '"' ) { SKIP_WHITESPACE(); - if (*input_line_pointer == '\"') { + 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); @@ -1913,21 +1942,33 @@ static void stringer(append_zero) /* Worker to do .ascii etc statements. */ FRAG_APPEND_1_CHAR(0); } know(input_line_pointer [-1] == '\"'); - } else { - as_warn("Expected \"-ed string"); + 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; } - --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. */ -static unsigned int next_char_of_string() { +unsigned int next_char_of_string() { register unsigned int c; c = *input_line_pointer++ & CHAR_MASK; @@ -2012,77 +2053,80 @@ static 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; - } - know(retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE); - return (retval); + 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); +#endif + 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 ++); } /* @@ -2092,29 +2136,29 @@ get_absolute_expression_and_terminator(val_pointer) * 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 int len; - - for (len = * len_pointer; - len > 0; - len--) - { - if (* s == 0) + register char * s; + + if ((s = demand_copy_string(len_pointer)) != 0) { - s = 0; - len = 1; - * len_pointer = 0; - as_bad("This string may not contain \'\\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\'"); + } + } } - } - } - return (s); + return (s); } /* @@ -2161,43 +2205,43 @@ int *lenP; * * Out: 1 if input_line_pointer->end-of-line. */ -static int is_it_end_of_statement() { - SKIP_WHITESPACE(); - return (is_end_of_line [* input_line_pointer]); +int is_it_end_of_statement() { + 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. */ @@ -2206,68 +2250,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 = malloc(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 **)malloc (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() */ |