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 | |
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')
94 files changed, 27964 insertions, 28544 deletions
diff --git a/gas/a.out.gnu.h b/gas/a.out.gnu.h index c4c9182..123e225 100755 --- a/gas/a.out.gnu.h +++ b/gas/a.out.gnu.h @@ -12,14 +12,14 @@ will lay out the same sizes or alignments. */ struct exec_bytes { - unsigned char a_info[4]; - unsigned char a_text[4]; - unsigned char a_data[4]; - unsigned char a_bss[4]; - unsigned char a_syms[4]; - unsigned char a_entry[4]; - unsigned char a_trsize[4]; - unsigned char a_drsize[4]; + unsigned char a_info[4]; + unsigned char a_text[4]; + unsigned char a_data[4]; + unsigned char a_bss[4]; + unsigned char a_syms[4]; + unsigned char a_entry[4]; + unsigned char a_trsize[4]; + unsigned char a_drsize[4]; }; /* How big the "struct exec" is on disk */ @@ -29,14 +29,14 @@ struct exec_bytes { struct exec { - unsigned long a_info; /* Use macros N_MAGIC, etc for access */ - unsigned a_text; /* length of text, in bytes */ - unsigned a_data; /* length of data, in bytes */ - unsigned a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned a_syms; /* length of symbol table data in file, in bytes */ - unsigned a_entry; /* start address */ - unsigned a_trsize; /* length of relocation info for text, in bytes */ - unsigned a_drsize; /* length of relocation info for data, in bytes */ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ }; #endif /* __STRUCT_EXEC_OVERRIDE__ */ @@ -48,37 +48,37 @@ struct exec #undef M_68020 #undef M_SPARC enum machine_type { - M_UNKNOWN = 0, - M_68010 = 1, - M_68020 = 2, - M_SPARC = 3, - /* skip a bunch so we don't run into any of sun's numbers */ - M_386 = 100, - M_29K = 101, - M_RS6000 = 102, /* IBM RS/6000 */ - /* HP/BSD formats */ - M_HP200 = 200, /* hp200 (68010) BSD binary */ - M_HP300 = 300, /* hp300 (68020+68881) BSD binary */ - M_HPUX23 = 0x020C, /* hp200/300 HPUX binary */ + M_UNKNOWN = 0, + M_68010 = 1, + M_68020 = 2, + M_SPARC = 3, + /* skip a bunch so we don't run into any of sun's numbers */ + M_386 = 100, + M_29K = 101, + M_RS6000 = 102, /* IBM RS/6000 */ + /* HP/BSD formats */ + M_HP200 = 200, /* hp200 (68010) BSD binary */ + M_HP300 = 300, /* hp300 (68020+68881) BSD binary */ + M_HPUX23 = 0x020C, /* hp200/300 HPUX binary */ }; #define N_MAGIC(exec) ((exec).a_info & 0xffff) #define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff)) #define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff) #define N_SET_INFO(exec, magic, type, flags) \ - ((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0xff) << 16) \ - | (((flags) & 0xff) << 24)) + ((exec).a_info = ((magic) & 0xffff) \ + | (((int)(type) & 0xff) << 16) \ + | (((flags) & 0xff) << 24)) #define N_SET_MAGIC(exec, magic) \ - ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff))) + ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff))) #define N_SET_MACHTYPE(exec, machtype) \ - ((exec).a_info = \ - ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16)) + ((exec).a_info = \ + ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16)) #define N_SET_FLAGS(exec, flags) \ - ((exec).a_info = \ - ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24)) + ((exec).a_info = \ + ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24)) /* Code indicating object file or impure executable. */ #define OMAGIC 0407 @@ -97,8 +97,8 @@ enum machine_type { #ifndef N_BADMAG #define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC) + && N_MAGIC(x) != NMAGIC \ + && N_MAGIC(x) != ZMAGIC) #endif /* By default, segment size is constant. But on some machines, it can @@ -106,16 +106,16 @@ enum machine_type { #ifndef N_SEGSIZE #define N_SEGSIZE(x) SEGMENT_SIZE #endif - -/* This complexity is for encapsulated COFF support */ + + /* This complexity is for encapsulated COFF support */ #ifndef _N_HDROFF #define _N_HDROFF(x) (N_SEGSIZE(x) - sizeof (struct exec)) #endif #ifndef N_TXTOFF #define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? \ - _N_HDROFF((x)) + sizeof (struct exec) : \ - sizeof (struct exec)) + _N_HDROFF((x)) + sizeof (struct exec) : \ + sizeof (struct exec)) #endif @@ -143,7 +143,7 @@ enum machine_type { #ifndef N_TXTADDR #define N_TXTADDR(x) 0 #endif - + #ifndef N_DATADDR #define N_DATADDR(x) \ (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) \ @@ -154,15 +154,15 @@ enum machine_type { #define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data) struct nlist { - union { - char *n_name; - struct nlist *n_next; - long n_strx; - } n_un; - unsigned char n_type; - char n_other; - short n_desc; - unsigned long n_value; + union { + char *n_name; + struct nlist *n_next; + long n_strx; + } n_un; + unsigned char n_type; + char n_other; + short n_desc; + unsigned long n_value; }; #define N_UNDF 0 @@ -183,7 +183,7 @@ struct nlist { /* The following type indicates the definition of a symbol as being an indirect reference to another symbol. The other symbol appears as an undefined reference, immediately following this symbol. - + Indirection is asymmetrical. The other symbol's value will be used to satisfy requests for the indirect symbol, but not vice versa. If the other symbol does not have a definition, libraries will @@ -196,7 +196,7 @@ struct nlist { Space is allocated for the set in the text section, and each set element's value is stored into one word of the space. The first word of the space is the length of the set (number of elements). - + The address of the set is made into an N_SETV symbol whose name is the same as the name of the set. This symbol acts like a N_DATA global symbol @@ -225,15 +225,15 @@ struct nlist { /* The following enum and struct were borrowed from SunOS's /usr/include/sun4/a.out.h and extended to handle other machines. It is currently used on SPARC and AMD 29000. - + reloc_ext_bytes is how it looks on disk. reloc_info_extended is how we might process it on a native host. */ struct reloc_ext_bytes { - unsigned char r_address[4]; - unsigned char r_index[3]; - unsigned char r_bits[1]; - unsigned char r_addend[4]; + unsigned char r_address[4]; + unsigned char r_index[3]; + unsigned char r_bits[1]; + unsigned char r_addend[4]; }; #define RELOC_EXT_BITS_EXTERN_BIG 0x80 @@ -248,23 +248,23 @@ struct reloc_ext_bytes { struct reloc_info_extended { - unsigned long r_address; - unsigned int r_index:24; + unsigned long r_address; + unsigned int r_index:24; # define r_symbolnum r_index - unsigned r_extern:1; - unsigned :2; -/* RS/6000 compiler does not support enum bitfield - enum reloc_type r_type:5; */ - enum reloc_type r_type; - long int r_addend; + unsigned r_extern:1; + unsigned :2; + /* RS/6000 compiler does not support enum bitfield + enum reloc_type r_type:5; */ + enum reloc_type r_type; + long int r_addend; }; /* The standard, old-fashioned, Berkeley compatible relocation struct */ struct reloc_std_bytes { - unsigned char r_address[4]; - unsigned char r_index[3]; - unsigned char r_bits[1]; + unsigned char r_address[4]; + unsigned char r_index[3]; + unsigned char r_bits[1]; }; #define RELOC_STD_BITS_PCREL_BIG 0x80 @@ -292,38 +292,40 @@ struct reloc_std_bytes { #ifndef CUSTOM_RELOC_FORMAT struct relocation_info { - /* Address (within segment) to be relocated. */ - int r_address; - /* The meaning of r_symbolnum depends on r_extern. */ - unsigned int r_symbolnum:24; - /* Nonzero means value is a pc-relative offset - and it should be relocated for changes in its own address - as well as for changes in the symbol or section specified. */ - unsigned int r_pcrel:1; - /* Length (as exponent of 2) of the field to be relocated. - Thus, a value of 2 indicates 1<<2 bytes. */ - unsigned int r_length:2; - /* 1 => relocate with value of symbol. - r_symbolnum is the index of the symbol - in file's the symbol table. - 0 => relocate with the address of a segment. - r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS - (the N_EXT bit may be set also, but signifies nothing). */ - unsigned int r_extern:1; - /* The next three bits are for SunOS shared libraries, and seem to - be undocumented. */ - unsigned int r_baserel:1; /* Linkage table relative */ - unsigned int r_jmptable:1; /* pc-relative to jump table */ - + /* Address (within segment) to be relocated. */ + int r_address; + /* The meaning of r_symbolnum depends on r_extern. */ + unsigned int r_symbolnum:24; + /* Nonzero means value is a pc-relative offset + and it should be relocated for changes in its own address + as well as for changes in the symbol or section specified. */ + unsigned int r_pcrel:1; + /* Length (as exponent of 2) of the field to be relocated. + Thus, a value of 2 indicates 1<<2 bytes. */ + unsigned int r_length:2; + /* 1 => relocate with value of symbol. + r_symbolnum is the index of the symbol + in file's the symbol table. + 0 => relocate with the address of a segment. + r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS + (the N_EXT bit may be set also, but signifies nothing). */ + unsigned int r_extern:1; + /* The next three bits are for SunOS shared libraries, and seem to + be undocumented. */ + unsigned int r_baserel:1; /* Linkage table relative */ + unsigned int r_jmptable:1; /* pc-relative to jump table */ + #ifdef TC_NS32K #define r_bsr r_baserel #define r_disp r_jmptable #endif /* TC_NS32K */ - - unsigned int r_relative:1; /* "relative relocation" */ - /* unused */ - unsigned int r_pad:1; /* Padding -- set to zero */ + + unsigned int r_relative:1; /* "relative relocation" */ + /* unused */ + unsigned int r_pad:1; /* Padding -- set to zero */ }; #endif /* CUSTOM_RELOC_FORMAT */ #endif /* __A_OUT_GNU_H__ */ + +/* end of a.out.gnu.h */ @@ -1,33 +1,31 @@ /* Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc. - -Modified by Allen Wirfs-Brock, Instantiations Inc 2/90 -*/ + + Modified by Allen Wirfs-Brock, Instantiations Inc 2/90 + */ /* This is the Assembler Pre-Processor Copyright (C) 1987 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. */ + + 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. */ /* App, the assembler pre-processor. This pre-processor strips out excess spaces, turns single-quoted characters into a decimal constant, and turns # <number> <filename> <garbage> into a .line <number>\n.app-file <filename> pair. This needs better error-handling. - */ - -/* static const char rcsid[] = "$Id$"; */ + */ #include <stdio.h> #include "as.h" /* For BAD_CASE() only */ @@ -38,7 +36,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ static char lex [256]; static char symbol_chars[] = - "$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + "$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; /* These will go in BSS if not defined elsewhere, producing empty strings. */ extern const char comment_chars[]; @@ -56,41 +54,57 @@ extern const char line_separator_chars[]; #define LEX_IS_COLON 9 #define LEX_IS_NEWLINE 10 #define LEX_IS_ONECHAR_QUOTE 11 -#define IS_SYMBOL_COMPONENT(c) (lex [c] == LEX_IS_SYMBOL_COMPONENT) -#define IS_WHITESPACE(c) (lex [c] == LEX_IS_WHITESPACE) -#define IS_LINE_SEPARATOR(c) (lex [c] == LEX_IS_LINE_SEPARATOR) -#define IS_COMMENT(c) (lex [c] == LEX_IS_COMMENT_START) -#define IS_LINE_COMMENT(c) (lex [c] == LEX_IS_LINE_COMMENT_START) -#define IS_NEWLINE(c) (lex [c] == LEX_IS_NEWLINE) +#define IS_SYMBOL_COMPONENT(c) (lex[c] == LEX_IS_SYMBOL_COMPONENT) +#define IS_WHITESPACE(c) (lex[c] == LEX_IS_WHITESPACE) +#define IS_LINE_SEPARATOR(c) (lex[c] == LEX_IS_LINE_SEPARATOR) +#define IS_COMMENT(c) (lex[c] == LEX_IS_COMMENT_START) +#define IS_LINE_COMMENT(c) (lex[c] == LEX_IS_LINE_COMMENT_START) +#define IS_NEWLINE(c) (lex[c] == LEX_IS_NEWLINE) + +/* FIXME-soon: The entire lexer/parser thingy should be + built statically at compile time rather than dynamically + each and every time the assembler is run. xoxorich. */ void do_scrub_begin() { const char *p; - - lex [' '] = LEX_IS_WHITESPACE; - lex ['\t'] = LEX_IS_WHITESPACE; - lex ['\n'] = LEX_IS_NEWLINE; - lex [';'] = LEX_IS_LINE_SEPARATOR; - lex ['"'] = LEX_IS_STRINGQUOTE; - lex ['\''] = LEX_IS_ONECHAR_QUOTE; - lex [':'] = LEX_IS_COLON; - + + lex[' '] = LEX_IS_WHITESPACE; + lex['\t'] = LEX_IS_WHITESPACE; + lex['\n'] = LEX_IS_NEWLINE; + lex[';'] = LEX_IS_LINE_SEPARATOR; + lex['"'] = LEX_IS_STRINGQUOTE; + lex['\''] = LEX_IS_ONECHAR_QUOTE; + lex[':'] = LEX_IS_COLON; + /* Note that these override the previous defaults, e.g. if ';' is a comment char, then it isn't a line separator. */ - for (p =symbol_chars;*p;++p) + for (p = symbol_chars; *p; ++p) { lex[*p] = LEX_IS_SYMBOL_COMPONENT; - for (p=comment_chars;*p;p++) - lex[*p] = LEX_IS_COMMENT_START; - for (p=line_comment_chars;*p;p++) + } /* declare symbol characters */ + + for (p = line_comment_chars; *p; p++) { lex[*p] = LEX_IS_LINE_COMMENT_START; - for (p=line_separator_chars;*p;p++) + } /* declare line comment chars */ + + for (p = comment_chars; *p; p++) { + lex[*p] = LEX_IS_COMMENT_START; + } /* declare comment chars */ + + for (p = line_separator_chars; *p; p++) { lex[*p] = LEX_IS_LINE_SEPARATOR; - + } /* declare line separators */ + /* Only allow slash-star comments if slash is not in use */ if (lex['/'] == 0) { - lex ['/'] = LEX_IS_TWOCHAR_COMMENT_1ST; - lex ['*'] = LEX_IS_TWOCHAR_COMMENT_2ND; + lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST; } -} + /* FIXME-soon. This is a bad hack but otherwise, we + can't do c-style comments when '/' is a line + comment char. xoxorich. */ + if (lex['*'] == 0) { + lex['*'] = LEX_IS_TWOCHAR_COMMENT_2ND; + } +} /* do_scrub_begin() */ FILE *scrub_file; @@ -130,49 +144,49 @@ static int add_newlines = 0; That's why we have to save it all. */ struct app_save { - int state; - int old_state; - char *out_string; - char out_buf[sizeof (out_buf)]; - int add_newlines; - char *scrub_string; - char *scrub_last_string; - FILE *scrub_file; + int state; + int old_state; + char *out_string; + char out_buf[sizeof (out_buf)]; + int add_newlines; + char *scrub_string; + char *scrub_last_string; + FILE *scrub_file; }; char *app_push() { - register struct app_save *saved; - - saved = (struct app_save *) xmalloc(sizeof (*saved)); - saved->state = state; - saved->old_state = old_state; - saved->out_string = out_string; - bcopy(saved->out_buf, out_buf, sizeof(out_buf)); - saved->add_newlines = add_newlines; - saved->scrub_string = scrub_string; - saved->scrub_last_string = scrub_last_string; - saved->scrub_file = scrub_file; - - /* do_scrub_begin() is not useful, just wastes time. */ - return (char *)saved; + register struct app_save *saved; + + saved = (struct app_save *) xmalloc(sizeof (*saved)); + saved->state = state; + saved->old_state = old_state; + saved->out_string = out_string; + bcopy(saved->out_buf, out_buf, sizeof(out_buf)); + saved->add_newlines = add_newlines; + saved->scrub_string = scrub_string; + saved->scrub_last_string = scrub_last_string; + saved->scrub_file = scrub_file; + + /* do_scrub_begin() is not useful, just wastes time. */ + return (char *)saved; } void app_pop(arg) char *arg; { - register struct app_save *saved = (struct app_save *)arg; - - /* There is no do_scrub_end (). */ - state = saved->state; - old_state = saved->old_state; - out_string = saved->out_string; - bcopy (out_buf, saved->out_buf, sizeof (out_buf)); - add_newlines = saved->add_newlines; - scrub_string = saved->scrub_string; - scrub_last_string = saved->scrub_last_string; - scrub_file = saved->scrub_file; - - free (arg); + register struct app_save *saved = (struct app_save *)arg; + + /* There is no do_scrub_end (). */ + state = saved->state; + old_state = saved->old_state; + out_string = saved->out_string; + bcopy (out_buf, saved->out_buf, sizeof (out_buf)); + add_newlines = saved->add_newlines; + scrub_string = saved->scrub_string; + scrub_last_string = saved->scrub_last_string; + scrub_file = saved->scrub_file; + + free (arg); } /* app_pop() */ int do_scrub_next_char(get,unget) @@ -180,20 +194,20 @@ int (*get)(); void (*unget)(); { /*State 0: beginning of normal line - 1: After first whitespace on line (flush more white) - 2: After first non-white (opcode) on line (keep 1white) - 3: after second white on line (into operands) (flush white) - 4: after putting out a .line, put out digits - 5: parsing a string, then go to old-state - 6: putting out \ escape in a "d string. - 7: After putting out a .app-file, put out string. - 8: After putting out a .app-file string, flush until newline. - -1: output string in out_string and go to the state in old_state - -2: flush text until a '*' '/' is seen, then go to state old_state - */ - - register int ch, ch2; - + 1: After first whitespace on line (flush more white) + 2: After first non-white (opcode) on line (keep 1white) + 3: after second white on line (into operands) (flush white) + 4: after putting out a .line, put out digits + 5: parsing a string, then go to old-state + 6: putting out \ escape in a "d string. + 7: After putting out a .app-file, put out string. + 8: After putting out a .app-file string, flush until newline. + -1: output string in out_string and go to the state in old_state + -2: flush text until a '*' '/' is seen, then go to state old_state + */ + + register int ch, ch2 = 0; + switch (state) { case -1: ch= *out_string++; @@ -202,33 +216,33 @@ void (*unget)(); old_state=3; } return ch; - + case -2: for(;;) { do { ch=(*get)(); } while(ch!=EOF && ch!='\n' && ch!='*'); if(ch=='\n' || ch==EOF) - return ch; - + return ch; + /* At this point, ch must be a '*' */ while ( (ch=(*get)()) == '*' ){ ; } if(ch==EOF || ch=='/') - break; + break; (*unget)(ch); } state=old_state; return ' '; - + case 4: ch=(*get)(); if(ch==EOF || (ch>='0' && ch<='9')) - return ch; + return ch; else { while(ch!=EOF && IS_WHITESPACE(ch)) - ch=(*get)(); + ch=(*get)(); if(ch=='"') { (*unget)(ch); out_string="\n.app-file "; @@ -237,11 +251,11 @@ void (*unget)(); return *out_string++; } else { while(ch!=EOF && ch!='\n') - ch=(*get)(); + ch=(*get)(); return ch; } } - + case 5: ch=(*get)(); if(ch=='"') { @@ -258,19 +272,19 @@ void (*unget)(); } else { return ch; } - + case 6: state=5; ch=(*get)(); switch(ch) { /* This is neet. Turn "string more string" into "string\n more string" - */ + */ case '\n': (*unget)('n'); add_newlines++; return '\\'; - + case '"': case '\\': case 'b': @@ -290,7 +304,7 @@ void (*unget)(); case '6': case '7': break; - + #ifdef ONLY_STANDARD_ESCAPES default: as_warn("Unknown escape '\\%c' in string: Ignored",ch); @@ -300,43 +314,43 @@ void (*unget)(); /* Accept \x as x for any x */ break; #endif /* ONLY_STANDARD_ESCAPES */ - + case EOF: as_warn("End of file in string: '\"' inserted"); return '"'; } return ch; - + case 7: ch=(*get)(); state=5; old_state=8; return ch; - + case 8: do ch= (*get)(); while(ch!='\n'); state=0; return ch; } - + /* OK, we are somewhere in states 0 through 4 */ - -/* flushchar: */ + + /* flushchar: */ ch=(*get)(); recycle: if (ch == EOF) { if (state != 0) - as_warn("End of file not at end of a line: Newline inserted."); + as_warn("End of file not at end of a line: Newline inserted."); return ch; } - + switch (lex[ch]) { case LEX_IS_WHITESPACE: do ch=(*get)(); while(ch!=EOF && IS_WHITESPACE(ch)); if(ch==EOF) - return ch; + return ch; if(IS_COMMENT(ch) || (state==0 && IS_LINE_COMMENT(ch)) || ch=='/' || IS_LINE_SEPARATOR(ch)) { goto recycle; } @@ -348,7 +362,7 @@ void (*unget)(); default: BAD_CASE(state); } break; - + case LEX_IS_TWOCHAR_COMMENT_1ST: ch2=(*get)(); if (ch2 != EOF && lex[ch2] == LEX_IS_TWOCHAR_COMMENT_2ND) { @@ -356,37 +370,38 @@ void (*unget)(); do { ch2=(*get)(); if(ch2 != EOF && IS_NEWLINE(ch2)) - add_newlines++; + add_newlines++; } while(ch2!=EOF && - (lex[ch2] != LEX_IS_TWOCHAR_COMMENT_2ND)); - + (lex[ch2] != LEX_IS_TWOCHAR_COMMENT_2ND)); + while (ch2!=EOF && - (lex[ch2] == LEX_IS_TWOCHAR_COMMENT_2ND)){ + (lex[ch2] == LEX_IS_TWOCHAR_COMMENT_2ND)){ ch2=(*get)(); } - + if(ch2==EOF - || lex[ch2] == LEX_IS_TWOCHAR_COMMENT_1ST) - break; + || lex[ch2] == LEX_IS_TWOCHAR_COMMENT_1ST) + break; (*unget)(ch); } if(ch2==EOF) - as_warn("End of file in multiline comment"); - + as_warn("End of file in multiline comment"); + ch = ' '; goto recycle; } else { if(ch2!=EOF) - (*unget)(ch2); + (*unget)(ch2); return ch; } break; - + case LEX_IS_STRINGQUOTE: old_state=state; state=5; return ch; - + +#ifndef IEEE_STYLE case LEX_IS_ONECHAR_QUOTE: ch=(*get)(); if(ch==EOF) { @@ -394,7 +409,7 @@ void (*unget)(); ch=0; } sprintf(out_buf,"%d", (int)(unsigned char)ch); - + /* None of these 'x constants for us. We want 'x'. */ if ( (ch=(*get)()) != '\'' ) { @@ -404,17 +419,17 @@ void (*unget)(); (*unget)(ch); #endif } - + old_state=state; state= -1; out_string=out_buf; return *out_string++; - +#endif case LEX_IS_COLON: if(state!=3) - state=0; + state=0; return ch; - + case LEX_IS_NEWLINE: /* Roll out a bunch of newlines from inside comments, etc. */ if(add_newlines) { @@ -422,14 +437,27 @@ void (*unget)(); (*unget)(ch); } /* fall thru into... */ - + case LEX_IS_LINE_SEPARATOR: state=0; return ch; - + case LEX_IS_LINE_COMMENT_START: if (state != 0) /* Not at start of line, act normal */ - goto de_fault; + goto de_fault; + + /* FIXME-someday: The two character comment stuff was badly + thought out. On i386, we want '/' as line comment start + AND we want C style comments. hence this hack. The + whole lexical process should be reworked. xoxorich. */ + + if (ch == '/' && (ch2 = (*get)()) == '*') { + state = -2; + return(do_scrub_next_char(get, unget)); + } else { + (*unget)(ch2); + } /* bad hack */ + do ch=(*get)(); while(ch!=EOF && IS_WHITESPACE(ch)); if(ch==EOF) { @@ -439,9 +467,9 @@ void (*unget)(); if(ch<'0' || ch>'9') { /* Non-numerics: Eat whole comment line */ while(ch!=EOF && !IS_NEWLINE(ch)) - ch=(*get)(); + ch=(*get)(); if(ch==EOF) - as_warn("EOF in Comment: Newline inserted"); + as_warn("EOF in Comment: Newline inserted"); state=0; return '\n'; } @@ -451,15 +479,15 @@ void (*unget)(); state= -1; out_string=".line "; return *out_string++; - + case LEX_IS_COMMENT_START: do ch=(*get)(); while(ch!=EOF && !IS_NEWLINE(ch)); if(ch==EOF) - as_warn("EOF in comment: Newline inserted"); + as_warn("EOF in comment: Newline inserted"); state=0; return '\n'; - + default: de_fault: /* Some relatively `normal' character. */ @@ -484,10 +512,10 @@ char line_comment_chars[] = "#"; main() { int ch; - + app_begin(); while((ch=do_scrub_next_char(stdin))!=EOF) - putc(ch,stdout); + putc(ch,stdout); } as_warn(str) @@ -1,23 +1,21 @@ /* as.c - GAS main program. Copyright (C) 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 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. */ - -/* 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. */ /* * Main program for AS; a 32-bit assembler of GNU. @@ -48,11 +46,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "subsegs.h" #ifdef __STDC__ - /* This prototype for got_sig() is ansi. If you want - anything else, then your compiler is lying to you when - it says that it is __STDC__. If you want to change it, - #ifdef protect it from those of us with real ansi - compilers. */ +/* This prototype for got_sig() is ansi. If you want + anything else, then your compiler is lying to you when + it says that it is __STDC__. If you want to change it, + #ifdef protect it from those of us with real ansi + compilers. */ #define SIGTY void @@ -91,18 +89,18 @@ char **argv; char *arg; /* an arg to program */ char a; /* an arg flag (after -) */ static const int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0}; - + for(a=0;sig[a]!=0;a++) - if(signal(sig[a], SIG_IGN) != SIG_IGN) - signal(sig[a], got_sig); - + if(signal(sig[a], SIG_IGN) != SIG_IGN) + signal(sig[a], got_sig); + myname=argv[0]; bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */ #ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME #define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out" #endif /* OBJ_DEFAULT_OUTPUT_FILE_NAME */ out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME; - + symbol_begin(); /* symbols.c */ subsegs_begin(); /* subsegs.c */ read_begin(); /* read.c */ @@ -121,84 +119,93 @@ char **argv; * name(s) and ""(s) denoting stdin. These file names are used * (perhaps more than once) later. */ - /* FIXME-SOMEDAY this should use getopt. */ + /* FIXME-SOMEDAY this should use getopt. */ work_argc = argc-1; /* don't count argv[0] */ work_argv = argv+1; /* skip argv[0] */ for (;work_argc--;work_argv++) { arg = * work_argv; /* work_argv points to this argument */ - + if (*arg!='-') /* Filename. We need it later. */ - continue; /* Keep scanning args looking for flags. */ + continue; /* Keep scanning args looking for flags. */ if (arg[1] == '-' && arg[2] == 0) { /* "--" as an argument means read STDIN */ /* on this scan, we don't want to think about filenames */ * work_argv = ""; /* Code that means 'use stdin'. */ continue; } - /* This better be a switch. */ + /* This better be a switch. */ arg ++; /*->letter. */ - + while ((a = * arg) != '\0') {/* scan all the 1-char flags */ arg ++; /* arg->after letter. */ a &= 0x7F; /* ascii only please */ /* if (flagseen[a]) - as_tsktsk("%s: Flag option - %c has already been seen.", myname, a); */ + as_tsktsk("%s: Flag option - %c has already been seen.", myname, a); */ flagseen[a] = 1; switch (a) { - - case 'a': - { - int loop =1; - - while (loop) { - switch (*arg) + + case 'a': { - case 'l': - listing |= LISTING_LISTING; - arg++; - break; - case 's': - listing |= LISTING_SYMBOLS; - arg++; - break; - case 'n': - listing |= LISTING_NOFORM; - arg++; - break; - default: - if (!listing) - listing= LISTING_DEFAULT; - loop = 0; - break; + int loop =1; + + while (loop) { + switch (*arg) + { + case 'l': + listing |= LISTING_LISTING; + arg++; + break; + case 's': + listing |= LISTING_SYMBOLS; + arg++; + break; + case 'h': + listing |= LISTING_HLL; + arg++; + break; + + case 'n': + listing |= LISTING_NOFORM; + arg++; + break; + case 'd': + listing |= LISTING_NODEBUG; + arg++; + break; + default: + if (!listing) + listing= LISTING_DEFAULT; + loop = 0; + break; + } + } } - } - } - - break; - - + + break; + + case 'f': break; /* -f means fast - no need for "app" preprocessor. */ - + case 'D': /* DEBUG is implemented: it debugs different */ /* things to other people's assemblers. */ break; - + #ifdef DONTDEF case 'G': /* GNU AS switch: include gdbsyms. */ if (*arg) /* Rest of argument is file-name. */ - gdb_symbol_file_name = stralloc (arg); + gdb_symbol_file_name = stralloc (arg); else if (work_argc) { /* Next argument is file-name. */ work_argc --; * work_argv = NULL; /* Not a source file-name. */ gdb_symbol_file_name = * ++ work_argv; } else - as_warn("%s: I expected a filename after -G", myname); + as_warn("%s: I expected a filename after -G", myname); arg = ""; /* Finished with this arg. */ break; #endif - + case 'I': { /* Include file directory */ char *temp = NULL; @@ -214,45 +221,45 @@ char **argv; arg = ""; /* Finished with this arg. */ break; } - + #ifndef WORKING_DOT_WORD case 'k': break; #endif - + case 'L': /* -L means keep L* symbols */ break; - + case 'o': if (*arg) /* Rest of argument is object file-name. */ - out_file_name = stralloc (arg); + out_file_name = stralloc (arg); else if (work_argc) { /* Want next arg for a file-name. */ * work_argv = NULL; /* This is not a file-name. */ work_argc--; out_file_name = * ++ work_argv; } else - as_warn("%s: I expected a filename after -o. \"%s\" assumed.", myname, out_file_name); + as_warn("%s: I expected a filename after -o. \"%s\" assumed.", myname, out_file_name); arg = ""; /* Finished with this arg. */ break; - + case 'R': /* -R means put data into text segment */ break; - + case 'v': #ifdef VMS { - extern char *compiler_version_string; - compiler_version_string = arg; + extern char *compiler_version_string; + compiler_version_string = arg; } #else /* not VMS */ fprintf(stderr,version_string); if(*arg && strcmp(arg,"ersion")) - as_warn("Unknown -v option ignored"); + as_warn("Unknown -v option ignored"); #endif while(*arg) arg++; /* Skip the rest */ break; - + case 'W': /* -W means don't warn about things */ case 'X': @@ -260,13 +267,13 @@ char **argv; case 'Z': /* -Z means attempt to generate object file even after errors. */ break; - + default: --arg; if(md_parse_option(&arg,&work_argc,&work_argv)==0) - as_warn("%s: I don't understand '%c' flag.", myname, a); + as_warn("%s: I don't understand '%c' flag.", myname, a); if(arg && *arg) - arg++; + arg++; break; } } @@ -282,7 +289,7 @@ char **argv; } #ifdef DONTDEF if (gdb_begin(gdb_symbol_file_name) == 0) - flagseen ['G'] = 0; /* Don't do any gdbsym stuff. */ + flagseen ['G'] = 0; /* Don't do any gdbsym stuff. */ #endif /* Here with flags set up in flagseen[]. */ perform_an_assembly_pass(argc,argv); /* Assemble it. */ @@ -294,14 +301,14 @@ char **argv; || had_errors() > 0)) { write_object_file(); /* relax() addresses then emit object file */ } /* we also check in write_object_file() just before emit. */ - + input_scrub_end(); md_end(); /* MACHINE.c */ - + #ifndef NO_LISTING listing_print(); #endif - + #ifndef VMS return((had_warnings() && flagseen['Z']) || had_errors() > 0); /* WIN */ @@ -309,7 +316,7 @@ char **argv; return(!((had_warnings() && flagseen['Z']) || had_errors() > 0)); /* WIN */ #endif /* VMS */ - + } /* main() */ @@ -328,43 +335,43 @@ static void perform_an_assembly_pass(argc, argv) int argc; char **argv; { - int saw_a_file = 0; - unsigned int i; - need_pass_2 = 0; - + int saw_a_file = 0; + unsigned int i; + need_pass_2 = 0; + #ifdef MANY_SEGMENTS - - for (i= SEG_E0; i < SEG_UNKNOWN; i++) - { - segment_info[i].fix_root = 0; - } - /* Create the three fixed ones */ - subseg_new (SEG_E0, 0); - subseg_new (SEG_E1, 0); - subseg_new (SEG_E2, 0); - strcpy(segment_info[SEG_E0].scnhdr.s_name,".text"); - strcpy(segment_info[SEG_E1].scnhdr.s_name,".data"); - strcpy(segment_info[SEG_E2].scnhdr.s_name,".bss"); - - subseg_new (SEG_E0, 0); + + for (i= SEG_E0; i < SEG_UNKNOWN; i++) + { + segment_info[i].fix_root = 0; + } + /* Create the three fixed ones */ + subseg_new (SEG_E0, 0); + subseg_new (SEG_E1, 0); + subseg_new (SEG_E2, 0); + strcpy(segment_info[SEG_E0].scnhdr.s_name,".text"); + strcpy(segment_info[SEG_E1].scnhdr.s_name,".data"); + strcpy(segment_info[SEG_E2].scnhdr.s_name,".bss"); + + subseg_new (SEG_E0, 0); #else - text_fix_root = NULL; - data_fix_root = NULL; - - subseg_new (SEG_TEXT, 0); + text_fix_root = NULL; + data_fix_root = NULL; + + subseg_new (SEG_TEXT, 0); #endif - argv++; /* skip argv[0] */ - argc--; /* skip argv[0] */ - while (argc--) { - if (*argv) { /* Is it a file-name argument? */ - saw_a_file++; - /* argv->"" if stdin desired, else->filename */ - read_a_source_file(*argv); - } - argv++; /* completed that argv */ - } - if(!saw_a_file) - read_a_source_file(""); + argv++; /* skip argv[0] */ + argc--; /* skip argv[0] */ + while (argc--) { + if (*argv) { /* Is it a file-name argument? */ + saw_a_file++; + /* argv->"" if stdin desired, else->filename */ + read_a_source_file(*argv); + } + argv++; /* completed that argv */ + } + if(!saw_a_file) + read_a_source_file(""); } /* perform_an_assembly_pass() */ /* @@ -375,12 +382,12 @@ char **argv; */ static char * -stralloc (str) + stralloc (str) char * str; { register char * retval; register long len; - + len = strlen (str) + 1; retval = xmalloc (len); (void) strcpy(retval, str); @@ -395,14 +402,14 @@ static void lose() { #endif /* comment */ static SIGTY -got_sig(sig) + got_sig(sig) int sig; { static here_before = 0; - + as_bad("Interrupted by signal %d", sig); if(here_before++) - exit(1); + exit(1); return((SIGTY) 0); } @@ -413,4 +420,4 @@ int sig; * End: */ -/* end: as.c */ +/* end of as.c */ @@ -1,26 +1,24 @@ /* as.h - global header file Copyright (C) 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 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. */ - -/* 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 GAS 1 - +#include <ansidecl.h> #include "host.h" #include "flonum.h" @@ -67,15 +65,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <assert.h> - +#include "listing.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free xfree -#define BAD_CASE(value) \ -{ \ - as_fatal("Case value %d unexpected at line %d of file \"%s\"\n", \ - value, __LINE__, __FILE__); \ -} +#define xfree free + +#define BAD_CASE(value) \ +{ \ + as_fatal("Case value %d unexpected at line %d of file \"%s\"\n", \ + value, __LINE__, __FILE__); \ + } /* These are assembler-wide concepts */ @@ -88,7 +88,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define COMMON extern /* our commons live elswhere */ #endif #endif - /* COMMON now defined */ +/* COMMON now defined */ #define DEBUG /* temporary */ #ifdef DEBUG @@ -99,9 +99,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #else #define know(p) /* know() checks are no-op.ed */ #endif - - -#define xfree free /* input_scrub.c */ @@ -163,8 +160,8 @@ typedef enum _segT { SEG_ABSENT, /* Mythical Segment (absent): NO expression seen. */ SEG_PASS1, /* Mythical Segment: Need another pass. */ SEG_GOOF, /* Only happens if AS has a logic error. */ - /* Invented so we don't crash printing */ - /* error message involving weird segment. */ + /* Invented so we don't crash printing */ + /* error message involving weird segment. */ SEG_BIG, /* Bigger than 32 bits constant. */ SEG_DIFFERENCE, /* Mythical Segment: absolute difference. */ SEG_DEBUG, /* Debug segment */ @@ -178,12 +175,12 @@ typedef enum _segT { typedef int subsegT; COMMON subsegT now_subseg; - /* What subseg we are accreting now? */ +/* What subseg we are accreting now? */ COMMON segT now_seg; - /* Segment our instructions emit to. */ - /* Only OK values are SEG_TEXT or SEG_DATA. */ +/* Segment our instructions emit to. */ +/* Only OK values are SEG_TEXT or SEG_DATA. */ extern char *const seg_name[]; @@ -199,12 +196,12 @@ typedef enum _relax_state { rs_align, /* Align: Fr_offset: power of 2. 1 variable char: fill character. */ - + rs_org, /* Org: Fr_offset, fr_symbol: address. 1 variable char: fill character. */ rs_machine_dependent, - + #ifndef WORKING_DOT_WORD rs_broken_word, /* JF: gunpoint */ #endif @@ -216,7 +213,7 @@ typedef enum _relax_state { typedef unsigned long relax_substateT; typedef unsigned long relax_addressT;/* Enough bits for address. */ - /* Still an integer type. */ +/* Still an integer type. */ /* frags.c */ @@ -232,41 +229,44 @@ typedef unsigned long relax_addressT;/* Enough bits for address. */ * of the 1st char of a frag is generally not known until after relax(). * Many things at assembly time describe an address by {object-file-address * of a particular frag}+offset. - + BUG: it may be smarter to have a single pointer off to various different -notes for different frag kinds. See how code pans + notes for different frag kinds. See how code pans */ struct frag /* a code fragment */ { unsigned long fr_address; /* Object file address. */ struct frag *fr_next; /* Chain forward; ascending address order. */ - /* Rooted in frch_root. */ - + /* Rooted in frch_root. */ + long fr_fix; /* (Fixed) number of chars we know we have. */ - /* May be 0. */ + /* May be 0. */ long fr_var; /* (Variable) number of chars after above. */ - /* May be 0. */ + /* May be 0. */ struct symbol *fr_symbol; /* For variable-length tail. */ long fr_offset; /* For variable-length tail. */ char *fr_opcode; /*->opcode low addr byte,for relax()ation*/ relax_stateT fr_type; /* What state is my tail in? */ relax_substateT fr_subtype; - /* These are needed only on the NS32K machines */ + /* These are needed only on the NS32K machines */ char fr_pcrel_adjust; char fr_bsr; +#ifndef NO_LISTING + struct list_info_struct *line; +#endif char fr_literal [1]; /* Chars begin here. */ - /* One day we will compile fr_literal[0]. */ + /* One day we will compile fr_literal[0]. */ }; #define SIZEOF_STRUCT_FRAG \ - ((int)zero_address_frag.fr_literal-(int)&zero_address_frag) - /* We want to say fr_literal[0] above. */ +((int)zero_address_frag.fr_literal-(int)&zero_address_frag) +/* We want to say fr_literal[0] above. */ typedef struct frag fragS; COMMON fragS * frag_now; /* -> current frag we are building. */ - /* This frag is incomplete. */ - /* It is, however, included in frchain_now. */ - /* Frag_now->fr_fix is bogus. Use: */ +/* This frag is incomplete. */ +/* It is, however, included in frchain_now. */ +/* Frag_now->fr_fix is bogus. Use: */ /* Virtual frag_now->fr_fix==obstack_next_free(&frags)-frag_now->fr_literal.*/ COMMON fragS zero_address_frag; /* For foreign-segment symbol fixups. */ @@ -275,17 +275,17 @@ COMMON fragS bss_address_frag; /* For local common (N_BSS segment) fixups. */ /* main program "as.c" (command arguments etc) */ COMMON char -flagseen[128]; /* ['x'] TRUE if "-x" seen. */ + flagseen[128]; /* ['x'] TRUE if "-x" seen. */ COMMON char * -out_file_name; /* name of emitted object file */ + out_file_name; /* name of emitted object file */ COMMON int need_pass_2; /* TRUE if we need a second pass. */ typedef struct { - char * poc_name; /* assembler mnemonic, lower case, no '.' */ - void (*poc_handler)(); /* Do the work */ - int poc_val; /* Value to pass to handler */ + char * poc_name; /* assembler mnemonic, lower case, no '.' */ + void (*poc_handler)(); /* Do the work */ + int poc_val; /* Value to pass to handler */ } pseudo_typeS; #if defined(__STDC__) & !defined(NO_STDARG) @@ -384,12 +384,12 @@ void subsegs_begin(); #endif /* __STDC__ */ - /* this one starts the chain of target dependant headers */ +/* this one starts the chain of target dependant headers */ #include "targ-env.h" - /* these define types needed by the interfaces */ +/* these define types needed by the interfaces */ #include "struc-symbol.h" -#include "reloc.h" +#include "aout/reloc.h" #include "write.h" #include "expr.h" #include "frags.h" @@ -407,5 +407,4 @@ void subsegs_begin(); * End: */ -/* end: as.h */ - +/* end of as.h */ diff --git a/gas/atof-generic.c b/gas/atof-generic.c index 7d2d8f4..42fcfa9 100644 --- a/gas/atof-generic.c +++ b/gas/atof-generic.c @@ -1,23 +1,21 @@ /* atof_generic.c - turn a string of digits into a Flonum Copyright (C) 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. */ #include <ctype.h> #include <string.h> @@ -40,510 +38,510 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* #define TRUE (1) */ /***********************************************************************\ -* * -* Given a string of decimal digits , with optional decimal * -* mark and optional decimal exponent (place value) of the * -* lowest_order decimal digit: produce a floating point * -* number. The number is 'generic' floating point: our * -* caller will encode it for a specific machine architecture. * -* * -* Assumptions * -* uses base (radix) 2 * -* this machine uses 2's complement binary integers * -* target flonums use " " " " * -* target flonums exponents fit in a long * -* * -\***********************************************************************/ + * * + * Given a string of decimal digits , with optional decimal * + * mark and optional decimal exponent (place value) of the * + * lowest_order decimal digit: produce a floating point * + * number. The number is 'generic' floating point: our * + * caller will encode it for a specific machine architecture. * + * * + * Assumptions * + * uses base (radix) 2 * + * this machine uses 2's complement binary integers * + * target flonums use " " " " * + * target flonums exponents fit in a long * + * * + \***********************************************************************/ /* - - Syntax: - -<flonum> ::= <optional-sign> <decimal-number> <optional-exponent> -<optional-sign> ::= '+' | '-' | {empty} -<decimal-number> ::= <integer> - | <integer> <radix-character> - | <integer> <radix-character> <integer> - | <radix-character> <integer> -<optional-exponent> ::= {empty} | <exponent-character> <optional-sign> <integer> -<integer> ::= <digit> | <digit> <integer> -<digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' -<exponent-character> ::= {one character from "string_of_decimal_exponent_marks"} -<radix-character> ::= {one character from "string_of_decimal_marks"} - -*/ + + Syntax: + + <flonum> ::= <optional-sign> <decimal-number> <optional-exponent> + <optional-sign> ::= '+' | '-' | {empty} + <decimal-number> ::= <integer> + | <integer> <radix-character> + | <integer> <radix-character> <integer> + | <radix-character> <integer> + <optional-exponent> ::= {empty} | <exponent-character> <optional-sign> <integer> + <integer> ::= <digit> | <digit> <integer> + <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' + <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"} + <radix-character> ::= {one character from "string_of_decimal_marks"} + + */ int /* 0 if OK */ -atof_generic ( - address_of_string_pointer, /* return pointer to just AFTER number we read. */ - string_of_decimal_marks, /* At most one per number. */ - string_of_decimal_exponent_marks, - address_of_generic_floating_point_number) + atof_generic ( + address_of_string_pointer, /* return pointer to just AFTER number we read. */ + string_of_decimal_marks, /* At most one per number. */ + string_of_decimal_exponent_marks, + address_of_generic_floating_point_number) - char * * address_of_string_pointer; - const char * string_of_decimal_marks; - const char * string_of_decimal_exponent_marks; - FLONUM_TYPE * address_of_generic_floating_point_number; +char * * address_of_string_pointer; +const char * string_of_decimal_marks; +const char * string_of_decimal_exponent_marks; +FLONUM_TYPE * address_of_generic_floating_point_number; { - - int return_value; /* 0 means OK. */ - char * first_digit; - /* char * last_digit; JF unused */ - int number_of_digits_before_decimal; - int number_of_digits_after_decimal; - long decimal_exponent; - int number_of_digits_available; - char digits_sign_char; - - { - /* - * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent. - * It would be simpler to modify the string, but we don't; just to be nice - * to caller. - * We need to know how many digits we have, so we can allocate space for - * the digits' value. - */ - - char * p; - char c; - int seen_significant_digit; - - first_digit = * address_of_string_pointer; - c= *first_digit; - if (c=='-' || c=='+') - { - digits_sign_char = c; - first_digit ++; - } - else - digits_sign_char = '+'; - - if( (first_digit[0]=='n' || first_digit[0]=='N') - && (first_digit[1]=='a' || first_digit[1]=='A') - && (first_digit[2]=='n' || first_digit[2]=='N')) { - address_of_generic_floating_point_number->sign=0; - address_of_generic_floating_point_number->exponent=0; - address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low; - (*address_of_string_pointer)=first_digit+3; - return 0; - } - if( (first_digit[0]=='i' || first_digit[0]=='I') - && (first_digit[1]=='n' || first_digit[1]=='N') - && (first_digit[2]=='f' || first_digit[2]=='F')) { - address_of_generic_floating_point_number->sign= digits_sign_char=='+' ? 'P' : 'N'; - address_of_generic_floating_point_number->exponent=0; - address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low; - if( (first_digit[3]=='i' || first_digit[3]=='I') - && (first_digit[4]=='n' || first_digit[4]=='N') - && (first_digit[5]=='i' || first_digit[5]=='I') - && (first_digit[6]=='t' || first_digit[6]=='T') - && (first_digit[7]=='y' || first_digit[7]=='Y')) - (*address_of_string_pointer)=first_digit+8; - else - (*address_of_string_pointer)=first_digit+3; - return 0; - } - - number_of_digits_before_decimal = 0; - number_of_digits_after_decimal = 0; - decimal_exponent = 0; - seen_significant_digit = 0; - for (p = first_digit; - ((c = * p) != '\0') - && (!c || ! strchr (string_of_decimal_marks, c) ) - && (!c || ! strchr (string_of_decimal_exponent_marks, c) ); - p ++) - { - if (isdigit(c)) - { - if (seen_significant_digit || c > '0') - { - number_of_digits_before_decimal ++; - seen_significant_digit = 1; - } - else - { - first_digit++; - } - } - else - { - break; /* p -> char after pre-decimal digits. */ - } - } /* For each digit before decimal mark. */ - + + int return_value; /* 0 means OK. */ + char * first_digit; + /* char * last_digit; JF unused */ + int number_of_digits_before_decimal; + int number_of_digits_after_decimal; + long decimal_exponent; + int number_of_digits_available; + char digits_sign_char; + + { + /* + * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent. + * It would be simpler to modify the string, but we don't; just to be nice + * to caller. + * We need to know how many digits we have, so we can allocate space for + * the digits' value. + */ + + char * p; + char c; + int seen_significant_digit; + + first_digit = * address_of_string_pointer; + c= *first_digit; + if (c=='-' || c=='+') + { + digits_sign_char = c; + first_digit ++; + } + else + digits_sign_char = '+'; + + if( (first_digit[0]=='n' || first_digit[0]=='N') + && (first_digit[1]=='a' || first_digit[1]=='A') + && (first_digit[2]=='n' || first_digit[2]=='N')) { + address_of_generic_floating_point_number->sign=0; + address_of_generic_floating_point_number->exponent=0; + address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low; + (*address_of_string_pointer)=first_digit+3; + return 0; + } + if( (first_digit[0]=='i' || first_digit[0]=='I') + && (first_digit[1]=='n' || first_digit[1]=='N') + && (first_digit[2]=='f' || first_digit[2]=='F')) { + address_of_generic_floating_point_number->sign= digits_sign_char=='+' ? 'P' : 'N'; + address_of_generic_floating_point_number->exponent=0; + address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low; + if( (first_digit[3]=='i' || first_digit[3]=='I') + && (first_digit[4]=='n' || first_digit[4]=='N') + && (first_digit[5]=='i' || first_digit[5]=='I') + && (first_digit[6]=='t' || first_digit[6]=='T') + && (first_digit[7]=='y' || first_digit[7]=='Y')) + (*address_of_string_pointer)=first_digit+8; + else + (*address_of_string_pointer)=first_digit+3; + return 0; + } + + number_of_digits_before_decimal = 0; + number_of_digits_after_decimal = 0; + decimal_exponent = 0; + seen_significant_digit = 0; + for (p = first_digit; + ((c = * p) != '\0') + && (!c || ! strchr (string_of_decimal_marks, c) ) + && (!c || ! strchr (string_of_decimal_exponent_marks, c) ); + p ++) + { + if (isdigit(c)) + { + if (seen_significant_digit || c > '0') + { + number_of_digits_before_decimal ++; + seen_significant_digit = 1; + } + else + { + first_digit++; + } + } + else + { + break; /* p -> char after pre-decimal digits. */ + } + } /* For each digit before decimal mark. */ + #ifndef OLD_FLOAT_READS - /* Ignore trailing 0's after the decimal point. The original code here - * (ifdef'd out) does not do this, and numbers like - * 4.29496729600000000000e+09 (2**31) - * come out inexact for some reason related to length of the digit - * string. - */ - if ( c && strchr(string_of_decimal_marks,c) ){ - int zeros = 0; /* Length of current string of zeros */ - - for ( p++; (c = *p) && isdigit(c); p++ ){ - if ( c == '0'){ - zeros++; - } else { - number_of_digits_after_decimal += 1 + zeros; - zeros = 0; + /* Ignore trailing 0's after the decimal point. The original code here + * (ifdef'd out) does not do this, and numbers like + * 4.29496729600000000000e+09 (2**31) + * come out inexact for some reason related to length of the digit + * string. + */ + if ( c && strchr(string_of_decimal_marks,c) ){ + int zeros = 0; /* Length of current string of zeros */ + + for ( p++; (c = *p) && isdigit(c); p++ ){ + if ( c == '0'){ + zeros++; + } else { + number_of_digits_after_decimal += 1 + zeros; + zeros = 0; + } } } - } #else - if (c && strchr (string_of_decimal_marks, c)) - { - for (p ++; - ((c = * p) != '\0') - && (!c || ! strchr (string_of_decimal_exponent_marks, c) ); - p ++) - { - if (isdigit(c)) - { - number_of_digits_after_decimal ++; /* This may be retracted below. */ - if (/* seen_significant_digit || */ c > '0') - { - seen_significant_digit = TRUE; - } - } - else - { - if ( ! seen_significant_digit) - { - number_of_digits_after_decimal = 0; - } - break; - } - } /* For each digit after decimal mark. */ - } - while(number_of_digits_after_decimal && first_digit[number_of_digits_before_decimal+number_of_digits_after_decimal]=='0') - --number_of_digits_after_decimal; -/* last_digit = p; JF unused */ + if (c && strchr (string_of_decimal_marks, c)) + { + for (p ++; + ((c = * p) != '\0') + && (!c || ! strchr (string_of_decimal_exponent_marks, c) ); + p ++) + { + if (isdigit(c)) + { + number_of_digits_after_decimal ++; /* This may be retracted below. */ + if (/* seen_significant_digit || */ c > '0') + { + seen_significant_digit = TRUE; + } + } + else + { + if ( ! seen_significant_digit) + { + number_of_digits_after_decimal = 0; + } + break; + } + } /* For each digit after decimal mark. */ + } + while(number_of_digits_after_decimal && first_digit[number_of_digits_before_decimal+number_of_digits_after_decimal]=='0') + --number_of_digits_after_decimal; + /* last_digit = p; JF unused */ #endif - - if (c && strchr (string_of_decimal_exponent_marks, c) ) - { - char digits_exponent_sign_char; - - c = * ++ p; - if (c && strchr ("+-",c)) - { - digits_exponent_sign_char = c; - c = * ++ p; - } - else - { - digits_exponent_sign_char = '+'; - } - for (; - (c); - c = * ++ p) - { - if (isdigit(c)) - { - decimal_exponent = decimal_exponent * 10 + c - '0'; - /* - * BUG! If we overflow here, we lose! - */ - } - else - { - break; - } - } - if (digits_exponent_sign_char == '-') - { - decimal_exponent = - decimal_exponent; - } - } - * address_of_string_pointer = p; - } - - number_of_digits_available = - number_of_digits_before_decimal - + number_of_digits_after_decimal; - return_value = 0; - if (number_of_digits_available == 0) - { - address_of_generic_floating_point_number -> exponent = 0; /* Not strictly necessary */ - address_of_generic_floating_point_number -> leader - = -1 + address_of_generic_floating_point_number -> low; - address_of_generic_floating_point_number -> sign = digits_sign_char; - /* We have just concocted (+/-)0.0E0 */ - } - else - { - LITTLENUM_TYPE * digits_binary_low; - int precision; - int maximum_useful_digits; - int number_of_digits_to_use; - int more_than_enough_bits_for_digits; - int more_than_enough_littlenums_for_digits; - int size_of_digits_in_littlenums; - int size_of_digits_in_chars; - FLONUM_TYPE power_of_10_flonum; - FLONUM_TYPE digits_flonum; - - - precision = (address_of_generic_floating_point_number -> high - - address_of_generic_floating_point_number -> low - + 1 - ); /* Number of destination littlenums. */ - /* Includes guard bits (two littlenums worth) */ - maximum_useful_digits = ( ((double) (precision - 2)) - * ((double) (LITTLENUM_NUMBER_OF_BITS)) - / (LOG_TO_BASE_2_OF_10) - ) - + 2; /* 2 :: guard digits. */ - if (number_of_digits_available > maximum_useful_digits) - { - number_of_digits_to_use = maximum_useful_digits; - } - else - { - number_of_digits_to_use = number_of_digits_available; + + if (c && strchr (string_of_decimal_exponent_marks, c) ) + { + char digits_exponent_sign_char; + + c = * ++ p; + if (c && strchr ("+-",c)) + { + digits_exponent_sign_char = c; + c = * ++ p; + } + else + { + digits_exponent_sign_char = '+'; + } + for (; + (c); + c = * ++ p) + { + if (isdigit(c)) + { + decimal_exponent = decimal_exponent * 10 + c - '0'; + /* + * BUG! If we overflow here, we lose! + */ + } + else + { + break; + } + } + if (digits_exponent_sign_char == '-') + { + decimal_exponent = - decimal_exponent; + } + } + * address_of_string_pointer = p; } - decimal_exponent += number_of_digits_before_decimal - number_of_digits_to_use; - - more_than_enough_bits_for_digits - = ((((double)number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1); - more_than_enough_littlenums_for_digits - = ( more_than_enough_bits_for_digits - / LITTLENUM_NUMBER_OF_BITS - ) - + 2; - - /* - * Compute (digits) part. In "12.34E56" this is the "1234" part. - * Arithmetic is exact here. If no digits are supplied then - * this part is a 0 valued binary integer. - * Allocate room to build up the binary number as littlenums. - * We want this memory to disappear when we leave this function. - * Assume no alignment problems => (room for n objects) == - * n * (room for 1 object). - */ - - size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits; - size_of_digits_in_chars = size_of_digits_in_littlenums - * sizeof( LITTLENUM_TYPE ); - digits_binary_low = (LITTLENUM_TYPE *) - alloca (size_of_digits_in_chars); - bzero ((char *)digits_binary_low, size_of_digits_in_chars); - - /* Digits_binary_low[] is allocated and zeroed. */ - - { - /* - * Parse the decimal digits as if * digits_low was in the units position. - * Emit a binary number into digits_binary_low[]. - * - * Use a large-precision version of: - * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit - */ - - char * p; - char c; - int count; /* Number of useful digits left to scan. */ - - for (p = first_digit, count = number_of_digits_to_use; - count; - p ++, -- count) - { - c = * p; - if (isdigit(c)) - { - /* - * Multiply by 10. Assume can never overflow. - * Add this digit to digits_binary_low[]. - */ - - long carry; - LITTLENUM_TYPE * littlenum_pointer; - LITTLENUM_TYPE * littlenum_limit; - - littlenum_limit - = digits_binary_low - + more_than_enough_littlenums_for_digits - - 1; - carry = c - '0'; /* char -> binary */ - for (littlenum_pointer = digits_binary_low; - littlenum_pointer <= littlenum_limit; - littlenum_pointer ++) - { - long work; + + number_of_digits_available = + number_of_digits_before_decimal + + number_of_digits_after_decimal; + return_value = 0; + if (number_of_digits_available == 0) + { + address_of_generic_floating_point_number -> exponent = 0; /* Not strictly necessary */ + address_of_generic_floating_point_number -> leader + = -1 + address_of_generic_floating_point_number -> low; + address_of_generic_floating_point_number -> sign = digits_sign_char; + /* We have just concocted (+/-)0.0E0 */ + } + else + { + LITTLENUM_TYPE * digits_binary_low; + int precision; + int maximum_useful_digits; + int number_of_digits_to_use; + int more_than_enough_bits_for_digits; + int more_than_enough_littlenums_for_digits; + int size_of_digits_in_littlenums; + int size_of_digits_in_chars; + FLONUM_TYPE power_of_10_flonum; + FLONUM_TYPE digits_flonum; + + + precision = (address_of_generic_floating_point_number -> high + - address_of_generic_floating_point_number -> low + + 1 + ); /* Number of destination littlenums. */ + /* Includes guard bits (two littlenums worth) */ + maximum_useful_digits = ( ((double) (precision - 2)) + * ((double) (LITTLENUM_NUMBER_OF_BITS)) + / (LOG_TO_BASE_2_OF_10) + ) + + 2; /* 2 :: guard digits. */ + if (number_of_digits_available > maximum_useful_digits) + { + number_of_digits_to_use = maximum_useful_digits; + } + else + { + number_of_digits_to_use = number_of_digits_available; + } + decimal_exponent += number_of_digits_before_decimal - number_of_digits_to_use; + + more_than_enough_bits_for_digits + = ((((double)number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1); + more_than_enough_littlenums_for_digits + = ( more_than_enough_bits_for_digits + / LITTLENUM_NUMBER_OF_BITS + ) + + 2; - work = carry + 10 * (long)(*littlenum_pointer); - * littlenum_pointer = work & LITTLENUM_MASK; - carry = work >> LITTLENUM_NUMBER_OF_BITS; - } - if (carry != 0) - { /* - * We have a GROSS internal error. - * This should never happen. + * Compute (digits) part. In "12.34E56" this is the "1234" part. + * Arithmetic is exact here. If no digits are supplied then + * this part is a 0 valued binary integer. + * Allocate room to build up the binary number as littlenums. + * We want this memory to disappear when we leave this function. + * Assume no alignment problems => (room for n objects) == + * n * (room for 1 object). */ - abort(); /* RMS prefers abort() to any message. */ - } - } - else - { - ++ count; /* '.' doesn't alter digits used count. */ - } /* if valid digit */ - } /* for each digit */ - } - - /* - * Digits_binary_low[] properly encodes the value of the digits. - * Forget about any high-order littlenums that are 0. - */ - while (digits_binary_low [size_of_digits_in_littlenums - 1] == 0 - && size_of_digits_in_littlenums >= 2) - size_of_digits_in_littlenums --; - - digits_flonum . low = digits_binary_low; - digits_flonum . high = digits_binary_low + size_of_digits_in_littlenums - 1; - digits_flonum . leader = digits_flonum . high; - digits_flonum . exponent = 0; - /* - * The value of digits_flonum . sign should not be important. - * We have already decided the output's sign. - * We trust that the sign won't influence the other parts of the number! - * So we give it a value for these reasons: - * (1) courtesy to humans reading/debugging - * these numbers so they don't get excited about strange values - * (2) in future there may be more meaning attached to sign, - * and what was - * harmless noise may become disruptive, ill-conditioned (or worse) - * input. - */ - digits_flonum . sign = '+'; - - { - /* - * Compute the mantssa (& exponent) of the power of 10. - * If sucessful, then multiply the power of 10 by the digits - * giving return_binary_mantissa and return_binary_exponent. - */ - - LITTLENUM_TYPE *power_binary_low; - int decimal_exponent_is_negative; - /* This refers to the "-56" in "12.34E-56". */ - /* FALSE: decimal_exponent is positive (or 0) */ - /* TRUE: decimal_exponent is negative */ - FLONUM_TYPE temporary_flonum; - LITTLENUM_TYPE *temporary_binary_low; - int size_of_power_in_littlenums; - int size_of_power_in_chars; - - size_of_power_in_littlenums = precision; -/* Precision has a built-in fudge factor so we get a few guard bits. */ - - - decimal_exponent_is_negative = decimal_exponent < 0; - if (decimal_exponent_is_negative) - { - decimal_exponent = - decimal_exponent; - } - /* From now on: the decimal exponent is > 0. Its sign is seperate. */ - - size_of_power_in_chars - = size_of_power_in_littlenums - * sizeof( LITTLENUM_TYPE ) + 2; - power_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars ); - temporary_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars ); - bzero ((char *)power_binary_low, size_of_power_in_chars); - * power_binary_low = 1; - power_of_10_flonum . exponent = 0; - power_of_10_flonum . low = power_binary_low; - power_of_10_flonum . leader = power_binary_low; - power_of_10_flonum . high = power_binary_low + size_of_power_in_littlenums - 1; - power_of_10_flonum . sign = '+'; - temporary_flonum . low = temporary_binary_low; - temporary_flonum . high = temporary_binary_low + size_of_power_in_littlenums - 1; - /* - * (power) == 1. - * Space for temporary_flonum allocated. - */ - - /* - * ... - * - * WHILE more bits - * DO find next bit (with place value) - * multiply into power mantissa - * OD - */ - { - int place_number_limit; - /* Any 10^(2^n) whose "n" exceeds this */ - /* value will fall off the end of */ - /* flonum_XXXX_powers_of_ten[]. */ - int place_number; - const FLONUM_TYPE * multiplicand; /* -> 10^(2^n) */ - - place_number_limit = table_size_of_flonum_powers_of_ten; - multiplicand - = ( decimal_exponent_is_negative - ? flonum_negative_powers_of_ten - : flonum_positive_powers_of_ten); - for (place_number = 1; /* Place value of this bit of exponent. */ - decimal_exponent; /* Quit when no more 1 bits in exponent. */ - decimal_exponent >>= 1 - , place_number ++) - { - if (decimal_exponent & 1) - { - if (place_number > place_number_limit) + + size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits; + size_of_digits_in_chars = size_of_digits_in_littlenums + * sizeof( LITTLENUM_TYPE ); + digits_binary_low = (LITTLENUM_TYPE *) + alloca (size_of_digits_in_chars); + bzero ((char *)digits_binary_low, size_of_digits_in_chars); + + /* Digits_binary_low[] is allocated and zeroed. */ + { - /* - * The decimal exponent has a magnitude so great that - * our tables can't help us fragment it. Although this - * routine is in error because it can't imagine a - * number that big, signal an error as if it is the - * user's fault for presenting such a big number. - */ - return_value = ERROR_EXPONENT_OVERFLOW; - /* - * quit out of loop gracefully - */ - decimal_exponent = 0; + /* + * Parse the decimal digits as if * digits_low was in the units position. + * Emit a binary number into digits_binary_low[]. + * + * Use a large-precision version of: + * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit + */ + + char * p; + char c; + int count; /* Number of useful digits left to scan. */ + + for (p = first_digit, count = number_of_digits_to_use; + count; + p ++, -- count) + { + c = * p; + if (isdigit(c)) + { + /* + * Multiply by 10. Assume can never overflow. + * Add this digit to digits_binary_low[]. + */ + + long carry; + LITTLENUM_TYPE * littlenum_pointer; + LITTLENUM_TYPE * littlenum_limit; + + littlenum_limit + = digits_binary_low + + more_than_enough_littlenums_for_digits + - 1; + carry = c - '0'; /* char -> binary */ + for (littlenum_pointer = digits_binary_low; + littlenum_pointer <= littlenum_limit; + littlenum_pointer ++) + { + long work; + + work = carry + 10 * (long)(*littlenum_pointer); + * littlenum_pointer = work & LITTLENUM_MASK; + carry = work >> LITTLENUM_NUMBER_OF_BITS; + } + if (carry != 0) + { + /* + * We have a GROSS internal error. + * This should never happen. + */ + as_fatal("failed sanity check."); /* RMS prefers abort() to any message. */ + } + } + else + { + ++ count; /* '.' doesn't alter digits used count. */ + } /* if valid digit */ + } /* for each digit */ } - else + + /* + * Digits_binary_low[] properly encodes the value of the digits. + * Forget about any high-order littlenums that are 0. + */ + while (digits_binary_low [size_of_digits_in_littlenums - 1] == 0 + && size_of_digits_in_littlenums >= 2) + size_of_digits_in_littlenums --; + + digits_flonum . low = digits_binary_low; + digits_flonum . high = digits_binary_low + size_of_digits_in_littlenums - 1; + digits_flonum . leader = digits_flonum . high; + digits_flonum . exponent = 0; + /* + * The value of digits_flonum . sign should not be important. + * We have already decided the output's sign. + * We trust that the sign won't influence the other parts of the number! + * So we give it a value for these reasons: + * (1) courtesy to humans reading/debugging + * these numbers so they don't get excited about strange values + * (2) in future there may be more meaning attached to sign, + * and what was + * harmless noise may become disruptive, ill-conditioned (or worse) + * input. + */ + digits_flonum . sign = '+'; + { + /* + * Compute the mantssa (& exponent) of the power of 10. + * If sucessful, then multiply the power of 10 by the digits + * giving return_binary_mantissa and return_binary_exponent. + */ + + LITTLENUM_TYPE *power_binary_low; + int decimal_exponent_is_negative; + /* This refers to the "-56" in "12.34E-56". */ + /* FALSE: decimal_exponent is positive (or 0) */ + /* TRUE: decimal_exponent is negative */ + FLONUM_TYPE temporary_flonum; + LITTLENUM_TYPE *temporary_binary_low; + int size_of_power_in_littlenums; + int size_of_power_in_chars; + + size_of_power_in_littlenums = precision; + /* Precision has a built-in fudge factor so we get a few guard bits. */ + + + decimal_exponent_is_negative = decimal_exponent < 0; + if (decimal_exponent_is_negative) + { + decimal_exponent = - decimal_exponent; + } + /* From now on: the decimal exponent is > 0. Its sign is seperate. */ + + size_of_power_in_chars + = size_of_power_in_littlenums + * sizeof( LITTLENUM_TYPE ) + 2; + power_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars ); + temporary_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars ); + bzero ((char *)power_binary_low, size_of_power_in_chars); + * power_binary_low = 1; + power_of_10_flonum . exponent = 0; + power_of_10_flonum . low = power_binary_low; + power_of_10_flonum . leader = power_binary_low; + power_of_10_flonum . high = power_binary_low + size_of_power_in_littlenums - 1; + power_of_10_flonum . sign = '+'; + temporary_flonum . low = temporary_binary_low; + temporary_flonum . high = temporary_binary_low + size_of_power_in_littlenums - 1; + /* + * (power) == 1. + * Space for temporary_flonum allocated. + */ + + /* + * ... + * + * WHILE more bits + * DO find next bit (with place value) + * multiply into power mantissa + * OD + */ + { + int place_number_limit; + /* Any 10^(2^n) whose "n" exceeds this */ + /* value will fall off the end of */ + /* flonum_XXXX_powers_of_ten[]. */ + int place_number; + const FLONUM_TYPE * multiplicand; /* -> 10^(2^n) */ + + place_number_limit = table_size_of_flonum_powers_of_ten; + multiplicand + = ( decimal_exponent_is_negative + ? flonum_negative_powers_of_ten + : flonum_positive_powers_of_ten); + for (place_number = 1; /* Place value of this bit of exponent. */ + decimal_exponent; /* Quit when no more 1 bits in exponent. */ + decimal_exponent >>= 1 + , place_number ++) + { + if (decimal_exponent & 1) + { + if (place_number > place_number_limit) + { + /* + * The decimal exponent has a magnitude so great that + * our tables can't help us fragment it. Although this + * routine is in error because it can't imagine a + * number that big, signal an error as if it is the + * user's fault for presenting such a big number. + */ + return_value = ERROR_EXPONENT_OVERFLOW; + /* + * quit out of loop gracefully + */ + decimal_exponent = 0; + } + else + { #ifdef TRACE -printf("before multiply, place_number = %d., power_of_10_flonum:\n", place_number); -flonum_print( & power_of_10_flonum ); -(void)putchar('\n'); + printf("before multiply, place_number = %d., power_of_10_flonum:\n", place_number); + flonum_print( & power_of_10_flonum ); + (void)putchar('\n'); #endif - flonum_multip(multiplicand + place_number, &power_of_10_flonum, &temporary_flonum); - flonum_copy (& temporary_flonum, & power_of_10_flonum); - } /* If this bit of decimal_exponent was computable.*/ - } /* If this bit of decimal_exponent was set. */ - } /* For each bit of binary representation of exponent */ + flonum_multip(multiplicand + place_number, &power_of_10_flonum, &temporary_flonum); + flonum_copy (& temporary_flonum, & power_of_10_flonum); + } /* If this bit of decimal_exponent was computable.*/ + } /* If this bit of decimal_exponent was set. */ + } /* For each bit of binary representation of exponent */ #ifdef TRACE -printf( " after computing power_of_10_flonum: " ); -flonum_print( & power_of_10_flonum ); -(void)putchar('\n'); + printf( " after computing power_of_10_flonum: " ); + flonum_print( & power_of_10_flonum ); + (void)putchar('\n'); #endif - } - - } - - /* - * power_of_10_flonum is power of ten in binary (mantissa) , (exponent). - * It may be the number 1, in which case we don't NEED to multiply. - * - * Multiply (decimal digits) by power_of_10_flonum. - */ - - flonum_multip (& power_of_10_flonum, & digits_flonum, address_of_generic_floating_point_number); - /* Assert sign of the number we made is '+'. */ - address_of_generic_floating_point_number -> sign = digits_sign_char; - - } /* If we had any significant digits. */ - return (return_value); -} /* atof_generic () */ + } + + } + + /* + * power_of_10_flonum is power of ten in binary (mantissa) , (exponent). + * It may be the number 1, in which case we don't NEED to multiply. + * + * Multiply (decimal digits) by power_of_10_flonum. + */ + + flonum_multip (& power_of_10_flonum, & digits_flonum, address_of_generic_floating_point_number); + /* Assert sign of the number we made is '+'. */ + address_of_generic_floating_point_number -> sign = digits_sign_char; + + } /* If we had any significant digits. */ + return (return_value); +} /* atof_generic () */ -/* end: atof_generic.c */ +/* end of atof_generic.c */ diff --git a/gas/bignum-copy.c b/gas/bignum-copy.c index 47e5a14..9a00f89 100644 --- a/gas/bignum-copy.c +++ b/gas/bignum-copy.c @@ -1,21 +1,21 @@ /* bignum_copy.c - copy a bignum Copyright (C) 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 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. */ #include "as.h" @@ -37,39 +37,39 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* void */ int -bignum_copy (in, in_length, out, out_length) - register LITTLENUM_TYPE * in; - register int in_length; /* in sizeof(littlenum)s */ - register LITTLENUM_TYPE * out; - register int out_length; /* in sizeof(littlenum)s */ + bignum_copy (in, in_length, out, out_length) +register LITTLENUM_TYPE * in; +register int in_length; /* in sizeof(littlenum)s */ +register LITTLENUM_TYPE * out; +register int out_length; /* in sizeof(littlenum)s */ { - register int significant_littlenums_dropped; - - if (out_length < in_length) - { - register LITTLENUM_TYPE * p; /* -> most significant (non-zero) input littlenum. */ - - bcopy ((char *)in, (char *)out, out_length << LITTLENUM_SHIFT); - for (p = in + in_length - 1; p >= in; -- p) - { - if (* p) break; - } - significant_littlenums_dropped = p - in - in_length + 1; - if (significant_littlenums_dropped < 0) - { - significant_littlenums_dropped = 0; - } - } - else - { - bcopy ((char *)in, (char *)out, in_length << LITTLENUM_SHIFT); - if (out_length > in_length) - { - bzero ((char *)(out + out_length), (out_length - in_length) << LITTLENUM_SHIFT); - } - significant_littlenums_dropped = 0; - } - return (significant_littlenums_dropped); + register int significant_littlenums_dropped; + + if (out_length < in_length) + { + register LITTLENUM_TYPE * p; /* -> most significant (non-zero) input littlenum. */ + + bcopy ((char *)in, (char *)out, out_length << LITTLENUM_SHIFT); + for (p = in + in_length - 1; p >= in; -- p) + { + if (* p) break; + } + significant_littlenums_dropped = p - in - in_length + 1; + if (significant_littlenums_dropped < 0) + { + significant_littlenums_dropped = 0; + } + } + else + { + bcopy ((char *)in, (char *)out, in_length << LITTLENUM_SHIFT); + if (out_length > in_length) + { + bzero ((char *)(out + out_length), (out_length - in_length) << LITTLENUM_SHIFT); + } + significant_littlenums_dropped = 0; + } + return (significant_littlenums_dropped); } -/* end: bignum_copy.c */ +/* end of bignum-copy.c */ diff --git a/gas/bignum.h b/gas/bignum.h index 9b1b8e8..130fee3 100644 --- a/gas/bignum.h +++ b/gas/bignum.h @@ -1,33 +1,33 @@ /* bignum.h-arbitrary precision integers Copyright (C) 1987 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. */ + + 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. */ /***********************************************************************\ -* * -* Arbitrary-precision integer arithmetic. * -* For speed, we work in groups of bits, even though this * -* complicates algorithms. * -* Each group of bits is called a 'littlenum'. * -* A bunch of littlenums representing a (possibly large) * -* integer is called a 'bignum'. * -* Bignums are >= 0. * -* * -\***********************************************************************/ + * * + * Arbitrary-precision integer arithmetic. * + * For speed, we work in groups of bits, even though this * + * complicates algorithms. * + * Each group of bits is called a 'littlenum'. * + * A bunch of littlenums representing a (possibly large) * + * integer is called a 'bignum'. * + * Bignums are >= 0. * + * * + \***********************************************************************/ #define LITTLENUM_NUMBER_OF_BITS (16) #define LITTLENUM_RADIX (1 << LITTLENUM_NUMBER_OF_BITS) @@ -42,6 +42,6 @@ typedef unsigned short LITTLENUM_TYPE; /* JF truncated this to get around a problem with GCC */ #define LOG_TO_BASE_2_OF_10 (3.3219280948873623478703194294893901758651 ) - /* WARNING: I haven't checked that the trailing digits are correct! */ +/* WARNING: I haven't checked that the trailing digits are correct! */ -/* end: bignum.h */ +/* end of bignum.h */ @@ -1,128 +1,235 @@ /* cond.c - conditional assembly pseudo-ops, and .include Copyright (C) 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 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. +#include "as.h" -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. +#include "obstack.h" -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. +/* This is allocated to grow and shrink as .ifdef/.endif pairs are scanned. */ +struct obstack cond_obstack; -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. */ +struct file_line { + char *logical_file; + int logical_line; + char *physical_file; + int physical_line; +}; /* file_line */ -/* static const char rcsid[] = "$Id$"; */ +/* This is what we push and pop. */ +struct conditional_frame { + struct file_line if_file_line; /* the source file & line number of the "if" */ + struct file_line else_file_line; /* the source file & line of the "else" */ + struct conditional_frame *previous_cframe; + int else_seen; /* have we seen an else yet? */ + int ignoring; /* if we are currently ignoring input. */ + int dead_tree; /* if a conditional at a higher level is ignoring input. */ +}; /* conditional_frame */ -#include "as.h" +#ifdef __STDC__ -#include "obstack.h" +static void get_file_line(struct file_line *into); +static void initialize_cframe(struct conditional_frame *cframe); +static void set_file_line(struct file_line *from); + +#else + +static void get_file_line(); +static void initialize_cframe(); +static void set_file_line(); + +#endif + +static struct conditional_frame *current_cframe = NULL; void s_ifdef(arg) int arg; { -/* register char c; */ - register char *name; /* points to name of symbol */ - register struct symbol * symbolP; /* Points to symbol */ + register char *name; /* points to name of symbol */ + register struct symbol *symbolP; /* Points to symbol */ + struct conditional_frame cframe; SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ name = input_line_pointer; + if (!is_name_beginner(*name)) { - as_bad("invalid identifier for .ifdef"); - obstack_1grow (&cond_obstack, 0); + as_bad("invalid identifier for \".ifdef\""); + obstack_1grow(&cond_obstack, 0); } else { get_symbol_end(); ++input_line_pointer; symbolP = symbol_find(name); - /* ??? Should we try to optimize such that if we hit a .endif - before a .else, we don't need to push state? */ - obstack_1grow(&cond_obstack, (symbolP != 0) ^ arg); - } + initialize_cframe(&cframe); + cframe.ignoring = cframe.dead_tree && !((symbolP != 0) ^ arg); + current_cframe = (struct conditional_frame *) obstack_copy(&cond_obstack, &cframe, sizeof(cframe)); + } /* if a valid identifyer name */ + + return; } /* s_ifdef() */ -/* This is allocated to grow and shrink as .ifdef/.endif pairs - are scanned. When the top element is nonzero, it means - we should accept input. Otherwise, we should ignore input. */ -struct obstack cond_obstack; - void s_if(arg) int arg; { expressionS operand; + struct conditional_frame cframe; - SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ + SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ expr(0, &operand); if (operand.X_add_symbol != NULL - || operand.X_subtract_symbol != NULL) - as_bad("non-constant expression in .if statement"); + || operand.X_subtract_symbol != NULL) { + as_bad("non-constant expression in \".if\" statement"); + } /* bad condition */ /* If the above error is signaled, this will dispatch using an undefined result. No big deal. */ - obstack_1grow(&cond_obstack, (operand.X_add_number != 0) ^ arg); + initialize_cframe(&cframe); + cframe.ignoring = cframe.dead_tree || !((operand.X_add_number != 0) ^ arg); + current_cframe = (struct conditional_frame *) obstack_copy(&cond_obstack, &cframe, sizeof(cframe)); + return; } /* s_if() */ void s_endif(arg) int arg; { - char *base = obstack_base(&cond_obstack); - char *ptr = obstack_next_free(&cond_obstack); + struct conditional_frame *hold; - if (ptr-1 == base) { - as_bad("unbalanced .endif"); + if (current_cframe == NULL) { + as_bad("\".endif\" without \".if\""); } else { - obstack_free(&cond_obstack, ptr-1); - cond_obstack.object_base = base; - } + hold = current_cframe; + current_cframe = current_cframe->previous_cframe; + obstack_free(&cond_obstack, hold); + } /* if one pop too many */ + + return; } /* s_endif() */ void s_else(arg) int arg; { - char *ptr = obstack_next_free(&cond_obstack); - if (ptr-1 == obstack_base(&cond_obstack)) { - as_bad(".else without matching .if"); + if (current_cframe == NULL) { + as_bad(".else without matching .if - ignored"); + + } else if (current_cframe->else_seen) { + struct file_line hold; + as_bad("duplicate \"else\" - ignored"); + + get_file_line(&hold); + set_file_line(¤t_cframe->else_file_line); + as_bad("here is the previous \"else\"."); + set_file_line(¤t_cframe->if_file_line); + as_bad("here is the matching \".if\"."); + set_file_line(&hold); + } else { - ptr[-1] = !ptr[-1]; - } + get_file_line(¤t_cframe->else_file_line); + + if (!current_cframe->dead_tree) { + current_cframe->ignoring = !current_cframe->ignoring; + } /* if not a dead tree */ + + current_cframe->else_seen = 1; + } /* if error else do it */ + + return; } /* s_else() */ void s_ifeqs(arg) int arg; { as_bad("ifeqs not implemented."); + + return; } /* s_ifeqs() */ void s_end(arg) int arg; { - ; + return; } /* s_end() */ int ignore_input() { - char *ptr = obstack_next_free (&cond_obstack); - - /* We cannot ignore certain pseudo ops. */ - if (input_line_pointer[-1] == '.') - { - if (input_line_pointer[0] == 'i' - && (!strncmp (input_line_pointer, "if", 2) - || !strncmp (input_line_pointer, "ifdef", 5) - || !strncmp (input_line_pointer, "ifndef", 6))) - return 0; - if (input_line_pointer[0] == 'e' - && (!strncmp (input_line_pointer, "else", 4) - || !strncmp (input_line_pointer, "endif", 5))) - return 0; - } - - return (ptr[-1] == 0); + char *ptr = obstack_next_free (&cond_obstack); + + /* We cannot ignore certain pseudo ops. */ + if (input_line_pointer[-1] == '.' + && ((input_line_pointer[0] == 'i' + && (!strncmp (input_line_pointer, "if", 2) + || !strncmp (input_line_pointer, "ifdef", 5) + || !strncmp (input_line_pointer, "ifndef", 6))) + || (input_line_pointer[0] == 'e' + && (!strncmp (input_line_pointer, "else", 4) + || !strncmp (input_line_pointer, "endif", 5))))) { + return 0; + } + + return((current_cframe != NULL) && (current_cframe->ignoring)); } /* ignore_input() */ +static void initialize_cframe(cframe) +struct conditional_frame *cframe; +{ + memset(cframe, 0, sizeof(*cframe)); + get_file_line(&(cframe->if_file_line)); + cframe->previous_cframe = current_cframe; + cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring; + + return; +} /* initialize_cframe() */ + +static void get_file_line(into) +struct file_line *into; +{ + extern char *logical_input_file; + extern char *physical_input_file; + extern int logical_input_line; + extern int physical_input_line; + + into->logical_file = logical_input_file; + into->logical_line = logical_input_line; + into->physical_file = physical_input_file; + into->physical_line = physical_input_line; + + return; +} /* get_file_line() */ + +static void set_file_line(from) +struct file_line *from; +{ + extern char *logical_input_file; + extern char *physical_input_file; + extern int logical_input_line; + extern int physical_input_line; + + logical_input_file = from->logical_file; + logical_input_line = from->logical_line; + physical_input_file = from->physical_file; + physical_input_line = from->physical_line; + return; +} /* set_file_line() */ + +/* + * Local Variables: + * fill-column: 131 + * comment-column: 0 + * End: + */ + /* end of cond.c */ diff --git a/gas/config/a.out.h b/gas/config/a.out.h index 5872241..ed39299 100755 --- a/gas/config/a.out.h +++ b/gas/config/a.out.h @@ -1,23 +1,21 @@ /* This file describes the a.out file format Copyright (C) 1987 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. */ - -/* $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. */ #ifdef USE_HP_INC_HDR #include "../binutils/hp-include/a.out.h" @@ -34,23 +32,23 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ struct exec { - unsigned short a_machtype; /* machine type */ - unsigned short a_magic; /* magic number */ - unsigned long a_spare1; - unsigned long a_spare2; - unsigned long a_text; /* length of text, in bytes */ - unsigned long a_data; /* length of data, in bytes */ - unsigned long a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned long a_trsize; /* length of relocation info for text, in bytes */ - unsigned long a_drsize; /* length of relocation info for data, in bytes */ - unsigned long a_spare3; /* HP = pascal interface size */ - unsigned long a_spare4; /* HP = symbol table size */ - unsigned long a_spare5; /* HP = debug name table size */ - unsigned long a_entry; /* start address */ - unsigned long a_spare6; /* HP = source line table size */ - unsigned long a_spare7; /* HP = value table size */ - unsigned long a_syms; /* length of symbol table data in file, in bytes */ - unsigned long a_spare8; + unsigned short a_machtype; /* machine type */ + unsigned short a_magic; /* magic number */ + unsigned long a_spare1; + unsigned long a_spare2; + unsigned long a_text; /* length of text, in bytes */ + unsigned long a_data; /* length of data, in bytes */ + unsigned long a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned long a_trsize; /* length of relocation info for text, in bytes */ + unsigned long a_drsize; /* length of relocation info for data, in bytes */ + unsigned long a_spare3; /* HP = pascal interface size */ + unsigned long a_spare4; /* HP = symbol table size */ + unsigned long a_spare5; /* HP = debug name table size */ + unsigned long a_entry; /* start address */ + unsigned long a_spare6; /* HP = source line table size */ + unsigned long a_spare7; /* HP = value table size */ + unsigned long a_syms; /* length of symbol table data in file, in bytes */ + unsigned long a_spare8; }; #define N_MAGIC(exec) ((exec) . a_magic) @@ -60,54 +58,54 @@ struct exec #define N_BADMAG(x) ((_N_BADMAG (x)) || (_N_BADMACH (x))) -#define _N_BADMACH(x) \ -(((N_MACHTYPE (x)) != HP9000S200_ID) && \ - ((N_MACHTYPE (x)) != HP98x6_ID)) +#define _N_BADMACH(x) \ + (((N_MACHTYPE (x)) != HP9000S200_ID) \ + && ((N_MACHTYPE (x)) != HP98x6_ID)) #define _N_BADMAG(x) \ - (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) + (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) #define HP98x6_ID 0x20A #define HP9000S200_ID 0x20C #else - /* A Generic machine. . . */ +/* A Generic machine. . . */ /* JF I'm not sure where this file came from. I put the permit.text message in it anyway. This file came to me as part of the original VAX assembler, but had no copyright notices in it. */ struct exec { - long a_magic; /* number identifies as .o file and gives type of such. */ - unsigned a_text; /* length of text, in bytes */ - unsigned a_data; /* length of data, in bytes */ + long a_magic; /* number identifies as .o file and gives type of such. */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ unsigned a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned a_syms; /* length of symbol table data in file, in bytes */ - unsigned a_entry; /* start address */ - unsigned a_trsize; /* length of relocation info for text, in bytes */ - unsigned a_drsize; /* length of relocation info for data, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ }; #define N_BADMAG(x) \ - (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) + (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) #endif - /* From here down is common to both the HP and the generic machine */ +/* From here down is common to both the HP and the generic machine */ #define OMAGIC 0407 #define NMAGIC 0410 #define ZMAGIC 0413 #define N_TXTOFF(x) \ - ((x).a_magic == ZMAGIC ? 1024 : sizeof(struct exec)) + ((x).a_magic == ZMAGIC ? 1024 : sizeof(struct exec)) #define N_SYMOFF(x) \ - (N_TXTOFF(x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize) + (N_TXTOFF(x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize) #define N_STROFF(x) \ - (N_SYMOFF(x) + (x).a_syms) + (N_SYMOFF(x) + (x).a_syms) struct nlist { union { @@ -127,8 +125,8 @@ struct nlist { #define N_DATA 6 #define N_BSS 8 #define N_FN 31 /* JF: Someone claims this should be 31 instead of - 15. I just inherited this file; I didn't write - it. Who is right? */ + 15. I just inherited this file; I didn't write + it. Who is right? */ #define N_EXT 1 @@ -136,15 +134,17 @@ struct nlist { #define N_STAB 0340 struct relocation_info { - int r_address; - unsigned r_symbolnum:24, - r_pcrel:1, - r_length:2, - r_extern:1, - r_bsr:1, /* OVE: used on ns32k based systems, if you want */ - r_disp:1, /* OVE: used on ns32k based systems, if you want */ - nuthin:2; + int r_address; + unsigned r_symbolnum:24; + unsigned r_pcrel:1; + unsigned r_length:2; + unsigned r_extern:1; + unsigned r_bsr:1; /* OVE: used on ns32k based systems, if you want */ + unsigned r_disp:1; /* OVE: used on ns32k based systems, if you want */ + unsigned nuthin:2; }; #endif #endif + +/* end of a.out.h */ diff --git a/gas/config/atof-ieee.c b/gas/config/atof-ieee.c index 323d4e1..d9bf68b 100644 --- a/gas/config/atof-ieee.c +++ b/gas/config/atof-ieee.c @@ -1,21 +1,21 @@ /* atof_ieee.c - turn a Flonum into an IEEE floating point number Copyright (C) 1987 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. */ + + 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. */ #include "as.h" @@ -31,51 +31,51 @@ extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */ #endif extern char EXP_CHARS[]; - /* Precision in LittleNums. */ +/* Precision in LittleNums. */ #define MAX_PRECISION (6) #define F_PRECISION (2) #define D_PRECISION (4) #define X_PRECISION (6) #define P_PRECISION (6) - /* Length in LittleNums of guard bits. */ +/* Length in LittleNums of guard bits. */ #define GUARD (2) static unsigned long mask [] = { - 0x00000000, - 0x00000001, - 0x00000003, - 0x00000007, - 0x0000000f, - 0x0000001f, - 0x0000003f, - 0x0000007f, - 0x000000ff, - 0x000001ff, - 0x000003ff, - 0x000007ff, - 0x00000fff, - 0x00001fff, - 0x00003fff, - 0x00007fff, - 0x0000ffff, - 0x0001ffff, - 0x0003ffff, - 0x0007ffff, - 0x000fffff, - 0x001fffff, - 0x003fffff, - 0x007fffff, - 0x00ffffff, - 0x01ffffff, - 0x03ffffff, - 0x07ffffff, - 0x0fffffff, - 0x1fffffff, - 0x3fffffff, - 0x7fffffff, - 0xffffffff - }; + 0x00000000, + 0x00000001, + 0x00000003, + 0x00000007, + 0x0000000f, + 0x0000001f, + 0x0000003f, + 0x0000007f, + 0x000000ff, + 0x000001ff, + 0x000003ff, + 0x000007ff, + 0x00000fff, + 0x00001fff, + 0x00003fff, + 0x00007fff, + 0x0000ffff, + 0x0001ffff, + 0x0003ffff, + 0x0007ffff, + 0x000fffff, + 0x001fffff, + 0x003fffff, + 0x007fffff, + 0x00ffffff, + 0x01ffffff, + 0x03ffffff, + 0x07ffffff, + 0x0fffffff, + 0x1fffffff, + 0x3fffffff, + 0x7fffffff, + 0xffffffff + }; static int bits_left_in_littlenum; @@ -83,35 +83,35 @@ static int littlenums_left; static LITTLENUM_TYPE *littlenum_pointer; static int -next_bits (number_of_bits) - int number_of_bits; + next_bits (number_of_bits) +int number_of_bits; { - int return_value; - - if(!littlenums_left) - return 0; - if (number_of_bits >= bits_left_in_littlenum) - { - return_value = mask [bits_left_in_littlenum] & *littlenum_pointer; - number_of_bits -= bits_left_in_littlenum; - return_value <<= number_of_bits; - if(--littlenums_left) { - bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; - littlenum_pointer --; - return_value |= (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits]; - } - } - else - { - bits_left_in_littlenum -= number_of_bits; - return_value = mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum); - } - return (return_value); + int return_value; + + if(!littlenums_left) + return 0; + if (number_of_bits >= bits_left_in_littlenum) + { + return_value = mask [bits_left_in_littlenum] & *littlenum_pointer; + number_of_bits -= bits_left_in_littlenum; + return_value <<= number_of_bits; + if(--littlenums_left) { + bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; + littlenum_pointer --; + return_value |= (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits]; + } + } + else + { + bits_left_in_littlenum -= number_of_bits; + return_value = mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum); + } + return (return_value); } /* Num had better be less than LITTLENUM_NUMBER_OF_BITS */ static void -unget_bits(num) + unget_bits(num) int num; { if(!littlenums_left) { @@ -123,12 +123,12 @@ int num; ++littlenum_pointer; ++littlenums_left; } else - bits_left_in_littlenum+=num; + bits_left_in_littlenum+=num; } static void -make_invalid_floating_point_number (words) - LITTLENUM_TYPE * words; + make_invalid_floating_point_number (words) +LITTLENUM_TYPE * words; { as_bad("cannot create floating-point number"); words[0]= ((unsigned)-1)>>1; /* Zero the leftmost bit */ @@ -140,43 +140,51 @@ make_invalid_floating_point_number (words) } /***********************************************************************\ -* Warning: this returns 16-bit LITTLENUMs. It is up to the caller * -* to figure out any alignment problems and to conspire for the * -* bytes/word to be emitted in the right order. Bigendians beware! * -* * -\***********************************************************************/ + * Warning: this returns 16-bit LITTLENUMs. It is up to the caller * + * to figure out any alignment problems and to conspire for the * + * bytes/word to be emitted in the right order. Bigendians beware! * + * * + \***********************************************************************/ /* Note that atof-ieee always has X and P precisions enabled. it is up to md_atof to filter them out if the target machine does not support them. */ char * /* Return pointer past text consumed. */ -atof_ieee (str, what_kind, words) - char * str; /* Text to convert to binary. */ - char what_kind; /* 'd', 'f', 'g', 'h' */ - LITTLENUM_TYPE * words; /* Build the binary here. */ + atof_ieee (str, what_kind, words) +char * str; /* Text to convert to binary. */ +char what_kind; /* 'd', 'f', 'g', 'h' */ +LITTLENUM_TYPE * words; /* Build the binary here. */ { static LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD]; - /* Extra bits for zeroed low-order bits. */ - /* The 1st MAX_PRECISION are zeroed, */ - /* the last contain flonum bits. */ + /* Extra bits for zeroed low-order bits. */ + /* The 1st MAX_PRECISION are zeroed, */ + /* the last contain flonum bits. */ char * return_value; int precision; /* Number of 16-bit words in the format. */ long exponent_bits; - + FLONUM_TYPE save_gen_flonum; + + /* We have to save the generic_floating_point_number because it + contains storage allocation about the array of LITTLENUMs + where the value is actually stored. We will allocate our + own array of littlenums below, but have to restore the global + one on exit. */ + save_gen_flonum = generic_floating_point_number; + return_value = str; generic_floating_point_number.low = bits + MAX_PRECISION; generic_floating_point_number.high = NULL; generic_floating_point_number.leader = NULL; generic_floating_point_number.exponent = NULL; generic_floating_point_number.sign = '\0'; - - /* Use more LittleNums than seems */ - /* necessary: the highest flonum may have */ - /* 15 leading 0 bits, so could be useless. */ - + + /* Use more LittleNums than seems */ + /* necessary: the highest flonum may have */ + /* 15 leading 0 bits, so could be useless. */ + bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION); - + switch(what_kind) { case 'f': case 'F': @@ -185,7 +193,7 @@ atof_ieee (str, what_kind, words) precision = F_PRECISION; exponent_bits = 8; break; - + case 'd': case 'D': case 'r': @@ -193,7 +201,7 @@ atof_ieee (str, what_kind, words) precision = D_PRECISION; exponent_bits = 11; break; - + case 'x': case 'X': case 'e': @@ -201,27 +209,32 @@ atof_ieee (str, what_kind, words) precision = X_PRECISION; exponent_bits = 15; break; - + case 'p': case 'P': precision = P_PRECISION; exponent_bits= -1; break; - + default: make_invalid_floating_point_number (words); return NULL; } - + generic_floating_point_number.high = generic_floating_point_number.low + precision - 1 + GUARD; - + if (atof_generic (& return_value, ".", EXP_CHARS, & generic_floating_point_number)) { /* as_bad("Error converting floating point number (Exponent overflow?)"); */ make_invalid_floating_point_number (words); return NULL; } gen_to_words(words, precision, exponent_bits); + + /* Restore the generic_floating_point_number's storage alloc + (and everything else). */ + generic_floating_point_number = save_gen_flonum; + return return_value; } @@ -232,7 +245,7 @@ int precision; long exponent_bits; { int return_value=0; - + long exponent_1; long exponent_2; long exponent_3; @@ -240,17 +253,17 @@ long exponent_bits; int exponent_skippage; LITTLENUM_TYPE word1; LITTLENUM_TYPE * lp; - + if (generic_floating_point_number.low > generic_floating_point_number.leader) { /* 0.0e0 seen. */ if(generic_floating_point_number.sign=='+') - words[0]=0x0000; + words[0]=0x0000; else - words[0]=0x8000; + words[0]=0x8000; bzero (&words[1], sizeof(LITTLENUM_TYPE) * (precision-1)); return return_value; } - + /* NaN: Do the right thing */ if(generic_floating_point_number.sign==0) { if(precision==F_PRECISION) { @@ -288,24 +301,24 @@ long exponent_bits; } return return_value; } - /* - * The floating point formats we support have: - * Bit 15 is sign bit. - * Bits 14:n are excess-whatever exponent. - * Bits n-1:0 (if any) are most significant bits of fraction. - * Bits 15:0 of the next word(s) are the next most significant bits. - * - * So we need: number of bits of exponent, number of bits of - * mantissa. - */ + /* + * The floating point formats we support have: + * Bit 15 is sign bit. + * Bits 14:n are excess-whatever exponent. + * Bits n-1:0 (if any) are most significant bits of fraction. + * Bits 15:0 of the next word(s) are the next most significant bits. + * + * So we need: number of bits of exponent, number of bits of + * mantissa. + */ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; littlenum_pointer = generic_floating_point_number.leader; littlenums_left = 1+generic_floating_point_number.leader - generic_floating_point_number.low; /* Seek (and forget) 1st significant bit */ for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) - ; + ; exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 - - generic_floating_point_number.low; + generic_floating_point_number.low; /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */ exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; /* Radix 2. */ @@ -313,23 +326,23 @@ long exponent_bits; /* Forget leading zeros, forget 1st bit. */ exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); /* Offset exponent. */ - + lp = words; - + /* Word 1. Sign, exponent and perhaps high bits. */ word1 = (generic_floating_point_number.sign == '+') ? 0 : (1<<(LITTLENUM_NUMBER_OF_BITS-1)); - + /* Assume 2's complement integers. */ if(exponent_4<1 && exponent_4>=-62) { int prec_bits; int num_bits; - + unget_bits(1); num_bits= -exponent_4; prec_bits=LITTLENUM_NUMBER_OF_BITS*precision-(exponent_bits+1+num_bits); if(precision==X_PRECISION && exponent_bits==15) - prec_bits-=LITTLENUM_NUMBER_OF_BITS+1; - + prec_bits-=LITTLENUM_NUMBER_OF_BITS+1; + if(num_bits>=LITTLENUM_NUMBER_OF_BITS-exponent_bits) { /* Bigger than one littlenum */ num_bits-=(LITTLENUM_NUMBER_OF_BITS-1)-exponent_bits; @@ -349,7 +362,7 @@ long exponent_bits; *lp++=0; } if(num_bits) - *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-(num_bits)); + *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-(num_bits)); } else { if(precision==X_PRECISION && exponent_bits==15) { *lp++=word1; @@ -358,9 +371,9 @@ long exponent_bits; *lp++=0; *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1); } else if(num_bits==LITTLENUM_NUMBER_OF_BITS-1) - *lp++=0; + *lp++=0; else - *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1-num_bits); + *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1-num_bits); num_bits=0; } else { word1|= next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - (exponent_bits+num_bits)); @@ -368,26 +381,26 @@ long exponent_bits; } } while(lp<words+precision) - *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS); - + *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS); + /* Round the mantissa up, but don't change the number */ if(next_bits(1)) { --lp; if(prec_bits>LITTLENUM_NUMBER_OF_BITS) { int n = 0; int tmp_bits; - + n=0; tmp_bits=prec_bits; while(tmp_bits>LITTLENUM_NUMBER_OF_BITS) { if(lp[n]!=(LITTLENUM_TYPE)-1) - break; + break; --n; tmp_bits-=LITTLENUM_NUMBER_OF_BITS; } if(tmp_bits>LITTLENUM_NUMBER_OF_BITS || (lp[n]&mask[tmp_bits])!=mask[tmp_bits]) { unsigned long carry; - + for (carry = 1; carry && (lp >= words); lp --) { carry = * lp + carry; * lp = carry; @@ -395,59 +408,59 @@ long exponent_bits; } } } else if((*lp&mask[prec_bits])!=mask[prec_bits]) - lp++; + lp++; } - + return return_value; } else if (exponent_4 & ~ mask [exponent_bits]) { - /* - * Exponent overflow. Lose immediately. - */ - - /* - * We leave return_value alone: admit we read the - * number, but return a floating exception - * because we can't encode the number. - */ + /* + * Exponent overflow. Lose immediately. + */ + + /* + * We leave return_value alone: admit we read the + * number, but return a floating exception + * because we can't encode the number. + */ make_invalid_floating_point_number (words); return return_value; } else { word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits)) - | next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits); + | next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits); } - + * lp ++ = word1; - + /* X_PRECISION is special: it has 16 bits of zero in the middle, followed by a 1 bit. */ if(exponent_bits==15 && precision==X_PRECISION) { *lp++=0; *lp++= 1<<(LITTLENUM_NUMBER_OF_BITS)|next_bits(LITTLENUM_NUMBER_OF_BITS-1); } - + /* The rest of the words are just mantissa bits. */ while(lp < words + precision) - *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); - + *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); + if (next_bits (1)) { unsigned long carry; - /* - * Since the NEXT bit is a 1, round UP the mantissa. - * The cunning design of these hidden-1 floats permits - * us to let the mantissa overflow into the exponent, and - * it 'does the right thing'. However, we lose if the - * highest-order bit of the lowest-order word flips. - * Is that clear? - */ - - -/* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) - Please allow at least 1 more bit in carry than is in a LITTLENUM. - We need that extra bit to hold a carry during a LITTLENUM carry - propagation. Another extra bit (kept 0) will assure us that we - don't get a sticky sign bit after shifting right, and that - permits us to propagate the carry without any masking of bits. -#endif */ + /* + * Since the NEXT bit is a 1, round UP the mantissa. + * The cunning design of these hidden-1 floats permits + * us to let the mantissa overflow into the exponent, and + * it 'does the right thing'. However, we lose if the + * highest-order bit of the lowest-order word flips. + * Is that clear? + */ + + + /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) + Please allow at least 1 more bit in carry than is in a LITTLENUM. + We need that extra bit to hold a carry during a LITTLENUM carry + propagation. Another extra bit (kept 0) will assure us that we + don't get a sticky sign bit after shifting right, and that + permits us to propagate the carry without any masking of bits. + #endif */ for (carry = 1, lp --; carry && (lp >= words); lp --) { carry = * lp + carry; * lp = carry; @@ -469,23 +482,23 @@ long exponent_bits; /* This routine is a real kludge. Someone really should do it better, but I'm too lazy, and I don't understand this stuff all too well anyway (JF) - */ + */ void -int_to_gen(x) + int_to_gen(x) long x; { char buf[20]; char *bufp; - + sprintf(buf,"%ld",x); bufp= &buf[0]; if(atof_generic(&bufp,".", EXP_CHARS, &generic_floating_point_number)) - as_bad("Error converting number to floating point (Exponent overflow?)"); + as_bad("Error converting number to floating point (Exponent overflow?)"); } #ifdef TEST char * -print_gen(gen) + print_gen(gen) FLONUM_TYPE *gen; { FLONUM_TYPE f; @@ -493,7 +506,7 @@ FLONUM_TYPE *gen; double dv; float fv; static char sbuf[40]; - + if(gen) { f=generic_floating_point_number; generic_floating_point_number= *gen; @@ -505,7 +518,9 @@ FLONUM_TYPE *gen; bcopy(&arr[0],&fv,sizeof(float)); sprintf(sbuf+strlen(sbuf),"%x %x %.12g\n",arr[0],arr[1],fv); if(gen) - generic_floating_point_number=f; + generic_floating_point_number=f; return sbuf; } #endif + +/* end of atof-ieee.c */ diff --git a/gas/config/atof-vax.c b/gas/config/atof-vax.c index 43c81d6..2f129be 100644 --- a/gas/config/atof-vax.c +++ b/gas/config/atof-vax.c @@ -1,110 +1,110 @@ /* atof_vax.c - turn a Flonum into a VAX floating point number Copyright (C) 1987 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. */ - - /* JF added these two for md_atof() */ + + 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. */ + +/* JF added these two for md_atof() */ #include "as.h" #include "flonum.h" - /* Precision in LittleNums. */ +/* Precision in LittleNums. */ #define MAX_PRECISION (8) #define H_PRECISION (8) #define G_PRECISION (4) #define D_PRECISION (4) #define F_PRECISION (2) - /* Length in LittleNums of guard bits. */ +/* Length in LittleNums of guard bits. */ #define GUARD (2) int /* Number of chars in flonum type 'letter'. */ -atof_vax_sizeof (letter) - char letter; + atof_vax_sizeof (letter) +char letter; { - int return_value; - - /* - * Permitting uppercase letters is probably a bad idea. - * Please use only lower-cased letters in case the upper-cased - * ones become unsupported! - */ - switch (letter) - { - case 'f': - case 'F': - return_value = 4; - break; - - case 'd': - case 'D': - case 'g': - case 'G': - return_value = 8; - break; - - case 'h': - case 'H': - return_value = 16; - break; - - default: - return_value = 0; - break; - } - return (return_value); -} /* atof_vax_sizeof */ + int return_value; + + /* + * Permitting uppercase letters is probably a bad idea. + * Please use only lower-cased letters in case the upper-cased + * ones become unsupported! + */ + switch (letter) + { + case 'f': + case 'F': + return_value = 4; + break; + + case 'd': + case 'D': + case 'g': + case 'G': + return_value = 8; + break; + + case 'h': + case 'H': + return_value = 16; + break; + + default: + return_value = 0; + break; + } + return (return_value); +} /* atof_vax_sizeof */ static const long mask [] = { - 0x00000000, - 0x00000001, - 0x00000003, - 0x00000007, - 0x0000000f, - 0x0000001f, - 0x0000003f, - 0x0000007f, - 0x000000ff, - 0x000001ff, - 0x000003ff, - 0x000007ff, - 0x00000fff, - 0x00001fff, - 0x00003fff, - 0x00007fff, - 0x0000ffff, - 0x0001ffff, - 0x0003ffff, - 0x0007ffff, - 0x000fffff, - 0x001fffff, - 0x003fffff, - 0x007fffff, - 0x00ffffff, - 0x01ffffff, - 0x03ffffff, - 0x07ffffff, - 0x0fffffff, - 0x1fffffff, - 0x3fffffff, - 0x7fffffff, - 0xffffffff - }; + 0x00000000, + 0x00000001, + 0x00000003, + 0x00000007, + 0x0000000f, + 0x0000001f, + 0x0000003f, + 0x0000007f, + 0x000000ff, + 0x000001ff, + 0x000003ff, + 0x000007ff, + 0x00000fff, + 0x00001fff, + 0x00003fff, + 0x00007fff, + 0x0000ffff, + 0x0001ffff, + 0x0003ffff, + 0x0007ffff, + 0x000fffff, + 0x001fffff, + 0x003fffff, + 0x007fffff, + 0x00ffffff, + 0x01ffffff, + 0x03ffffff, + 0x07ffffff, + 0x0fffffff, + 0x1fffffff, + 0x3fffffff, + 0x7fffffff, + 0xffffffff + }; /* Shared between flonum_gen2vax and next_bits */ @@ -113,135 +113,135 @@ static LITTLENUM_TYPE * littlenum_pointer; static LITTLENUM_TYPE * littlenum_end; static int -next_bits (number_of_bits) - int number_of_bits; + next_bits (number_of_bits) +int number_of_bits; { - int return_value; - - if(littlenum_pointer<littlenum_end) - return 0; - if (number_of_bits >= bits_left_in_littlenum) - { - return_value = mask [bits_left_in_littlenum] & * littlenum_pointer; - number_of_bits -= bits_left_in_littlenum; - return_value <<= number_of_bits; - bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; - littlenum_pointer --; - if(littlenum_pointer>=littlenum_end) - return_value |= ( (* littlenum_pointer) >> (bits_left_in_littlenum) ) & mask [number_of_bits]; - } - else - { - bits_left_in_littlenum -= number_of_bits; - return_value = mask [number_of_bits] & ( (* littlenum_pointer) >> bits_left_in_littlenum); - } - return (return_value); + int return_value; + + if(littlenum_pointer<littlenum_end) + return 0; + if (number_of_bits >= bits_left_in_littlenum) + { + return_value = mask [bits_left_in_littlenum] & * littlenum_pointer; + number_of_bits -= bits_left_in_littlenum; + return_value <<= number_of_bits; + bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; + littlenum_pointer --; + if(littlenum_pointer>=littlenum_end) + return_value |= ( (* littlenum_pointer) >> (bits_left_in_littlenum) ) & mask [number_of_bits]; + } + else + { + bits_left_in_littlenum -= number_of_bits; + return_value = mask [number_of_bits] & ( (* littlenum_pointer) >> bits_left_in_littlenum); + } + return (return_value); } static void -make_invalid_floating_point_number (words) - LITTLENUM_TYPE * words; + make_invalid_floating_point_number (words) +LITTLENUM_TYPE * words; { - * words = 0x8000; /* Floating Reserved Operand Code */ + * words = 0x8000; /* Floating Reserved Operand Code */ } static int /* 0 means letter is OK. */ -what_kind_of_float (letter, precisionP, exponent_bitsP) - char letter; /* In: lowercase please. What kind of float? */ - int * precisionP; /* Number of 16-bit words in the float. */ - long * exponent_bitsP; /* Number of exponent bits. */ + what_kind_of_float (letter, precisionP, exponent_bitsP) +char letter; /* In: lowercase please. What kind of float? */ +int * precisionP; /* Number of 16-bit words in the float. */ +long * exponent_bitsP; /* Number of exponent bits. */ { - int retval; /* 0: OK. */ - - retval = 0; - switch (letter) - { - case 'f': - * precisionP = F_PRECISION; - * exponent_bitsP = 8; - break; - - case 'd': - * precisionP = D_PRECISION; - * exponent_bitsP = 8; - break; - - case 'g': - * precisionP = G_PRECISION; - * exponent_bitsP = 11; - break; - - case 'h': - * precisionP = H_PRECISION; - * exponent_bitsP = 15; - break; - - default: - retval = 69; - break; - } - return (retval); + int retval; /* 0: OK. */ + + retval = 0; + switch (letter) + { + case 'f': + * precisionP = F_PRECISION; + * exponent_bitsP = 8; + break; + + case 'd': + * precisionP = D_PRECISION; + * exponent_bitsP = 8; + break; + + case 'g': + * precisionP = G_PRECISION; + * exponent_bitsP = 11; + break; + + case 'h': + * precisionP = H_PRECISION; + * exponent_bitsP = 15; + break; + + default: + retval = 69; + break; + } + return (retval); } /***********************************************************************\ -* * -* Warning: this returns 16-bit LITTLENUMs, because that is * -* what the VAX thinks in. It is up to the caller to figure * -* out any alignment problems and to conspire for the bytes/word * -* to be emitted in the right order. Bigendians beware! * -* * -\***********************************************************************/ + * * + * Warning: this returns 16-bit LITTLENUMs, because that is * + * what the VAX thinks in. It is up to the caller to figure * + * out any alignment problems and to conspire for the bytes/word * + * to be emitted in the right order. Bigendians beware! * + * * + \***********************************************************************/ char * /* Return pointer past text consumed. */ -atof_vax (str, what_kind, words) - char * str; /* Text to convert to binary. */ - char what_kind; /* 'd', 'f', 'g', 'h' */ - LITTLENUM_TYPE * words; /* Build the binary here. */ + atof_vax (str, what_kind, words) +char * str; /* Text to convert to binary. */ +char what_kind; /* 'd', 'f', 'g', 'h' */ +LITTLENUM_TYPE * words; /* Build the binary here. */ { - FLONUM_TYPE f; - LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD]; - /* Extra bits for zeroed low-order bits. */ - /* The 1st MAX_PRECISION are zeroed, */ - /* the last contain flonum bits. */ - char * return_value; - int precision; /* Number of 16-bit words in the format. */ - long exponent_bits; - - return_value = str; - f . low = bits + MAX_PRECISION; - f . high = NULL; - f . leader = NULL; - f . exponent = NULL; - f . sign = '\0'; - - if (what_kind_of_float (what_kind, & precision, & exponent_bits)) - { - return_value = NULL; /* We lost. */ - make_invalid_floating_point_number (words); - } - if (return_value) - { - bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION); - - /* Use more LittleNums than seems */ - /* necessary: the highest flonum may have */ - /* 15 leading 0 bits, so could be useless. */ - f . high = f . low + precision - 1 + GUARD; - - if (atof_generic (& return_value, ".", "eE", & f)) - { - make_invalid_floating_point_number (words); - return_value = NULL; /* we lost */ - } - else - { - if (flonum_gen2vax (what_kind, & f, words)) + FLONUM_TYPE f; + LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD]; + /* Extra bits for zeroed low-order bits. */ + /* The 1st MAX_PRECISION are zeroed, */ + /* the last contain flonum bits. */ + char * return_value; + int precision; /* Number of 16-bit words in the format. */ + long exponent_bits; + + return_value = str; + f . low = bits + MAX_PRECISION; + f . high = NULL; + f . leader = NULL; + f . exponent = NULL; + f . sign = '\0'; + + if (what_kind_of_float (what_kind, & precision, & exponent_bits)) + { + return_value = NULL; /* We lost. */ + make_invalid_floating_point_number (words); + } + if (return_value) { - return_value = NULL; + bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION); + + /* Use more LittleNums than seems */ + /* necessary: the highest flonum may have */ + /* 15 leading 0 bits, so could be useless. */ + f . high = f . low + precision - 1 + GUARD; + + if (atof_generic (& return_value, ".", "eE", & f)) + { + make_invalid_floating_point_number (words); + return_value = NULL; /* we lost */ + } + else + { + if (flonum_gen2vax (what_kind, & f, words)) + { + return_value = NULL; + } + } } - } - } - return (return_value); + return (return_value); } /* @@ -250,169 +250,169 @@ atof_vax (str, what_kind, words) */ int /* 0: OK. */ -flonum_gen2vax (format_letter, f, words) - char format_letter; /* One of 'd' 'f' 'g' 'h'. */ - FLONUM_TYPE * f; - LITTLENUM_TYPE * words; /* Deliver answer here. */ + flonum_gen2vax (format_letter, f, words) +char format_letter; /* One of 'd' 'f' 'g' 'h'. */ +FLONUM_TYPE * f; +LITTLENUM_TYPE * words; /* Deliver answer here. */ { - LITTLENUM_TYPE * lp; - int precision; - long exponent_bits; - int return_value; /* 0 == OK. */ - - return_value = what_kind_of_float (format_letter, & precision, & exponent_bits); - if (return_value != 0) - { - make_invalid_floating_point_number (words); - } - else - { - if (f -> low > f -> leader) - { - /* 0.0e0 seen. */ - bzero (words, sizeof(LITTLENUM_TYPE) * precision); - } - else - { - long exponent_1; - long exponent_2; - long exponent_3; - long exponent_4; - int exponent_skippage; - LITTLENUM_TYPE word1; - - /* JF: Deal with new Nan, +Inf and -Inf codes */ - if(f->sign!='-' && f->sign!='+') { - make_invalid_floating_point_number(words); - return return_value; - } - /* - * All vaxen floating_point formats (so far) have: - * Bit 15 is sign bit. - * Bits 14:n are excess-whatever exponent. - * Bits n-1:0 (if any) are most significant bits of fraction. - * Bits 15:0 of the next word are the next most significant bits. - * And so on for each other word. - * - * All this to be compatible with a KF11?? (Which is still faster - * than lots of vaxen I can think of, but it also has higher - * maintenance costs ... sigh). - * - * So we need: number of bits of exponent, number of bits of - * mantissa. - */ - -#ifdef NEVER /******* This zeroing seems redundant - Dean 3may86 **********/ - /* - * No matter how few bits we got back from the atof() - * routine, add enough zero littlenums so the rest of the - * code won't run out of "significant" bits in the mantissa. - */ - { - LITTLENUM_TYPE * ltp; - for (ltp = f -> leader + 1; - ltp <= f -> low + precision; - ltp ++) - { - * ltp = 0; - } - } -#endif - - bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; - littlenum_pointer = f -> leader; - littlenum_end = f->low; - /* Seek (and forget) 1st significant bit */ - for (exponent_skippage = 0; - ! next_bits(1); - exponent_skippage ++) - { - } - exponent_1 = f -> exponent + f -> leader + 1 - f -> low; - /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */ - exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; - /* Radix 2. */ - exponent_3 = exponent_2 - exponent_skippage; - /* Forget leading zeros, forget 1st bit. */ - exponent_4 = exponent_3 + (1 << (exponent_bits - 1)); - /* Offset exponent. */ - - if (exponent_4 & ~ mask [exponent_bits]) + LITTLENUM_TYPE * lp; + int precision; + long exponent_bits; + int return_value; /* 0 == OK. */ + + return_value = what_kind_of_float (format_letter, & precision, & exponent_bits); + if (return_value != 0) { - /* - * Exponent overflow. Lose immediately. - */ - - make_invalid_floating_point_number (words); - - /* - * We leave return_value alone: admit we read the - * number, but return a floating exception - * because we can't encode the number. - */ + make_invalid_floating_point_number (words); } - else + else { - lp = words; - - /* Word 1. Sign, exponent and perhaps high bits. */ - /* Assume 2's complement integers. */ - word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits)) - | ((f -> sign == '+') ? 0 : 0x8000) - | next_bits (15 - exponent_bits); - * lp ++ = word1; - - /* The rest of the words are just mantissa bits. */ - for (; lp < words + precision; lp++) - { - * lp = next_bits (LITTLENUM_NUMBER_OF_BITS); - } - - if (next_bits (1)) - { - /* - * Since the NEXT bit is a 1, round UP the mantissa. - * The cunning design of these hidden-1 floats permits - * us to let the mantissa overflow into the exponent, and - * it 'does the right thing'. However, we lose if the - * highest-order bit of the lowest-order word flips. - * Is that clear? - */ - - unsigned long carry; - - /* - #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) - Please allow at least 1 more bit in carry than is in a LITTLENUM. - We need that extra bit to hold a carry during a LITTLENUM carry - propagation. Another extra bit (kept 0) will assure us that we - don't get a sticky sign bit after shifting right, and that - permits us to propagate the carry without any masking of bits. - #endif - */ - for (carry = 1, lp --; - carry && (lp >= words); - lp --) - { - carry = * lp + carry; - * lp = carry; - carry >>= LITTLENUM_NUMBER_OF_BITS; - } - - if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) - { - make_invalid_floating_point_number (words); - /* - * We leave return_value alone: admit we read the - * number, but return a floating exception - * because we can't encode the number. - */ - } - } /* if (we needed to round up) */ - } /* if (exponent overflow) */ - } /* if (0.0e0) */ - } /* if (float_type was OK) */ - return (return_value); + if (f -> low > f -> leader) + { + /* 0.0e0 seen. */ + bzero (words, sizeof(LITTLENUM_TYPE) * precision); + } + else + { + long exponent_1; + long exponent_2; + long exponent_3; + long exponent_4; + int exponent_skippage; + LITTLENUM_TYPE word1; + + /* JF: Deal with new Nan, +Inf and -Inf codes */ + if(f->sign!='-' && f->sign!='+') { + make_invalid_floating_point_number(words); + return return_value; + } + /* + * All vaxen floating_point formats (so far) have: + * Bit 15 is sign bit. + * Bits 14:n are excess-whatever exponent. + * Bits n-1:0 (if any) are most significant bits of fraction. + * Bits 15:0 of the next word are the next most significant bits. + * And so on for each other word. + * + * All this to be compatible with a KF11?? (Which is still faster + * than lots of vaxen I can think of, but it also has higher + * maintenance costs ... sigh). + * + * So we need: number of bits of exponent, number of bits of + * mantissa. + */ + +#ifdef NEVER /******* This zeroing seems redundant - Dean 3may86 **********/ + /* + * No matter how few bits we got back from the atof() + * routine, add enough zero littlenums so the rest of the + * code won't run out of "significant" bits in the mantissa. + */ + { + LITTLENUM_TYPE * ltp; + for (ltp = f -> leader + 1; + ltp <= f -> low + precision; + ltp ++) + { + * ltp = 0; + } + } +#endif + + bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; + littlenum_pointer = f -> leader; + littlenum_end = f->low; + /* Seek (and forget) 1st significant bit */ + for (exponent_skippage = 0; + ! next_bits(1); + exponent_skippage ++) + { + } + exponent_1 = f -> exponent + f -> leader + 1 - f -> low; + /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */ + exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; + /* Radix 2. */ + exponent_3 = exponent_2 - exponent_skippage; + /* Forget leading zeros, forget 1st bit. */ + exponent_4 = exponent_3 + (1 << (exponent_bits - 1)); + /* Offset exponent. */ + + if (exponent_4 & ~ mask [exponent_bits]) + { + /* + * Exponent overflow. Lose immediately. + */ + + make_invalid_floating_point_number (words); + + /* + * We leave return_value alone: admit we read the + * number, but return a floating exception + * because we can't encode the number. + */ + } + else + { + lp = words; + + /* Word 1. Sign, exponent and perhaps high bits. */ + /* Assume 2's complement integers. */ + word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits)) + | ((f -> sign == '+') ? 0 : 0x8000) + | next_bits (15 - exponent_bits); + * lp ++ = word1; + + /* The rest of the words are just mantissa bits. */ + for (; lp < words + precision; lp++) + { + * lp = next_bits (LITTLENUM_NUMBER_OF_BITS); + } + + if (next_bits (1)) + { + /* + * Since the NEXT bit is a 1, round UP the mantissa. + * The cunning design of these hidden-1 floats permits + * us to let the mantissa overflow into the exponent, and + * it 'does the right thing'. However, we lose if the + * highest-order bit of the lowest-order word flips. + * Is that clear? + */ + + unsigned long carry; + + /* + #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) + Please allow at least 1 more bit in carry than is in a LITTLENUM. + We need that extra bit to hold a carry during a LITTLENUM carry + propagation. Another extra bit (kept 0) will assure us that we + don't get a sticky sign bit after shifting right, and that + permits us to propagate the carry without any masking of bits. + #endif + */ + for (carry = 1, lp --; + carry && (lp >= words); + lp --) + { + carry = * lp + carry; + * lp = carry; + carry >>= LITTLENUM_NUMBER_OF_BITS; + } + + if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) + { + make_invalid_floating_point_number (words); + /* + * We leave return_value alone: admit we read the + * number, but return a floating exception + * because we can't encode the number. + */ + } + } /* if (we needed to round up) */ + } /* if (exponent overflow) */ + } /* if (0.0e0) */ + } /* if (float_type was OK) */ + return (return_value); } @@ -438,72 +438,72 @@ flonum_gen2vax (format_letter, f, words) #define MAXIMUM_NUMBER_OF_LITTLENUMS (8) /* For .hfloats. */ char * -md_atof (what_statement_type, literalP, sizeP) - char what_statement_type; - char * literalP; - int * sizeP; + md_atof (what_statement_type, literalP, sizeP) +char what_statement_type; +char * literalP; +int * sizeP; { - LITTLENUM_TYPE words [MAXIMUM_NUMBER_OF_LITTLENUMS]; - register char kind_of_float; - register int number_of_chars; - register LITTLENUM_TYPE * littlenum_pointer; - - switch (what_statement_type) - { - case 'F': /* .float */ - case 'f': /* .ffloat */ - kind_of_float = 'f'; - break; - - case 'D': /* .double */ - case 'd': /* .dfloat */ - kind_of_float = 'd'; - break; - - case 'g': /* .gfloat */ - kind_of_float = 'g'; - break; - - case 'h': /* .hfloat */ - kind_of_float = 'h'; - break; - - default: - kind_of_float = 0; - break; - }; - - if (kind_of_float) - { - register LITTLENUM_TYPE * limit; - - input_line_pointer = atof_vax (input_line_pointer, - kind_of_float, - words); - /* - * The atof_vax() builds up 16-bit numbers. - * Since the assembler may not be running on - * a little-endian machine, be very careful about - * converting words to chars. - */ - number_of_chars = atof_vax_sizeof (kind_of_float); - know( number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof(LITTLENUM_TYPE) ); - limit = words + (number_of_chars / sizeof(LITTLENUM_TYPE)); - for (littlenum_pointer = words; - littlenum_pointer < limit; - littlenum_pointer ++) - { - md_number_to_chars (literalP, * littlenum_pointer, sizeof(LITTLENUM_TYPE)); - literalP += sizeof(LITTLENUM_TYPE); - }; - } - else - { - number_of_chars = 0; - }; - - * sizeP = number_of_chars; - return (kind_of_float ? "" : "Bad call to md_atof()"); + LITTLENUM_TYPE words [MAXIMUM_NUMBER_OF_LITTLENUMS]; + register char kind_of_float; + register int number_of_chars; + register LITTLENUM_TYPE * littlenum_pointer; + + switch (what_statement_type) + { + case 'F': /* .float */ + case 'f': /* .ffloat */ + kind_of_float = 'f'; + break; + + case 'D': /* .double */ + case 'd': /* .dfloat */ + kind_of_float = 'd'; + break; + + case 'g': /* .gfloat */ + kind_of_float = 'g'; + break; + + case 'h': /* .hfloat */ + kind_of_float = 'h'; + break; + + default: + kind_of_float = 0; + break; + }; + + if (kind_of_float) + { + register LITTLENUM_TYPE * limit; + + input_line_pointer = atof_vax (input_line_pointer, + kind_of_float, + words); + /* + * The atof_vax() builds up 16-bit numbers. + * Since the assembler may not be running on + * a little-endian machine, be very careful about + * converting words to chars. + */ + number_of_chars = atof_vax_sizeof (kind_of_float); + know( number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof(LITTLENUM_TYPE) ); + limit = words + (number_of_chars / sizeof(LITTLENUM_TYPE)); + for (littlenum_pointer = words; + littlenum_pointer < limit; + littlenum_pointer ++) + { + md_number_to_chars (literalP, * littlenum_pointer, sizeof(LITTLENUM_TYPE)); + literalP += sizeof(LITTLENUM_TYPE); + }; + } + else + { + number_of_chars = 0; + }; + + * sizeP = number_of_chars; + return (kind_of_float ? "" : "Bad call to md_atof()"); } /* md_atof() */ -/* atof_vax.c */ +/* end of atof_vax.c */ diff --git a/gas/config/coff.gnu.h b/gas/config/coff.gnu.h index 281ac17..3c61938 100755 --- a/gas/config/coff.gnu.h +++ b/gas/config/coff.gnu.h @@ -1,3 +1,22 @@ +/* coff.gnu.h + Copyright (C) 1987 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. */ + /*** coff information for 80960. Origins: Intel, AMD, etc., natch. */ /* @@ -110,7 +129,7 @@ typedef struct { #define REGMAGIC (0414) /* (?) a PAGEMAGIC2 alias? */ #define PAGEMAGIC3 (0415) /* (?) like ZMAGIC, but address zero mapped. */ #define A_MAGIC5 (0437) /* (?) "system overlay, separated I&D" */ - /* intended for non-unix cross development */ +/* intended for non-unix cross development */ #define SASMAGIC (010000) /* Single Address Space */ #define MASMAGIC (020000) /* (?) "Multiple (separate I & D) Address Spaces" */ @@ -127,7 +146,7 @@ typedef struct aouthdr { unsigned long entry; /* entry pt. */ unsigned long text_start; /* base of text used for this file */ unsigned long data_start; /* base of data used for this file */ - /* CAREFUL: some formats omit the tagentries member. */ + /* CAREFUL: some formats omit the tagentries member. */ unsigned long tagentries; /* number of tag entries to follow (always zero for i960) */ } AOUTHDR; @@ -187,9 +206,9 @@ typedef struct aouthdr { used to avoid name conflicts. */ #ifdef TC_I960 - /* New storage classes for 80960 */ +/* New storage classes for 80960 */ #define C_SCALL 107 /* Procedure reachable via system call */ - /* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */ +/* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */ #define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */ #define C_LEAFEXT 108 #define C_OPTVAR 109 /* Optimized variable */ @@ -216,7 +235,7 @@ struct scnhdr { unsigned short s_nreloc; /* number of relocation entries */ unsigned short s_nlnno; /* number of line number entries */ long s_flags; /* flags */ - + #ifdef TC_I960 unsigned long s_align; /* section alignment */ #endif /* TC_I960 */ @@ -288,7 +307,7 @@ struct lineno { } l_addr; unsigned short l_lnno; /* line number */ #ifdef TC_I960 - /* not used on a29k */ + /* not used on a29k */ char padding[2]; /* force alignment */ #endif /* TC_I960 */ }; @@ -299,40 +318,40 @@ struct lineno { /********************** SYMBOLS **********************/ -#define SYMNMLEN 8 /* # characters in a symbol name */ -#define FILNMLEN 14 /* # characters in a file name */ +#define SYMNMLEN 8 /* # characters in a symbol name */ +#define FILNMLEN 14 /* # characters in a file name */ #define DIMNUM 4 /* # array dimensions in auxiliary entry */ struct syment { union { - char _n_name[SYMNMLEN]; /* old COFF version */ + char _n_name[SYMNMLEN]; /* old COFF version */ struct { - long _n_zeroes; /* new == 0 */ + long _n_zeroes; /* new == 0 */ long _n_offset; /* offset into string table */ } _n_n; - char *_n_nptr[2]; /* allows for overlaying */ + char *_n_nptr[2]; /* allows for overlaying */ } _n; - long n_value; /* value of symbol */ - short n_scnum; /* section number */ - + long n_value; /* value of symbol */ + short n_scnum; /* section number */ + #ifdef TC_I960 - /* This isn't yet used on the i960. In some formats this - is two bytes of padding. In others, it is missing entirely. */ - unsigned short n_flags; /* copy of flags from filhdr */ + /* This isn't yet used on the i960. In some formats this + is two bytes of padding. In others, it is missing entirely. */ + unsigned short n_flags; /* copy of flags from filhdr */ #endif /* TC_I960 */ - + #ifdef TC_A29K - unsigned short n_type; /* type and derived type */ + unsigned short n_type; /* type and derived type */ #else /* TC_A29K */ - /* at least i960 uses long */ - unsigned long n_type; /* type and derived type */ + /* at least i960 uses long */ + unsigned long n_type; /* type and derived type */ #endif /* TC_A29K */ - - char n_sclass; /* storage class */ - char n_numaux; /* number of aux. entries */ - + + char n_sclass; /* storage class */ + char n_numaux; /* number of aux. entries */ + #ifndef TC_A29K - char pad2[2]; /* force alignment */ + char pad2[2]; /* force alignment */ #endif /* TC_A29K */ }; @@ -343,12 +362,12 @@ struct syment { #define n_ptr _n._n_nptr[1] #define n_zeroes _n._n_n._n_zeroes #define n_offset _n._n_n._n_offset - -/* - * Relocatable symbols have number of the section in which they are defined, - * or one of the following: - */ - + + /* + * Relocatable symbols have number of the section in which they are defined, + * or one of the following: + */ + #define N_SCNUM ((short) 1-65535) /* section num where symbol defined */ #define N_UNDEF ((short)0) /* undefined symbol */ #define N_ABS ((short)-1) /* value of symbol is absolute */ @@ -360,8 +379,7 @@ struct syment { * Type of a symbol, in low 4 bits of the word */ #define T_NULL 0 /* type not assigned */ -#define T_VOID 1 /* function argument (only used by compiler) (but now - real void). */ +#define T_VOID 1 /* function argument (only used by compiler) (but now real void). */ #define T_CHAR 2 /* character */ #define T_SHORT 3 /* short integer */ #define T_INT 4 /* integer */ @@ -418,24 +436,24 @@ union auxent { long x_tagndx; /* str, un, or enum tag indx */ union { struct { - unsigned short x_lnno; /* declaration line number */ - unsigned short x_size; /* str/union/array size */ + unsigned short x_lnno; /* declaration line number */ + unsigned short x_size; /* str/union/array size */ } x_lnsz; long x_fsize; /* size of function */ } x_misc; union { struct { /* if ISFCN, tag, or .bb */ - long x_lnnoptr; /* ptr to fcn line # */ - long x_endndx; /* entry ndx past block end */ + long x_lnnoptr; /* ptr to fcn line # */ + long x_endndx; /* entry ndx past block end */ } x_fcn; struct { /* if ISARY, up to 4 dimen. */ - unsigned short x_dimen[DIMNUM]; + unsigned short x_dimen[DIMNUM]; } x_ary; } x_fcnary; unsigned short x_tvndx; /* tv index */ } x_sym; - - /* This was just a struct x_file with x_fname only in a29k. xoxorich. */ + + /* This was just a struct x_file with x_fname only in a29k. xoxorich. */ union { char x_fname[FILNMLEN]; struct { @@ -443,40 +461,40 @@ union auxent { long x_offset; } x_n; } x_file; - + struct { long x_scnlen; /* section length */ unsigned short x_nreloc; /* # relocation entries */ unsigned short x_nlinno; /* # line numbers */ } x_scn; - + struct { long x_tvfill; /* tv fill value */ unsigned short x_tvlen; /* length of .tv */ - - /* This field was typo'd x_tvrna on a29k. xoxorich. */ + + /* This field was typo'd x_tvrna on a29k. xoxorich. */ unsigned short x_tvran[2]; /* tv range */ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - + #ifdef TC_I960 /****************************************** * I960-specific *2nd* aux. entry formats ******************************************/ struct { - /* This is a very old typo that keeps getting propogated. */ + /* This is a very old typo that keeps getting propogated. */ #define x_stdindx x_stindx long x_stindx; /* sys. table entry */ } x_sc; /* system call entry */ - + struct { unsigned long x_balntry; /* BAL entry point */ } x_bal; /* BAL-callable function */ - + struct { unsigned long x_timestamp; /* time stamp */ char x_idstring[20]; /* producer identity string */ } x_ident; /* Producer ident info */ - + char a[sizeof(struct syment)]; /* force auxent/syment sizes to match */ #endif /* TC_I960 */ }; @@ -497,7 +515,7 @@ struct reloc { long r_symndx; /* Index into symbol table */ unsigned short r_type; /* Relocation type */ #ifdef TC_I960 - /* not used for a29k */ + /* not used for a29k */ char pad[2]; /* Unused */ #endif /* TC_I960 */ }; @@ -555,10 +573,9 @@ struct reloc { #define DEFAULT_DATA_SECTION_ALIGNMENT 4 #define DEFAULT_BSS_SECTION_ALIGNMENT 4 #define DEFAULT_TEXT_SECTION_ALIGNMENT 16 -/* For new sections we havn't heard of before */ +/* For new sections we haven't heard of before */ #define DEFAULT_SECTION_ALIGNMENT 4 - /* * Local Variables: * comment-column: 0 diff --git a/gas/config/cplus-dem.c b/gas/config/cplus-dem.c index 12b9d06..9849d43 100644 --- a/gas/config/cplus-dem.c +++ b/gas/config/cplus-dem.c @@ -6,12 +6,12 @@ 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. - + This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -20,7 +20,7 @@ require changes for any other version. */ /* This file exports one function - + char *cplus_demangle (const char *name) If `name' is a mangled function name produced by g++, then @@ -28,25 +28,25 @@ of the name will be returned; otherwise NULL will be returned. It is the caller's responsibility to free the string which is returned. - + For example, cplus_demangle ("_foo__1Ai") returns - + "A::foo(int)" - + This file imports xmalloc and xrealloc, which are like malloc and realloc except that they generate a fatal error if there is no available memory. */ /* #define nounderscore 1 /* define this is names don't start with _ */ - + #include <stdio.h> #include <string.h> #include <ctype.h> - + #if !defined(sequent) && !defined(NeXT) #include <memory.h> #else @@ -78,45 +78,45 @@ static int ntypes = 0; static int typevec_size = 0; static struct { - const char *in; - const char *out; + const char *in; + const char *out; } optable[] = { - "new", " new", - "delete", " delete", - "ne", "!=", - "eq", "==", - "ge", ">=", - "gt", ">", - "le", "<=", - "lt", "<", - "plus", "+", - "minus", "-", - "mult", "*", - "negate", "-", - "trunc_mod", "%", - "trunc_div", "/", - "truth_andif", "&&", - "truth_orif", "||", - "postincrement", "++", - "postdecrement", "--", - "bit_ior", "|", - "bit_xor", "^", - "bit_and", "&", - "bit_not", "~", - "call", "()", - "cond", "?:", - "alshift", "<<", - "arshift", ">>", - "component", "->", - "nop", "", /* for operator= */ + "new", " new", + "delete", " delete", + "ne", "!=", + "eq", "==", + "ge", ">=", + "gt", ">", + "le", "<=", + "lt", "<", + "plus", "+", + "minus", "-", + "mult", "*", + "negate", "-", + "trunc_mod", "%", + "trunc_div", "/", + "truth_andif", "&&", + "truth_orif", "||", + "postincrement", "++", + "postdecrement", "--", + "bit_ior", "|", + "bit_xor", "^", + "bit_and", "&", + "bit_not", "~", + "call", "()", + "cond", "?:", + "alshift", "<<", + "arshift", ">>", + "component", "->", + "nop", "", /* for operator= */ }; /* Beware: these aren't '\0' terminated. */ typedef struct { - char *b; /* pointer to start of string */ - char *p; /* pointer after last character */ - char *e; /* pointer after end of allocated space */ + char *b; /* pointer to start of string */ + char *p; /* pointer after last character */ + char *e; /* pointer after end of allocated space */ } string; #ifdef __STDC__ @@ -160,766 +160,768 @@ static void munge_function_name (); #endif char * -cplus_demangle (type) - const char *type; + cplus_demangle (type) +const char *type; { - string decl; - int n; - int success = 0; - int constructor = 0; - int const_flag = 0; - int i; - const char *p; - - if (type == NULL || *type == '\0') - return NULL; + string decl; + int n; + int success = 0; + int constructor = 0; + int const_flag = 0; + int i; + const char *p; + + if (type == NULL || *type == '\0') + return NULL; #ifndef nounderscore - if (*type++ != '_') - return NULL; + if (*type++ != '_') + return NULL; #endif - p = type; - while (*p != '\0' && !(*p == '_' && p[1] == '_')) - p++; - if (*p == '\0') - { - /* destructor */ - if (type[0] == '_' && type[1] == '$' && type[2] == '_') - { - int n = (strlen (type) - 3)*2 + 3 + 2 + 1; - char *tem = (char *) xmalloc (n); - strcpy (tem, type + 3); - strcat (tem, "::~"); - strcat (tem, type + 3); - strcat (tem, "()"); - return tem; - } - /* static data member */ - if (*type != '_' && (p = strchr (type, '$')) != '\0') - { - int n = strlen (type) + 2; - char *tem = (char *) xmalloc (n); - memcpy (tem, type, p - type); - strcpy (tem + (p - type), "::"); - strcpy (tem + (p - type) + 2, p + 1); - return tem; - } - return NULL; - } - - string_init (&decl); - - if (p == type) - { - if (!isdigit (p[2])) - { - string_delete (&decl); - return NULL; - } - constructor = 1; - } - else - { - string_appendn (&decl, type, p - type); - munge_function_name (&decl); - } - p += 2; - - switch (*p) - { - case 'C': - /* a const member function */ - if (!isdigit (p[1])) - { - string_delete (&decl); - return NULL; - } - p += 1; - const_flag = 1; - /* fall through */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - n = 0; - do - { - n *= 10; - n += *p - '0'; - p += 1; - } - while (isdigit (*p)); - if (strlen (p) < n) - { - string_delete (&decl); - return NULL; - } - if (constructor) - { - string_appendn (&decl, p, n); - string_append (&decl, "::"); - string_appendn (&decl, p, n); - } - else - { - string_prepend (&decl, "::"); - string_prependn (&decl, p, n); - } - p += n; - success = do_args (&p, &decl); - if (const_flag) - string_append (&decl, " const"); - break; - case 'F': - p += 1; - success = do_args (&p, &decl); - break; - } - - for (i = 0; i < ntypes; i++) - if (typevec[i] != NULL) - free (typevec[i]); - ntypes = 0; - if (typevec != NULL) - { - free ((char *)typevec); - typevec = NULL; - typevec_size = 0; - } - - if (success) - { - string_appendn (&decl, "", 1); - return decl.b; - } - else - { - string_delete (&decl); - return NULL; - } + p = type; + while (*p != '\0' && !(*p == '_' && p[1] == '_')) + p++; + if (*p == '\0') + { + /* destructor */ + if (type[0] == '_' && type[1] == '$' && type[2] == '_') + { + int n = (strlen (type) - 3)*2 + 3 + 2 + 1; + char *tem = (char *) xmalloc (n); + strcpy (tem, type + 3); + strcat (tem, "::~"); + strcat (tem, type + 3); + strcat (tem, "()"); + return tem; + } + /* static data member */ + if (*type != '_' && (p = strchr (type, '$')) != '\0') + { + int n = strlen (type) + 2; + char *tem = (char *) xmalloc (n); + memcpy (tem, type, p - type); + strcpy (tem + (p - type), "::"); + strcpy (tem + (p - type) + 2, p + 1); + return tem; + } + return NULL; + } + + string_init (&decl); + + if (p == type) + { + if (!isdigit (p[2])) + { + string_delete (&decl); + return NULL; + } + constructor = 1; + } + else + { + string_appendn (&decl, type, p - type); + munge_function_name (&decl); + } + p += 2; + + switch (*p) + { + case 'C': + /* a const member function */ + if (!isdigit (p[1])) + { + string_delete (&decl); + return NULL; + } + p += 1; + const_flag = 1; + /* fall through */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + n = 0; + do + { + n *= 10; + n += *p - '0'; + p += 1; + } + while (isdigit (*p)); + if (strlen (p) < n) + { + string_delete (&decl); + return NULL; + } + if (constructor) + { + string_appendn (&decl, p, n); + string_append (&decl, "::"); + string_appendn (&decl, p, n); + } + else + { + string_prepend (&decl, "::"); + string_prependn (&decl, p, n); + } + p += n; + success = do_args (&p, &decl); + if (const_flag) + string_append (&decl, " const"); + break; + case 'F': + p += 1; + success = do_args (&p, &decl); + break; + } + + for (i = 0; i < ntypes; i++) + if (typevec[i] != NULL) + free (typevec[i]); + ntypes = 0; + if (typevec != NULL) + { + free ((char *)typevec); + typevec = NULL; + typevec_size = 0; + } + + if (success) + { + string_appendn (&decl, "", 1); + return decl.b; + } + else + { + string_delete (&decl); + return NULL; + } } static int -get_count (type, count) - const char **type; - int *count; + get_count (type, count) +const char **type; +int *count; { - if (!isdigit (**type)) - return 0; - *count = **type - '0'; - *type += 1; - /* see flush_repeats in cplus-method.c */ - if (isdigit (**type)) - { - const char *p = *type; - int n = *count; - do - { - n *= 10; - n += *p - '0'; - p += 1; - } - while (isdigit (*p)); - if (*p == '_') - { - *type = p + 1; - *count = n; - } - } - return 1; + if (!isdigit (**type)) + return 0; + *count = **type - '0'; + *type += 1; + /* see flush_repeats in cplus-method.c */ + if (isdigit (**type)) + { + const char *p = *type; + int n = *count; + do + { + n *= 10; + n += *p - '0'; + p += 1; + } + while (isdigit (*p)); + if (*p == '_') + { + *type = p + 1; + *count = n; + } + } + return 1; } /* result will be initialised here; it will be freed on failure */ static int -do_type (type, result) - const char **type; - string *result; + do_type (type, result) +const char **type; +string *result; { - int n; - int done; - int non_empty; - int success; - string decl; - const char *remembered_type; - - string_init (&decl); - string_init (result); - - done = 0; - success = 1; - while (success && !done) - { - int member; - switch (**type) - { - case 'P': - *type += 1; - string_prepend (&decl, "*"); - break; - - case 'R': - *type += 1; - string_prepend (&decl, "&"); - break; - - case 'T': - *type += 1; - if (!get_count (type, &n) || n >= ntypes) - success = 0; - else + int n; + int done; + int non_empty; + int success; + string decl; + const char *remembered_type; + + string_init (&decl); + string_init (result); + + done = 0; + success = 1; + while (success && !done) { - remembered_type = typevec[n]; - type = &remembered_type; + int member; + switch (**type) + { + case 'P': + *type += 1; + string_prepend (&decl, "*"); + break; + + case 'R': + *type += 1; + string_prepend (&decl, "&"); + break; + + case 'T': + *type += 1; + if (!get_count (type, &n) || n >= ntypes) + success = 0; + else + { + remembered_type = typevec[n]; + type = &remembered_type; + } + break; + + case 'F': + *type += 1; + if (!string_empty (&decl) && decl.b[0] == '*') + { + string_prepend (&decl, "("); + string_append (&decl, ")"); + } + if (!do_args (type, &decl) || **type != '_') + success = 0; + else + *type += 1; + break; + + case 'M': + case 'O': + { + int constp = 0; + int volatilep = 0; + + member = **type == 'M'; + *type += 1; + if (!isdigit (**type)) + { + success = 0; + break; + } + n = 0; + do + { + n *= 10; + n += **type - '0'; + *type += 1; + } + while (isdigit (**type)); + if (strlen (*type) < n) + { + success = 0; + break; + } + string_append (&decl, ")"); + string_prepend (&decl, "::"); + string_prependn (&decl, *type, n); + string_prepend (&decl, "("); + *type += n; + if (member) + { + if (**type == 'C') + { + *type += 1; + constp = 1; + } + if (**type == 'V') + { + *type += 1; + volatilep = 1; + } + if (*(*type)++ != 'F') + { + success = 0; + break; + } + } + if ((member && !do_args (type, &decl)) || **type != '_') + { + success = 0; + break; + } + *type += 1; + if (constp) + { + if (non_empty) + string_append (&decl, " "); + else + non_empty = 1; + string_append (&decl, "const"); + } + if (volatilep) + { + if (non_empty) + string_append (&decl, " "); + else + non_empty = 1; + string_append (&decl, "volatilep"); + } + break; + } + + case 'C': + if ((*type)[1] == 'P') + { + *type += 1; + if (!string_empty (&decl)) + string_prepend (&decl, " "); + string_prepend (&decl, "const"); + break; + } + + /* fall through */ + default: + done = 1; + break; + } } - break; - - case 'F': - *type += 1; - if (!string_empty (&decl) && decl.b[0] == '*') + + done = 0; + non_empty = 0; + while (success && !done) { - string_prepend (&decl, "("); - string_append (&decl, ")"); + switch (**type) + { + case 'C': + *type += 1; + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "const"); + break; + case 'U': + *type += 1; + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "unsigned"); + break; + case 'V': + *type += 1; + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "volatile"); + break; + default: + done = 1; + break; + } } - if (!do_args (type, &decl) || **type != '_') - success = 0; - else - *type += 1; - break; - - case 'M': - case 'O': - { - int constp = 0; - int volatilep = 0; - - member = **type == 'M'; - *type += 1; - if (!isdigit (**type)) - { - success = 0; - break; - } - n = 0; - do - { - n *= 10; - n += **type - '0'; - *type += 1; - } - while (isdigit (**type)); - if (strlen (*type) < n) - { - success = 0; - break; - } - string_append (&decl, ")"); - string_prepend (&decl, "::"); - string_prependn (&decl, *type, n); - string_prepend (&decl, "("); - *type += n; - if (member) - { - if (**type == 'C') - { - *type += 1; - constp = 1; - } - if (**type == 'V') - { - *type += 1; - volatilep = 1; - } - if (*(*type)++ != 'F') - { - success = 0; - break; - } - } - if ((member && !do_args (type, &decl)) || **type != '_') - { - success = 0; - break; - } - *type += 1; - if (constp) - { - if (non_empty) - string_append (&decl, " "); - else - non_empty = 1; - string_append (&decl, "const"); - } - if (volatilep) - { - if (non_empty) - string_append (&decl, " "); - else - non_empty = 1; - string_append (&decl, "volatilep"); - } - break; - } - - case 'C': - if ((*type)[1] == 'P') + + if (success) + switch (**type) + { + case '\0': + case '_': + break; + case 'v': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "void"); + break; + case 'l': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "long"); + break; + case 'i': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "int"); + break; + case 's': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "short"); + break; + case 'c': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "char"); + break; + case 'r': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "long double"); + break; + case 'd': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "double"); + break; + case 'f': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "float"); + break; + case 'G': + *type += 1; + if (!isdigit (**type)) + { + success = 0; + break; + } + /* fall through */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + n = 0; + do + { + n *= 10; + n += **type - '0'; + *type += 1; + } + while (isdigit (**type)); + if (strlen (*type) < n) + { + success = 0; + break; + } + if (non_empty) + string_append (result, " "); + string_appendn (result, *type, n); + *type += n; + break; + default: + success = 0; + break; + } + + if (success) { - *type += 1; - if (!string_empty (&decl)) - string_prepend (&decl, " "); - string_prepend (&decl, "const"); - break; + if (!string_empty (&decl)) + { + string_append (result, " "); + string_appends (result, &decl); + } + string_delete (&decl); + return 1; + } + else + { + string_delete (&decl); + string_delete (result); + return 0; } - - /* fall through */ - default: - done = 1; - break; - } - } - - done = 0; - non_empty = 0; - while (success && !done) - { - switch (**type) - { - case 'C': - *type += 1; - if (non_empty) - string_append (result, " "); - else - non_empty = 1; - string_append (result, "const"); - break; - case 'U': - *type += 1; - if (non_empty) - string_append (result, " "); - else - non_empty = 1; - string_append (result, "unsigned"); - break; - case 'V': - *type += 1; - if (non_empty) - string_append (result, " "); - else - non_empty = 1; - string_append (result, "volatile"); - break; - default: - done = 1; - break; - } - } - - if (success) - switch (**type) - { - case '\0': - case '_': - break; - case 'v': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "void"); - break; - case 'l': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "long"); - break; - case 'i': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "int"); - break; - case 's': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "short"); - break; - case 'c': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "char"); - break; - case 'r': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "long double"); - break; - case 'd': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "double"); - break; - case 'f': - *type += 1; - if (non_empty) - string_append (result, " "); - string_append (result, "float"); - break; - case 'G': - *type += 1; - if (!isdigit (**type)) - { - success = 0; - break; - } - /* fall through */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - n = 0; - do - { - n *= 10; - n += **type - '0'; - *type += 1; - } - while (isdigit (**type)); - if (strlen (*type) < n) - { - success = 0; - break; - } - if (non_empty) - string_append (result, " "); - string_appendn (result, *type, n); - *type += n; - break; - default: - success = 0; - break; - } - - if (success) - { - if (!string_empty (&decl)) - { - string_append (result, " "); - string_appends (result, &decl); - } - string_delete (&decl); - return 1; - } - else - { - string_delete (&decl); - string_delete (result); - return 0; - } } /* `result' will be initialised in do_type; it will be freed on failure */ static int -do_arg (type, result) - const char **type; - string *result; + do_arg (type, result) +const char **type; +string *result; { - char *tem; - int len; - const char *start; - const char *end; - - start = *type; - if (!do_type (type, result)) - return 0; - end = *type; - if (ntypes >= typevec_size) - { - if (typevec_size == 0) - { - typevec_size = 3; - typevec = (char **) xmalloc (sizeof (char*)*typevec_size); - } - else - { - typevec_size *= 2; - typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size); - } - } - len = end - start; - tem = (char *) xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - typevec[ntypes++] = tem; - return 1; + char *tem; + int len; + const char *start; + const char *end; + + start = *type; + if (!do_type (type, result)) + return 0; + end = *type; + if (ntypes >= typevec_size) + { + if (typevec_size == 0) + { + typevec_size = 3; + typevec = (char **) xmalloc (sizeof (char*)*typevec_size); + } + else + { + typevec_size *= 2; + typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size); + } + } + len = end - start; + tem = (char *) xmalloc (len + 1); + memcpy (tem, start, len); + tem[len] = '\0'; + typevec[ntypes++] = tem; + return 1; } /* `decl' must be already initialised, usually non-empty; it won't be freed on failure */ static int -do_args (type, decl) - const char **type; - string *decl; + do_args (type, decl) +const char **type; +string *decl; { - string arg; - int need_comma = 0; - - string_append (decl, "("); - - while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v') - { - if (**type == 'N') - { - int r; - int t; - *type += 1; - if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes) - return 0; - while (--r >= 0) + string arg; + int need_comma = 0; + + string_append (decl, "("); + + while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v') { - const char *tem = typevec[t]; - if (need_comma) - string_append (decl, ", "); - if (!do_arg (&tem, &arg)) - return 0; - string_appends (decl, &arg); - string_delete (&arg); - need_comma = 1; + if (**type == 'N') + { + int r; + int t; + *type += 1; + if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes) + return 0; + while (--r >= 0) + { + const char *tem = typevec[t]; + if (need_comma) + string_append (decl, ", "); + if (!do_arg (&tem, &arg)) + return 0; + string_appends (decl, &arg); + string_delete (&arg); + need_comma = 1; + } + } + else + { + if (need_comma) + string_append (decl, ", "); + if (!do_arg (type, &arg)) + return 0; + string_appends (decl, &arg); + string_delete (&arg); + need_comma = 1; + } } - } - else - { - if (need_comma) - string_append (decl, ", "); - if (!do_arg (type, &arg)) - return 0; - string_appends (decl, &arg); - string_delete (&arg); - need_comma = 1; - } - } - - if (**type == 'v') - *type += 1; - else if (**type == 'e') - { - *type += 1; - if (need_comma) - string_append (decl, ","); - string_append (decl, "..."); - } - - string_append (decl, ")"); - return 1; + + if (**type == 'v') + *type += 1; + else if (**type == 'e') + { + *type += 1; + if (need_comma) + string_append (decl, ","); + string_append (decl, "..."); + } + + string_append (decl, ")"); + return 1; } static void -munge_function_name (name) - string *name; + munge_function_name (name) +string *name; { - if (!string_empty (name) && name->p - name->b >= 3 - && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$') - { - int i; - /* see if it's an assignment expression */ - if (name->p - name->b >= 10 /* op$assign_ */ - && memcmp (name->b + 3, "assign_", 7) == 0) - { - for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + if (!string_empty (name) && name->p - name->b >= 3 + && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$') { - int len = name->p - name->b - 10; - if (strlen (optable[i].in) == len - && memcmp (optable[i].in, name->b + 10, len) == 0) - { - string_clear (name); - string_append (name, "operator"); - string_append (name, optable[i].out); - string_append (name, "="); - return; - } + int i; + /* see if it's an assignment expression */ + if (name->p - name->b >= 10 /* op$assign_ */ + && memcmp (name->b + 3, "assign_", 7) == 0) + { + for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + { + int len = name->p - name->b - 10; + if (strlen (optable[i].in) == len + && memcmp (optable[i].in, name->b + 10, len) == 0) + { + string_clear (name); + string_append (name, "operator"); + string_append (name, optable[i].out); + string_append (name, "="); + return; + } + } + } + else + { + for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + { + int len = name->p - name->b - 3; + if (strlen (optable[i].in) == len + && memcmp (optable[i].in, name->b + 3, len) == 0) + { + string_clear (name); + string_append (name, "operator"); + string_append (name, optable[i].out); + return; + } + } + } + return; } - } - else - { - for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + else if (!string_empty (name) && name->p - name->b >= 5 + && memcmp (name->b, "type$", 5) == 0) { - int len = name->p - name->b - 3; - if (strlen (optable[i].in) == len - && memcmp (optable[i].in, name->b + 3, len) == 0) - { - string_clear (name); - string_append (name, "operator"); - string_append (name, optable[i].out); - return; - } + /* type conversion operator */ + string type; + const char *tem = name->b + 5; + if (do_type (&tem, &type)) + { + string_clear (name); + string_append (name, "operator "); + string_appends (name, &type); + string_delete (&type); + return; + } } - } - return; - } - else if (!string_empty (name) && name->p - name->b >= 5 - && memcmp (name->b, "type$", 5) == 0) - { - /* type conversion operator */ - string type; - const char *tem = name->b + 5; - if (do_type (&tem, &type)) - { - string_clear (name); - string_append (name, "operator "); - string_appends (name, &type); - string_delete (&type); - return; - } - } } /* a mini string-handling package */ static void -string_need (s, n) - string *s; - int n; + string_need (s, n) +string *s; +int n; { - if (s->b == NULL) - { - if (n < 32) - n = 32; - s->p = s->b = (char *) xmalloc (n); - s->e = s->b + n; - } - else if (s->e - s->p < n) - { - int tem = s->p - s->b; - n += tem; - n *= 2; - s->b = (char *) xrealloc (s->b, n); - s->p = s->b + tem; - s->e = s->b + n; - } + if (s->b == NULL) + { + if (n < 32) + n = 32; + s->p = s->b = (char *) xmalloc (n); + s->e = s->b + n; + } + else if (s->e - s->p < n) + { + int tem = s->p - s->b; + n += tem; + n *= 2; + s->b = (char *) xrealloc (s->b, n); + s->p = s->b + tem; + s->e = s->b + n; + } } static void -string_delete (s) - string *s; + string_delete (s) +string *s; { - if (s->b != NULL) - { - free (s->b); - s->b = s->e = s->p = NULL; - } + if (s->b != NULL) + { + free (s->b); + s->b = s->e = s->p = NULL; + } } static void -string_init (s) - string *s; + string_init (s) +string *s; { - s->b = s->p = s->e = NULL; + s->b = s->p = s->e = NULL; } static void -string_clear (s) - string *s; + string_clear (s) +string *s; { - s->p = s->b; + s->p = s->b; } static int -string_empty (s) - string *s; + string_empty (s) +string *s; { - return s->b == s->p; + return s->b == s->p; } static void -string_append (p, s) - string *p; - const char *s; + string_append (p, s) +string *p; +const char *s; { - int n; - if (s == NULL || *s == '\0') - return; - n = strlen (s); - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; + int n; + if (s == NULL || *s == '\0') + return; + n = strlen (s); + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; } static void -string_appends (p, s) - string *p, *s; + string_appends (p, s) +string *p, *s; { - int n; - if (s->b == s->p) - return; - n = s->p - s->b; - string_need (p, n); - memcpy (p->p, s->b, n); - p->p += n; + int n; + if (s->b == s->p) + return; + n = s->p - s->b; + string_need (p, n); + memcpy (p->p, s->b, n); + p->p += n; } static void -string_appendn (p, s, n) - string *p; - const char *s; - int n; + string_appendn (p, s, n) +string *p; +const char *s; +int n; { - if (n == 0) - return; - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; + if (n == 0) + return; + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; } static void -string_prepend (p, s) - string *p; - const char *s; + string_prepend (p, s) +string *p; +const char *s; { - if (s == NULL || *s == '\0') - return; - string_prependn (p, s, strlen (s)); + if (s == NULL || *s == '\0') + return; + string_prependn (p, s, strlen (s)); } #if 0 static void -string_prepends (p, s) - string *p, *s; + string_prepends (p, s) +string *p, *s; { - if (s->b == s->p) - return; - string_prependn (p, s->b, s->p - s->b); + if (s->b == s->p) + return; + string_prependn (p, s->b, s->p - s->b); } #endif static void -string_prependn (p, s, n) - string *p; - const char *s; - int n; + string_prependn (p, s, n) +string *p; +const char *s; +int n; { - char *q; - - if (n == 0) - return; - string_need (p, n); - for (q = p->p - 1; q >= p->b; q--) - q[n] = q[0]; - memcpy (p->b, s, n); - p->p += n; + char *q; + + if (n == 0) + return; + string_need (p, n); + for (q = p->p - 1; q >= p->b; q--) + q[n] = q[0]; + memcpy (p->b, s, n); + p->p += n; } + +/* end of cplus-dem.c */ diff --git a/gas/config/ho-a29k.h b/gas/config/ho-a29k.h index 949e07c..a42bec9 100755 --- a/gas/config/ho-a29k.h +++ b/gas/config/ho-a29k.h @@ -1,23 +1,23 @@ /* ho-a29k.h Host-specific header file intended for "eb" board with HIF. - + Copyright (C) 1987, 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 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. */ /* $Id$ */ @@ -27,7 +27,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * $Log$ - * Revision 1.2 1991/06/14 14:01:53 rich + * Revision 1.3 1992/02/13 08:31:13 rich + * 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. + * + * Revision 1.2 1991/06/14 14:01:53 rich * Version 2 GPL. * * Revision 1.1 1991/04/13 10:03:23 rich diff --git a/gas/config/ho-ansi.h b/gas/config/ho-ansi.h index 1e8ed7d..16bfa65 100644 --- a/gas/config/ho-ansi.h +++ b/gas/config/ho-ansi.h @@ -1,21 +1,21 @@ /* ho-ansi.h Host-specific header file for generic ansi environments. Copyright (C) 1987, 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 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. */ /* $Id$ */ @@ -31,7 +31,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * $Log$ - * Revision 1.2 1991/06/14 14:01:54 rich + * Revision 1.3 1992/02/13 08:31:15 rich + * 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. + * + * Revision 1.2 1991/06/14 14:01:54 rich * Version 2 GPL. * * Revision 1.1.1.1 1991/04/04 18:15:39 rich diff --git a/gas/config/ho-cygnus.h b/gas/config/ho-cygnus.h index 27cfebd..9066f56 100755 --- a/gas/config/ho-cygnus.h +++ b/gas/config/ho-cygnus.h @@ -1,21 +1,21 @@ /* ho-ansi.h Host-specific header file for generic ansi environments. Copyright (C) 1987, 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 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. */ /* $Id$ */ @@ -32,7 +32,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * $Log$ - * Revision 1.2 1991/06/14 14:01:55 rich + * Revision 1.3 1992/02/13 08:31:17 rich + * 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. + * + * Revision 1.2 1991/06/14 14:01:55 rich * Version 2 GPL. * * Revision 1.1.1.1 1991/04/04 18:15:42 rich @@ -44,4 +50,4 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * */ -/* end of ho-ansi.h */ +/* end of ho-cygnus.h */ diff --git a/gas/config/ho-decstation.h b/gas/config/ho-decstation.h index b6b8c75..c759d0f 100644 --- a/gas/config/ho-decstation.h +++ b/gas/config/ho-decstation.h @@ -1,21 +1,21 @@ /* ho-pmax.h Host-specific header file for decstation 3100. Copyright (C) 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 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. */ #include <string.h> @@ -26,4 +26,4 @@ extern int free(); #define know(x) #endif /* not gcc */ -/* end of ho-pmax.h */ +/* end of ho-decstation.h */ diff --git a/gas/config/ho-generic.h b/gas/config/ho-generic.h index cb61b56..93d843a 100644 --- a/gas/config/ho-generic.h +++ b/gas/config/ho-generic.h @@ -1,21 +1,25 @@ /* ho-generic.h Generic host-specific header file. Copyright 1987, 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. */ + +/* It is my intent that this become a file capable of config'ing and + compiling for nearly any host as aid for testing and porting. + xoxorich. */ /* $Id$ */ diff --git a/gas/config/ho-hpux.h b/gas/config/ho-hpux.h index 015fd20..a353448 100644 --- a/gas/config/ho-hpux.h +++ b/gas/config/ho-hpux.h @@ -1,21 +1,21 @@ /* ho-hpux.h -- Header to compile the assembler under HP-UX Copyright (C) 1988, 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 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. */ /* $Id$ */ @@ -32,3 +32,5 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif /* setbuffer */ #define setbuffer(stream, buf, size) + +/* end of ho-hpux.h */ diff --git a/gas/config/ho-i386.h b/gas/config/ho-i386.h index d701b1a..78d79a9 100644 --- a/gas/config/ho-i386.h +++ b/gas/config/ho-i386.h @@ -1,21 +1,21 @@ /* ho-i386.h i386 specific header file. Copyright (C) 1987, 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 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. */ /* $Id$ */ diff --git a/gas/config/ho-rs6000.h b/gas/config/ho-rs6000.h index 250b23c..c5a86eb 100644 --- a/gas/config/ho-rs6000.h +++ b/gas/config/ho-rs6000.h @@ -1,21 +1,21 @@ /* ho-rs6000.h Rs6000 host-specific header file. Copyright (C) 1987, 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 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 M_RS6000 1 diff --git a/gas/config/ho-sysv.h b/gas/config/ho-sysv.h index 18560af..49494e2 100644 --- a/gas/config/ho-sysv.h +++ b/gas/config/ho-sysv.h @@ -1,21 +1,21 @@ /* ho-sysv.h System V specific header file. Copyright (C) 1987, 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 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. */ /* $Id$ */ diff --git a/gas/config/ho-vax.h b/gas/config/ho-vax.h index 6c2b89d..26b3d87 100644 --- a/gas/config/ho-vax.h +++ b/gas/config/ho-vax.h @@ -1,21 +1,21 @@ /* ho-vax.h Intended for vax ultrix Copyright (C) 1987, 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 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 M_VAX 1 diff --git a/gas/config/obj-aout.c b/gas/config/obj-aout.c index 6c1e100..7b7b59d 100644 --- a/gas/config/obj-aout.c +++ b/gas/config/obj-aout.c @@ -1,44 +1,42 @@ /* a.out object file format Copyright (C) 1989, 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. */ - -/* $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. */ #include "as.h" - +#include "aout/stab_gnu.h" #include "obstack.h" - /* in: segT out: N_TYPE bits */ +/* in: segT out: N_TYPE bits */ const short seg_N_TYPE[] = { - N_ABS, - N_TEXT, - N_DATA, - N_BSS, - N_UNDF, /* unknown */ - N_UNDF, /* absent */ - N_UNDF, /* pass1 */ - N_UNDF, /* error */ - N_UNDF, /* bignum/flonum */ - N_UNDF, /* difference */ - N_UNDF, /* debug */ - N_UNDF, /* ntv */ - N_UNDF, /* ptv */ - N_REGISTER, /* register */ + N_ABS, + N_TEXT, + N_DATA, + N_BSS, + N_UNDF, /* unknown */ + N_UNDF, /* absent */ + N_UNDF, /* pass1 */ + N_UNDF, /* error */ + N_UNDF, /* bignum/flonum */ + N_UNDF, /* difference */ + N_UNDF, /* debug */ + N_UNDF, /* ntv */ + N_UNDF, /* ptv */ + N_REGISTER, /* register */ }; const segT N_TYPE_seg [N_TYPE+2] = { /* N_TYPE == 0x1E = 32-2 */ @@ -70,13 +68,43 @@ static void obj_aout_line(); #endif /* __STDC__ */ const pseudo_typeS obj_pseudo_table[] = { +#ifndef IGNORE_DEBUG + /* stabs debug info */ { "line", obj_aout_line, 0 }, /* source code line number */ - { "ln", obj_aout_line, 0 }, /* source code line number */ - { "desc", obj_aout_desc, 0 }, /* def */ + { "ln", obj_aout_line, 0 }, /* coff line number that we use anyway */ + { "desc", obj_aout_desc, 0 }, /* desc */ { "stabd", obj_aout_stab, 'd' }, /* stabs */ { "stabn", obj_aout_stab, 'n' }, /* stabs */ { "stabs", obj_aout_stab, 's' }, /* stabs */ - +#else /* IGNORE_DEBUG */ + { "line", obj_aout_line, 0 }, /* source code line number */ + { "ln", obj_aout_line, 0 }, /* coff line number that we use anyway */ + { "desc", obj_aout_desc, 0 }, /* desc */ + { "stabd", obj_aout_stab, 'd' }, /* stabs */ + { "stabn", obj_aout_stab, 'n' }, /* stabs */ + { "stabs", obj_aout_stab, 's' }, /* stabs */ +#endif /* IGNORE_DEBUG */ + + /* coff debug pseudos (ignored) */ + { "def", s_ignore, 0 }, + { "dim", s_ignore, 0 }, + { "endef", s_ignore, 0 }, + { "ident", s_ignore, 0 }, + { "line", s_ignore, 0 }, + { "ln", s_ignore, 0 }, + { "scl", s_ignore, 0 }, + { "size", s_ignore, 0 }, + { "tag", s_ignore, 0 }, + { "type", s_ignore, 0 }, + { "val", s_ignore, 0 }, + { "version", s_ignore, 0 }, + + /* stabs-in-coff (?) debug pseudos (ignored) */ + { "optim", s_ignore, 0 }, /* For sun386i cc (?) */ + + /* other stuff */ + { "ABORT", s_abort, 0 }, + { NULL} /* end sentinel */ }; /* obj_pseudo_table */ @@ -84,16 +112,6 @@ const pseudo_typeS obj_pseudo_table[] = { /* Relocation. */ /* - * In: length of relocation (or of address) in chars: 1, 2 or 4. - * Out: GNU LD relocation length code: 0, 1, or 2. - */ - -static unsigned char -nbytes_r_length [] = { - 42, 0, 1, 42, 2 - }; - -/* * emit_relocations() * * Crawl along a fixS chain. Emit the segment's relocations. @@ -103,42 +121,15 @@ char **where; fixS *fixP; /* Fixup chain for this segment. */ relax_addressT segment_address_in_file; { - struct reloc_info_generic ri; - register symbolS *symbolP; - - /* If a machine dependent emitter is needed, call it instead. */ - if (md_emit_relocations) { - (*md_emit_relocations) (fixP, segment_address_in_file); - return; - } - - /* JF this is for paranoia */ - bzero((char *)&ri,sizeof(ri)); for (; fixP; fixP = fixP->fx_next) { - if ((symbolP = fixP->fx_addsy) != 0) { - ri.r_bsr = fixP->fx_bsr; - ri.r_disp = fixP->fx_im_disp; - ri.r_callj = fixP->fx_callj; - ri.r_length = nbytes_r_length [fixP->fx_size]; - ri.r_pcrel = fixP->fx_pcrel; - ri.r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file; - - if (S_GET_TYPE(symbolP) == N_UNDF) { - ri.r_extern = 1; - ri.r_symbolnum = symbolP->sy_number; - } else { - ri.r_extern = 0; - ri.r_symbolnum = S_GET_TYPE(symbolP); - } - - /* Output the relocation information in machine-dependent form. */ - md_ri_to_chars(*where, &ri); + if (fixP->fx_addsy != NULL) { + tc_aout_fix_to_chars(*where, fixP, segment_address_in_file); *where += md_reloc_size; } /* if there is an add symbol */ } /* for each fix */ - + return; -} /* emit_relocations() */ +} /* obj_emit_relocations() */ /* Aout file generation & utilities */ void obj_header_append(where, headers) @@ -146,8 +137,8 @@ char **where; object_headers *headers; { tc_headers_hook(headers); - -#ifdef CROSS_ASSEMBLE + +#ifdef CROSS_COMPILE md_number_to_chars(*where, headers->header.a_info, sizeof(headers->header.a_info)); *where += sizeof(headers->header.a_info); md_number_to_chars(*where, headers->header.a_text, sizeof(headers->header.a_text)); @@ -164,20 +155,12 @@ object_headers *headers; *where += sizeof(headers->header.a_trsize); md_number_to_chars(*where, headers->header.a_drsize, sizeof(headers->header.a_drsize)); *where += sizeof(headers->header.a_drsize); -#ifdef EXEC_MACHINE_TYPE - md_number_to_chars(*where, headers->header.a_machtype, sizeof(headers->header.a_machtype)); - *where += sizeof(headers->header.a_machtype); -#endif /* EXEC_MACHINE_TYPE */ -#ifdef EXEC_VERSION - md_number_to_chars(*where, headers->header.a_version, sizeof(headers->header.a_version)); - *where += sizeof(headers->header.a_version); -#endif /* EXEC_VERSION */ - -#else /* CROSS_ASSEMBLE */ - + +#else /* CROSS_COMPILE */ + append(where, (char *) &headers->header, sizeof(headers->header)); -#endif /* CROSS_ASSEMBLE */ - +#endif /* CROSS_COMPILE */ + return; } /* obj_append_header() */ @@ -188,7 +171,7 @@ symbolS *symbolP; md_number_to_chars((char *)&(S_GET_OFFSET(symbolP)), S_GET_OFFSET(symbolP), sizeof(S_GET_OFFSET(symbolP))); md_number_to_chars((char *)&(S_GET_DESC(symbolP)), S_GET_DESC(symbolP), sizeof(S_GET_DESC(symbolP))); md_number_to_chars((char *)&(S_GET_VALUE(symbolP)), S_GET_VALUE(symbolP), sizeof(S_GET_VALUE(symbolP))); - + append(where, (char *)&symbolP->sy_symbol, sizeof(obj_symbol_type)); } /* obj_symbol_to_chars() */ @@ -196,27 +179,29 @@ void obj_emit_symbols(where, symbol_rootP) char **where; symbolS *symbol_rootP; { - symbolS * symbolP; - - /* - * Emit all symbols left in the symbol chain. - */ - for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - /* Used to save the offset of the name. It is used to point - to the string in memory but must be a file offset. */ - register char *temp; - - temp = S_GET_NAME(symbolP); - S_SET_OFFSET(symbolP, symbolP->sy_name_offset); - - /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ - if (!S_IS_DEBUG(symbolP) && !S_IS_DEFINED(symbolP)) S_SET_EXTERNAL(symbolP); - - obj_symbol_to_chars(where, symbolP); - S_SET_NAME(symbolP,temp); - } + symbolS * symbolP; + + /* + * Emit all symbols left in the symbol chain. + */ + for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { + /* Used to save the offset of the name. It is used to point + to the string in memory but must be a file offset. */ + register char *temp; + + temp = S_GET_NAME(symbolP); + S_SET_OFFSET(symbolP, symbolP->sy_name_offset); + + /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ + if (!S_IS_DEBUG(symbolP) && !S_IS_DEFINED(symbolP)) S_SET_EXTERNAL(symbolP); + + obj_symbol_to_chars(where, symbolP); + S_SET_NAME(symbolP,temp); + } } /* emit_symbols() */ +#if comment +/* uneeded if symbol is born zeroed. */ void obj_symbol_new_hook(symbolP) symbolS *symbolP; { @@ -224,6 +209,7 @@ symbolS *symbolP; S_SET_DESC(symbolP, 0); return; } /* obj_symbol_new_hook() */ +#endif /* comment */ static void obj_aout_line() { /* Assume delimiter is part of expression. */ @@ -255,33 +241,35 @@ static void obj_aout_line() { static void obj_aout_stab(what) int what; { - register symbolS * symbolP = 0; - register char * string; - int saved_type = 0; - int length; - int goof; /* TRUE if we have aborted. */ - long longint; - -/* - * Enter with input_line_pointer pointing past .stabX and any following - * whitespace. - */ + extern int listing; + + register symbolS * symbolP = 0; + register char * string; + int saved_type = 0; + int length; + int goof; /* TRUE if we have aborted. */ + long longint; + + /* + * Enter with input_line_pointer pointing past .stabX and any following + * whitespace. + */ goof = 0; /* JF who forgot this?? */ if (what == 's') { string = demand_copy_C_string(& length); SKIP_WHITESPACE(); if (* input_line_pointer == ',') - input_line_pointer ++; + input_line_pointer ++; else { as_bad("I need a comma after symbol's name"); goof = 1; } } else - string = ""; - -/* - * Input_line_pointer->after ','. String->symbol name. - */ + string = ""; + + /* + * Input_line_pointer->after ','. String->symbol name. + */ if (! goof) { symbolP = symbol_new(string, SEG_UNKNOWN, @@ -293,39 +281,39 @@ int what; S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal); symbolP->sy_frag = frag_now; break; - + case 'n': symbolP->sy_frag = &zero_address_frag; break; - + case 's': symbolP->sy_frag = & zero_address_frag; break; - + default: BAD_CASE(what); break; } - + if (get_absolute_expression_and_terminator(&longint) == ',') - symbolP->sy_symbol.n_type = saved_type = longint; + symbolP->sy_symbol.n_type = saved_type = longint; else { as_bad("I want a comma after the n_type expression"); goof = 1; input_line_pointer --; /* Backup over a non-',' char. */ } } - + if (!goof) { if (get_absolute_expression_and_terminator(&longint) == ',') - S_SET_OTHER(symbolP, longint); + S_SET_OTHER(symbolP, longint); else { as_bad("I want a comma after the n_other expression"); goof = 1; input_line_pointer--; /* Backup over a non-',' char. */ } } - + if (!goof) { S_SET_DESC(symbolP, get_absolute_expression()); if (what == 's' || what == 'n') { @@ -337,16 +325,31 @@ int what; } } } - + if ((!goof) && (what=='s' || what=='n')) { pseudo_set(symbolP); symbolP->sy_symbol.n_type = saved_type; } - +#ifndef NO_LISTING + if (listing && !goof) + { + if (symbolP->sy_symbol.n_type == N_SLINE) + { + + listing_source_line(symbolP->sy_symbol.n_desc); + } + else if (symbolP->sy_symbol.n_type == N_SO + || symbolP->sy_symbol.n_type == N_SOL) + { + listing_source_file(string); + } + } +#endif + if (goof) - ignore_rest_of_line(); + ignore_rest_of_line(); else - demand_empty_rest_of_line (); + demand_empty_rest_of_line (); } /* obj_aout_stab() */ static void obj_aout_desc() { @@ -355,10 +358,10 @@ static void obj_aout_desc() { register char *p; register symbolS *symbolP; register int temp; - + /* * Frob invented at RMS' request. Set the n_desc of a symbol. - */ + */ name = input_line_pointer; c = get_symbol_end(); p = input_line_pointer; @@ -390,44 +393,44 @@ object_headers *headers; symbolS *symbolP; symbolS **symbolPP; int symbol_number = 0; - + /* JF deal with forward references first... */ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { if (symbolP->sy_forward) { S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + S_GET_VALUE(symbolP->sy_forward) + symbolP->sy_forward->sy_frag->fr_address); - + symbolP->sy_forward=0; } /* if it has a forward reference */ } /* walk the symbol chain */ - + tc_crawl_symbol_chain(headers); - + symbolPP = &symbol_rootP; /*->last symbol chain link. */ while ((symbolP = *symbolPP) != NULL) { if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) { S_SET_SEGMENT(symbolP, SEG_TEXT); } /* if pusing data into text */ - + S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); - + /* OK, here is how we decide which symbols go out into the brave new symtab. Symbols that do are: - + * symbols with no name (stabd's?) * symbols with debug info in their N_TYPE - + Symbols that don't are: * symbols that are registers * symbols with \1 as their 3rd character (numeric labels) * "local labels" as defined by S_LOCAL_NAME(name) if the -L switch was passed to gas. - + All other symbols are output. We complain if a deleted symbol was marked external. */ - - + + if (!S_IS_REGISTER(symbolP) && (!S_GET_NAME(symbolP) || S_IS_DEBUG(symbolP) @@ -438,7 +441,7 @@ object_headers *headers; #endif /* TC_I960 */ || (S_GET_NAME(symbolP)[0] != '\001' && (flagseen ['L'] || ! S_LOCAL_NAME(symbolP))))) { symbolP->sy_number = symbol_number++; - + /* The + 1 after strlen account for the \0 at the end of each string */ if (!S_IS_STABD(symbolP)) { @@ -451,16 +454,16 @@ object_headers *headers; symbolPP = &(symbol_next(symbolP)); } else { if (S_IS_EXTERNAL(symbolP) || !S_IS_DEFINED(symbolP)) { - as_bad("Local symbol %s never defined", S_GET_NAME(symbolP)); + as_bad("Local symbol %s never defined.", decode_local_label_name(S_GET_NAME(symbolP))); } /* oops. */ - + /* Unhook it from the chain */ *symbolPP = symbol_next(symbolP); } /* if this symbol should be in the output */ } /* for each symbol */ - + H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number); - + return; } /* obj_crawl_symbol_chain() */ @@ -472,24 +475,34 @@ void obj_emit_strings(where) char **where; { symbolS *symbolP; - -#ifdef CROSS_ASSEMBLE + +#ifdef CROSS_COMPILE /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ md_number_to_chars(*where, string_byte_count, sizeof(string_byte_count)); *where += sizeof(string_byte_count); -#else /* CROSS_ASSEMBLE */ +#else /* CROSS_COMPILE */ append (where, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count)); -#endif /* CROSS_ASSEMBLE */ - +#endif /* CROSS_COMPILE */ + for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { if(S_GET_NAME(symbolP)) append(&next_object_file_charP, S_GET_NAME(symbolP), (unsigned long)(strlen (S_GET_NAME(symbolP)) + 1)); } /* walk symbol chain */ - + return; } /* obj_emit_strings() */ +void obj_pre_write_hook(headers) +object_headers *headers; +{ + H_SET_DYNAMIC(headers, 0); + H_SET_VERSION(headers, 0); + H_SET_MACHTYPE(headers, AOUT_MACHTYPE); + tc_aout_pre_write_hook(headers); + return; +} /* obj_pre_write_hook() */ + /* * Local Variables: * comment-column: 0 diff --git a/gas/config/obj-aout.h b/gas/config/obj-aout.h index 44e2c3a..4884fed 100644 --- a/gas/config/obj-aout.h +++ b/gas/config/obj-aout.h @@ -1,21 +1,21 @@ /* a.out object file format Copyright (C) 1989, 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 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. */ /* $Id$ */ @@ -30,23 +30,9 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "a_out.h" #endif -struct reloc_info_generic -{ - unsigned long r_address; -/* - * Using bit fields here is a bad idea because the order is not portable. :-( - */ - unsigned int r_index; -#define r_symbolnum r_index - unsigned r_extern : 1; - unsigned r_pcrel:1; - unsigned r_length:2; /* 0=>byte 1=>short 2=>long 3=>8byte */ - unsigned r_bsr:1; /* NS32K */ - unsigned r_disp:1; /* NS32k */ - unsigned r_callj:1; /* i960 */ - enum reloc_type r_type; - long r_addend; -}; +#ifndef AOUT_MACHTYPE +#define AOUT_MACHTYPE 0 +#endif /* AOUT_MACHTYPE */ extern const short seg_N_TYPE[]; extern const segT N_TYPE_seg[]; @@ -60,12 +46,6 @@ extern const segT N_TYPE_seg[]; typedef struct nlist obj_symbol_type; /* Symbol table entry */ -/* If compiler generate leading underscores, remove them. */ - -#ifndef STRIP_UNDERSCORE -#define STRIP_UNDERSCORE 0 -#endif /* STRIP_UNDERSCORE */ - /* Symbol table macros and constants */ /* @@ -116,7 +96,7 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ /* Set the value of the symbol */ #define S_SET_VALUE(s,v) ((s)->sy_symbol.n_value = (unsigned long) (v)) /* Assume that a symbol cannot be simultaneously in more than on segment */ - /* set segment */ +/* set segment */ #define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg)) /* The symbol is external */ #define S_SET_EXTERNAL(s) ((s)->sy_symbol.n_type |= N_EXT) @@ -148,18 +128,34 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define H_GET_TEXT_RELOCATION_SIZE(h) ((h)->header.a_trsize) #define H_GET_DATA_RELOCATION_SIZE(h) ((h)->header.a_drsize) #define H_GET_SYMBOL_TABLE_SIZE(h) ((h)->header.a_syms) -#define H_GET_MAGIC_NUMBER(h) ((h)->header.a_info) #define H_GET_ENTRY_POINT(h) ((h)->header.a_entry) #define H_GET_STRING_SIZE(h) ((h)->string_table_size) #define H_GET_LINENO_SIZE(h) (0) -#ifdef EXEC_MACHINE_TYPE -#define H_GET_MACHINE_TYPE(h) ((h)->header.a_machtype) -#endif /* EXEC_MACHINE_TYPE */ +#define H_GET_DYNAMIC(h) ((h)->header.a_info >> 31) +#define H_GET_VERSION(h) (((h)->header.a_info >> 24) & 0x7f) +#define H_GET_MACHTYPE(h) (((h)->header.a_info >> 16) & 0xff) +#define H_GET_MAGIC_NUMBER(h) ((h)->header.a_info & 0xffff) -#ifdef EXEC_VERSION -#define H_GET_VERSION(h) ((h)->header.a_version) -#endif /* EXEC_VERSION */ +#define H_SET_DYNAMIC(h,v) ((h)->header.a_info = (((v) << 31) \ + | (H_GET_VERSION(h) << 24) \ + | (H_GET_MACHTYPE(h) << 16) \ + | (H_GET_MAGIC_NUMBER(h)))) + +#define H_SET_VERSION(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \ + | ((v) << 24) \ + | (H_GET_MACHTYPE(h) << 16) \ + | (H_GET_MAGIC_NUMBER(h)))) + +#define H_SET_MACHTYPE(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \ + | (H_GET_VERSION(h) << 24) \ + | ((v) << 16) \ + | (H_GET_MAGIC_NUMBER(h)))) + +#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \ + | (H_GET_VERSION(h) << 24) \ + | (H_GET_MACHTYPE(h) << 16) \ + | ((v)))) #define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = md_section_align(SEG_TEXT, (v))) #define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = md_section_align(SEG_DATA, (v))) @@ -173,16 +169,8 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->header.a_syms = (v) * \ sizeof(struct nlist)) -#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_info = (v)) - #define H_SET_ENTRY_POINT(h,v) ((h)->header.a_entry = (v)) #define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v)) -#ifdef EXEC_MACHINE_TYPE -#define H_SET_MACHINE_TYPE(h,v) ((h)->header.a_machtype = (v)) -#endif /* EXEC_MACHINE_TYPE */ -#ifdef EXEC_VERSION -#define H_SET_VERSION(h,v) ((h)->header.a_version = (v)) -#endif /* EXEC_VERSION */ /* * Current means for getting the name of a segment. @@ -192,13 +180,21 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ extern char *const seg_name[]; typedef struct { - struct exec header; /* a.out header */ - long string_table_size; /* names + '\0' + sizeof(int) */ + struct exec header; /* a.out header */ + long string_table_size; /* names + '\0' + sizeof(int) */ } object_headers; /* line numbering stuff. */ -#define OBJ_EMIT_LINENO(a, b, c) ; -#define obj_pre_write_hook(a) ; +#define OBJ_EMIT_LINENO(a, b, c) {;} + +#define obj_symbol_new_hook(s) {;} + +#ifdef __STDC__ +struct fix; +void tc_aout_fix_to_chars(char *where, struct fix *fixP, relax_addressT segment_address); +#else +void tc_aout_fix_to_chars(); +#endif /* __STDC__ */ /* * Local Variables: diff --git a/gas/config/obj-bfd-sunos.c b/gas/config/obj-bfd-sunos.c index 0bbc600..d8cff8c 100644 --- a/gas/config/obj-bfd-sunos.c +++ b/gas/config/obj-bfd-sunos.c @@ -1,20 +1,40 @@ +/* obj-bfd-sunos.c + Copyright (C) 1987 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. */ + + #include "as.h" static - -const short seg_N_TYPE[] = { - N_ABS, - N_TEXT, - N_DATA, - N_BSS, - N_UNDF, /* unknown */ - N_UNDF, /* absent */ - N_UNDF, /* pass1 */ - N_UNDF, /* error */ - N_UNDF, /* bignum/flonum */ - N_UNDF, /* difference */ - N_REGISTER, /* register */ -}; + + const short seg_N_TYPE[] = { + N_ABS, + N_TEXT, + N_DATA, + N_BSS, + N_UNDF, /* unknown */ + N_UNDF, /* absent */ + N_UNDF, /* pass1 */ + N_UNDF, /* error */ + N_UNDF, /* bignum/flonum */ + N_UNDF, /* difference */ + N_REGISTER, /* register */ + }; const segT N_TYPE_seg [N_TYPE+2] = { /* N_TYPE == 0x1E = 32-2 */ SEG_UNKNOWN, /* N_UNDF == 0 */ diff --git a/gas/config/obj-bfd-sunos.h b/gas/config/obj-bfd-sunos.h index 0d32758..1a28e57 100644 --- a/gas/config/obj-bfd-sunos.h +++ b/gas/config/obj-bfd-sunos.h @@ -1,14 +1,33 @@ /* + Copyright (C) 1987 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 obj-bfd-sunos.h. */ - /* define an obj specific macro off which target cpu back ends may key. */ +/* define an obj specific macro off which target cpu back ends may key. */ #define OBJ_BFD #define OBJ_BFD_SUNOS #include "bfd.h" - /* include whatever target cpu is appropriate. */ +/* include whatever target cpu is appropriate. */ #include "targ-cpu.h" /* @@ -23,7 +42,7 @@ * facilities are available, and they are macros. */ - /* #define SYMBOLS_NEED_PACKPOINTERS */ +/* #define SYMBOLS_NEED_PACKPOINTERS */ typedef asymbol obj_symbol_type; typedef void *object_headers; diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c index 4de551f..3b822a5 100644 --- a/gas/config/obj-bout.c +++ b/gas/config/obj-bout.c @@ -1,21 +1,21 @@ /* b.out object file format Copyright (C) 1989, 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 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. */ /* $Id$ */ @@ -23,19 +23,19 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "obstack.h" #include "aout/stab_gnu.h" const short /* in: segT out: N_TYPE bits */ -seg_N_TYPE[] = { - N_ABS, - N_TEXT, - N_DATA, - N_BSS, - N_UNDF, /* unknown */ - N_UNDF, /* absent */ - N_UNDF, /* pass1 */ - N_UNDF, /* error */ - N_UNDF, /* bignum/flonum */ - N_UNDF, /* difference */ - N_REGISTER, /* register */ -}; + seg_N_TYPE[] = { + N_ABS, + N_TEXT, + N_DATA, + N_BSS, + N_UNDF, /* unknown */ + N_UNDF, /* absent */ + N_UNDF, /* pass1 */ + N_UNDF, /* error */ + N_UNDF, /* bignum/flonum */ + N_UNDF, /* difference */ + N_REGISTER, /* register */ + }; const segT N_TYPE_seg [N_TYPE+2] = { /* N_TYPE == 0x1E = 32-2 */ SEG_UNKNOWN, /* N_UNDF == 0 */ @@ -66,14 +66,14 @@ static void obj_bout_line(); #endif /* __STDC__ */ const pseudo_typeS obj_pseudo_table[] = { - /* stabs (aka a.out aka b.out directives for debug symbols) */ + /* stabs (aka a.out aka b.out directives for debug symbols) */ { "desc", obj_bout_desc, 0 }, /* def */ { "line", obj_bout_line, 0 }, /* source code line number */ { "stabd", obj_bout_stab, 'd' }, /* stabs */ { "stabn", obj_bout_stab, 'n' }, /* stabs */ { "stabs", obj_bout_stab, 's' }, /* stabs */ - - /* coff debugging directives. Currently ignored silently */ + + /* coff debugging directives. Currently ignored silently */ { "def", s_ignore, 0 }, { "dim", s_ignore, 0 }, { "endef", s_ignore, 0 }, @@ -83,11 +83,11 @@ const pseudo_typeS obj_pseudo_table[] = { { "tag", s_ignore, 0 }, { "type", s_ignore, 0 }, { "val", s_ignore, 0 }, - - /* other stuff we don't handle */ + + /* other stuff we don't handle */ { "ABORT", s_ignore, 0 }, { "ident", s_ignore, 0 }, - + { NULL} /* end sentinel */ }; /* obj_pseudo_table */ @@ -109,7 +109,7 @@ relax_addressT segment_address_in_file; *where += sizeof(struct relocation_info); } /* if there's a symbol */ } /* for each fixup */ - + } /* emit_relocations() */ /* Aout file generation & utilities */ @@ -120,19 +120,19 @@ char **where; object_headers *headers; { /* Always leave in host byte order */ - + headers->header.a_talign = section_alignment[SEG_TEXT]; - + if (headers->header.a_talign < 2){ headers->header.a_talign = 2; } /* force to at least 2 */ - + headers->header.a_dalign = section_alignment[SEG_DATA]; headers->header.a_balign = section_alignment[SEG_BSS]; - + headers->header.a_tload = 0; headers->header.a_dload = md_section_align(SEG_DATA, H_GET_TEXT_SIZE(headers)); - + append(where, (char *) &headers->header, sizeof(headers->header)); } /* a_header_append() */ @@ -140,7 +140,7 @@ void obj_symbol_to_chars(where, symbolP) char **where; symbolS *symbolP; { - /* leave in host byte order */ + /* leave in host byte order */ append(where, (char *)&symbolP->sy_symbol, sizeof(obj_symbol_type)); } /* obj_symbol_to_chars() */ @@ -148,25 +148,25 @@ void obj_emit_symbols(where, symbol_rootP) char **where; symbolS *symbol_rootP; { - symbolS * symbolP; - - /* - * Emit all symbols left in the symbol chain. - */ - for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - /* Used to save the offset of the name. It is used to point - to the string in memory but must be a file offset. */ - char *temp; - - temp = S_GET_NAME(symbolP); - S_SET_OFFSET(symbolP, symbolP->sy_name_offset); - - /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ - if (!S_IS_DEBUG(symbolP) && !S_IS_DEFINED(symbolP)) S_SET_EXTERNAL(symbolP); - - obj_symbol_to_chars(where, symbolP); - S_SET_NAME(symbolP,temp); - } + symbolS * symbolP; + + /* + * Emit all symbols left in the symbol chain. + */ + for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { + /* Used to save the offset of the name. It is used to point + to the string in memory but must be a file offset. */ + char *temp; + + temp = S_GET_NAME(symbolP); + S_SET_OFFSET(symbolP, symbolP->sy_name_offset); + + /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ + if (!S_IS_DEBUG(symbolP) && !S_IS_DEFINED(symbolP)) S_SET_EXTERNAL(symbolP); + + obj_symbol_to_chars(where, symbolP); + S_SET_NAME(symbolP,temp); + } } /* emit_symbols() */ void obj_symbol_new_hook(symbolP) @@ -207,33 +207,33 @@ static void obj_bout_line() { static void obj_bout_stab(what) int what; { - register symbolS * symbolP = 0; - register char * string; - int saved_type = 0; - int length; - int goof; /* TRUE if we have aborted. */ - long longint; - -/* - * Enter with input_line_pointer pointing past .stabX and any following - * whitespace. - */ + register symbolS * symbolP = 0; + register char * string; + int saved_type = 0; + int length; + int goof; /* TRUE if we have aborted. */ + long longint; + + /* + * Enter with input_line_pointer pointing past .stabX and any following + * whitespace. + */ goof = 0; /* JF who forgot this?? */ if (what == 's') { string = demand_copy_C_string(& length); SKIP_WHITESPACE(); if (*input_line_pointer == ',') - input_line_pointer ++; + input_line_pointer ++; else { as_bad("I need a comma after symbol's name"); goof = 1; } } else - string = ""; - -/* - * Input_line_pointer->after ','. String->symbol name. - */ + string = ""; + + /* + * Input_line_pointer->after ','. String->symbol name. + */ if (!goof) { symbolP = symbol_new(string, SEG_UNKNOWN, @@ -246,21 +246,21 @@ int what; frag_now->fr_literal); symbolP->sy_frag = frag_now; break; - + case 'n': symbolP->sy_frag = &zero_address_frag; break; - + case 's': symbolP->sy_frag = & zero_address_frag; break; - + default: BAD_CASE(what); break; } if (get_absolute_expression_and_terminator(& longint) == ',') - symbolP->sy_symbol.n_type = saved_type = longint; + symbolP->sy_symbol.n_type = saved_type = longint; else { as_bad("I want a comma after the n_type expression"); goof = 1; @@ -269,7 +269,7 @@ int what; } if (! goof) { if (get_absolute_expression_and_terminator (& longint) == ',') - S_SET_OTHER(symbolP,longint); + S_SET_OTHER(symbolP,longint); else { as_bad("I want a comma after the n_other expression"); goof = 1; @@ -292,30 +292,30 @@ int what; symbolP->sy_symbol.n_type = saved_type; } #ifndef NO_LISTING -{ - extern int listing; - - if (listing && !goof) - { - if (symbolP->sy_symbol.n_type == N_SLINE) - { - - listing_source_line(symbolP->sy_symbol.n_desc); - } - else if (symbolP->sy_symbol.n_type == N_SO - || symbolP->sy_symbol.n_type == N_SOL) - { - listing_source_file(string); - } - } -} - + { + extern int listing; + + if (listing && !goof) + { + if (symbolP->sy_symbol.n_type == N_SLINE) + { + + listing_source_line(symbolP->sy_symbol.n_desc); + } + else if (symbolP->sy_symbol.n_type == N_SO + || symbolP->sy_symbol.n_type == N_SOL) + { + listing_source_file(string); + } + } + } + #endif - + if (goof) - ignore_rest_of_line (); + ignore_rest_of_line (); else - demand_empty_rest_of_line (); + demand_empty_rest_of_line (); } /* obj_bout_stab() */ static void obj_bout_desc() { @@ -324,7 +324,7 @@ static void obj_bout_desc() { register char *p; register symbolS * symbolP; register int temp; - + /* * Frob invented at RMS' request. Set the n_desc of a symbol. */ @@ -359,44 +359,44 @@ object_headers *headers; symbolS **symbolPP; symbolS *symbolP; int symbol_number = 0; - + /* JF deal with forward references first... */ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { if (symbolP->sy_forward) { S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + S_GET_VALUE(symbolP->sy_forward) + symbolP->sy_forward->sy_frag->fr_address); - + symbolP->sy_forward=0; } /* if it has a forward reference */ } /* walk the symbol chain */ - + tc_crawl_symbol_chain(headers); - + symbolPP = & symbol_rootP; /*->last symbol chain link. */ while ((symbolP = *symbolPP) != NULL) { if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) { S_SET_SEGMENT(symbolP, SEG_TEXT); } /* if pusing data into text */ - + S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); - + /* OK, here is how we decide which symbols go out into the brave new symtab. Symbols that do are: - + * symbols with no name (stabd's?) * symbols with debug info in their N_TYPE - + Symbols that don't are: * symbols that are registers * symbols with \1 as their 3rd character (numeric labels) * "local labels" as defined by S_LOCAL_NAME(name) if the -L switch was passed to gas. - + All other symbols are output. We complain if a deleted symbol was marked external. */ - - + + if (1 && !S_IS_REGISTER(symbolP) && (!S_GET_NAME(symbolP) @@ -408,7 +408,7 @@ object_headers *headers; #endif /* TC_I960 */ || (S_GET_NAME(symbolP)[0] != '\001' && (flagseen ['L'] || ! S_LOCAL_NAME(symbolP))))) { symbolP->sy_number = symbol_number++; - + /* The + 1 after strlen account for the \0 at the end of each string */ if (!S_IS_STABD(symbolP)) { @@ -423,14 +423,14 @@ object_headers *headers; if (S_IS_EXTERNAL(symbolP) || !S_IS_DEFINED(symbolP)) { as_bad("Local symbol %s never defined", S_GET_NAME(symbolP)); } /* oops. */ - + /* Unhook it from the chain */ *symbolPP = symbol_next(symbolP); } /* if this symbol should be in the output */ } /* for each symbol */ - + H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number); - + return; } /* obj_crawl_symbol_chain() */ @@ -442,7 +442,7 @@ void obj_emit_strings(where) char **where; { symbolS *symbolP; - + #ifdef CROSS_COMPILE /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ md_number_to_chars(*where, string_byte_count, sizeof(string_byte_count)); @@ -450,12 +450,12 @@ char **where; #else /* CROSS_COMPILE */ append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count)); #endif /* CROSS_COMPILE */ - + for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { if(S_GET_NAME(symbolP)) append(where, S_GET_NAME(symbolP), (unsigned long)(strlen (S_GET_NAME(symbolP)) + 1)); } /* walk symbol chain */ - + return; } /* obj_emit_strings() */ diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h index 272c0c4..609e8c8 100644 --- a/gas/config/obj-bout.h +++ b/gas/config/obj-bout.h @@ -1,22 +1,22 @@ /* b.out object file format Copyright (C) 1989, 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 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. */ /* $Id$ */ @@ -59,12 +59,12 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA #include "targ-cpu.h" - /* bout uses host byte order for headers */ +/* bout uses host byte order for headers */ #ifdef CROSS_COMPILE #undef CROSS_COMPILE #endif /* CROSS_COMPILE */ - /* We want \v. */ +/* We want \v. */ #define BACKSLASH_V 1 #define OBJ_DEFAULT_OUTPUT_FILE_NAME "b.out" @@ -100,7 +100,7 @@ struct exec { unsigned long a_entry; /* Runtime start address */ unsigned long a_trsize; /* Length of text relocation info */ unsigned long a_drsize; /* Length of data relocation info */ - + /* Added for i960 */ unsigned long a_tload; /* Text runtime load address */ unsigned long a_dload; /* Data runtime load address */ @@ -151,21 +151,21 @@ typedef struct nlist obj_symbol_type; struct relocation_info { int r_address; /* File address of item to be relocated */ unsigned - r_index:24,/* Index of symbol on which relocation is based*/ - r_pcrel:1, /* 1 => relocate PC-relative; else absolute - * On i960, pc-relative implies 24-bit - * address, absolute implies 32-bit. - */ - r_length:2, /* Number of bytes to relocate: - * 0 => 1 byte - * 1 => 2 bytes - * 2 => 4 bytes -- only value used for i960 - */ - r_extern:1, - r_bsr:1, /* Something for the GNU NS32K assembler */ - r_disp:1, /* Something for the GNU NS32K assembler */ - r_callj:1, /* 1 if relocation target is an i960 'callj' */ - nuthin:1; /* Unused */ + r_index:24,/* Index of symbol on which relocation is based*/ + r_pcrel:1, /* 1 => relocate PC-relative; else absolute + * On i960, pc-relative implies 24-bit + * address, absolute implies 32-bit. + */ + r_length:2, /* Number of bytes to relocate: + * 0 => 1 byte + * 1 => 2 bytes + * 2 => 4 bytes -- only value used for i960 + */ + r_extern:1, + r_bsr:1, /* Something for the GNU NS32K assembler */ + r_disp:1, /* Something for the GNU NS32K assembler */ + r_callj:1, /* 1 if relocation target is an i960 'callj' */ + nuthin:1; /* Unused */ }; #endif /* CUSTOM_RELOC_FORMAT */ @@ -217,7 +217,7 @@ struct relocation_info { /* Set the value of the symbol */ #define S_SET_VALUE(s,v) ((s)->sy_symbol.n_value = (unsigned long) (v)) /* Assume that a symbol cannot be simultaneously in more than on segment */ - /* set segment */ +/* set segment */ #define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg)) /* The symbol is external */ #define S_SET_EXTERNAL(s) ((s)->sy_symbol.n_type |= N_EXT) @@ -291,8 +291,8 @@ struct relocation_info { extern char *const seg_name[]; typedef struct { - struct exec header; /* a.out header */ - long string_table_size; /* names + '\0' + sizeof(int) */ + struct exec header; /* a.out header */ + long string_table_size; /* names + '\0' + sizeof(int) */ } object_headers; /* unused hooks. */ diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index b157acc..77b75f8 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1,21 +1,21 @@ /* coff object file format Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. - -This file is part of GAS. - -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. + + 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. */ /* $Id$ */ @@ -47,19 +47,19 @@ const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */ const segT N_TYPE_seg [32] = { - SEG_PTV, /* C_PTV_SECTION == -4 */ - SEG_NTV, /* C_NTV_SECTION == -3 */ - SEG_DEBUG, /* C_DEBUG_SECTION == -2 */ - SEG_ABSOLUTE, /* C_ABS_SECTION == -1 */ - SEG_UNKNOWN, /* C_UNDEF_SECTION == 0 */ - SEG_TEXT, /* C_TEXT_SECTION == 1 */ - SEG_DATA, /* C_DATA_SECTION == 2 */ - SEG_BSS, /* C_BSS_SECTION == 3 */ - SEG_REGISTER, /* C_REGISTER_SECTION == 4 */ - SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF, - SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF, - SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF -}; + SEG_PTV, /* C_PTV_SECTION == -4 */ + SEG_NTV, /* C_NTV_SECTION == -3 */ + SEG_DEBUG, /* C_DEBUG_SECTION == -2 */ + SEG_ABSOLUTE, /* C_ABS_SECTION == -1 */ + SEG_UNKNOWN, /* C_UNDEF_SECTION == 0 */ + SEG_TEXT, /* C_TEXT_SECTION == 1 */ + SEG_DATA, /* C_DATA_SECTION == 2 */ + SEG_BSS, /* C_BSS_SECTION == 3 */ + SEG_REGISTER, /* C_REGISTER_SECTION == 4 */ + SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF, + SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF, + SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF + }; #ifdef __STDC__ @@ -134,29 +134,29 @@ const pseudo_typeS obj_pseudo_table[] = { { "type", s_ignore, 0 }, { "val", s_ignore, 0 }, #endif /* ignore debug */ - + { "ident", s_ignore, 0 }, /* we don't yet handle this. */ - - - /* stabs aka a.out aka b.out directives for debug symbols. - Currently ignored silently. Except for .line at which - we guess from context. */ + + + /* stabs aka a.out aka b.out directives for debug symbols. + Currently ignored silently. Except for .line at which + we guess from context. */ { "desc", s_ignore, 0 }, /* def */ -/* { "line", s_ignore, 0 }, */ /* source code line number */ + /* { "line", s_ignore, 0 }, */ /* source code line number */ { "stabd", obj_coff_stab, 'd' }, /* stabs */ { "stabn", obj_coff_stab, 'n' }, /* stabs */ { "stabs", obj_coff_stab, 's' }, /* stabs */ - - /* stabs-in-coff (?) debug pseudos (ignored) */ + + /* stabs-in-coff (?) debug pseudos (ignored) */ { "optim", s_ignore, 0 }, /* For sun386i cc (?) */ - /* other stuff */ + /* other stuff */ { "ABORT", s_abort, 0 }, - + { NULL} /* end sentinel */ }; /* obj_pseudo_table */ - /* obj dependant output values */ +/* obj dependant output values */ #ifdef BFD_HEADERS static struct internal_scnhdr bss_section_header; struct internal_scnhdr data_section_header; @@ -185,7 +185,7 @@ relax_addressT segment_address_in_file; RELOC ri; #endif symbolS *symbolP; - + bzero((char *)&ri,sizeof(ri)); for (; fixP; fixP = fixP->fx_next) { if (symbolP = fixP->fx_addsy) { @@ -212,7 +212,7 @@ relax_addressT segment_address_in_file; : R_RELLONG); #elif defined(TC_A29K) ri.r_type = tc_coff_fix2rtype(fixP); - + #else you lose #endif /* TC_M68K || TC_I386 */ @@ -244,7 +244,7 @@ relax_addressT segment_address_in_file; : ((SF_GET_LOCAL(symbolP) ? dot_bss_symbol->sy_number : symbolP->sy_number)))); /* bss or undefined */ - + /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */ @@ -255,34 +255,34 @@ relax_addressT segment_address_in_file; Two relocations are emmited, R_IHIHALF, and R_IHCONST. The second one doesn't contain a symbol, but uses the value for offset */ if (ri.r_type == R_IHIHALF) { - /* now emit the second bit */ - ri.r_type = R_IHCONST; - ri.r_symndx = fixP->fx_addnumber; - *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where); + /* now emit the second bit */ + ri.r_type = R_IHCONST; + ri.r_symndx = fixP->fx_addnumber; + *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where); } - + #endif - + #else append(where, (char *) &ri, sizeof(ri)); #endif - + #ifdef TC_I960 if (fixP->fx_callj) { ri.r_type = R_OPTCALL; #ifdef BFD_HEADERS - *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where); + *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where); #else - append(where, (char *) &ri, sizeof(ri)); + append(where, (char *) &ri, sizeof(ri)); #endif - - + + } /* if it's a callj, do it again for the opcode */ #endif /* TC_I960 */ - + } /* if there's a symbol */ } /* for each fixP */ - + return; } /* obj_emit_relocations() */ @@ -293,15 +293,15 @@ void obj_header_append(where, headers) char **where; object_headers *headers; { - tc_headers_hook(headers); - *where += bfd_coff_swap_filehdr_out(stdoutput, &(headers->filehdr), *where); + tc_headers_hook(headers); + *where += bfd_coff_swap_filehdr_out(stdoutput, &(headers->filehdr), *where); #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER - *where += bfd_coff_swap_aouthdr_out(stdoutput, &(headers->aouthdr), *where); + *where += bfd_coff_swap_aouthdr_out(stdoutput, &(headers->aouthdr), *where); #endif - obj_coff_section_header_append(where, &text_section_header); - obj_coff_section_header_append(where, &data_section_header); - obj_coff_section_header_append(where, &bss_section_header); - + obj_coff_section_header_append(where, &text_section_header); + obj_coff_section_header_append(where, &data_section_header); + obj_coff_section_header_append(where, &bss_section_header); + } #else @@ -311,7 +311,7 @@ char **where; object_headers *headers; { tc_headers_hook(headers); - + #ifdef CROSS_COMPILE /* Eventually swap bytes for cross compilation for file header */ md_number_to_chars(*where, headers->filehdr.f_magic, sizeof(headers->filehdr.f_magic)); @@ -328,7 +328,7 @@ object_headers *headers; *where += sizeof(headers->filehdr.f_opthdr); md_number_to_chars(*where, headers->filehdr.f_flags, sizeof(headers->filehdr.f_flags)); *where += sizeof(headers->filehdr.f_flags); - + #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER /* Eventually swap bytes for cross compilation for a.out header */ md_number_to_chars(*where, headers->aouthdr.magic, sizeof(headers->aouthdr.magic)); @@ -350,21 +350,21 @@ object_headers *headers; md_number_to_chars(*where, headers->aouthdr.tagentries, sizeof(headers->aouthdr.tagentries)); *where += sizeof(headers->aouthdr.tagentries); #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */ - + #else /* CROSS_COMPILE */ - + append(where, (char *) &headers->filehdr, sizeof(headers->filehdr)); #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER append(where, (char *) &headers->aouthdr, sizeof(headers->aouthdr)); #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */ - + #endif /* CROSS_COMPILE */ - + /* Output the section headers */ obj_coff_section_header_append(where, &text_section_header); obj_coff_section_header_append(where, &data_section_header); obj_coff_section_header_append(where, &bss_section_header); - + return; } /* obj_header_append() */ #endif @@ -373,97 +373,99 @@ char **where; symbolS *symbolP; { #ifdef BFD_HEADERS - unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; - unsigned int i; - + unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; + unsigned int i; + if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) { - S_SET_SEGMENT(symbolP, SEG_ABSOLUTE); + S_SET_SEGMENT(symbolP, SEG_ABSOLUTE); } - *where += bfd_coff_swap_sym_out(stdoutput, &symbolP->sy_symbol.ost_entry, - *where); - - for (i = 0; i < numaux; i++) - { - *where += bfd_coff_swap_aux_out(stdoutput, - &symbolP->sy_symbol.ost_auxent[i], - S_GET_DATA_TYPE(symbolP), - S_GET_STORAGE_CLASS(symbolP), + *where += bfd_coff_swap_sym_out(stdoutput, &symbolP->sy_symbol.ost_entry, *where); - } - -#else - SYMENT *syment = &symbolP->sy_symbol.ost_entry; - int i; - char numaux = syment->n_numaux; - unsigned short type = S_GET_DATA_TYPE(symbolP); - + + for (i = 0; i < numaux; i++) + { + *where += bfd_coff_swap_aux_out(stdoutput, + &symbolP->sy_symbol.ost_auxent[i], + S_GET_DATA_TYPE(symbolP), + S_GET_STORAGE_CLASS(symbolP), + *where); + } + +#else /* BFD_HEADERS */ + SYMENT *syment = &symbolP->sy_symbol.ost_entry; + int i; + char numaux = syment->n_numaux; + unsigned short type = S_GET_DATA_TYPE(symbolP); + #ifdef CROSS_COMPILE - md_number_to_chars(*where, syment->n_value, sizeof(syment->n_value)); - *where += sizeof(syment->n_value); - md_number_to_chars(*where, syment->n_scnum, sizeof(syment->n_scnum)); - *where += sizeof(syment->n_scnum); - md_number_to_chars(*where, syment->n_type, sizeof(syment->n_type)); - *where += sizeof(syment->n_type); - md_number_to_chars(*where, syment->n_sclass, sizeof(syment->n_sclass)); - *where += sizeof(syment->n_sclass); - md_number_to_chars(*where, syment->n_numaux, sizeof(syment->n_numaux)); - *where += sizeof(syment->n_numaux); + md_number_to_chars(*where, syment->n_value, sizeof(syment->n_value)); + *where += sizeof(syment->n_value); + md_number_to_chars(*where, syment->n_scnum, sizeof(syment->n_scnum)); + *where += sizeof(syment->n_scnum); + md_number_to_chars(*where, 0, sizeof(short)); /* pad n_flags */ + *where += sizeof(short); + md_number_to_chars(*where, syment->n_type, sizeof(syment->n_type)); + *where += sizeof(syment->n_type); + md_number_to_chars(*where, syment->n_sclass, sizeof(syment->n_sclass)); + *where += sizeof(syment->n_sclass); + md_number_to_chars(*where, syment->n_numaux, sizeof(syment->n_numaux)); + *where += sizeof(syment->n_numaux); #else /* CROSS_COMPILE */ - append(where, (char *) syment, sizeof(*syment)); + append(where, (char *) syment, sizeof(*syment)); #endif /* CROSS_COMPILE */ - - /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */ - if (numaux > OBJ_COFF_MAX_AUXENTRIES) { - as_bad("Internal error? too many auxents for symbol"); - } /* too many auxents */ - - for (i = 0; i < numaux; ++i) { + + /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */ + if (numaux > OBJ_COFF_MAX_AUXENTRIES) { + as_bad("Internal error? too many auxents for symbol"); + } /* too many auxents */ + + for (i = 0; i < numaux; ++i) { #ifdef CROSS_COMPILE #if 0 /* This code has never been tested */ - /* The most common case, x_sym entry. */ - if ((SF_GET(symbolP) & (SF_FILE | SF_STATICS)) == 0) { - md_number_to_chars(*where, auxP->x_sym.x_tagndx, sizeof(auxP->x_sym.x_tagndx)); - *where += sizeof(auxP->x_sym.x_tagndx); - if (ISFCN(type)) { - md_number_to_chars(*where, auxP->x_sym.x_misc.x_fsize, sizeof(auxP->x_sym.x_misc.x_fsize)); - *where += sizeof(auxP->x_sym.x_misc.x_fsize); - } else { - md_number_to_chars(*where, auxP->x_sym.x_misc.x_lnno, sizeof(auxP->x_sym.x_misc.x_lnno)); - *where += sizeof(auxP->x_sym.x_misc.x_lnno); - md_number_to_chars(*where, auxP->x_sym.x_misc.x_size, sizeof(auxP->x_sym.x_misc.x_size)); - *where += sizeof(auxP->x_sym.x_misc.x_size); - } - if (ISARY(type)) { - register int index; - for (index = 0; index < DIMNUM; index++) - md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_ary.x_dimen[index], sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index])); - *where += sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]); - } else { - md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr)); - *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr); - md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_endndx, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx)); - *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx); - } - md_number_to_chars(*where, auxP->x_sym.x_tvndx, sizeof(auxP->x_sym.x_tvndx)); - *where += sizeof(auxP->x_sym.x_tvndx); - } else if (SF_GET_FILE(symbolP)) { /* .file */ - ; - } else if (SF_GET_STATICS(symbolP)) { /* .text, .data, .bss symbols */ - md_number_to_chars(*where, auxP->x_scn.x_scnlen, sizeof(auxP->x_scn.x_scnlen)); - *where += sizeof(auxP->x_scn.x_scnlen); - md_number_to_chars(*where, auxP->x_scn.x_nreloc, sizeof(auxP->x_scn.x_nreloc)); - *where += sizeof(auxP->x_scn.x_nreloc); - md_number_to_chars(*where, auxP->x_scn.x_nlinno, sizeof(auxP->x_scn.x_nlinno)); - *where += sizeof(auxP->x_scn.x_nlinno); - } + /* The most common case, x_sym entry. */ + if ((SF_GET(symbolP) & (SF_FILE | SF_STATICS)) == 0) { + md_number_to_chars(*where, auxP->x_sym.x_tagndx, sizeof(auxP->x_sym.x_tagndx)); + *where += sizeof(auxP->x_sym.x_tagndx); + if (ISFCN(type)) { + md_number_to_chars(*where, auxP->x_sym.x_misc.x_fsize, sizeof(auxP->x_sym.x_misc.x_fsize)); + *where += sizeof(auxP->x_sym.x_misc.x_fsize); + } else { + md_number_to_chars(*where, auxP->x_sym.x_misc.x_lnno, sizeof(auxP->x_sym.x_misc.x_lnno)); + *where += sizeof(auxP->x_sym.x_misc.x_lnno); + md_number_to_chars(*where, auxP->x_sym.x_misc.x_size, sizeof(auxP->x_sym.x_misc.x_size)); + *where += sizeof(auxP->x_sym.x_misc.x_size); + } + if (ISARY(type)) { + register int index; + for (index = 0; index < DIMNUM; index++) + md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_ary.x_dimen[index], sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index])); + *where += sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]); + } else { + md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr)); + *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr); + md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_endndx, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx)); + *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx); + } + md_number_to_chars(*where, auxP->x_sym.x_tvndx, sizeof(auxP->x_sym.x_tvndx)); + *where += sizeof(auxP->x_sym.x_tvndx); + } else if (SF_GET_FILE(symbolP)) { /* .file */ + ; + } else if (SF_GET_STATICS(symbolP)) { /* .text, .data, .bss symbols */ + md_number_to_chars(*where, auxP->x_scn.x_scnlen, sizeof(auxP->x_scn.x_scnlen)); + *where += sizeof(auxP->x_scn.x_scnlen); + md_number_to_chars(*where, auxP->x_scn.x_nreloc, sizeof(auxP->x_scn.x_nreloc)); + *where += sizeof(auxP->x_scn.x_nreloc); + md_number_to_chars(*where, auxP->x_scn.x_nlinno, sizeof(auxP->x_scn.x_nlinno)); + *where += sizeof(auxP->x_scn.x_nlinno); + } #endif /* 0 */ #else /* CROSS_COMPILE */ - append(where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof(symbolP->sy_symbol.ost_auxent[i])); + append(where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof(symbolP->sy_symbol.ost_auxent[i])); #endif /* CROSS_COMPILE */ - - }; /* for each aux in use */ + + }; /* for each aux in use */ #endif /* BFD_HEADERS */ - return; + return; } /* obj_symbol_to_chars() */ #ifdef BFD_HEADERS @@ -471,7 +473,7 @@ static void obj_coff_section_header_append(where, header) char **where; struct internal_scnhdr *header; { - *where += bfd_coff_swap_scnhdr_out(stdoutput, header, *where); + *where += bfd_coff_swap_scnhdr_out(stdoutput, header, *where); } #else static void obj_coff_section_header_append(where, header) @@ -513,13 +515,13 @@ SCNHDR *header; md_number_to_chars(*where, header->s_align, sizeof(header->s_align)); *where += sizeof(header->s_align); #endif /* TC_I960 */ - + #else /* CROSS_COMPILE */ append(where, (char *) header, sizeof(*header)); #endif /* CROSS_COMPILE */ - + return; } /* obj_coff_section_header_append() */ @@ -528,28 +530,28 @@ void obj_emit_symbols(where, symbol_rootP) char **where; symbolS *symbol_rootP; { - symbolS *symbolP; - /* - * Emit all symbols left in the symbol chain. - */ - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - /* Used to save the offset of the name. It is used to point - to the string in memory but must be a file offset. */ - register char * temp; - - tc_coff_symbol_emit_hook(symbolP); - - temp = S_GET_NAME(symbolP); - if (SF_GET_STRING(symbolP)) { - S_SET_OFFSET(symbolP, symbolP->sy_name_offset); - S_SET_ZEROES(symbolP, 0); - } else { - bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN); - strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN); - } - obj_symbol_to_chars(where, symbolP); - S_SET_NAME(symbolP,temp); - } + symbolS *symbolP; + /* + * Emit all symbols left in the symbol chain. + */ + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { + /* Used to save the offset of the name. It is used to point + to the string in memory but must be a file offset. */ + register char * temp; + + tc_coff_symbol_emit_hook(symbolP); + + temp = S_GET_NAME(symbolP); + if (SF_GET_STRING(symbolP)) { + S_SET_OFFSET(symbolP, symbolP->sy_name_offset); + S_SET_ZEROES(symbolP, 0); + } else { + bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN); + strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN); + } + obj_symbol_to_chars(where, symbolP); + S_SET_NAME(symbolP,temp); + } } /* obj_emit_symbols() */ /* Merge a debug symbol containing debug information into a normal symbol. */ @@ -560,15 +562,15 @@ symbolS *normal; { S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug)); S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug)); - + if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) { S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug)); } /* take the most we have */ - + if (S_GET_NUMBER_AUXILIARY(debug) > 0) { memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ); } /* Move all the auxiliary information */ - + /* Move the debug flags. */ SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug)); } /* c_symbol_merge() */ @@ -578,32 +580,32 @@ static symbolS *previous_file_symbol = NULL; void c_dot_file_symbol(filename) char *filename; { - symbolS* symbolP; - - symbolP = symbol_new(".file", - SEG_DEBUG, - 0, - &zero_address_frag); - - S_SET_STORAGE_CLASS(symbolP, C_FILE); - S_SET_NUMBER_AUXILIARY(symbolP, 1); - SA_SET_FILE_FNAME(symbolP, filename); - SF_SET_DEBUG(symbolP); - S_SET_VALUE(symbolP, (long) previous_file_symbol); - - previous_file_symbol = symbolP; - - /* Make sure that the symbol is first on the symbol chain */ - if (symbol_rootP != symbolP) { - if (symbolP == symbol_lastP) { - symbol_lastP = symbol_lastP->sy_previous; - } /* if it was the last thing on the list */ - - symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); - symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); - symbol_rootP = symbolP; - } /* if not first on the list */ - + symbolS* symbolP; + + symbolP = symbol_new(".file", + SEG_DEBUG, + 0, + &zero_address_frag); + + S_SET_STORAGE_CLASS(symbolP, C_FILE); + S_SET_NUMBER_AUXILIARY(symbolP, 1); + SA_SET_FILE_FNAME(symbolP, filename); + SF_SET_DEBUG(symbolP); + S_SET_VALUE(symbolP, (long) previous_file_symbol); + + previous_file_symbol = symbolP; + + /* Make sure that the symbol is first on the symbol chain */ + if (symbol_rootP != symbolP) { + if (symbolP == symbol_lastP) { + symbol_lastP = symbol_lastP->sy_previous; + } /* if it was the last thing on the list */ + + symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); + symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); + symbol_rootP = symbolP; + } /* if not first on the list */ + } /* c_dot_file_symbol() */ /* * Build a 'section static' symbol. @@ -616,27 +618,27 @@ long length; unsigned short nreloc; unsigned short nlnno; { - symbolS *symbolP; - - symbolP = symbol_new(name, - (name[1] == 't' - ? SEG_TEXT - : (name[1] == 'd' - ? SEG_DATA - : SEG_BSS)), - value, - &zero_address_frag); - - S_SET_STORAGE_CLASS(symbolP, C_STAT); - S_SET_NUMBER_AUXILIARY(symbolP, 1); - - SA_SET_SCN_SCNLEN(symbolP, length); - SA_SET_SCN_NRELOC(symbolP, nreloc); - SA_SET_SCN_NLINNO(symbolP, nlnno); - - SF_SET_STATICS(symbolP); - - return (char*)symbolP; + symbolS *symbolP; + + symbolP = symbol_new(name, + (name[1] == 't' + ? SEG_TEXT + : (name[1] == 'd' + ? SEG_DATA + : SEG_BSS)), + value, + &zero_address_frag); + + S_SET_STORAGE_CLASS(symbolP, C_STAT); + S_SET_NUMBER_AUXILIARY(symbolP, 1); + + SA_SET_SCN_SCNLEN(symbolP, length); + SA_SET_SCN_NRELOC(symbolP, nreloc); + SA_SET_SCN_NLINNO(symbolP, nlnno); + + SF_SET_STATICS(symbolP); + + return (char*)symbolP; } /* c_section_symbol() */ void c_section_header(header, @@ -671,7 +673,7 @@ long alignment; header->s_lnnoptr = lineno_ptr; header->s_nreloc = reloc_number; header->s_nlnno = lineno_number; - + #ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT #ifdef OBJ_COFF_BROKEN_ALIGNMENT header->s_align = ((name[1] == 'b' || (size > 0)) ? 16 : 0); @@ -681,7 +683,7 @@ long alignment; : (1 << alignment)); #endif /* OBJ_COFF_BROKEN_ALIGNMENT */ #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */ - + header->s_flags = STYP_REG | (name[1] == 't' ? STYP_TEXT : (name[1] == 'd' @@ -705,24 +707,24 @@ int our_lineno_number = 0; /* we use this to build pointers from .bf's lineno* lineno_lastP = (lineno*)0; int -c_line_new(paddr, line_number, frag) + c_line_new(paddr, line_number, frag) long paddr; unsigned short line_number; fragS* frag; { - lineno* new_line = (lineno*)xmalloc(sizeof(lineno)); - - new_line->line.l_addr.l_paddr = paddr; - new_line->line.l_lnno = line_number; - new_line->frag = (char*)frag; - new_line->next = (lineno*)0; - - if (lineno_rootP == (lineno*)0) - lineno_rootP = new_line; - else - lineno_lastP->next = new_line; - lineno_lastP = new_line; - return LINESZ * our_lineno_number++; + lineno* new_line = (lineno*)xmalloc(sizeof(lineno)); + + new_line->line.l_addr.l_paddr = paddr; + new_line->line.l_lnno = line_number; + new_line->frag = (char*)frag; + new_line->next = (lineno*)0; + + if (lineno_rootP == (lineno*)0) + lineno_rootP = new_line; + else + lineno_lastP->next = new_line; + lineno_lastP = new_line; + return LINESZ * our_lineno_number++; } void obj_emit_lineno(where, line, file_start) @@ -737,23 +739,23 @@ char *file_start; #endif for (; line; line = line->next) { line_entry = &line->line; - - /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in - write_object_file() but their symbols need a fileptr to the lnno, so - I moved this resolution check here. xoxorich. */ - + + /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in + write_object_file() but their symbols need a fileptr to the lnno, so + I moved this resolution check here. xoxorich. */ + if (line_entry->l_lnno == 0) { /* There is a good chance that the symbol pointed to is not the one that will be emitted and that the sy_number is not accurate. */ -/* char *name; */ + /* char *name; */ symbolS *symbolP; - + symbolP = (symbolS *) line_entry->l_addr.l_symndx; - + line_entry->l_addr.l_symndx = symbolP->sy_number; symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start; - + } /* if this is a function linno */ #ifdef BFD_HEADERS *where += bfd_coff_swap_lineno_out(stdoutput, line_entry, *where); @@ -763,15 +765,23 @@ char *file_start; #ifdef CROSS_COMPILE md_number_to_chars(*where, line_entry->l_addr.l_paddr, sizeof(line_entry->l_addr.l_paddr)); *where += sizeof(line_entry->l_addr.l_paddr); - + md_number_to_chars(*where, line_entry->l_lnno, sizeof(line_entry->l_lnno)); *where += sizeof(line_entry->l_lnno); + +#ifdef TC_I960 + **where = '0'; + ++*where; + **where = '0'; + ++*where; +#endif /* TC_I960 */ + #else /* CROSS_COMPILE */ append(where, (char *) line_entry, LINESZ); #endif /* CROSS_COMPILE */ -#endif +#endif /* BFD_HEADERS */ } /* for each line number */ - + return ; } /* obj_emit_lineno() */ @@ -779,7 +789,7 @@ void obj_symbol_new_hook(symbolP) symbolS *symbolP; { char underscore = 0; /* Symbol has leading _ */ - + /* Effective symbol */ /* Store the pointer in the offset. */ S_SET_ZEROES(symbolP, 0L); @@ -790,8 +800,8 @@ symbolS *symbolP; symbolP->sy_symbol.ost_flags = 0; /* Auxiliary entries */ bzero((char*)&symbolP->sy_symbol.ost_auxent[0], AUXESZ); - -#if STRIP_UNDERSCORE + +#ifdef STRIP_UNDERSCORE /* Remove leading underscore at the beginning of the symbol. * This is to be compatible with the standard librairies. */ @@ -800,22 +810,22 @@ symbolS *symbolP; S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1); } /* strip underscore */ #endif /* STRIP_UNDERSCORE */ - + if (S_IS_STRING(symbolP)) SF_SET_STRING(symbolP); if (!underscore && S_IS_LOCAL(symbolP)) SF_SET_LOCAL(symbolP); - + return; } /* obj_symbol_new_hook() */ - /* stack stuff */ +/* stack stuff */ stack* stack_init(chunk_size, element_size) unsigned long chunk_size; unsigned long element_size; { stack* st; - + if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0) return (stack*)0; if ((st->data = malloc(chunk_size)) == (char*)0) { @@ -832,8 +842,8 @@ unsigned long element_size; void stack_delete(st) stack* st; { - free(st->data); - free(st); + free(st->data); + free(st); } char *stack_push(st, element) @@ -853,17 +863,17 @@ char *element; char* stack_pop(st) stack* st; { - if ((st->pointer -= st->element_size) < 0) { - st->pointer = 0; - return (char*)0; - } - return st->data + st->pointer; + if ((st->pointer -= st->element_size) < 0) { + st->pointer = 0; + return (char*)0; + } + return st->data + st->pointer; } char* stack_top(st) stack* st; { - return st->data + st->pointer - st->element_size; + return st->data + st->pointer - st->element_size; } @@ -877,11 +887,11 @@ static void obj_coff_ln() { demand_empty_rest_of_line(); return; } /* wrong context */ - + c_line_new(obstack_next_free(&frags) - frag_now->fr_literal, get_absolute_expression(), frag_now); - + demand_empty_rest_of_line(); return; } /* obj_coff_line() */ @@ -902,71 +912,71 @@ static void obj_coff_ln() { #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';') #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \ - *input_line_pointer == '\t') \ - input_line_pointer++; + *input_line_pointer == '\t') \ + input_line_pointer++; static void obj_coff_def(what) int what; { - char name_end; /* Char after the end of name */ - char *symbol_name; /* Name of the debug symbol */ - char *symbol_name_copy; /* Temporary copy of the name */ - unsigned int symbol_name_length; - /*$char* directiveP;$ */ /* Name of the pseudo opcode */ - /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */ - /*$char end = 0;$ */ /* If 1, stop parsing */ - - if (def_symbol_in_progress != NULL) { - as_warn(".def pseudo-op used inside of .def/.endef: ignored."); - demand_empty_rest_of_line(); - return; - } /* if not inside .def/.endef */ - - SKIP_WHITESPACES(); - - def_symbol_in_progress = (symbolS *) obstack_alloc(¬es, sizeof(*def_symbol_in_progress)); - bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress)); - - symbol_name = input_line_pointer; - name_end = get_symbol_end(); - symbol_name_length = strlen(symbol_name); - symbol_name_copy = xmalloc(symbol_name_length + 1); - strcpy(symbol_name_copy, symbol_name); - - /* Initialize the new symbol */ -#if STRIP_UNDERSCORE - S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_' - ? symbol_name_copy + 1 - : symbol_name_copy)); + char name_end; /* Char after the end of name */ + char *symbol_name; /* Name of the debug symbol */ + char *symbol_name_copy; /* Temporary copy of the name */ + unsigned int symbol_name_length; + /*$char* directiveP;$ */ /* Name of the pseudo opcode */ + /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */ + /*$char end = 0;$ */ /* If 1, stop parsing */ + + if (def_symbol_in_progress != NULL) { + as_warn(".def pseudo-op used inside of .def/.endef: ignored."); + demand_empty_rest_of_line(); + return; + } /* if not inside .def/.endef */ + + SKIP_WHITESPACES(); + + def_symbol_in_progress = (symbolS *) obstack_alloc(¬es, sizeof(*def_symbol_in_progress)); + bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress)); + + symbol_name = input_line_pointer; + name_end = get_symbol_end(); + symbol_name_length = strlen(symbol_name); + symbol_name_copy = xmalloc(symbol_name_length + 1); + strcpy(symbol_name_copy, symbol_name); + + /* Initialize the new symbol */ +#ifdef STRIP_UNDERSCORE + S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_' + ? symbol_name_copy + 1 + : symbol_name_copy)); #else /* STRIP_UNDERSCORE */ - S_SET_NAME(def_symbol_in_progress, symbol_name_copy); + S_SET_NAME(def_symbol_in_progress, symbol_name_copy); #endif /* STRIP_UNDERSCORE */ - /* free(symbol_name_copy); */ - def_symbol_in_progress->sy_name_offset = ~0; - def_symbol_in_progress->sy_number = ~0; - def_symbol_in_progress->sy_frag = &zero_address_frag; - - if (S_IS_STRING(def_symbol_in_progress)) { - SF_SET_STRING(def_symbol_in_progress); - } /* "long" name */ - - *input_line_pointer = name_end; - - demand_empty_rest_of_line(); - return; + /* free(symbol_name_copy); */ + def_symbol_in_progress->sy_name_offset = ~0; + def_symbol_in_progress->sy_number = ~0; + def_symbol_in_progress->sy_frag = &zero_address_frag; + + if (S_IS_STRING(def_symbol_in_progress)) { + SF_SET_STRING(def_symbol_in_progress); + } /* "long" name */ + + *input_line_pointer = name_end; + + demand_empty_rest_of_line(); + return; } /* obj_coff_def() */ unsigned int dim_index; static void obj_coff_endef() { symbolS *symbolP; -/* DIM BUG FIX sac@cygnus.com */ + /* DIM BUG FIX sac@cygnus.com */ dim_index =0; if (def_symbol_in_progress == NULL) { as_warn(".endef pseudo-op used outside of .def/.endef: ignored."); demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + /* Set the section number according to storage class. */ switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) { case C_STRTAG: @@ -979,7 +989,7 @@ static void obj_coff_endef() { SF_SET_DEBUG(def_symbol_in_progress); S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG); break; - + case C_EFCN: SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */ /* intentional fallthrough */ @@ -988,7 +998,7 @@ static void obj_coff_endef() { /* intentional fallthrough */ case C_FCN: S_SET_SEGMENT(def_symbol_in_progress, SEG_TEXT); - + if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */ if (function_lineoff < 0) { fprintf(stderr, "`.bf' symbol without preceding function\n"); @@ -998,7 +1008,7 @@ static void obj_coff_endef() { function_lineoff = -1; } break; - + #ifdef C_AUTOARG case C_AUTOARG: #endif /* C_AUTOARG */ @@ -1014,25 +1024,25 @@ static void obj_coff_endef() { SF_SET_DEBUG(def_symbol_in_progress); S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE); break; - + case C_EXT: case C_STAT: case C_LABEL: - /* Valid but set somewhere else (s_comm, s_lcomm, colon) */ + /* Valid but set somewhere else (s_comm, s_lcomm, colon) */ break; - + case C_USTATIC: case C_EXTDEF: case C_ULABEL: as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress)); break; } /* switch on storage class */ - + /* Now that we have built a debug symbol, try to find if we should merge with an existing symbol or not. If a symbol is C_EFCN or SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */ - + /* Two cases for functions. Either debug followed by definition or definition followed by debug. For definition first, we will merge the debug @@ -1043,19 +1053,19 @@ static void obj_coff_endef() { symbol into the real symbol. Therefor, let's presume the debug symbol is a real function reference. */ - + /* FIXME-SOON If for some reason the definition label/symbol is never seen, this will probably leave an undefined symbol at link time. */ - + if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG && !SF_GET_TAG(def_symbol_in_progress)) || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) { - + symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); - + } else { /* This symbol already exists, merge the newly created symbol into the old one. @@ -1064,14 +1074,14 @@ static void obj_coff_endef() { guess that it save a *lot* of space if the assembly file defines a lot of symbols. [loic] */ - + /* The debug entry (def_symbol_in_progress) is merged into the previous definition. */ - + c_symbol_merge(def_symbol_in_progress, symbolP); /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */ def_symbol_in_progress = symbolP; - + if (SF_GET_FUNCTION(def_symbol_in_progress) || SF_GET_TAG(def_symbol_in_progress)) { /* For functions, and tags, the symbol *must* be where the debug symbol @@ -1083,106 +1093,74 @@ static void obj_coff_endef() { } /* if not already in place */ } /* if function */ } /* normal or mergable */ - + if (SF_GET_TAG(def_symbol_in_progress) && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) { tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress); } /* If symbol is a {structure,union} tag, associate symbol to its name. */ - + if (SF_GET_FUNCTION(def_symbol_in_progress)) { know(sizeof(def_symbol_in_progress) <= sizeof(long)); function_lineoff = c_line_new((long) def_symbol_in_progress, 0, &zero_address_frag); SF_SET_PROCESS(def_symbol_in_progress); - + if (symbolP == NULL) { /* That is, if this is the first time we've seen the function... */ symbol_table_insert(def_symbol_in_progress); } /* definition follows debug */ } /* Create the line number entry pointing to the function being defined */ - + def_symbol_in_progress = NULL; demand_empty_rest_of_line(); return; } /* obj_coff_endef() */ -#ifndef TC_I960 -/*This code expects all the dims to be after one another, and that is not true -for gcc960 -sac@cygnus.com */ -static void obj_coff_dim() { - register int dim_index; +static void obj_coff_dim() +{ + register int dim_index; + if (def_symbol_in_progress == NULL) { as_warn(".dim pseudo-op used outside of .def/.endef: ignored."); demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); - + for (dim_index = 0; dim_index < DIMNUM; dim_index++) { SKIP_WHITESPACES(); SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression()); - + switch (*input_line_pointer) { - + case ',': input_line_pointer++; break; - + default: as_warn("badly formed .dim directive ignored"); /* intentional fallthrough */ + case '\n': case ';': dim_index = DIMNUM; break; } /* switch on following character */ } /* for each dimension */ - - demand_empty_rest_of_line(); - return; -} /* obj_coff_dim() */ -#else - -static void -obj_coff_dim() -{ - if (def_symbol_in_progress == NULL) { - as_warn(".dim pseudo-op used outside of .def/.endef: ignored."); + demand_empty_rest_of_line(); return; - } /* if not inside .def/.endef */ - - - S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); - - /* Grab as many dims as we can fit, until ; or full */ - while (dim_index < DIMNUM) - { - SKIP_WHITESPACES(); - SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression()); - dim_index++; - if (*input_line_pointer == ';') break; - if (*input_line_pointer != ',') { - as_warn("badly formed .dim directive ignored"); - break; - } - input_line_pointer++; - } - demand_empty_rest_of_line(); - return; } /* obj_coff_dim() */ -#endif static void obj_coff_line() { if (def_symbol_in_progress == NULL) { obj_coff_ln(); return; } /* if it looks like a stabs style line */ - + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression()); - + demand_empty_rest_of_line(); return; } /* obj_coff_line() */ @@ -1193,7 +1171,7 @@ static void obj_coff_size() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression()); demand_empty_rest_of_line(); @@ -1206,7 +1184,7 @@ static void obj_coff_scl() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression()); demand_empty_rest_of_line(); return; @@ -1215,27 +1193,27 @@ static void obj_coff_scl() { static void obj_coff_tag() { char *symbol_name; char name_end; - + if (def_symbol_in_progress == NULL) { as_warn(".tag pseudo-op used outside of .def/.endef ignored."); demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); symbol_name = input_line_pointer; name_end = get_symbol_end(); - + /* Assume that the symbol referred to by .tag is always defined. */ /* This was a bad assumption. I've added find_or_make. xoxorich. */ SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name)); if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) { as_warn("tag not found for .tag %s", symbol_name); } /* not defined */ - + SF_SET_TAGGED(def_symbol_in_progress); *input_line_pointer = name_end; - + demand_empty_rest_of_line(); return; } /* obj_coff_tag() */ @@ -1246,14 +1224,14 @@ static void obj_coff_type() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression()); - + if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) && S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) { SF_SET_FUNCTION(def_symbol_in_progress); } /* is a function */ - + demand_empty_rest_of_line(); return; } /* obj_coff_type() */ @@ -1264,18 +1242,18 @@ static void obj_coff_val() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + if (is_name_beginner(*input_line_pointer)) { char *symbol_name = input_line_pointer; char name_end = get_symbol_end(); - + if (!strcmp(symbol_name, ".")) { def_symbol_in_progress->sy_frag = frag_now; S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal); /* If the .val is != from the .def (e.g. statics) */ } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) { def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name); - + /* If the segment is undefined when the forward reference is solved, then copy the segment id from the forward symbol. */ @@ -1286,7 +1264,7 @@ static void obj_coff_val() { } else { S_SET_VALUE(def_symbol_in_progress, get_absolute_expression()); } /* if symbol based */ - + demand_empty_rest_of_line(); return; } /* obj_coff_val() */ @@ -1296,8 +1274,8 @@ static void obj_coff_val() { */ static void tag_init() { - tag_hash = hash_new(); - return ; + tag_hash = hash_new(); + return ; } /* tag_init() */ static void tag_insert(name, symbolP) @@ -1305,7 +1283,7 @@ char *name; symbolS *symbolP; { register char * error_string; - + if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) { as_fatal("Inserting \"%s\" into structure table failed: %s", name, error_string); @@ -1317,37 +1295,37 @@ static symbolS *tag_find_or_make(name) char *name; { symbolS *symbolP; - + if ((symbolP = tag_find(name)) == NULL) { symbolP = symbol_new(name, SEG_UNKNOWN, 0, &zero_address_frag); - + tag_insert(S_GET_NAME(symbolP), symbolP); symbol_table_insert(symbolP); } /* not found */ - + return(symbolP); } /* tag_find_or_make() */ static symbolS *tag_find(name) char *name; { -#if STRIP_UNDERSCORE +#ifdef STRIP_UNDERSCORE if (*name == '_') name++; #endif /* STRIP_UNDERSCORE */ return((symbolS*)hash_find(tag_hash, name)); } /* tag_find() */ void obj_read_begin_hook() { - /* These had better be the same. Usually 18 bytes. */ + /* These had better be the same. Usually 18 bytes. */ #ifndef BFD_HEADERS know(sizeof(SYMENT) == sizeof(AUXENT)); know(SYMESZ == AUXESZ); #endif tag_init(); - + return; } /* obj_read_begin_hook() */ @@ -1361,28 +1339,28 @@ object_headers *headers; symbolS *symbolP; symbolS *symbol_externP = NULL; symbolS *symbol_extern_lastP = NULL; - + /* Initialize the stack used to keep track of the matching .bb .be */ stack* block_stack = stack_init(512, sizeof(symbolS*)); - + /* JF deal with forward references first... */ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - + if (symbolP->sy_forward) { S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP) + S_GET_VALUE(symbolP->sy_forward) + symbolP->sy_forward->sy_frag->fr_address)); - + if (SF_GET_GET_SEGMENT(symbolP)) { S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward)); } /* forward segment also */ - + symbolP->sy_forward=0; } /* if it has a forward reference */ } /* walk the symbol chain */ - + tc_crawl_symbol_chain(headers); - + /* The symbol list should be ordered according to the following sequence * order : * . .file symbol @@ -1393,13 +1371,13 @@ object_headers *headers; * But this is not mandatory. The only important point is to put the * undefined symbols at the end of the list. */ - + if (symbol_rootP == NULL || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) { know(!previous_file_symbol); c_dot_file_symbol("fake"); } /* Is there a .file symbol ? If not insert one at the beginning. */ - + /* * Build up static symbols for .text, .data and .bss */ @@ -1409,25 +1387,25 @@ object_headers *headers; H_GET_TEXT_SIZE(headers), 0/*text_relocation_number */, 0/*text_lineno_number */); - + dot_data_symbol = (symbolS*) c_section_symbol(".data", H_GET_TEXT_SIZE(headers), H_GET_DATA_SIZE(headers), 0/*data_relocation_number */, 0); /* There are no data lineno entries */ - + dot_bss_symbol = (symbolS*) c_section_symbol(".bss", H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers), H_GET_BSS_SIZE(headers), 0, /* No relocation for a bss section. */ 0); /* There are no bss lineno entries */ - + #if defined(DEBUG) verify_symbol_chain(symbol_rootP, symbol_lastP); #endif /* DEBUG */ - + /* Three traversals of symbol chains here. The first traversal yanks externals into a temporary chain, removing the externals from the global @@ -1441,7 +1419,7 @@ object_headers *headers; reference preceeds a definition as the definition has no number at the time we process the reference. */ - + /* Note that symbolP will be NULL at the end of a loop if an external was at the beginning of the list (it gets moved off the list). Hence the weird check in @@ -1450,10 +1428,10 @@ object_headers *headers; for (symbolP = symbol_rootP; symbolP; symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) { - if (!SF_GET_DEBUG(symbolP)) { + if (!SF_GET_DEBUG(symbolP)) { /* Debug symbols do not need all this rubbish */ symbolS* real_symbolP; - + /* L* and C_EFCN symbols never merge. */ if (!SF_GET_LOCAL(symbolP) && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) @@ -1474,13 +1452,13 @@ object_headers *headers; symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); symbolP = real_symbolP; } /* if not local but dup'd */ - + if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) { S_SET_SEGMENT(symbolP, SEG_TEXT); } /* push data into text */ - + S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); - + if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) { S_SET_EXTERNAL(symbolP); } else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL) { @@ -1490,7 +1468,7 @@ object_headers *headers; S_SET_STORAGE_CLASS(symbolP, C_STAT); } } /* no storage class yet */ - + /* Mainly to speed up if not -g */ if (SF_GET_PROCESS(symbolP)) { /* Handle the nested blocks auxiliary info. */ @@ -1513,11 +1491,11 @@ object_headers *headers; if (last_functionP == (symbolS*)0 && SF_GET_FUNCTION(symbolP)) { last_functionP = symbolP; - + if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) { S_SET_NUMBER_AUXILIARY(symbolP, 1); } /* make it at least 1 */ - + /* Clobber possible stale .dim information. */ bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen, sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen)); @@ -1540,7 +1518,7 @@ object_headers *headers; /* First descriptor of a structure must point to the first slot after the structure description. */ last_tagP = symbolP; - + } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) { /* +2 take in account the current symbol */ SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2); @@ -1550,7 +1528,7 @@ object_headers *headers; S_SET_VALUE(symbolP, 0); } /* no one points at the first .file symbol */ } /* if debug or tag or eos or file */ - + /* We must put the external symbols apart. The loader does not bomb if we do not. But the references in the endndx field for a .bb symbol are not corrected @@ -1561,18 +1539,18 @@ object_headers *headers; [22] .be ld will move the symbol 21 to the end of the list but endndx will still be 22 instead of 21. */ - - + + if (SF_GET_LOCAL(symbolP)) { /* remove C_EFCN and LOCAL (L...) symbols */ /* next pointer remains valid */ symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); - + } else if (!S_IS_DEFINED(symbolP) && !S_IS_DEBUG(symbolP) && !SF_GET_STATICS(symbolP)) { -/* S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) { */ + /* S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) { */ /* if external, Remove from the list */ symbolS *hold = symbol_previous(symbolP); - + symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); symbol_clear_list_pointers(symbolP); symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP); @@ -1584,19 +1562,19 @@ object_headers *headers; } else { symbolP->sy_name_offset = 0; } /* fix "long" names */ - + symbolP->sy_number = symbol_number; symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP); } /* if local symbol */ } /* traverse the symbol list */ - + for (symbolP = symbol_externP; symbol_externP;) { symbolS *tmp = symbol_externP; - + /* append */ symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP); symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP); - + /* and process */ if (SF_GET_STRING(tmp)) { tmp->sy_name_offset = string_byte_count; @@ -1604,31 +1582,31 @@ object_headers *headers; } else { tmp->sy_name_offset = 0; } /* fix "long" names */ - + tmp->sy_number = symbol_number; symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp); } /* append the entire extern chain */ - + /* When a tag reference preceeds the tag definition, the definition will not have a number at the time we process the reference during the first traversal. Thus, a second traversal. */ - + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { if (SF_GET_TAGGED(symbolP)) { SA_SET_SYM_TAGNDX(symbolP, ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number); } /* If the symbol has a tagndx entry, resolve it */ } /* second traversal */ - + know(symbol_externP == NULL); know(symbol_extern_lastP == NULL); - + /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section headers, and I'm resolving the addresses since I'm not sure how to do it later. I am NOT resolving the linno's representing functions. Their symbols need a fileptr pointing to this linno when emitted. Thus, I resolve them on emit. xoxorich. */ - + for (lineP = lineno_rootP; lineP; lineP = lineP->next) { if (lineP->line.l_lnno > 0) { lineP->line.l_addr.l_paddr += ((fragS*)lineP->frag)->fr_address; @@ -1637,9 +1615,9 @@ object_headers *headers; } text_lineno_number++; } /* for each line number */ - + H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number); - + return; } /* obj_crawl_symbol_chain() */ @@ -1651,7 +1629,7 @@ void obj_emit_strings(where) char **where; { symbolS *symbolP; - + #ifdef CROSS_COMPILE /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ md_number_to_chars(*where, string_byte_count, sizeof(string_byte_count)); @@ -1659,13 +1637,13 @@ char **where; #else /* CROSS_COMPILE */ append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count)); #endif /* CROSS_COMPILE */ - + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { if (SF_GET_STRING(symbolP)) { append(where, S_GET_NAME(symbolP), (unsigned long)(strlen(S_GET_NAME(symbolP)) + 1)); } /* if it has a string */ } /* walk the symbol chain */ - + return; } /* obj_emit_strings() */ @@ -1675,7 +1653,7 @@ object_headers *headers; register int text_relocation_number = 0; register int data_relocation_number = 0; register fixS *fixP; - + /* FIXME-SOMEDAY this should be done at fixup_segment time but I'm going to wait until I do multiple segments. xoxorich. */ @@ -1691,52 +1669,52 @@ object_headers *headers; #endif /* TC_I960 */ #ifdef TC_A29K /* Count 2 for a constH */ - if (fixP->fx_r_type == RELOC_CONSTH) { - ++text_relocation_number; - } + if (fixP->fx_r_type == RELOC_CONSTH) { + ++text_relocation_number; + } #endif - + } /* if not yet fixed */ } /* for each fix */ - + SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number); /* Assign the number of line number entries for the text section */ SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number); /* Assign the size of the section */ SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(headers)); - + for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) { if (fixP->fx_addsy) { ++data_relocation_number; } /* if still relocatable */ #ifdef TC_A29K - /* Count 2 for a constH */ - if (fixP->fx_r_type == RELOC_CONSTH) { - ++data_relocation_number; - } + /* Count 2 for a constH */ + if (fixP->fx_r_type == RELOC_CONSTH) { + ++data_relocation_number; + } #endif - + } /* for each fix */ - - + + SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number); /* Assign the size of the section */ SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(headers)); - + /* Assign the size of the section */ SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(headers)); - - /* pre write hook can add relocs (for 960 and 29k coff) so */ + + /* pre write hook can add relocs (for 960 and 29k coff) so */ headers->relocation_size = text_relocation_number * RELSZ + - data_relocation_number *RELSZ; - - - + data_relocation_number *RELSZ; + + + /* Fill in extra coff fields */ - + /* Initialize general line number information. */ H_SET_LINENO_SIZE(headers, text_lineno_number * LINESZ); - + /* filehdr */ H_SET_FILE_MAGIC_NUMBER(headers, FILE_HEADER_MAGIC); H_SET_NUMBER_OF_SECTIONS(headers, 3); /* text+data+bss */ @@ -1747,27 +1725,27 @@ object_headers *headers; #endif /* OBJ_COFF_OMIT_TIMESTAMP */ H_SET_SYMBOL_TABLE_POINTER(headers, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers)); #if 0 -printf("FILHSZ %x\n", FILHSZ); -printf("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ); -printf("section headers %x\n", H_GET_NUMBER_OF_SECTIONS(headers) * SCNHSZ); -printf("get text size %x\n", H_GET_TEXT_SIZE(headers)); -printf("get data size %x\n", H_GET_DATA_SIZE(headers)); -printf("get relocation size %x\n", H_GET_RELOCATION_SIZE(headers)); -printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers)); + printf("FILHSZ %x\n", FILHSZ); + printf("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ); + printf("section headers %x\n", H_GET_NUMBER_OF_SECTIONS(headers) * SCNHSZ); + printf("get text size %x\n", H_GET_TEXT_SIZE(headers)); + printf("get data size %x\n", H_GET_DATA_SIZE(headers)); + printf("get relocation size %x\n", H_GET_RELOCATION_SIZE(headers)); + printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers)); #endif /* symbol table size allready set */ H_SET_SIZEOF_OPTIONAL_HEADER(headers, OBJ_COFF_AOUTHDRSZ); H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0) | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG) | BYTE_ORDERING); - + /* aouthdr */ /* magic number allready set */ H_SET_VERSION_STAMP(headers, 0); /* Text, data, bss size; entry point; text_start and data_start are already set */ - + /* Build section headers */ - + c_section_header(&text_section_header, ".text", 0, @@ -1782,7 +1760,7 @@ printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers)); SA_GET_SCN_NRELOC(dot_text_symbol), text_lineno_number, section_alignment[(int) SEG_TEXT]); - + c_section_header(&data_section_header, ".data", H_GET_TEXT_SIZE(headers), @@ -1798,7 +1776,7 @@ printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers)); SA_GET_SCN_NRELOC(dot_data_symbol), 0, /* No line number information */ section_alignment[(int) SEG_DATA]); - + c_section_header(&bss_section_header, ".bss", H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers), @@ -1809,7 +1787,7 @@ printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers)); 0, /* No relocation information */ 0, /* No line number information */ section_alignment[(int) SEG_BSS]); - + return; } /* obj_pre_write_hook() */ @@ -1825,11 +1803,11 @@ int what; int saved_type = 0; long longint; symbolS *symbolP = 0; - + if (what == 's') { string = demand_copy_C_string(&length); SKIP_WHITESPACE(); - + if (*input_line_pointer == ',') { input_line_pointer++; } else { @@ -1837,7 +1815,7 @@ int what; goof = 1; } /* better be a comma */ } /* skip the string */ - + /* * Input_line_pointer->after ','. String->symbol name. */ @@ -1848,7 +1826,7 @@ int what; input_line_pointer--; /* Backup over a non-',' char. */ } /* on error */ } /* no error */ - + if (!goof) { if (get_absolute_expression_and_terminator(&longint) != ',') { as_bad("I want a comma after the n_other expression"); @@ -1856,10 +1834,10 @@ int what; input_line_pointer--; /* Backup over a non-',' char. */ } /* on error */ } /* no error */ - + if (!goof) { get_absolute_expression(); - + if (what == 's' || what == 'n') { if (*input_line_pointer != ',') { as_bad("I want a comma after the n_desc expression"); @@ -1869,9 +1847,9 @@ int what; } /* on goof */ } /* not stabd */ } /* no error */ - + expression(&e); - + if (goof) { ignore_rest_of_line(); } else { @@ -1880,7 +1858,7 @@ int what; } /* obj_coff_stab() */ #ifdef DEBUG - /* for debugging */ +/* for debugging */ char *s_get_name(s) symbolS *s; { @@ -1889,7 +1867,7 @@ symbolS *s; void symbol_dump() { symbolS *symbolP; - + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n", symbolP->sy_number, @@ -1899,7 +1877,7 @@ void symbol_dump() { S_GET_STORAGE_CLASS(symbolP), (int) S_GET_SEGMENT(symbolP)); } /* traverse symbols */ - + return; } /* symbol_dump() */ #endif /* DEBUG */ diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index f85ef5a..0cb7e82 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -1,21 +1,21 @@ /* coff object file format Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. - -This file is part of GAS. - -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. + + 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. */ /* $Id$ */ @@ -28,33 +28,33 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef BFD_HEADERS #ifdef TC_A29K #include "bfd.h" -#include "coff-a29k.h" +#include "coff/a29k.h" /* This internal_lineno crap is to stop namespace pollution from the bfd internal coff headerfile. */ #define internal_lineno bfd_internal_lineno -#include "internalcoff.h" +#include "coff/internal.h" #undef internal_lineno /* -#undef RELOC -#undef SYMENT -#undef AUXENT -#undef LINENO -#undef FILHDR -#undef SCNHDR -#define RELOC struct internal_reloc -#define SYMENT struct internal_syment -#define AUXENT union internal_auxent -#define SCNHDR struct internal_scnhdr -#define LINENO struct bfd_internal_lineno -#define AOUTHDR struct internal_aouthdr -#define FILHDR struct internal_filehdr -#define AOUTHDRSZ sizeof(struct external_aouthdr) -*/ + #undef RELOC + #undef SYMENT + #undef AUXENT + #undef LINENO + #undef FILHDR + #undef SCNHDR + #define RELOC struct internal_reloc + #define SYMENT struct internal_syment + #define AUXENT union internal_auxent + #define SCNHDR struct internal_scnhdr + #define LINENO struct bfd_internal_lineno + #define AOUTHDR struct internal_aouthdr + #define FILHDR struct internal_filehdr + #define AOUTHDRSZ sizeof(struct external_aouthdr) + */ /*#define x_endndx x_endndx.l -#define x_tagndx x_tagndx.l*/ + #define x_tagndx x_tagndx.l*/ #define TARGET_FORMAT "coff-a29k-big" extern bfd *stdoutput; #else @@ -63,7 +63,7 @@ help me #else #include "coff.gnu.h" #endif - + #ifdef USE_NATIVE_HEADERS #include <filehdr.h> #include <aouthdr.h> @@ -74,16 +74,16 @@ help me #include <reloc.h> #include <sys/types.h> #endif /* USE_NATIVE_HEADERS */ - -/* Define some processor dependent values according to the processor we are - on. */ + + /* Define some processor dependent values according to the processor we are + on. */ #ifdef TC_M68K - + #define BYTE_ORDERING F_AR32W /* See filehdr.h for more info. */ #ifndef FILE_HEADER_MAGIC #define FILE_HEADER_MAGIC MC68MAGIC /* ... */ #endif /* FILE_HEADER_MAGIC */ - + #elif defined(TC_I386) #define BYTE_ORDERING F_AR32WR /* See filehdr.h for more info. */ @@ -108,12 +108,12 @@ help me #else you lose #endif - + #ifndef OBJ_COFF_MAX_AUXENTRIES #define OBJ_COFF_MAX_AUXENTRIES 1 #endif /* OBJ_COFF_MAX_AUXENTRIES */ - -extern const short seg_N_TYPE[]; + + extern const short seg_N_TYPE[]; extern const segT N_TYPE_seg[]; /* Magic number of paged executable. */ @@ -129,7 +129,7 @@ extern const segT N_TYPE_seg[]; /* SYMBOL TABLE */ - /* targets may also set this */ +/* targets may also set this */ #ifndef SYMBOLS_NEED_BACKPOINTERS #define SYMBOLS_NEED_BACKPOINTERS 1 #endif /* SYMBOLS_NEED_BACKPOINTERS */ @@ -147,11 +147,6 @@ typedef struct { unsigned int ost_flags; /* obj_coff internal use only flags */ } obj_symbol_type; -/* If compiler generate leading underscores, remove them. */ - -#ifndef STRIP_UNDERSCORE -#define STRIP_UNDERSCORE 0 -#endif /* STRIP_UNDERSCORE */ #define DO_NOT_STRIP 0 #define DO_STRIP 1 @@ -181,8 +176,8 @@ typedef struct { /* True if the symbol is external */ #define S_IS_EXTERNAL(s) ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION) /* True if symbol has been defined, ie : - section > 0 (DATA, TEXT or BSS) - section == 0 and value > 0 (external bss symbol) */ + section > 0 (DATA, TEXT or BSS) + section == 0 and value > 0 (external bss symbol) */ #define S_IS_DEFINED(s) ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION || \ ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION && \ (s)->sy_symbol.ost_entry.n_value > 0)) @@ -318,7 +313,7 @@ typedef struct { #define SF_TAG (0x00080000) /* Is a tag */ #define SF_DEBUG (0x00100000) /* Is in debug or abs section */ #define SF_GET_SEGMENT (0x00200000) /* Get the section of the forward symbol. */ - /* All other bits are unused. */ +/* All other bits are unused. */ /* Accessors */ #define SF_GET(s) ((s)->sy_symbol.ost_flags) @@ -465,22 +460,22 @@ typedef struct { #define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v)) #define H_SET_LINENO_SIZE(h,v) ((h)->lineno_size = (v)) - /* Segment flipping */ +/* Segment flipping */ #define segment_name(v) (seg_name[(int) (v)]) typedef struct { #ifdef BFD_HEADERS - struct internal_aouthdr aouthdr; /* a.out header */ - struct internal_filehdr filehdr; /* File header, not machine dep. */ + struct internal_aouthdr aouthdr; /* a.out header */ + struct internal_filehdr filehdr; /* File header, not machine dep. */ #else - AOUTHDR aouthdr; /* a.out header */ - FILHDR filehdr; /* File header, not machine dep. */ + AOUTHDR aouthdr; /* a.out header */ + FILHDR filehdr; /* File header, not machine dep. */ #endif - long string_table_size; /* names + '\0' + sizeof(int) */ - long relocation_size; /* Cumulated size of relocation + long string_table_size; /* names + '\0' + sizeof(int) */ + long relocation_size; /* Cumulated size of relocation information for all sections in bytes. */ - long lineno_size; /* Size of the line number information + long lineno_size; /* Size of the line number information table in bytes */ } object_headers; @@ -491,12 +486,12 @@ extern int text_lineno_number; typedef struct internal_lineno { #ifdef BFD_HEADERS - struct bfd_internal_lineno line; + struct bfd_internal_lineno line; #else - LINENO line; /* The lineno structure itself */ + LINENO line; /* The lineno structure itself */ #endif - char* frag; /* Frag to which the line number is related */ - struct internal_lineno* next; /* Forward chain pointer */ + char* frag; /* Frag to which the line number is related */ + struct internal_lineno* next; /* Forward chain pointer */ } lineno; extern lineno *lineno_lastP; @@ -509,13 +504,13 @@ void obj_emit_lineno(char **where, lineno *line, char *file_start); void obj_emit_lineno(); #endif /* __STDC__ */ - /* stack stuff */ +/* stack stuff */ typedef struct { - unsigned long chunk_size; - unsigned long element_size; - unsigned long size; - char* data; - unsigned long pointer; + unsigned long chunk_size; + unsigned long element_size; + unsigned long size; + char* data; + unsigned long pointer; } stack; #ifdef __STDC__ @@ -542,7 +537,7 @@ void c_section_header( #else SCNHDR *header, #endif - + char *name, long core_address, long size, @@ -569,7 +564,7 @@ void tc_coff_symbol_emit_hook(); #endif /* __STDC__ */ - /* sanity check */ +/* sanity check */ #ifdef TC_I960 #ifndef C_LEAFSTAT @@ -577,12 +572,13 @@ hey! Where is the C_LEAFSTAT definition? i960-coff support is depending on it. #endif /* no C_LEAFSTAT */ #endif /* TC_I960 */ #ifdef BFD_HEADERS -extern struct internal_scnhdr data_section_header; + extern struct internal_scnhdr data_section_header; extern struct internal_scnhdr text_section_header; #else extern SCNHDR data_section_header; extern SCNHDR text_section_header; #endif + /* * Local Variables: * comment-column: 0 diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c index eb8342b..8ad737d 100644 --- a/gas/config/obj-coffbfd.c +++ b/gas/config/obj-coffbfd.c @@ -1,40 +1,40 @@ /* coff object file format with bfd Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. - -This file is part of GAS. - -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. + + 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. */ /* - - How does this releate to the rest of GAS ? - - Well, all the other files in gas are more or less a black box. It - takes care of opening files, parsing command lines, stripping blanks - etc etc. This module gets a chance to register what it wants to do by - saying that it is interested in various pseduo ops. The other big - change is write_object_file. This runs through all the data - structures that gas builds, and outputs the file in the format of our - choice. - - Hacked for BFDness by steve chamberlain - - This object module now supports the Hitachi H8/300 and the AMD 29k - - sac@cygnus.com -*/ + + How does this releate to the rest of GAS ? + + Well, all the other files in gas are more or less a black box. It + takes care of opening files, parsing command lines, stripping blanks + etc etc. This module gets a chance to register what it wants to do by + saying that it is interested in various pseduo ops. The other big + change is write_object_file. This runs through all the data + structures that gas builds, and outputs the file in the format of our + choice. + + Hacked for BFDness by steve chamberlain + + This object module now supports the Hitachi H8/300 and the AMD 29k + + sac@cygnus.com + */ #include "as.h" #include "obstack.h" @@ -45,7 +45,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This vector is used to turn an internal segment into a section # suitable for insertion into a coff symbol table - */ + */ const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */ C_ABS_SECTION, @@ -86,7 +86,7 @@ int text_lineno_number = 0; /* Add 4 to the real value to get the index and compensate the negatives. This vector is used by S_GET_SEGMENT to turn a coff section number into a segment number -*/ + */ static symbolS *previous_file_symbol = NULL; void c_symbol_merge(); static int line_base; @@ -97,7 +97,7 @@ void EXFUN(bfd_as_write_hook,(struct internal_filehdr *, bfd *abfd)); static void EXFUN(fixup_segment,(fixS * fixP, - segT this_segment_type)); + segT this_segment_type)); static void EXFUN(fill_section,(bfd *abfd , struct internal_filehdr *f, unsigned @@ -110,11 +110,11 @@ static symbolS* EXFUN(tag_find,(char *name)); static int -EXFUN(c_line_new,( - symbolS *symbol, - long paddr, - unsigned short line_number, - fragS* frag)); + EXFUN(c_line_new,( + symbolS *symbol, + long paddr, + unsigned short line_number, + fragS* frag)); static void EXFUN(w_symbols, @@ -169,84 +169,84 @@ const pseudo_typeS obj_pseudo_table[] = { /* Section stuff - + We allow more than just the standard 3 sections, infact, we allow 10 sections, (though the usual three have to be there). - + This structure performs the mappings for us: - -*/ + + */ /* OBS stuff -static struct internal_scnhdr bss_section_header; -struct internal_scnhdr data_section_header; -struct internal_scnhdr text_section_header; - -const segT N_TYPE_seg [32] = -{ - -}; - -*/ + static struct internal_scnhdr bss_section_header; + struct internal_scnhdr data_section_header; + struct internal_scnhdr text_section_header; + + const segT N_TYPE_seg [32] = + { + + }; + + */ #define N_SEG 32 typedef struct { - segT seg_t; -int i; + segT seg_t; + int i; } seg_info_type; seg_info_type seg_info_off_by_4[N_SEG] = { -{SEG_PTV, }, -{SEG_NTV, }, -{SEG_DEBUG, }, -{SEG_ABSOLUTE, }, -{SEG_UNKNOWN, }, -{SEG_E0}, -{SEG_E1}, -{SEG_E2}, -{SEG_E3}, -{SEG_E4}, -{SEG_E5}, -{SEG_E6}, -{SEG_E7}, -{SEG_E8}, -{SEG_E9}, -{15}, -{16}, -{17}, -{18}, -{19}, -{20}, -{0}, -{0}, -{0}, -{SEG_REGISTER},0,0,0,0}; + {SEG_PTV, }, + {SEG_NTV, }, + {SEG_DEBUG, }, + {SEG_ABSOLUTE, }, + {SEG_UNKNOWN, }, + {SEG_E0}, + {SEG_E1}, + {SEG_E2}, + {SEG_E3}, + {SEG_E4}, + {SEG_E5}, + {SEG_E6}, + {SEG_E7}, + {SEG_E8}, + {SEG_E9}, + {15}, + {16}, + {17}, + {18}, + {19}, + {20}, + {0}, + {0}, + {0}, + {SEG_REGISTER},0,0,0,0}; #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4]) #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)]) - relax_addressT -DEFUN(relax_align,(address, alignment), -register relax_addressT address AND -register long alignment ) +relax_addressT + DEFUN(relax_align,(address, alignment), + register relax_addressT address AND + register long alignment ) { - relax_addressT mask; - relax_addressT new_address; - - mask = ~ ( (~0) << alignment ); - new_address = (address + mask) & (~ mask); - return (new_address - address); + relax_addressT mask; + relax_addressT new_address; + + mask = ~ ( (~0) << alignment ); + new_address = (address + mask) & (~ mask); + return (new_address - address); } /* relax_align() */ segT -DEFUN(s_get_segment,(x) , -symbolS* x) + DEFUN(s_get_segment,(x) , + symbolS* x) { - return SEG_INFO_FROM_SECTION_NUMBER(x->sy_symbol.ost_entry.n_scnum).seg_t; + return SEG_INFO_FROM_SECTION_NUMBER(x->sy_symbol.ost_entry.n_scnum).seg_t; } @@ -254,61 +254,61 @@ symbolS* x) /* calculate the size of the frag chain and fill in the section header to contain all of it, also fill in the addr of the sections */ static unsigned int DEFUN(size_section,(abfd, idx), - bfd *abfd AND - unsigned int idx) + bfd *abfd AND + unsigned int idx) { - - unsigned int size = 0; - fragS *frag = segment_info[idx].frchainP->frch_root; - while (frag) { - if (frag->fr_address != size) { - printf("Out of step\n"); - size = frag->fr_address; - } - size += frag->fr_fix; - switch (frag->fr_type) { - case rs_fill: - case rs_org: - size += frag->fr_offset * frag->fr_var; - break; - case rs_align: - size += relax_align(size, frag->fr_offset); + + unsigned int size = 0; + fragS *frag = segment_info[idx].frchainP->frch_root; + while (frag) { + if (frag->fr_address != size) { + printf("Out of step\n"); + size = frag->fr_address; + } + size += frag->fr_fix; + switch (frag->fr_type) { + case rs_fill: + case rs_org: + size += frag->fr_offset * frag->fr_var; + break; + case rs_align: + size += relax_align(size, frag->fr_offset); + } + frag = frag->fr_next; } - frag = frag->fr_next; - } - segment_info[idx].scnhdr.s_size = size; - return size; + segment_info[idx].scnhdr.s_size = size; + return size; } static unsigned int DEFUN(count_entries_in_chain,(idx), unsigned int idx) { - unsigned int nrelocs; - fixS *fixup_ptr; - - /* Count the relocations */ - fixup_ptr = segment_info[idx].fix_root; - nrelocs = 0; - while (fixup_ptr != (fixS *)NULL) - { - if (TC_COUNT_RELOC(fixup_ptr)) - { - + unsigned int nrelocs; + fixS *fixup_ptr; + + /* Count the relocations */ + fixup_ptr = segment_info[idx].fix_root; + nrelocs = 0; + while (fixup_ptr != (fixS *)NULL) + { + if (TC_COUNT_RELOC(fixup_ptr)) + { + #ifdef TC_A29K - - if (fixup_ptr->fx_r_type == RELOC_CONSTH) - nrelocs+=2; - else - nrelocs++; + + if (fixup_ptr->fx_r_type == RELOC_CONSTH) + nrelocs+=2; + else + nrelocs++; #else - nrelocs++; + nrelocs++; #endif - } - - fixup_ptr = fixup_ptr->fx_next; - } - return nrelocs; + } + + fixup_ptr = fixup_ptr->fx_next; + } + return nrelocs; } /* output all the relocations for a section */ @@ -316,192 +316,192 @@ void DEFUN(do_relocs_for,(abfd, file_cursor), bfd *abfd AND unsigned long *file_cursor) { - unsigned int nrelocs; - unsigned int idx; - - for (idx = SEG_E0; idx < SEG_E9; idx++) - { - if (segment_info[idx].scnhdr.s_name[0]) - { - - struct external_reloc *ext_ptr; - struct external_reloc *external_reloc_vec; - unsigned int external_reloc_size; - unsigned int count = 0; - unsigned int base = segment_info[idx].scnhdr.s_paddr; - fixS * fix_ptr = segment_info[idx].fix_root; - nrelocs = count_entries_in_chain(idx); - external_reloc_size = nrelocs * RELSZ; - external_reloc_vec = - (struct external_reloc*)malloc(external_reloc_size); - - - - ext_ptr = external_reloc_vec; - - /* Fill in the internal coff style reloc struct from the - internal fix list */ - while (fix_ptr) - { - symbolS *symbol_ptr; - struct internal_reloc intr; - - /* Only output some of the relocations */ - if (TC_COUNT_RELOC(fix_ptr)) - { + unsigned int nrelocs; + unsigned int idx; + + for (idx = SEG_E0; idx < SEG_E9; idx++) + { + if (segment_info[idx].scnhdr.s_name[0]) + { + + struct external_reloc *ext_ptr; + struct external_reloc *external_reloc_vec; + unsigned int external_reloc_size; + unsigned int count = 0; + unsigned int base = segment_info[idx].scnhdr.s_paddr; + fixS * fix_ptr = segment_info[idx].fix_root; + nrelocs = count_entries_in_chain(idx); + external_reloc_size = nrelocs * RELSZ; + external_reloc_vec = + (struct external_reloc*)malloc(external_reloc_size); + + + + ext_ptr = external_reloc_vec; + + /* Fill in the internal coff style reloc struct from the + internal fix list */ + while (fix_ptr) + { + symbolS *symbol_ptr; + struct internal_reloc intr; + + /* Only output some of the relocations */ + if (TC_COUNT_RELOC(fix_ptr)) + { #ifdef TC_RELOC_MANGLE - TC_RELOC_MANGLE(fix_ptr, &intr, base); - + TC_RELOC_MANGLE(fix_ptr, &intr, base); + #else - symbolS *dot; - symbol_ptr = fix_ptr->fx_addsy; - - intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr); - intr.r_vaddr = - base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where ; - - intr.r_offset = fix_ptr->fx_offset; - - intr.r_offset = 0; - - /* Turn the segment of the symbol into an offset - */ - if (symbol_ptr) - { - dot = segment_info[S_GET_SEGMENT(symbol_ptr)].dot; - if (dot) - { - intr.r_symndx = dot->sy_number; - } - else - { - intr.r_symndx = symbol_ptr->sy_number; - } - - } - else - { - intr.r_symndx = -1; - - - } + symbolS *dot; + symbol_ptr = fix_ptr->fx_addsy; + + intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr); + intr.r_vaddr = + base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where ; + + intr.r_offset = fix_ptr->fx_offset; + + intr.r_offset = 0; + + /* Turn the segment of the symbol into an offset + */ + if (symbol_ptr) + { + dot = segment_info[S_GET_SEGMENT(symbol_ptr)].dot; + if (dot) + { + intr.r_symndx = dot->sy_number; + } + else + { + intr.r_symndx = symbol_ptr->sy_number; + } + + } + else + { + intr.r_symndx = -1; + + + } #endif - - (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr); - ext_ptr++; - + + (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr); + ext_ptr++; + #if defined(TC_A29K) - /* The 29k has a special kludge for the high 16 bit reloc. - Two relocations are emmited, R_IHIHALF, and - R_IHCONST. The second one doesn't contain a symbol, - but uses the value for offset */ - - if (intr.r_type == R_IHIHALF) - { - /* now emit the second bit */ - intr.r_type = R_IHCONST; - intr.r_symndx = fix_ptr->fx_addnumber; - (void)bfd_coff_swap_reloc_out(abfd,&intr,ext_ptr); - ext_ptr++; - } + /* The 29k has a special kludge for the high 16 bit reloc. + Two relocations are emmited, R_IHIHALF, and + R_IHCONST. The second one doesn't contain a symbol, + but uses the value for offset */ + + if (intr.r_type == R_IHIHALF) + { + /* now emit the second bit */ + intr.r_type = R_IHCONST; + intr.r_symndx = fix_ptr->fx_addnumber; + (void)bfd_coff_swap_reloc_out(abfd,&intr,ext_ptr); + ext_ptr++; + } #endif - } - - fix_ptr = fix_ptr->fx_next; - } - - /* Write out the reloc table */ - segment_info[idx].scnhdr.s_relptr = *file_cursor; - segment_info[idx].scnhdr.s_nreloc = nrelocs; - bfd_write((PTR)external_reloc_vec, 1, external_reloc_size, abfd); - *file_cursor += external_reloc_size; - free( external_reloc_vec); - } - } + } + + fix_ptr = fix_ptr->fx_next; + } + + /* Write out the reloc table */ + segment_info[idx].scnhdr.s_relptr = *file_cursor; + segment_info[idx].scnhdr.s_nreloc = nrelocs; + bfd_write((PTR)external_reloc_vec, 1, external_reloc_size, abfd); + *file_cursor += external_reloc_size; + free( external_reloc_vec); + } + } } /* run through a frag chain and write out the data to go with it, fill in the scnhdrs with the info on the file postions -*/ + */ static void DEFUN(fill_section,(abfd, filehdr, file_cursor), bfd *abfd AND struct internal_filehdr *filehdr AND unsigned long *file_cursor) { - - unsigned int i; - unsigned int paddr = 0; - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - unsigned int offset = 0; - - struct internal_scnhdr *s = &( segment_info[i].scnhdr); - - if (s->s_name[0]) - { - fragS *frag = segment_info[i].frchainP->frch_root; - char *buffer = malloc(s->s_size); - s->s_scnptr = *file_cursor; - s->s_paddr = paddr; - s->s_vaddr = paddr; - - s->s_flags = STYP_REG; - if (strcmp(s->s_name,".text")==0) - s->s_flags |= STYP_TEXT; - else if (strcmp(s->s_name,".data")==0) - s->s_flags |= STYP_DATA; - else if (strcmp(s->s_name,".bss")==0) - s->s_flags |= STYP_BSS | STYP_NOLOAD; - - while (frag) { - unsigned int fill_size; - switch (frag->fr_type) { - - case rs_fill: - case rs_align: - case rs_org: - if(frag->fr_fix) - { - memcpy(buffer + frag->fr_address, - frag->fr_literal, - frag->fr_fix); - offset += frag->fr_fix; - } - - fill_size = frag->fr_var; - if (fill_size) - { - unsigned int count ; - unsigned int off = frag->fr_fix; - for (count = frag->fr_offset; count; count--) - { - memcpy(buffer + frag->fr_address + off, - frag->fr_literal + frag->fr_fix, - fill_size); - off += fill_size; - offset += fill_size; - + + unsigned int i; + unsigned int paddr = 0; + + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + { + unsigned int offset = 0; + + struct internal_scnhdr *s = &( segment_info[i].scnhdr); + + if (s->s_name[0]) + { + fragS *frag = segment_info[i].frchainP->frch_root; + char *buffer = malloc(s->s_size); + s->s_scnptr = *file_cursor; + s->s_paddr = paddr; + s->s_vaddr = paddr; + + s->s_flags = STYP_REG; + if (strcmp(s->s_name,".text")==0) + s->s_flags |= STYP_TEXT; + else if (strcmp(s->s_name,".data")==0) + s->s_flags |= STYP_DATA; + else if (strcmp(s->s_name,".bss")==0) + s->s_flags |= STYP_BSS | STYP_NOLOAD; + + while (frag) { + unsigned int fill_size; + switch (frag->fr_type) { + + case rs_fill: + case rs_align: + case rs_org: + if(frag->fr_fix) + { + memcpy(buffer + frag->fr_address, + frag->fr_literal, + frag->fr_fix); + offset += frag->fr_fix; + } + + fill_size = frag->fr_var; + if (fill_size) + { + unsigned int count ; + unsigned int off = frag->fr_fix; + for (count = frag->fr_offset; count; count--) + { + memcpy(buffer + frag->fr_address + off, + frag->fr_literal + frag->fr_fix, + fill_size); + off += fill_size; + offset += fill_size; + + } + + } + break; + default: + abort(); + } + frag = frag->fr_next; } - - } - break; - default: - abort(); - } - frag = frag->fr_next; - } - - - bfd_write(buffer, s->s_size,1,abfd); - free(buffer); - - *file_cursor += s->s_size; - paddr += s->s_size; - } - } - + + + bfd_write(buffer, s->s_size,1,abfd); + free(buffer); + + *file_cursor += s->s_size; + paddr += s->s_size; + } + } + } @@ -510,74 +510,74 @@ static void DEFUN(fill_section,(abfd, filehdr, file_cursor), static void -DEFUN(coff_header_append,(abfd, filehdr, aouthdr), - bfd *abfd AND - struct internal_filehdr *filehdr AND - struct internal_aouthdr *aouthdr) + DEFUN(coff_header_append,(abfd, filehdr, aouthdr), + bfd *abfd AND + struct internal_filehdr *filehdr AND + struct internal_aouthdr *aouthdr) { - unsigned int i; - char buffer[1000]; - char buffero[1000]; - - bfd_seek(abfd, 0, 0); + unsigned int i; + char buffer[1000]; + char buffero[1000]; + + bfd_seek(abfd, 0, 0); #if 0 - filehdr.f_opthdr = bfd_coff_swap_aouthdr_out(abfd, aouthdr, - buffero); + filehdr.f_opthdr = bfd_coff_swap_aouthdr_out(abfd, aouthdr, + buffero); #else - filehdr->f_opthdr = 0; + filehdr->f_opthdr = 0; #endif - i = bfd_coff_swap_filehdr_out(abfd, filehdr, buffer); - - bfd_write(buffer, i ,1, abfd); - bfd_write(buffero, filehdr->f_opthdr, 1, abfd); - - for (i = SEG_E0; i < SEG_E9; i++) - { - if (segment_info[i].scnhdr.s_name[0]) - { - unsigned int size = - bfd_coff_swap_scnhdr_out(abfd, - &(segment_info[i].scnhdr), - buffer); - bfd_write(buffer, size, 1, abfd); - } - } + i = bfd_coff_swap_filehdr_out(abfd, filehdr, buffer); + + bfd_write(buffer, i ,1, abfd); + bfd_write(buffero, filehdr->f_opthdr, 1, abfd); + + for (i = SEG_E0; i < SEG_E9; i++) + { + if (segment_info[i].scnhdr.s_name[0]) + { + unsigned int size = + bfd_coff_swap_scnhdr_out(abfd, + &(segment_info[i].scnhdr), + buffer); + bfd_write(buffer, size, 1, abfd); + } + } } char * -DEFUN(symbol_to_chars,(abfd, where, symbolP), - bfd*abfd AND - char *where AND - symbolS *symbolP) + DEFUN(symbol_to_chars,(abfd, where, symbolP), + bfd*abfd AND + char *where AND + symbolS *symbolP) { - unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; - unsigned int i; - - /* Turn any symbols with register attributes into abs symbols */ - if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) - { - S_SET_SEGMENT(symbolP, SEG_ABSOLUTE); - } - /* At the same time, relocate all symbols to their output value */ - - S_SET_VALUE(symbolP, - segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr - + S_GET_VALUE(symbolP)); - - where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry, - where); - - for (i = 0; i < numaux; i++) - { - where += bfd_coff_swap_aux_out(abfd, - &symbolP->sy_symbol.ost_auxent[i], - S_GET_DATA_TYPE(symbolP), - S_GET_STORAGE_CLASS(symbolP), + unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; + unsigned int i; + + /* Turn any symbols with register attributes into abs symbols */ + if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) + { + S_SET_SEGMENT(symbolP, SEG_ABSOLUTE); + } + /* At the same time, relocate all symbols to their output value */ + + S_SET_VALUE(symbolP, + segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr + + S_GET_VALUE(symbolP)); + + where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry, where); - } - return where; - + + for (i = 0; i < numaux; i++) + { + where += bfd_coff_swap_aux_out(abfd, + &symbolP->sy_symbol.ost_auxent[i], + S_GET_DATA_TYPE(symbolP), + S_GET_STORAGE_CLASS(symbolP), + where); + } + return where; + } @@ -587,7 +587,7 @@ void obj_symbol_new_hook(symbolP) symbolS *symbolP; { char underscore = 0; /* Symbol has leading _ */ - + /* Effective symbol */ /* Store the pointer in the offset. */ S_SET_ZEROES(symbolP, 0L); @@ -598,7 +598,7 @@ symbolS *symbolP; symbolP->sy_symbol.ost_flags = 0; /* Auxiliary entries */ bzero((char*)&symbolP->sy_symbol.ost_auxent[0], AUXESZ); - + #ifdef STRIP_UNDERSCORE /* Remove leading underscore at the beginning of the symbol. * This is to be compatible with the standard librairies. @@ -608,22 +608,22 @@ symbolS *symbolP; S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1); } /* strip underscore */ #endif /* STRIP_UNDERSCORE */ - + if (S_IS_STRING(symbolP)) SF_SET_STRING(symbolP); if (!underscore && S_IS_LOCAL(symbolP)) SF_SET_LOCAL(symbolP); - + return; } /* obj_symbol_new_hook() */ - /* stack stuff */ +/* stack stuff */ stack* stack_init(chunk_size, element_size) unsigned long chunk_size; unsigned long element_size; { stack* st; - + if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0) return (stack*)0; if ((st->data = malloc(chunk_size)) == (char*)0) { @@ -640,8 +640,8 @@ unsigned long element_size; void stack_delete(st) stack* st; { - free(st->data); - free(st); + free(st->data); + free(st); } char *stack_push(st, element) @@ -661,18 +661,18 @@ char *element; char* stack_pop(st) stack* st; { - if ((st->pointer -= st->element_size) < 0) { - st->pointer = 0; - return (char*)0; - } - - return st->data + st->pointer; + if ((st->pointer -= st->element_size) < 0) { + st->pointer = 0; + return (char*)0; + } + + return st->data + st->pointer; } char* stack_top(st) stack* st; { - return st->data + st->pointer - st->element_size; + return st->data + st->pointer - st->element_size; } @@ -682,31 +682,31 @@ stack* st; static void obj_coff_ln() { - int l; - - if (def_symbol_in_progress != NULL) { - as_warn(".ln pseudo-op inside .def/.endef: ignored."); - demand_empty_rest_of_line(); - return; - } /* wrong context */ - - c_line_new(0, - obstack_next_free(&frags) - frag_now->fr_literal, - l = get_absolute_expression(), - frag_now); + int l; + + if (def_symbol_in_progress != NULL) { + as_warn(".ln pseudo-op inside .def/.endef: ignored."); + demand_empty_rest_of_line(); + return; + } /* wrong context */ + + c_line_new(0, + obstack_next_free(&frags) - frag_now->fr_literal, + l = get_absolute_expression(), + frag_now); #ifndef NO_LISTING -{ - extern int listing; - - if (listing) - { - listing_source_line(l + line_base - 1); - } - -} + { + extern int listing; + + if (listing) + { + listing_source_line(l + line_base - 1); + } + + } #endif - demand_empty_rest_of_line(); - return; + demand_empty_rest_of_line(); + return; } /* obj_coff_line() */ /* @@ -725,163 +725,163 @@ static void obj_coff_ln() #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';') #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \ - *input_line_pointer == '\t') \ - input_line_pointer++; + *input_line_pointer == '\t') \ + input_line_pointer++; static void -DEFUN(obj_coff_def,(what), - int what) + DEFUN(obj_coff_def,(what), + int what) { - char name_end; /* Char after the end of name */ - char *symbol_name; /* Name of the debug symbol */ - char *symbol_name_copy; /* Temporary copy of the name */ - unsigned int symbol_name_length; - /*$char* directiveP;$ */ /* Name of the pseudo opcode */ - /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */ - /*$char end = 0;$ */ /* If 1, stop parsing */ - - if (def_symbol_in_progress != NULL) { - as_warn(".def pseudo-op used inside of .def/.endef: ignored."); - demand_empty_rest_of_line(); - return; + char name_end; /* Char after the end of name */ + char *symbol_name; /* Name of the debug symbol */ + char *symbol_name_copy; /* Temporary copy of the name */ + unsigned int symbol_name_length; + /*$char* directiveP;$ */ /* Name of the pseudo opcode */ + /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */ + /*$char end = 0;$ */ /* If 1, stop parsing */ + + if (def_symbol_in_progress != NULL) { + as_warn(".def pseudo-op used inside of .def/.endef: ignored."); + demand_empty_rest_of_line(); + return; } /* if not inside .def/.endef */ - - SKIP_WHITESPACES(); - - def_symbol_in_progress = (symbolS *) obstack_alloc(¬es, sizeof(*def_symbol_in_progress)); - bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress)); - - symbol_name = input_line_pointer; - name_end = get_symbol_end(); - symbol_name_length = strlen(symbol_name); - symbol_name_copy = xmalloc(symbol_name_length + 1); - strcpy(symbol_name_copy, symbol_name); - - /* Initialize the new symbol */ + + SKIP_WHITESPACES(); + + def_symbol_in_progress = (symbolS *) obstack_alloc(¬es, sizeof(*def_symbol_in_progress)); + bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress)); + + symbol_name = input_line_pointer; + name_end = get_symbol_end(); + symbol_name_length = strlen(symbol_name); + symbol_name_copy = xmalloc(symbol_name_length + 1); + strcpy(symbol_name_copy, symbol_name); + + /* Initialize the new symbol */ #ifdef STRIP_UNDERSCORE - S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_' - ? symbol_name_copy + 1 - : symbol_name_copy)); + S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_' + ? symbol_name_copy + 1 + : symbol_name_copy)); #else /* STRIP_UNDERSCORE */ - S_SET_NAME(def_symbol_in_progress, symbol_name_copy); + S_SET_NAME(def_symbol_in_progress, symbol_name_copy); #endif /* STRIP_UNDERSCORE */ - /* free(symbol_name_copy); */ - def_symbol_in_progress->sy_name_offset = ~0; - def_symbol_in_progress->sy_number = ~0; - def_symbol_in_progress->sy_frag = &zero_address_frag; - - if (S_IS_STRING(def_symbol_in_progress)) { - SF_SET_STRING(def_symbol_in_progress); + /* free(symbol_name_copy); */ + def_symbol_in_progress->sy_name_offset = ~0; + def_symbol_in_progress->sy_number = ~0; + def_symbol_in_progress->sy_frag = &zero_address_frag; + + if (S_IS_STRING(def_symbol_in_progress)) { + SF_SET_STRING(def_symbol_in_progress); } /* "long" name */ - - *input_line_pointer = name_end; - - demand_empty_rest_of_line(); - return; + + *input_line_pointer = name_end; + + demand_empty_rest_of_line(); + return; } /* obj_coff_def() */ unsigned int dim_index; static void -DEFUN_VOID(obj_coff_endef) + DEFUN_VOID(obj_coff_endef) { - symbolS *symbolP = 0; - /* DIM BUG FIX sac@cygnus.com */ - dim_index =0; - if (def_symbol_in_progress == NULL) { - as_warn(".endef pseudo-op used outside of .def/.endef: ignored."); - demand_empty_rest_of_line(); - return; + symbolS *symbolP = 0; + /* DIM BUG FIX sac@cygnus.com */ + dim_index =0; + if (def_symbol_in_progress == NULL) { + as_warn(".endef pseudo-op used outside of .def/.endef: ignored."); + demand_empty_rest_of_line(); + return; } /* if not inside .def/.endef */ - - /* Set the section number according to storage class. */ - switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) { - case C_STRTAG: - case C_ENTAG: - case C_UNTAG: - SF_SET_TAG(def_symbol_in_progress); - /* intentional fallthrough */ - case C_FILE: - case C_TPDEF: - SF_SET_DEBUG(def_symbol_in_progress); - S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG); - break; - - case C_EFCN: - SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */ - /* intentional fallthrough */ - case C_BLOCK: - SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */ - /* intentional fallthrough */ - case C_FCN: - S_SET_SEGMENT(def_symbol_in_progress, SEG_E0); - - if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */ - if (function_lineoff < 0) { - fprintf(stderr, "`.bf' symbol without preceding function\n"); + + /* Set the section number according to storage class. */ + switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) { + case C_STRTAG: + case C_ENTAG: + case C_UNTAG: + SF_SET_TAG(def_symbol_in_progress); + /* intentional fallthrough */ + case C_FILE: + case C_TPDEF: + SF_SET_DEBUG(def_symbol_in_progress); + S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG); + break; + + case C_EFCN: + SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */ + /* intentional fallthrough */ + case C_BLOCK: + SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */ + /* intentional fallthrough */ + case C_FCN: + S_SET_SEGMENT(def_symbol_in_progress, SEG_E0); + + if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */ + if (function_lineoff < 0) { + fprintf(stderr, "`.bf' symbol without preceding function\n"); } /* missing function symbol */ - SA_GET_SYM_LNNOPTR(def_symbol_in_progress) = function_lineoff; - SF_SET_PROCESS(def_symbol_in_progress); /* Will need relocating */ - function_lineoff = -1; + SA_GET_SYM_LNNOPTR(def_symbol_in_progress) = function_lineoff; + SF_SET_PROCESS(def_symbol_in_progress); /* Will need relocating */ + function_lineoff = -1; } - break; - + break; + #ifdef C_AUTOARG - case C_AUTOARG: + case C_AUTOARG: #endif /* C_AUTOARG */ - case C_AUTO: - case C_REG: - case C_MOS: - case C_MOE: - case C_MOU: - case C_ARG: - case C_REGPARM: - case C_FIELD: - case C_EOS: - SF_SET_DEBUG(def_symbol_in_progress); - S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE); - break; - - case C_EXT: - case C_STAT: - case C_LABEL: - /* Valid but set somewhere else (s_comm, s_lcomm, colon) */ - break; - - case C_USTATIC: - case C_EXTDEF: - case C_ULABEL: - as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress)); - break; + case C_AUTO: + case C_REG: + case C_MOS: + case C_MOE: + case C_MOU: + case C_ARG: + case C_REGPARM: + case C_FIELD: + case C_EOS: + SF_SET_DEBUG(def_symbol_in_progress); + S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE); + break; + + case C_EXT: + case C_STAT: + case C_LABEL: + /* Valid but set somewhere else (s_comm, s_lcomm, colon) */ + break; + + case C_USTATIC: + case C_EXTDEF: + case C_ULABEL: + as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress)); + break; } /* switch on storage class */ - - /* Now that we have built a debug symbol, try to - find if we should merge with an existing symbol - or not. If a symbol is C_EFCN or SEG_ABSOLUTE or - untagged SEG_DEBUG it never merges. */ - - /* Two cases for functions. Either debug followed - by definition or definition followed by debug. - For definition first, we will merge the debug - symbol into the definition. For debug first, the - lineno entry MUST point to the definition - function or else it will point off into space - when crawl_symbols() merges the debug - symbol into the real symbol. Therefor, let's - presume the debug symbol is a real function - reference. */ - - /* FIXME-SOON If for some reason the definition - label/symbol is never seen, this will probably - leave an undefined symbol at link time. */ - - if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN - || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG - && !SF_GET_TAG(def_symbol_in_progress)) - || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE - || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) { - - symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); - + + /* Now that we have built a debug symbol, try to + find if we should merge with an existing symbol + or not. If a symbol is C_EFCN or SEG_ABSOLUTE or + untagged SEG_DEBUG it never merges. */ + + /* Two cases for functions. Either debug followed + by definition or definition followed by debug. + For definition first, we will merge the debug + symbol into the definition. For debug first, the + lineno entry MUST point to the definition + function or else it will point off into space + when crawl_symbols() merges the debug + symbol into the real symbol. Therefor, let's + presume the debug symbol is a real function + reference. */ + + /* FIXME-SOON If for some reason the definition + label/symbol is never seen, this will probably + leave an undefined symbol at link time. */ + + if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN + || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG + && !SF_GET_TAG(def_symbol_in_progress)) + || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE + || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) { + + symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); + } else { /* This symbol already exists, merge the newly created symbol into the old one. @@ -890,14 +890,14 @@ DEFUN_VOID(obj_coff_endef) guess that it save a *lot* of space if the assembly file defines a lot of symbols. [loic] */ - + /* The debug entry (def_symbol_in_progress) is merged into the previous definition. */ - + c_symbol_merge(def_symbol_in_progress, symbolP); /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */ def_symbol_in_progress = symbolP; - + if (SF_GET_FUNCTION(def_symbol_in_progress) || SF_GET_TAG(def_symbol_in_progress)) { /* For functions, and tags, the symbol *must* be where the debug symbol @@ -906,105 +906,105 @@ DEFUN_VOID(obj_coff_endef) if (def_symbol_in_progress != symbol_lastP) { symbol_remove(def_symbol_in_progress, &symbol_rootP, &symbol_lastP); symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); - } /* if not already in place */ - } /* if function */ - } /* normal or mergable */ - - if (SF_GET_TAG(def_symbol_in_progress) - && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) { - tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress); + } /* if not already in place */ + } /* if function */ + } /* normal or mergable */ + + if (SF_GET_TAG(def_symbol_in_progress) + && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) { + tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress); } /* If symbol is a {structure,union} tag, associate symbol to its name. */ - - if (SF_GET_FUNCTION(def_symbol_in_progress)) { - know(sizeof(def_symbol_in_progress) <= sizeof(long)); - function_lineoff - = c_line_new(def_symbol_in_progress,0, 0, &zero_address_frag); - - - - SF_SET_PROCESS(def_symbol_in_progress); - - if (symbolP == NULL) { - /* That is, if this is the first - time we've seen the function... */ - symbol_table_insert(def_symbol_in_progress); + + if (SF_GET_FUNCTION(def_symbol_in_progress)) { + know(sizeof(def_symbol_in_progress) <= sizeof(long)); + function_lineoff + = c_line_new(def_symbol_in_progress,0, 0, &zero_address_frag); + + + + SF_SET_PROCESS(def_symbol_in_progress); + + if (symbolP == NULL) { + /* That is, if this is the first + time we've seen the function... */ + symbol_table_insert(def_symbol_in_progress); } /* definition follows debug */ } /* Create the line number entry pointing to the function being defined */ - - def_symbol_in_progress = NULL; - demand_empty_rest_of_line(); - return; + + def_symbol_in_progress = NULL; + demand_empty_rest_of_line(); + return; } /* obj_coff_endef() */ static void -DEFUN_VOID(obj_coff_dim) + DEFUN_VOID(obj_coff_dim) { - register int dim_index; - - if (def_symbol_in_progress == NULL) - { - as_warn(".dim pseudo-op used outside of .def/.endef: ignored."); + register int dim_index; + + if (def_symbol_in_progress == NULL) + { + as_warn(".dim pseudo-op used outside of .def/.endef: ignored."); + demand_empty_rest_of_line(); + return; + } /* if not inside .def/.endef */ + + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); + + for (dim_index = 0; dim_index < DIMNUM; dim_index++) + { + SKIP_WHITESPACES(); + SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression()); + + switch (*input_line_pointer) + { + + case ',': + input_line_pointer++; + break; + + default: + as_warn("badly formed .dim directive ignored"); + /* intentional fallthrough */ + case '\n': + case ';': + dim_index = DIMNUM; + break; + } /* switch on following character */ + } /* for each dimension */ + demand_empty_rest_of_line(); return; - } /* if not inside .def/.endef */ - - S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); - - for (dim_index = 0; dim_index < DIMNUM; dim_index++) - { - SKIP_WHITESPACES(); - SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression()); - - switch (*input_line_pointer) - { - - case ',': - input_line_pointer++; - break; - - default: - as_warn("badly formed .dim directive ignored"); - /* intentional fallthrough */ - case '\n': - case ';': - dim_index = DIMNUM; - break; - } /* switch on following character */ - } /* for each dimension */ - - demand_empty_rest_of_line(); - return; } /* obj_coff_dim() */ static void obj_coff_line() { - int this_base; - - if (def_symbol_in_progress == NULL) { - obj_coff_ln(); - return; - } /* if it looks like a stabs style line */ - - this_base = get_absolute_expression(); - if (this_base > line_base) - { - line_base = this_base; - } - - + int this_base; + + if (def_symbol_in_progress == NULL) { + obj_coff_ln(); + return; + } /* if it looks like a stabs style line */ + + this_base = get_absolute_expression(); + if (this_base > line_base) + { + line_base = this_base; + } + + #ifndef NO_LISTING -{ - extern int listing; - if (listing && 0) { - listing_source_line(line_base); - } -} + { + extern int listing; + if (listing && 0) { + listing_source_line(line_base); + } + } #endif - S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); - SA_SET_SYM_LNNO(def_symbol_in_progress, line_base); - - demand_empty_rest_of_line(); - return; + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); + SA_SET_SYM_LNNO(def_symbol_in_progress, line_base); + + demand_empty_rest_of_line(); + return; } /* obj_coff_line() */ static void obj_coff_size() { @@ -1013,7 +1013,7 @@ static void obj_coff_size() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression()); demand_empty_rest_of_line(); @@ -1026,7 +1026,7 @@ static void obj_coff_scl() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression()); demand_empty_rest_of_line(); return; @@ -1035,27 +1035,27 @@ static void obj_coff_scl() { static void obj_coff_tag() { char *symbol_name; char name_end; - + if (def_symbol_in_progress == NULL) { as_warn(".tag pseudo-op used outside of .def/.endef ignored."); demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1); symbol_name = input_line_pointer; name_end = get_symbol_end(); - + /* Assume that the symbol referred to by .tag is always defined. */ /* This was a bad assumption. I've added find_or_make. xoxorich. */ SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name)); if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) { as_warn("tag not found for .tag %s", symbol_name); } /* not defined */ - + SF_SET_TAGGED(def_symbol_in_progress); *input_line_pointer = name_end; - + demand_empty_rest_of_line(); return; } /* obj_coff_tag() */ @@ -1066,14 +1066,14 @@ static void obj_coff_type() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression()); - + if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) && S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) { SF_SET_FUNCTION(def_symbol_in_progress); } /* is a function */ - + demand_empty_rest_of_line(); return; } /* obj_coff_type() */ @@ -1084,18 +1084,18 @@ static void obj_coff_val() { demand_empty_rest_of_line(); return; } /* if not inside .def/.endef */ - + if (is_name_beginner(*input_line_pointer)) { char *symbol_name = input_line_pointer; char name_end = get_symbol_end(); - + if (!strcmp(symbol_name, ".")) { def_symbol_in_progress->sy_frag = frag_now; S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal); /* If the .val is != from the .def (e.g. statics) */ } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) { def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name); - + /* If the segment is undefined when the forward reference is solved, then copy the segment id from the forward symbol. */ @@ -1106,7 +1106,7 @@ static void obj_coff_val() { } else { S_SET_VALUE(def_symbol_in_progress, get_absolute_expression()); } /* if symbol based */ - + demand_empty_rest_of_line(); return; } /* obj_coff_val() */ @@ -1116,8 +1116,8 @@ static void obj_coff_val() { */ static void tag_init() { - tag_hash = hash_new(); - return ; + tag_hash = hash_new(); + return ; } /* tag_init() */ static void tag_insert(name, symbolP) @@ -1125,7 +1125,7 @@ char *name; symbolS *symbolP; { register char * error_string; - + if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) { as_fatal("Inserting \"%s\" into structure table failed: %s", name, error_string); @@ -1137,17 +1137,17 @@ static symbolS *tag_find_or_make(name) char *name; { symbolS *symbolP; - + if ((symbolP = tag_find(name)) == NULL) { symbolP = symbol_new(name, SEG_UNKNOWN, 0, &zero_address_frag); - + tag_insert(S_GET_NAME(symbolP), symbolP); symbol_table_insert(symbolP); } /* not found */ - + return(symbolP); } /* tag_find_or_make() */ @@ -1161,13 +1161,13 @@ char *name; } /* tag_find() */ void obj_read_begin_hook() { - /* These had better be the same. Usually 18 bytes. */ + /* These had better be the same. Usually 18 bytes. */ #ifndef BFD_HEADERS know(sizeof(SYMENT) == sizeof(AUXENT)); know(SYMESZ == AUXESZ); #endif tag_init(); - + return; } /* obj_read_begin_hook() */ @@ -1179,305 +1179,305 @@ symbolS *symbol_externP = NULL; symbolS *symbol_extern_lastP = NULL; stack*block_stack; - symbolS *last_functionP = NULL; - symbolS *last_tagP; +symbolS *last_functionP = NULL; +symbolS *last_tagP; static unsigned int DEFUN_VOID(yank_symbols) { - symbolS *symbolP; - unsigned int symbol_number =0; - - for (symbolP = symbol_rootP; - symbolP; - symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) { - if (!SF_GET_DEBUG(symbolP)) { - /* Debug symbols do not need all this rubbish */ - symbolS* real_symbolP; - - /* L* and C_EFCN symbols never merge. */ - if (!SF_GET_LOCAL(symbolP) - && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) - && real_symbolP != symbolP) { - /* FIXME-SOON: where do dups come from? - Maybe tag references before definitions? xoxorich. */ - /* Move the debug data from the debug symbol to the - real symbol. Do NOT do the oposite (i.e. move from - real symbol to debug symbol and remove real symbol from the - list.) Because some pointers refer to the real symbol - whereas no pointers refer to the debug symbol. */ - c_symbol_merge(symbolP, real_symbolP); - /* Replace the current symbol by the real one */ - /* The symbols will never be the last or the first - because : 1st symbol is .file and 3 last symbols are - .text, .data, .bss */ - symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP); - symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP); - symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); - symbolP = real_symbolP; - } /* if not local but dup'd */ - - if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_E1)) { - S_SET_SEGMENT(symbolP, SEG_E0); - } /* push data into text */ - - S_SET_VALUE(symbolP, - S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); - - if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) - { - S_SET_EXTERNAL(symbolP); - } - else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL) - { - if (S_GET_SEGMENT(symbolP) == SEG_E0) - { - S_SET_STORAGE_CLASS(symbolP, C_LABEL); - } - else - { - S_SET_STORAGE_CLASS(symbolP, C_STAT); - } - } - - /* Mainly to speed up if not -g */ - if (SF_GET_PROCESS(symbolP)) - { - /* Handle the nested blocks auxiliary info. */ - if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) { - if (!strcmp(S_GET_NAME(symbolP), ".bb")) - stack_push(block_stack, (char *) &symbolP); - else { /* .eb */ - register symbolS* begin_symbolP; - begin_symbolP = *(symbolS**)stack_pop(block_stack); - if (begin_symbolP == (symbolS*)0) - as_warn("mismatched .eb"); - else - SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2); - } - } - /* If we are able to identify the type of a function, and we - are out of a function (last_functionP == 0) then, the - function symbol will be associated with an auxiliary - entry. */ - if (last_functionP == (symbolS*)0 && - SF_GET_FUNCTION(symbolP)) { - last_functionP = symbolP; - - if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) { - S_SET_NUMBER_AUXILIARY(symbolP, 1); - } /* make it at least 1 */ - - /* Clobber possible stale .dim information. */ - bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen, - sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen)); - } - /* The C_FCN doesn't need any additional information. - I don't even know if this is needed for sdb. But the - standard assembler generates it, so... - */ - if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) { - if (last_functionP == (symbolS*)0) - as_fatal("C_EFCN symbol out of scope"); - SA_SET_SYM_FSIZE(last_functionP, - (long)(S_GET_VALUE(symbolP) - - S_GET_VALUE(last_functionP))); - SA_SET_SYM_ENDNDX(last_functionP, symbol_number); - last_functionP = (symbolS*)0; - } - } - } else if (SF_GET_TAG(symbolP)) { - /* First descriptor of a structure must point to - the first slot after the structure description. */ - last_tagP = symbolP; - - } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) { - /* +2 take in account the current symbol */ - SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2); - } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) { - if (S_GET_VALUE(symbolP)) { - S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number); - S_SET_VALUE(symbolP, 0); - } /* no one points at the first .file symbol */ - } /* if debug or tag or eos or file */ - - /* We must put the external symbols apart. The loader - does not bomb if we do not. But the references in - the endndx field for a .bb symbol are not corrected - if an external symbol is removed between .bb and .be. - I.e in the following case : - [20] .bb endndx = 22 - [21] foo external - [22] .be - ld will move the symbol 21 to the end of the list but - endndx will still be 22 instead of 21. */ - - - if (SF_GET_LOCAL(symbolP)) { - /* remove C_EFCN and LOCAL (L...) symbols */ - /* next pointer remains valid */ - symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); - - } - else if (!S_IS_DEFINED(symbolP) - && !S_IS_DEBUG(symbolP) - && !SF_GET_STATICS(symbolP) && - S_GET_STORAGE_CLASS(symbolP) == C_EXT) - { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */ - /* if external, Remove from the list */ - symbolS *hold = symbol_previous(symbolP); - - symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); - symbol_clear_list_pointers(symbolP); - symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP); - symbolP = hold; - } else { - if (SF_GET_STRING(symbolP)) { - symbolP->sy_name_offset = string_byte_count; - string_byte_count += strlen(S_GET_NAME(symbolP)) + 1; - } else { - symbolP->sy_name_offset = 0; - } /* fix "long" names */ - - symbolP->sy_number = symbol_number; - symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP); - } /* if local symbol */ - } /* traverse the symbol list */ - return symbol_number; - + symbolS *symbolP; + unsigned int symbol_number =0; + + for (symbolP = symbol_rootP; + symbolP; + symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) { + if (!SF_GET_DEBUG(symbolP)) { + /* Debug symbols do not need all this rubbish */ + symbolS* real_symbolP; + + /* L* and C_EFCN symbols never merge. */ + if (!SF_GET_LOCAL(symbolP) + && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) + && real_symbolP != symbolP) { + /* FIXME-SOON: where do dups come from? + Maybe tag references before definitions? xoxorich. */ + /* Move the debug data from the debug symbol to the + real symbol. Do NOT do the oposite (i.e. move from + real symbol to debug symbol and remove real symbol from the + list.) Because some pointers refer to the real symbol + whereas no pointers refer to the debug symbol. */ + c_symbol_merge(symbolP, real_symbolP); + /* Replace the current symbol by the real one */ + /* The symbols will never be the last or the first + because : 1st symbol is .file and 3 last symbols are + .text, .data, .bss */ + symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP); + symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP); + symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); + symbolP = real_symbolP; + } /* if not local but dup'd */ + + if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_E1)) { + S_SET_SEGMENT(symbolP, SEG_E0); + } /* push data into text */ + + S_SET_VALUE(symbolP, + S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); + + if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) + { + S_SET_EXTERNAL(symbolP); + } + else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL) + { + if (S_GET_SEGMENT(symbolP) == SEG_E0) + { + S_SET_STORAGE_CLASS(symbolP, C_LABEL); + } + else + { + S_SET_STORAGE_CLASS(symbolP, C_STAT); + } + } + + /* Mainly to speed up if not -g */ + if (SF_GET_PROCESS(symbolP)) + { + /* Handle the nested blocks auxiliary info. */ + if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) { + if (!strcmp(S_GET_NAME(symbolP), ".bb")) + stack_push(block_stack, (char *) &symbolP); + else { /* .eb */ + register symbolS* begin_symbolP; + begin_symbolP = *(symbolS**)stack_pop(block_stack); + if (begin_symbolP == (symbolS*)0) + as_warn("mismatched .eb"); + else + SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2); + } + } + /* If we are able to identify the type of a function, and we + are out of a function (last_functionP == 0) then, the + function symbol will be associated with an auxiliary + entry. */ + if (last_functionP == (symbolS*)0 && + SF_GET_FUNCTION(symbolP)) { + last_functionP = symbolP; + + if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) { + S_SET_NUMBER_AUXILIARY(symbolP, 1); + } /* make it at least 1 */ + + /* Clobber possible stale .dim information. */ + bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen, + sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen)); + } + /* The C_FCN doesn't need any additional information. + I don't even know if this is needed for sdb. But the + standard assembler generates it, so... + */ + if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) { + if (last_functionP == (symbolS*)0) + as_fatal("C_EFCN symbol out of scope"); + SA_SET_SYM_FSIZE(last_functionP, + (long)(S_GET_VALUE(symbolP) - + S_GET_VALUE(last_functionP))); + SA_SET_SYM_ENDNDX(last_functionP, symbol_number); + last_functionP = (symbolS*)0; + } + } + } else if (SF_GET_TAG(symbolP)) { + /* First descriptor of a structure must point to + the first slot after the structure description. */ + last_tagP = symbolP; + + } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) { + /* +2 take in account the current symbol */ + SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2); + } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) { + if (S_GET_VALUE(symbolP)) { + S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number); + S_SET_VALUE(symbolP, 0); + } /* no one points at the first .file symbol */ + } /* if debug or tag or eos or file */ + + /* We must put the external symbols apart. The loader + does not bomb if we do not. But the references in + the endndx field for a .bb symbol are not corrected + if an external symbol is removed between .bb and .be. + I.e in the following case : + [20] .bb endndx = 22 + [21] foo external + [22] .be + ld will move the symbol 21 to the end of the list but + endndx will still be 22 instead of 21. */ + + + if (SF_GET_LOCAL(symbolP)) { + /* remove C_EFCN and LOCAL (L...) symbols */ + /* next pointer remains valid */ + symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); + + } + else if (!S_IS_DEFINED(symbolP) + && !S_IS_DEBUG(symbolP) + && !SF_GET_STATICS(symbolP) && + S_GET_STORAGE_CLASS(symbolP) == C_EXT) + { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */ + /* if external, Remove from the list */ + symbolS *hold = symbol_previous(symbolP); + + symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); + symbol_clear_list_pointers(symbolP); + symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP); + symbolP = hold; + } else { + if (SF_GET_STRING(symbolP)) { + symbolP->sy_name_offset = string_byte_count; + string_byte_count += strlen(S_GET_NAME(symbolP)) + 1; + } else { + symbolP->sy_name_offset = 0; + } /* fix "long" names */ + + symbolP->sy_number = symbol_number; + symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP); + } /* if local symbol */ + } /* traverse the symbol list */ + return symbol_number; + } static unsigned int DEFUN_VOID(glue_symbols) { - unsigned int symbol_number = 0; - symbolS *symbolP; - for (symbolP = symbol_externP; symbol_externP;) { - symbolS *tmp = symbol_externP; - - /* append */ - symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP); - symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP); - - /* and process */ - if (SF_GET_STRING(tmp)) { - tmp->sy_name_offset = string_byte_count; - string_byte_count += strlen(S_GET_NAME(tmp)) + 1; - } else { - tmp->sy_name_offset = 0; - } /* fix "long" names */ - - tmp->sy_number = symbol_number; - symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp); - } /* append the entire extern chain */ - return symbol_number; - + unsigned int symbol_number = 0; + symbolS *symbolP; + for (symbolP = symbol_externP; symbol_externP;) { + symbolS *tmp = symbol_externP; + + /* append */ + symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP); + symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP); + + /* and process */ + if (SF_GET_STRING(tmp)) { + tmp->sy_name_offset = string_byte_count; + string_byte_count += strlen(S_GET_NAME(tmp)) + 1; + } else { + tmp->sy_name_offset = 0; + } /* fix "long" names */ + + tmp->sy_number = symbol_number; + symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp); + } /* append the entire extern chain */ + return symbol_number; + } static unsigned int DEFUN_VOID(tie_tags) { - unsigned int symbol_number = 0; - - symbolS*symbolP; - for (symbolP = symbol_rootP; symbolP; symbolP = - symbol_next(symbolP)) - { - symbolP->sy_number = symbol_number; - - - - if (SF_GET_TAGGED(symbolP)) - { - SA_SET_SYM_TAGNDX - (symbolP, - ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number); - } - - symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP); - } - return symbol_number; - + unsigned int symbol_number = 0; + + symbolS*symbolP; + for (symbolP = symbol_rootP; symbolP; symbolP = + symbol_next(symbolP)) + { + symbolP->sy_number = symbol_number; + + + + if (SF_GET_TAGGED(symbolP)) + { + SA_SET_SYM_TAGNDX + (symbolP, + ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number); + } + + symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP); + } + return symbol_number; + } static void -DEFUN(crawl_symbols,(headers, abfd), - struct internal_filehdr *headers AND - bfd *abfd) + DEFUN(crawl_symbols,(headers, abfd), + struct internal_filehdr *headers AND + bfd *abfd) { - - unsigned int i; - unsigned int ptr = 0; - - - symbolS *symbolP; - - /* Initialize the stack used to keep track of the matching .bb .be */ - - block_stack = stack_init(512, sizeof(symbolS*)); - /* JF deal with forward references first... */ - for (symbolP = symbol_rootP; - symbolP; - symbolP = symbol_next(symbolP)) - { - - if (symbolP->sy_forward) { - S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP) - + S_GET_VALUE(symbolP->sy_forward) - + symbolP->sy_forward->sy_frag->fr_address)); - - if (SF_GET_GET_SEGMENT(symbolP)) { - S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward)); - } /* forward segment also */ - - symbolP->sy_forward=0; - } /* if it has a forward reference */ - } /* walk the symbol chain */ - - - /* The symbol list should be ordered according to the following sequence - * order : - * . .file symbol - * . debug entries for functions - * . fake symbols for the sections, including.text .data and .bss - * . defined symbols - * . undefined symbols - * But this is not mandatory. The only important point is to put the - * undefined symbols at the end of the list. - */ - - if (symbol_rootP == NULL - || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) { - c_dot_file_symbol("fake"); - } - /* Is there a .file symbol ? If not insert one at the beginning. */ - - /* - * Build up static symbols for the sections, they are filled in later - */ - - - for (i = SEG_E0; i < SEG_E9; i++) - { - if (segment_info[i].scnhdr.s_name[0]) - { - segment_info[i].dot = - c_section_symbol(segment_info[i].scnhdr.s_name, - i-SEG_E0+1); - - } - } - - - /* Take all the externals out and put them into another chain */ - headers->f_nsyms = yank_symbols(); - /* Take the externals and glue them onto the end.*/ - headers->f_nsyms += glue_symbols(); - - headers->f_nsyms = tie_tags(); - know(symbol_externP == NULL); - know(symbol_extern_lastP == NULL); - - return; + + unsigned int i; + unsigned int ptr = 0; + + + symbolS *symbolP; + + /* Initialize the stack used to keep track of the matching .bb .be */ + + block_stack = stack_init(512, sizeof(symbolS*)); + /* JF deal with forward references first... */ + for (symbolP = symbol_rootP; + symbolP; + symbolP = symbol_next(symbolP)) + { + + if (symbolP->sy_forward) { + S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP) + + S_GET_VALUE(symbolP->sy_forward) + + symbolP->sy_forward->sy_frag->fr_address)); + + if (SF_GET_GET_SEGMENT(symbolP)) { + S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward)); + } /* forward segment also */ + + symbolP->sy_forward=0; + } /* if it has a forward reference */ + } /* walk the symbol chain */ + + + /* The symbol list should be ordered according to the following sequence + * order : + * . .file symbol + * . debug entries for functions + * . fake symbols for the sections, including.text .data and .bss + * . defined symbols + * . undefined symbols + * But this is not mandatory. The only important point is to put the + * undefined symbols at the end of the list. + */ + + if (symbol_rootP == NULL + || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) { + c_dot_file_symbol("fake"); + } + /* Is there a .file symbol ? If not insert one at the beginning. */ + + /* + * Build up static symbols for the sections, they are filled in later + */ + + + for (i = SEG_E0; i < SEG_E9; i++) + { + if (segment_info[i].scnhdr.s_name[0]) + { + segment_info[i].dot = + c_section_symbol(segment_info[i].scnhdr.s_name, + i-SEG_E0+1); + + } + } + + + /* Take all the externals out and put them into another chain */ + headers->f_nsyms = yank_symbols(); + /* Take the externals and glue them onto the end.*/ + headers->f_nsyms += glue_symbols(); + + headers->f_nsyms = tie_tags(); + know(symbol_externP == NULL); + know(symbol_extern_lastP == NULL); + + return; } /* @@ -1487,26 +1487,26 @@ DEFUN(crawl_symbols,(headers, abfd), void DEFUN(w_strings,(where), char *where) { - symbolS *symbolP; - - /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ - md_number_to_chars(where, string_byte_count, sizeof(string_byte_count)); - where += sizeof(string_byte_count); - for (symbolP = symbol_rootP; - symbolP; - symbolP = symbol_next(symbolP)) - { - unsigned int size; - - if (SF_GET_STRING(symbolP)) { - size = strlen(S_GET_NAME(symbolP)) + 1; - - memcpy(where, S_GET_NAME(symbolP),size); - where += size; - - } - } - + symbolS *symbolP; + + /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ + md_number_to_chars(where, string_byte_count, sizeof(string_byte_count)); + where += sizeof(string_byte_count); + for (symbolP = symbol_rootP; + symbolP; + symbolP = symbol_next(symbolP)) + { + unsigned int size; + + if (SF_GET_STRING(symbolP)) { + size = strlen(S_GET_NAME(symbolP)) + 1; + + memcpy(where, S_GET_NAME(symbolP),size); + where += size; + + } + } + } @@ -1514,59 +1514,59 @@ void DEFUN(w_strings,(where), static void -DEFUN(do_linenos_for,(abfd, file_cursor), - bfd *abfd AND - unsigned long *file_cursor) + DEFUN(do_linenos_for,(abfd, file_cursor), + bfd *abfd AND + unsigned long *file_cursor) { - unsigned int idx; - - for (idx = SEG_E0; idx < SEG_E9; idx++) - { - segment_info_type *s = segment_info + idx; - - - if (s->scnhdr.s_nlnno != 0) - { - struct lineno_list *line_ptr ; - - struct external_lineno *buffer = - (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ); - - struct external_lineno *dst= buffer; - - /* Run through the table we've built and turn it into its external - form, take this chance to remove duplicates */ - - for (line_ptr = s->lineno_list_head; - line_ptr != (struct lineno_list *)NULL; - line_ptr = line_ptr->next) - { - - if (line_ptr->line.l_lnno == 0) - { - /* Turn a pointer to a symbol into the symbols' index */ - line_ptr->line.l_addr.l_symndx = - ( (symbolS *)line_ptr->line.l_addr.l_symndx)->sy_number; - } - else - { - line_ptr->line.l_addr.l_paddr += ((struct frag * )(line_ptr->frag))->fr_address; - } - - - (void) bfd_coff_swap_lineno_out(abfd, &(line_ptr->line), dst); - dst++; + unsigned int idx; - } - - s->scnhdr.s_lnnoptr = *file_cursor; - - bfd_write(buffer, 1, s->scnhdr.s_nlnno* LINESZ, abfd); - free(buffer); - - *file_cursor += s->scnhdr.s_nlnno * LINESZ; - } - } + for (idx = SEG_E0; idx < SEG_E9; idx++) + { + segment_info_type *s = segment_info + idx; + + + if (s->scnhdr.s_nlnno != 0) + { + struct lineno_list *line_ptr ; + + struct external_lineno *buffer = + (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ); + + struct external_lineno *dst= buffer; + + /* Run through the table we've built and turn it into its external + form, take this chance to remove duplicates */ + + for (line_ptr = s->lineno_list_head; + line_ptr != (struct lineno_list *)NULL; + line_ptr = line_ptr->next) + { + + if (line_ptr->line.l_lnno == 0) + { + /* Turn a pointer to a symbol into the symbols' index */ + line_ptr->line.l_addr.l_symndx = + ( (symbolS *)line_ptr->line.l_addr.l_symndx)->sy_number; + } + else + { + line_ptr->line.l_addr.l_paddr += ((struct frag * )(line_ptr->frag))->fr_address; + } + + + (void) bfd_coff_swap_lineno_out(abfd, &(line_ptr->line), dst); + dst++; + + } + + s->scnhdr.s_lnnoptr = *file_cursor; + + bfd_write(buffer, 1, s->scnhdr.s_nlnno* LINESZ, abfd); + free(buffer); + + *file_cursor += s->scnhdr.s_nlnno * LINESZ; + } + } } @@ -1576,216 +1576,216 @@ DEFUN(do_linenos_for,(abfd, file_cursor), static void DEFUN_VOID(remove_subsegs) { - unsigned int i; - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - frchainS *head = segment_info[i].frchainP; - fragS dummy; - fragS * prev_frag = &dummy; + unsigned int i; - while (head && head->frch_seg == i) - { - prev_frag->fr_next = head->frch_root; - prev_frag = head->frch_last; - head = head->frch_next; - } - prev_frag->fr_next = 0; - } + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + { + frchainS *head = segment_info[i].frchainP; + fragS dummy; + fragS * prev_frag = &dummy; + + while (head && head->frch_seg == i) + { + prev_frag->fr_next = head->frch_root; + prev_frag = head->frch_last; + head = head->frch_next; + } + prev_frag->fr_next = 0; + } } extern void DEFUN_VOID(write_object_file) { - int i; - struct frchain *frchain_ptr; - - struct internal_filehdr filehdr; - struct internal_aouthdr aouthdr; - unsigned long file_cursor; - bfd *abfd; - unsigned int addr = 0; - abfd = bfd_openw(out_file_name, TARGET_FORMAT); - - - if (abfd == 0) { - as_perror ("FATAL: Can't create %s", out_file_name); - exit(42); + int i; + struct frchain *frchain_ptr; + + struct internal_filehdr filehdr; + struct internal_aouthdr aouthdr; + unsigned long file_cursor; + bfd *abfd; + unsigned int addr = 0; + abfd = bfd_openw(out_file_name, TARGET_FORMAT); + + + if (abfd == 0) { + as_perror ("FATAL: Can't create %s", out_file_name); + exit(42); } - bfd_set_format(abfd, bfd_object); - bfd_set_arch_mach(abfd, BFD_ARCH, 0); - - - - string_byte_count = 4; - - for (frchain_ptr = frchain_root; - frchain_ptr != (struct frchain *)NULL; - frchain_ptr = frchain_ptr->frch_next) { - /* Run through all the sub-segments and align them up. Also close any - open frags. We tack a .fill onto the end of the frag chain so - that any .align's size can be worked by looking at the next - frag */ - - subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg); + bfd_set_format(abfd, bfd_object); + bfd_set_arch_mach(abfd, BFD_ARCH, 0); + + + + string_byte_count = 4; + + for (frchain_ptr = frchain_root; + frchain_ptr != (struct frchain *)NULL; + frchain_ptr = frchain_ptr->frch_next) { + /* Run through all the sub-segments and align them up. Also close any + open frags. We tack a .fill onto the end of the frag chain so + that any .align's size can be worked by looking at the next + frag */ + + subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg); #define SUB_SEGMENT_ALIGN 1 - frag_align(SUB_SEGMENT_ALIGN,0); - frag_wane(frag_now); - frag_now->fr_fix = 0; - know( frag_now->fr_next == NULL ); + frag_align(SUB_SEGMENT_ALIGN,0); + frag_wane(frag_now); + frag_now->fr_fix = 0; + know( frag_now->fr_next == NULL ); } - - - remove_subsegs(); - - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - relax_segment(segment_info[i].frchainP->frch_root, i); - } - - - - - - filehdr.f_nscns = 0; - - /* Find out how big the sections are */ - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - - if (segment_info[i].scnhdr.s_name[0]) - { - filehdr.f_nscns++; - } - segment_info[i].scnhdr.s_paddr = addr; - if (i == SEG_E2) { - /* THis is a special case, we leave the size alone, which will have */ - /* been made up from all and any lcomms seen */ - } - else { - addr += size_section(abfd, i); - } - } - - - - /* Turn the gas native symbol table shape into a coff symbol table */ - crawl_symbols(&filehdr, abfd); + + + remove_subsegs(); + + + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + { + relax_segment(segment_info[i].frchainP->frch_root, i); + } + + + + + + filehdr.f_nscns = 0; + + /* Find out how big the sections are */ + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + { + + if (segment_info[i].scnhdr.s_name[0]) + { + filehdr.f_nscns++; + } + segment_info[i].scnhdr.s_paddr = addr; + if (i == SEG_E2) { + /* THis is a special case, we leave the size alone, which will have */ + /* been made up from all and any lcomms seen */ + } + else { + addr += size_section(abfd, i); + } + } + + + + /* Turn the gas native symbol table shape into a coff symbol table */ + crawl_symbols(&filehdr, abfd); #ifndef TC_H8300 - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - fixup_segment(segment_info[i].fix_root, i); - } + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + { + fixup_segment(segment_info[i].fix_root, i); + } #endif - - file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns ; - - bfd_seek(abfd, file_cursor, 0); - - - do_relocs_for(abfd, &file_cursor); - - do_linenos_for(abfd, &file_cursor); - - - /* Plant the data */ - - fill_section(abfd,&filehdr, &file_cursor); - - filehdr.f_magic = COFF_MAGIC; - filehdr.f_timdat = 0; - filehdr.f_flags = 0; - - - - { - - unsigned int symtable_size = filehdr.f_nsyms * SYMESZ; - char *buffer1 = malloc(symtable_size + string_byte_count + 4); - char *ptr = buffer1; - filehdr.f_symptr = bfd_tell(abfd); - w_symbols(abfd, buffer1, symbol_rootP); - w_strings(buffer1 + symtable_size); - bfd_write(buffer1, 1,symtable_size + string_byte_count + 4, abfd); - free(buffer1); - - } - coff_header_append(abfd, &filehdr, &aouthdr); - - bfd_close_all_done(abfd); + + file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns ; + + bfd_seek(abfd, file_cursor, 0); + + + do_relocs_for(abfd, &file_cursor); + + do_linenos_for(abfd, &file_cursor); + + + /* Plant the data */ + + fill_section(abfd,&filehdr, &file_cursor); + + filehdr.f_magic = COFF_MAGIC; + filehdr.f_timdat = 0; + filehdr.f_flags = 0; + + + + { + + unsigned int symtable_size = filehdr.f_nsyms * SYMESZ; + char *buffer1 = malloc(symtable_size + string_byte_count + 4); + char *ptr = buffer1; + filehdr.f_symptr = bfd_tell(abfd); + w_symbols(abfd, buffer1, symbol_rootP); + w_strings(buffer1 + symtable_size); + bfd_write(buffer1, 1,symtable_size + string_byte_count + 4, abfd); + free(buffer1); + + } + coff_header_append(abfd, &filehdr, &aouthdr); + + bfd_close_all_done(abfd); } static void DEFUN(change_to_section,(name, len, exp), - char *name AND - unsigned int len AND - unsigned int exp) + char *name AND + unsigned int len AND + unsigned int exp) { - unsigned int i; - /* Find out if we've already got a section of this name etc */ - for(i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0] ; i++) - { - if (strncmp(segment_info[i].scnhdr.s_name, name, len) == 0) - { - subseg_new(i, exp); - return; - - } - } - /* No section, add one */ - strncpy(segment_info[i].scnhdr.s_name, name, 8); - subseg_new(i, exp); + unsigned int i; + /* Find out if we've already got a section of this name etc */ + for(i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0] ; i++) + { + if (strncmp(segment_info[i].scnhdr.s_name, name, len) == 0) + { + subseg_new(i, exp); + return; + + } + } + /* No section, add one */ + strncpy(segment_info[i].scnhdr.s_name, name, 8); + subseg_new(i, exp); } static void -DEFUN_VOID(obj_coff_section) + DEFUN_VOID(obj_coff_section) { - /* Strip out the section name */ - char *section_name ; - char *section_name_end; - char c; - - unsigned int len; - unsigned int exp; - - section_name = input_line_pointer; - c = get_symbol_end(); - section_name_end = input_line_pointer; - - len = section_name_end - section_name ; - input_line_pointer++; - SKIP_WHITESPACE(); - if (c == ',') - { - exp = get_absolute_expression(); - } - else if ( *input_line_pointer == ',') - { - + /* Strip out the section name */ + char *section_name ; + char *section_name_end; + char c; + + unsigned int len; + unsigned int exp; + + section_name = input_line_pointer; + c = get_symbol_end(); + section_name_end = input_line_pointer; + + len = section_name_end - section_name ; input_line_pointer++; - exp = get_absolute_expression(); - } - else - { - exp = 0; - } - - change_to_section(section_name, len,exp); -*section_name_end = c; - + SKIP_WHITESPACE(); + if (c == ',') + { + exp = get_absolute_expression(); + } + else if ( *input_line_pointer == ',') + { + + input_line_pointer++; + exp = get_absolute_expression(); + } + else + { + exp = 0; + } + + change_to_section(section_name, len,exp); + *section_name_end = c; + } static void obj_coff_text() { - change_to_section(".text",5, get_absolute_expression()); + change_to_section(".text",5, get_absolute_expression()); } static void obj_coff_data() { - change_to_section(".data",5, get_absolute_expression()); + change_to_section(".data",5, get_absolute_expression()); } void c_symbol_merge(debug, normal) @@ -1794,97 +1794,97 @@ symbolS *normal; { S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug)); S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug)); - + if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) { S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug)); } /* take the most we have */ - + if (S_GET_NUMBER_AUXILIARY(debug) > 0) { memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ); } /* Move all the auxiliary information */ - + /* Move the debug flags. */ SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug)); } /* c_symbol_merge() */ static int -DEFUN(c_line_new,(symbol, paddr, line_number, frag), - symbolS *symbol AND - long paddr AND - unsigned short line_number AND - fragS* frag) + DEFUN(c_line_new,(symbol, paddr, line_number, frag), + symbolS *symbol AND + long paddr AND + unsigned short line_number AND + fragS* frag) { - struct lineno_list* new_line = - (struct lineno_list *)xmalloc(sizeof(struct lineno_list)); - - segment_info_type *s = segment_info + now_seg; - new_line->line.l_lnno = line_number; - - if (line_number == 0) - { - new_line->line.l_addr.l_symndx = (long)symbol; - } - else - { - new_line->line.l_addr.l_paddr = paddr; - } - - new_line->frag = (char*)frag; - new_line->next = (struct lineno_list*)NULL; - - - if (s->lineno_list_head == (struct lineno_list *)NULL) - { - s->lineno_list_head = new_line; - } - else - { - s->lineno_list_tail->next = new_line; - } - s->lineno_list_tail = new_line; - return LINESZ * s->scnhdr.s_nlnno ++; + struct lineno_list* new_line = + (struct lineno_list *)xmalloc(sizeof(struct lineno_list)); + + segment_info_type *s = segment_info + now_seg; + new_line->line.l_lnno = line_number; + + if (line_number == 0) + { + new_line->line.l_addr.l_symndx = (long)symbol; + } + else + { + new_line->line.l_addr.l_paddr = paddr; + } + + new_line->frag = (char*)frag; + new_line->next = (struct lineno_list*)NULL; + + + if (s->lineno_list_head == (struct lineno_list *)NULL) + { + s->lineno_list_head = new_line; + } + else + { + s->lineno_list_tail->next = new_line; + } + s->lineno_list_tail = new_line; + return LINESZ * s->scnhdr.s_nlnno ++; } void c_dot_file_symbol(filename) char *filename; { - symbolS* symbolP; - - symbolP = symbol_new(".file", - SEG_DEBUG, - 0, - &zero_address_frag); - - S_SET_STORAGE_CLASS(symbolP, C_FILE); - S_SET_NUMBER_AUXILIARY(symbolP, 1); - SA_SET_FILE_FNAME(symbolP, filename); + symbolS* symbolP; + + symbolP = symbol_new(".file", + SEG_DEBUG, + 0, + &zero_address_frag); + + S_SET_STORAGE_CLASS(symbolP, C_FILE); + S_SET_NUMBER_AUXILIARY(symbolP, 1); + SA_SET_FILE_FNAME(symbolP, filename); #ifndef NO_LISTING - { - extern int listing; - if (listing) - { - listing_source_file(filename); - } - - } - + { + extern int listing; + if (listing) + { + listing_source_file(filename); + } + + } + #endif - SF_SET_DEBUG(symbolP); - S_SET_VALUE(symbolP, (long) previous_file_symbol); - - previous_file_symbol = symbolP; - - /* Make sure that the symbol is first on the symbol chain */ - if (symbol_rootP != symbolP) { - if (symbolP == symbol_lastP) { - symbol_lastP = symbol_lastP->sy_previous; - } /* if it was the last thing on the list */ - - symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); - symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); - symbol_rootP = symbolP; - } /* if not first on the list */ - + SF_SET_DEBUG(symbolP); + S_SET_VALUE(symbolP, (long) previous_file_symbol); + + previous_file_symbol = symbolP; + + /* Make sure that the symbol is first on the symbol chain */ + if (symbol_rootP != symbolP) { + if (symbolP == symbol_lastP) { + symbol_lastP = symbol_lastP->sy_previous; + } /* if it was the last thing on the list */ + + symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); + symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); + symbol_rootP = symbolP; + } /* if not first on the list */ + } /* c_dot_file_symbol() */ /* @@ -1895,284 +1895,288 @@ symbolS *c_section_symbol(name,idx) char *name; int idx; { - symbolS *symbolP; - - symbolP = symbol_new(name,idx, - 0, - &zero_address_frag); - - S_SET_STORAGE_CLASS(symbolP, C_STAT); - S_SET_NUMBER_AUXILIARY(symbolP, 1); - - SF_SET_STATICS(symbolP); - - return symbolP; + symbolS *symbolP; + + symbolP = symbol_new(name,idx, + 0, + &zero_address_frag); + + S_SET_STORAGE_CLASS(symbolP, C_STAT); + S_SET_NUMBER_AUXILIARY(symbolP, 1); + + SF_SET_STATICS(symbolP); + + return symbolP; } /* c_section_symbol() */ static void -DEFUN(w_symbols,(abfd, where, symbol_rootP), -bfd *abfd AND -char *where AND -symbolS *symbol_rootP) + DEFUN(w_symbols,(abfd, where, symbol_rootP), + bfd *abfd AND + char *where AND + symbolS *symbol_rootP) { - symbolS *symbolP; - unsigned int i; - - /* First fill in those values we have only just worked out */ - for (i = SEG_E0; i < SEG_E9; i++) - { - symbolP = segment_info[i].dot; - if (symbolP) - { - - SA_SET_SCN_SCNLEN(symbolP, segment_info[i].scnhdr.s_size); - SA_SET_SCN_NRELOC(symbolP, segment_info[i].scnhdr.s_nreloc); - SA_SET_SCN_NLINNO(symbolP, segment_info[i].scnhdr.s_nlnno); - - } - } - - /* - * Emit all symbols left in the symbol chain. - */ - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - /* Used to save the offset of the name. It is used to point - to the string in memory but must be a file offset. */ - register char * temp; - - tc_coff_symbol_emit_hook(symbolP); - - temp = S_GET_NAME(symbolP); - if (SF_GET_STRING(symbolP)) { - S_SET_OFFSET(symbolP, symbolP->sy_name_offset); - S_SET_ZEROES(symbolP, 0); + symbolS *symbolP; + unsigned int i; + + /* First fill in those values we have only just worked out */ + for (i = SEG_E0; i < SEG_E9; i++) + { + symbolP = segment_info[i].dot; + if (symbolP) + { + + SA_SET_SCN_SCNLEN(symbolP, segment_info[i].scnhdr.s_size); + SA_SET_SCN_NRELOC(symbolP, segment_info[i].scnhdr.s_nreloc); + SA_SET_SCN_NLINNO(symbolP, segment_info[i].scnhdr.s_nlnno); + + } + } + + /* + * Emit all symbols left in the symbol chain. + */ + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { + /* Used to save the offset of the name. It is used to point + to the string in memory but must be a file offset. */ + register char * temp; + + tc_coff_symbol_emit_hook(symbolP); + + temp = S_GET_NAME(symbolP); + if (SF_GET_STRING(symbolP)) { + S_SET_OFFSET(symbolP, symbolP->sy_name_offset); + S_SET_ZEROES(symbolP, 0); } else { bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN); strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN); - } - where = symbol_to_chars(abfd, where, symbolP); - S_SET_NAME(symbolP,temp); + } + where = symbol_to_chars(abfd, where, symbolP); + S_SET_NAME(symbolP,temp); } - + } /* w_symbols() */ static void DEFUN_VOID(obj_coff_lcomm) { - char *name; - char c; - int temp; - char *p; - symbolS *symbolP; - name = input_line_pointer; - - - - c = get_symbol_end(); - p = input_line_pointer; - *p = c; - SKIP_WHITESPACE(); - if (*input_line_pointer != ',') { - as_bad("Expected comma after name"); - ignore_rest_of_line(); - return; + char *name; + char c; + int temp; + char *p; + symbolS *symbolP; + name = input_line_pointer; + + + + c = get_symbol_end(); + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE(); + if (*input_line_pointer != ',') { + as_bad("Expected comma after name"); + ignore_rest_of_line(); + return; } - if (*input_line_pointer == '\n') { - as_bad("Missing size expression"); - return; + if (*input_line_pointer == '\n') { + as_bad("Missing size expression"); + return; } - input_line_pointer++; - if ((temp = get_absolute_expression ()) < 0) { - as_warn("lcomm length (%d.) <0! Ignored.", temp); - ignore_rest_of_line(); - return; + input_line_pointer++; + if ((temp = get_absolute_expression ()) < 0) { + as_warn("lcomm length (%d.) <0! Ignored.", temp); + ignore_rest_of_line(); + return; } - *p = 0; - symbolP = symbol_find_or_make(name); - S_SET_VALUE(symbolP, segment_info[SEG_E2].scnhdr.s_size); - S_SET_SEGMENT(symbolP, SEG_E2); - segment_info[SEG_E2].scnhdr.s_size += temp; - S_SET_STORAGE_CLASS(symbolP, C_STAT); - demand_empty_rest_of_line(); + *p = 0; + symbolP = symbol_find_or_make(name); + S_SET_VALUE(symbolP, segment_info[SEG_E2].scnhdr.s_size); + S_SET_SEGMENT(symbolP, SEG_E2); + segment_info[SEG_E2].scnhdr.s_size += temp; + S_SET_STORAGE_CLASS(symbolP, C_STAT); + demand_empty_rest_of_line(); } #if 1 static void DEFUN(fixup_segment,(fixP, this_segment_type), -register fixS * fixP AND -segT this_segment_type) + register fixS * fixP AND + segT this_segment_type) { - register symbolS *add_symbolP; - register symbolS *sub_symbolP; - register long add_number; - register int size; - register char *place; - register long where; - register char pcrel; - register fragS *fragP; - register segT add_symbol_segment = SEG_ABSOLUTE; - - - for ( ; fixP; fixP = fixP->fx_next) - { - fragP = fixP->fx_frag; - know(fragP); - where = fixP->fx_where; - place = fragP->fr_literal + where; - size = fixP->fx_size; - add_symbolP = fixP->fx_addsy; + register symbolS *add_symbolP; + register symbolS *sub_symbolP; + register long add_number; + register int size; + register char *place; + register long where; + register char pcrel; + register fragS *fragP; + register segT add_symbol_segment = SEG_ABSOLUTE; + + + for ( ; fixP; fixP = fixP->fx_next) + { + fragP = fixP->fx_frag; + know(fragP); + where = fixP->fx_where; + place = fragP->fr_literal + where; + size = fixP->fx_size; + add_symbolP = fixP->fx_addsy; #ifdef TC_I960 - if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) { - /* Relocation should be done via the - associated 'bal' entry point - symbol. */ - - if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) { - as_bad("No 'bal' entry point for leafproc %s", - S_GET_NAME(add_symbolP)); - continue; - } - fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP); - } /* callj relocation */ + if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) { + /* Relocation should be done via the + associated 'bal' entry point + symbol. */ + + if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) { + as_bad("No 'bal' entry point for leafproc %s", + S_GET_NAME(add_symbolP)); + continue; + } + fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP); + } /* callj relocation */ #endif - sub_symbolP = fixP->fx_subsy; - add_number = fixP->fx_offset; - pcrel = fixP->fx_pcrel; - - if (add_symbolP) { - add_symbol_segment = S_GET_SEGMENT(add_symbolP); - } /* if there is an addend */ - - if (sub_symbolP) { - if (!add_symbolP) { - /* Its just -sym */ - if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) { - as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP)); - } /* not absolute */ - - add_number -= S_GET_VALUE(sub_symbolP); - - /* if sub_symbol is in the same segment that add_symbol - and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */ - } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment) - && (SEG_NORMAL(add_symbol_segment) - || (add_symbol_segment == SEG_ABSOLUTE))) { - /* Difference of 2 symbols from same segment. */ - /* Can't make difference of 2 undefineds: 'value' means */ - /* something different for N_UNDF. */ + sub_symbolP = fixP->fx_subsy; + add_number = fixP->fx_offset; + pcrel = fixP->fx_pcrel; + + if (add_symbolP) { + add_symbol_segment = S_GET_SEGMENT(add_symbolP); + } /* if there is an addend */ + + if (sub_symbolP) { + if (!add_symbolP) { + /* Its just -sym */ + if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) { + as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP)); + } /* not absolute */ + + add_number -= S_GET_VALUE(sub_symbolP); + + /* if sub_symbol is in the same segment that add_symbol + and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */ + } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment) + && (SEG_NORMAL(add_symbol_segment) + || (add_symbol_segment == SEG_ABSOLUTE))) { + /* Difference of 2 symbols from same segment. */ + /* Can't make difference of 2 undefineds: 'value' means */ + /* something different for N_UNDF. */ #ifdef TC_I960 - /* Makes no sense to use the difference of 2 arbitrary symbols - * as the target of a call instruction. - */ - if (fixP->fx_callj) { - as_bad("callj to difference of 2 symbols"); - } + /* Makes no sense to use the difference of 2 arbitrary symbols + * as the target of a call instruction. + */ + if (fixP->fx_callj) { + as_bad("callj to difference of 2 symbols"); + } #endif /* TC_I960 */ - add_number += S_GET_VALUE(add_symbolP) - - S_GET_VALUE(sub_symbolP); - - add_symbolP = NULL; - fixP->fx_addsy = NULL; - } else { - /* Different segments in subtraction. */ - know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE))); - - if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) { - add_number -= S_GET_VALUE(sub_symbolP); + add_number += S_GET_VALUE(add_symbolP) - + S_GET_VALUE(sub_symbolP); + + add_symbolP = NULL; + fixP->fx_addsy = NULL; + } else { + /* Different segments in subtraction. */ + know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE))); + + if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) { + add_number -= S_GET_VALUE(sub_symbolP); } else { as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.", segment_name(S_GET_SEGMENT(sub_symbolP)), S_GET_NAME(sub_symbolP), fragP->fr_address + where); - } /* if absolute */ + } /* if absolute */ } - } /* if sub_symbolP */ - - if (add_symbolP) { - if (add_symbol_segment == this_segment_type && pcrel) { - /* - * This fixup was made when the symbol's segment was - * SEG_UNKNOWN, but it is now in the local segment. - * So we know how to do the address without relocation. - */ + } /* if sub_symbolP */ + + if (add_symbolP) { + if (add_symbol_segment == this_segment_type && pcrel) { + /* + * This fixup was made when the symbol's segment was + * SEG_UNKNOWN, but it is now in the local segment. + * So we know how to do the address without relocation. + */ #ifdef TC_I960 - /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal', - * in which cases it modifies *fixP as appropriate. In the case - * of a 'calls', no further work is required, and *fixP has been - * set up to make the rest of the code below a no-op. - */ - reloc_callj(fixP); + /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal', + * in which cases it modifies *fixP as appropriate. In the case + * of a 'calls', no further work is required, and *fixP has been + * set up to make the rest of the code below a no-op. + */ + reloc_callj(fixP); #endif /* TC_I960 */ - - add_number += S_GET_VALUE(add_symbolP); - add_number -= md_pcrel_from (fixP); - pcrel = 0; /* Lie. Don't want further pcrel processing. */ - fixP->fx_addsy = NULL; /* No relocations please. */ - } else - { - switch (add_symbol_segment) - { - case SEG_ABSOLUTE: + + add_number += S_GET_VALUE(add_symbolP); + add_number -= md_pcrel_from (fixP); + pcrel = 0; /* Lie. Don't want further pcrel processing. */ + fixP->fx_addsy = NULL; /* No relocations please. */ + } else + { + switch (add_symbol_segment) + { + case SEG_ABSOLUTE: #ifdef TC_I960 - reloc_callj(fixP); /* See comment about reloc_callj() above*/ + reloc_callj(fixP); /* See comment about reloc_callj() above*/ #endif /* TC_I960 */ - add_number += S_GET_VALUE(add_symbolP); - fixP->fx_addsy = NULL; - add_symbolP = NULL; - break; - default: - - add_number += S_GET_VALUE(add_symbolP) + - segment_info[S_GET_SEGMENT(add_symbolP)].scnhdr.s_paddr ; - break; - - case SEG_UNKNOWN: + add_number += S_GET_VALUE(add_symbolP); + fixP->fx_addsy = NULL; + add_symbolP = NULL; + break; + default: + + add_number += S_GET_VALUE(add_symbolP) + + segment_info[S_GET_SEGMENT(add_symbolP)].scnhdr.s_paddr ; + break; + + case SEG_UNKNOWN: #ifdef TC_I960 - if ((int)fixP->fx_bit_fixP == 13) { - /* This is a COBR instruction. They have only a - * 13-bit displacement and are only to be used - * for local branches: flag as error, don't generate - * relocation. - */ - as_bad("can't use COBR format with external label"); - fixP->fx_addsy = NULL; /* No relocations please. */ - continue; - } /* COBR */ + if ((int)fixP->fx_bit_fixP == 13) { + /* This is a COBR instruction. They have only a + * 13-bit displacement and are only to be used + * for local branches: flag as error, don't generate + * relocation. + */ + as_bad("can't use COBR format with external label"); + fixP->fx_addsy = NULL; /* No relocations please. */ + continue; + } /* COBR */ #endif /* TC_I960 */ - - - - break; - - - } /* switch on symbol seg */ - } /* if not in local seg */ - } /* if there was a + symbol */ - - if (pcrel) { - add_number -= md_pcrel_from(fixP); - if (add_symbolP == 0) { - fixP->fx_addsy = & abs_symbol; - } /* if there's an add_symbol */ - } /* if pcrel */ - - if (!fixP->fx_bit_fixP) { - if ((size==1 && - (add_number& ~0xFF) && (add_number&~0xFF!=(-1&~0xFF))) || - (size==2 && - (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) { - as_bad("Value of %d too large for field of %d bytes at 0x%x", - add_number, size, fragP->fr_address + where); - } /* generic error checking */ - } /* not a bit fix */ - /* once this fix has been applied, we don't have to output anything - nothing more need be done -*/ - md_apply_fix(fixP, add_number); - - } /* For each fixS in this segment. */ - - -} /* fixup_segment() */ + + + + break; + + + } /* switch on symbol seg */ + } /* if not in local seg */ + } /* if there was a + symbol */ + + if (pcrel) { + add_number -= md_pcrel_from(fixP); + if (add_symbolP == 0) { + fixP->fx_addsy = & abs_symbol; + } /* if there's an add_symbol */ + } /* if pcrel */ + + if (!fixP->fx_bit_fixP) { + if ((size==1 && + (add_number& ~0xFF) && (add_number&~0xFF!=(-1&~0xFF))) || + (size==2 && + (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) { + as_bad("Value of %d too large for field of %d bytes at 0x%x", + add_number, size, fragP->fr_address + where); + } /* generic error checking */ + } /* not a bit fix */ + /* once this fix has been applied, we don't have to output anything + nothing more need be done -*/ + md_apply_fix(fixP, add_number); + + } /* For each fixS in this segment. */ + + +} /* fixup_segment() */ #endif +/* + * Local Variables: + * fill-column: 131 + * End: + */ - - +/* end of obj-coffbfd.c */ diff --git a/gas/config/obj-coffbfd.h b/gas/config/obj-coffbfd.h index 5527181..cba86a1 100644 --- a/gas/config/obj-coffbfd.h +++ b/gas/config/obj-coffbfd.h @@ -2,22 +2,22 @@ #define OBJ_FORMAT_H /* coff object file format Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. - -This file is part of GAS. - -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. + + 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. */ /* $Id$ */ @@ -44,10 +44,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #else help me #endif - + #if 0 -/* Define some processor dependent values according to the processor we are - on. */ + /* Define some processor dependent values according to the processor we are + on. */ #if defined(TC_H8300) #define BYTE_ORDERING 0 #define FILE_HEADER_MAGIC H8300MAGIC @@ -82,15 +82,15 @@ help me #else you lose #endif - + #endif - + #ifndef OBJ_COFF_MAX_AUXENTRIES #define OBJ_COFF_MAX_AUXENTRIES 1 #endif /* OBJ_COFF_MAX_AUXENTRIES */ - - -extern const segT N_TYPE_seg[]; + + + extern const segT N_TYPE_seg[]; /* Magic number of paged executable. */ #define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 0x8300 @@ -98,7 +98,7 @@ extern const segT N_TYPE_seg[]; /* SYMBOL TABLE */ - /* targets may also set this */ +/* targets may also set this */ #ifndef SYMBOLS_NEED_BACKPOINTERS #define SYMBOLS_NEED_BACKPOINTERS 1 #endif /* SYMBOLS_NEED_BACKPOINTERS */ @@ -107,10 +107,10 @@ extern const segT N_TYPE_seg[]; typedef struct { - struct internal_syment ost_entry; /* Basic symbol */ - union internal_auxent ost_auxent[OBJ_COFF_MAX_AUXENTRIES]; /* Auxiliary entry. */ - - unsigned int ost_flags; /* obj_coff internal use only flags */ + struct internal_syment ost_entry; /* Basic symbol */ + union internal_auxent ost_auxent[OBJ_COFF_MAX_AUXENTRIES]; /* Auxiliary entry. */ + + unsigned int ost_flags; /* obj_coff internal use only flags */ } obj_symbol_type; #ifndef DO_NOT_STRIP @@ -140,8 +140,8 @@ typedef struct /* True if the symbol is external */ #define S_IS_EXTERNAL(s) ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION) /* True if symbol has been defined, ie : - section > 0 (DATA, TEXT or BSS) - section == 0 and value > 0 (external bss symbol) */ + section > 0 (DATA, TEXT or BSS) + section == 0 and value > 0 (external bss symbol) */ #define S_IS_DEFINED(s) ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION || \ ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION && \ (s)->sy_symbol.ost_entry.n_value > 0)) @@ -277,7 +277,7 @@ typedef struct #define SF_TAG (0x00080000) /* Is a tag */ #define SF_DEBUG (0x00100000) /* Is in debug or abs section */ #define SF_GET_SEGMENT (0x00200000) /* Get the section of the forward symbol. */ - /* All other bits are unused. */ +/* All other bits are unused. */ /* Accessors */ #define SF_GET(s) ((s)->sy_symbol.ost_flags) @@ -424,22 +424,22 @@ typedef struct #define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v)) #define H_SET_LINENO_SIZE(h,v) ((h)->lineno_size = (v)) - /* Segment flipping */ +/* Segment flipping */ #define segment_name(v) (seg_name[(int) (v)]) typedef struct { #ifdef BFD_HEADERS - struct internal_aouthdr aouthdr; /* a.out header */ - struct internal_filehdr filehdr; /* File header, not machine dep. */ + struct internal_aouthdr aouthdr; /* a.out header */ + struct internal_filehdr filehdr; /* File header, not machine dep. */ #else - AOUTHDR aouthdr; /* a.out header */ - FILHDR filehdr; /* File header, not machine dep. */ + AOUTHDR aouthdr; /* a.out header */ + FILHDR filehdr; /* File header, not machine dep. */ #endif - long string_table_size; /* names + '\0' + sizeof(int) */ - long relocation_size; /* Cumulated size of relocation + long string_table_size; /* names + '\0' + sizeof(int) */ + long relocation_size; /* Cumulated size of relocation information for all sections in bytes. */ - long lineno_size; /* Size of the line number information + long lineno_size; /* Size of the line number information table in bytes */ } object_headers; @@ -447,22 +447,22 @@ typedef struct { struct lineno_list { - - struct bfd_internal_lineno line; - char* frag; /* Frag to which the line number is related */ - struct lineno_list* next; /* Forward chain pointer */ + + struct bfd_internal_lineno line; + char* frag; /* Frag to which the line number is related */ + struct lineno_list* next; /* Forward chain pointer */ } ; - /* stack stuff */ +/* stack stuff */ typedef struct { - unsigned long chunk_size; - unsigned long element_size; - unsigned long size; - char* data; - unsigned long pointer; + unsigned long chunk_size; + unsigned long element_size; + unsigned long size; + char* data; + unsigned long pointer; } stack; @@ -478,20 +478,20 @@ void EXFUN(stack_delete,(stack *st)); void EXFUN(c_section_header,( - - struct internal_scnhdr *header, - char *name, - long core_address, - long size, - long data_ptr, - long reloc_ptr, - long lineno_ptr, - long reloc_number, - long lineno_number, - long alignment)); + + struct internal_scnhdr *header, + char *name, + long core_address, + long size, + long data_ptr, + long reloc_ptr, + long lineno_ptr, + long reloc_number, + long lineno_number, + long alignment)); - /* sanity check */ +/* sanity check */ #ifdef TC_I960 #ifndef C_LEAFSTAT @@ -499,12 +499,14 @@ hey! Where is the C_LEAFSTAT definition? i960-coff support is depending on it. #endif /* no C_LEAFSTAT */ #endif /* TC_I960 */ #ifdef BFD_HEADERS -extern struct internal_scnhdr data_section_header; + extern struct internal_scnhdr data_section_header; extern struct internal_scnhdr text_section_header; #else extern SCNHDR data_section_header; extern SCNHDR text_section_header; #endif +#endif + /* * Local Variables: * comment-column: 0 @@ -513,4 +515,3 @@ extern SCNHDR text_section_header; */ /* end of obj-coff.h */ -#endif diff --git a/gas/config/obj-generic.h b/gas/config/obj-generic.h index d9e03dc..69bf1f3 100644 --- a/gas/config/obj-generic.h +++ b/gas/config/obj-generic.h @@ -3,10 +3,10 @@ * object format specific header files. */ - /* define an obj specific macro off which target cpu back ends may key. */ +/* define an obj specific macro off which target cpu back ends may key. */ #define OBJ_GENERIC 1 - /* include whatever target cpu is appropriate. */ +/* include whatever target cpu is appropriate. */ #include "targ-cpu.h" /* @@ -21,29 +21,29 @@ * facilities are available, and they are macros. */ - /* #define SYMBOLS_NEED_PACKPOINTERS */ +/* #define SYMBOLS_NEED_PACKPOINTERS */ - /* */ +/* */ typedef struct { void *nothing; } obj_symbol_type; /* should be the format's symbol structure */ typedef void *object_headers; - /* symbols have names */ +/* symbols have names */ #define S_GET_NAME(s) ("foo") /* get the name of a symbolP */ #define S_SET_NAME(s,v) ; - /* symbols have segments */ + /* symbols have segments */ #define S_GET_SEGMENT(s) (SEG_UNKNOWN) #define S_SET_SEGMENT(s,v) ; - /* symbols have a value */ + /* symbols have a value */ #define S_GET_VALUE(s) (0) #define S_SET_VALUE(s,v) ; - /* symbols may be external */ + /* symbols may be external */ #define S_IS_EXTERNAL(s) (0) #define S_SET_EXTERNAL(s) ; - - /* symbols may or may not be defined */ + + /* symbols may or may not be defined */ #define S_IS_DEFINED(s) (0) diff --git a/gas/config/obj-ieee.c b/gas/config/obj-ieee.c index aaffab5..56ebcf6a 100644 --- a/gas/config/obj-ieee.c +++ b/gas/config/obj-ieee.c @@ -1,33 +1,33 @@ /* obj-format for ieee-695 records. Copyright (C) 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 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. */ /* created by - + steve chamberlain steve@cygnus.com -*/ + */ /* - this will hopefully become the port through which bfd and gas talk, - for the moment, only ieee is known to work well. -*/ + this will hopefully become the port through which bfd and gas talk, + for the moment, only ieee is known to work well. + */ #include "bfd.h" #include "as.h" @@ -42,12 +42,12 @@ static relax_addressT relax_align(address, alignment) register relax_addressT address; /* Address now. */ register long alignment; /* Alignment (binary). */ { - relax_addressT mask; - relax_addressT new_address; - - mask = ~ ( (~0) << alignment ); - new_address = (address + mask) & (~ mask); - return (new_address - address); + relax_addressT mask; + relax_addressT new_address; + + mask = ~ ( (~0) << alignment ); + new_address = (address + mask) & (~ mask); + return (new_address - address); } /* relax_align() */ /* calculate the size of the frag chain and create a bfd section @@ -56,36 +56,36 @@ static void DEFUN(size_section,(abfd, idx), bfd *abfd AND unsigned int idx) { - asection *sec; - unsigned int size = 0; - fragS *frag = segment_info[idx].frag_root; - while (frag) { - if (frag->fr_address != size) { - printf("Out of step\n"); - size = frag->fr_address; - } - size += frag->fr_fix; - switch (frag->fr_type) { - case rs_fill: - case rs_org: - size += frag->fr_offset * frag->fr_var; - break; - case rs_align: - size += relax_align(size, frag->fr_offset); - } - frag = frag->fr_next; - } - if (size) { - char *name = segment_info[idx].name; - if (name == (char *)NULL) { - name = ".data"; - } - segment_info[idx].user_stuff = (char *)(sec = bfd_make_section(abfd, name)); - /* Make it output through itself */ - sec->output_section = sec; - sec->flags |= SEC_HAS_CONTENTS; - bfd_set_section_size(abfd, sec, size); - } + asection *sec; + unsigned int size = 0; + fragS *frag = segment_info[idx].frag_root; + while (frag) { + if (frag->fr_address != size) { + printf("Out of step\n"); + size = frag->fr_address; + } + size += frag->fr_fix; + switch (frag->fr_type) { + case rs_fill: + case rs_org: + size += frag->fr_offset * frag->fr_var; + break; + case rs_align: + size += relax_align(size, frag->fr_offset); + } + frag = frag->fr_next; + } + if (size) { + char *name = segment_info[idx].name; + if (name == (char *)NULL) { + name = ".data"; + } + segment_info[idx].user_stuff = (char *)(sec = bfd_make_section(abfd, name)); + /* Make it output through itself */ + sec->output_section = sec; + sec->flags |= SEC_HAS_CONTENTS; + bfd_set_section_size(abfd, sec, size); + } } /* run through a frag chain and write out the data to go with it */ @@ -93,47 +93,47 @@ static void DEFUN(fill_section,(abfd, idx), bfd *abfd AND unsigned int idx) { - asection *sec = segment_info[idx].user_stuff; - if (sec) { - fragS *frag = segment_info[idx].frag_root; - unsigned int offset = 0; - while (frag) { - unsigned int fill_size; - unsigned int count; - switch (frag->fr_type) { - case rs_fill: - case rs_align: - case rs_org: - if(frag->fr_fix) - { - bfd_set_section_contents(abfd, - sec, - frag->fr_literal, - frag->fr_address, - frag->fr_fix); - } - offset += frag->fr_fix; - fill_size = frag->fr_var; - if (fill_size) - { - unsigned int off = frag->fr_fix; - for (count = frag->fr_offset; count; count--) - { - bfd_set_section_contents(abfd, sec, - frag->fr_literal + - frag->fr_fix, - frag->fr_address + off, - fill_size); - off += fill_size; - } - } - break; - default: - abort(); - } - frag = frag->fr_next; - } - } + asection *sec = segment_info[idx].user_stuff; + if (sec) { + fragS *frag = segment_info[idx].frag_root; + unsigned int offset = 0; + while (frag) { + unsigned int fill_size; + unsigned int count; + switch (frag->fr_type) { + case rs_fill: + case rs_align: + case rs_org: + if(frag->fr_fix) + { + bfd_set_section_contents(abfd, + sec, + frag->fr_literal, + frag->fr_address, + frag->fr_fix); + } + offset += frag->fr_fix; + fill_size = frag->fr_var; + if (fill_size) + { + unsigned int off = frag->fr_fix; + for (count = frag->fr_offset; count; count--) + { + bfd_set_section_contents(abfd, sec, + frag->fr_literal + + frag->fr_fix, + frag->fr_address + off, + fill_size); + off += fill_size; + } + } + break; + default: + abort(); + } + frag = frag->fr_next; + } + } } /* Count the relocations in a chain */ @@ -141,154 +141,154 @@ static void DEFUN(fill_section,(abfd, idx), static unsigned int DEFUN(count_entries_in_chain,(idx), unsigned int idx) { - unsigned int nrelocs; - fixS *fixup_ptr; - - /* Count the relocations */ - fixup_ptr = segment_info[idx].fix_root; - nrelocs = 0; - while (fixup_ptr != (fixS *)NULL) - { - fixup_ptr = fixup_ptr->fx_next; - nrelocs ++ ; - } - return nrelocs; + unsigned int nrelocs; + fixS *fixup_ptr; + + /* Count the relocations */ + fixup_ptr = segment_info[idx].fix_root; + nrelocs = 0; + while (fixup_ptr != (fixS *)NULL) + { + fixup_ptr = fixup_ptr->fx_next; + nrelocs ++ ; + } + return nrelocs; } /* output all the relocations for a section */ void DEFUN(do_relocs_for,(idx), unsigned int idx) { - unsigned int nrelocs; - arelent **reloc_ptr_vector; - arelent *reloc_vector; - asymbol **ptrs; - asection *section = (asection *)(segment_info[idx].user_stuff); - unsigned int i; - fixS *from; - if (section) { - nrelocs = count_entries_in_chain(idx); - - reloc_ptr_vector = (arelent**)malloc((nrelocs+1) * sizeof(arelent *)); - reloc_vector = (arelent*)malloc(nrelocs * sizeof(arelent)); - ptrs = (asymbol **)malloc(nrelocs * sizeof(asymbol *)); - from = segment_info[idx].fix_root; - for (i = 0; i < nrelocs; i++) - { - arelent *to = reloc_vector + i; - asymbol *s ; - reloc_ptr_vector[i] = to; - to->howto = (reloc_howto_type *)(from->fx_r_type); - - /* We can't represent complicated things in a reloc yet */ - /* if (from->fx_addsy == 0 || - from->fx_subsy != 0) abort(); - */ - s = &( from->fx_addsy->sy_symbol.sy); - to->address = ((char *)( from->fx_frag->fr_address + - from->fx_where)) - - ((char *)(&(from->fx_frag->fr_literal))); - to->addend = from->fx_offset ; - /* If we know the symbol which we want to relocate to, turn this - reloaction into a section relative. - - If this relocation is pcrelative, and we know the - destination, we still want to keep the relocation - since - the linker might relax some of the bytes, but it stops - being pc relative and turns into an absolute relocation. - - */ - if (s) { - if ((s->flags & BSF_UNDEFINED)==0) { - to->section = s->section; - to->addend += s->value ; - to->sym_ptr_ptr = 0; - if (to->howto->pcrel_offset) { - /* This is a pcrel relocation, the addend should be adjusted */ - to->addend -= to->address +1; - } - } - else { - to->section = 0; - *ptrs = &(from->fx_addsy->sy_symbol.sy); - to->sym_ptr_ptr = ptrs; - - if (to->howto->pcrel_offset) { - /* This is a pcrel relocation, the addend should be adjusted */ - to->addend -= to->address -1; - } - } - - } - else { - to->section = 0; - } - - ptrs++; - from = from->fx_next; - } - - /* attatch to the section */ - section->orelocation = reloc_ptr_vector; - section->reloc_count = nrelocs; - section->flags |= SEC_LOAD; - } + unsigned int nrelocs; + arelent **reloc_ptr_vector; + arelent *reloc_vector; + asymbol **ptrs; + asection *section = (asection *)(segment_info[idx].user_stuff); + unsigned int i; + fixS *from; + if (section) { + nrelocs = count_entries_in_chain(idx); + + reloc_ptr_vector = (arelent**)malloc((nrelocs+1) * sizeof(arelent *)); + reloc_vector = (arelent*)malloc(nrelocs * sizeof(arelent)); + ptrs = (asymbol **)malloc(nrelocs * sizeof(asymbol *)); + from = segment_info[idx].fix_root; + for (i = 0; i < nrelocs; i++) + { + arelent *to = reloc_vector + i; + asymbol *s ; + reloc_ptr_vector[i] = to; + to->howto = (reloc_howto_type *)(from->fx_r_type); + + /* We can't represent complicated things in a reloc yet */ + /* if (from->fx_addsy == 0 || + from->fx_subsy != 0) abort(); + */ + s = &( from->fx_addsy->sy_symbol.sy); + to->address = ((char *)( from->fx_frag->fr_address + + from->fx_where)) + - ((char *)(&(from->fx_frag->fr_literal))); + to->addend = from->fx_offset ; + /* If we know the symbol which we want to relocate to, turn this + reloaction into a section relative. + + If this relocation is pcrelative, and we know the + destination, we still want to keep the relocation - since + the linker might relax some of the bytes, but it stops + being pc relative and turns into an absolute relocation. + + */ + if (s) { + if ((s->flags & BSF_UNDEFINED)==0) { + to->section = s->section; + to->addend += s->value ; + to->sym_ptr_ptr = 0; + if (to->howto->pcrel_offset) { + /* This is a pcrel relocation, the addend should be adjusted */ + to->addend -= to->address +1; + } + } + else { + to->section = 0; + *ptrs = &(from->fx_addsy->sy_symbol.sy); + to->sym_ptr_ptr = ptrs; + + if (to->howto->pcrel_offset) { + /* This is a pcrel relocation, the addend should be adjusted */ + to->addend -= to->address -1; + } + } + + } + else { + to->section = 0; + } + + ptrs++; + from = from->fx_next; + } + + /* attatch to the section */ + section->orelocation = reloc_ptr_vector; + section->reloc_count = nrelocs; + section->flags |= SEC_LOAD; + } } /* do the symbols.. */ static void DEFUN(do_symbols, (abfd), bfd *abfd) { - extern symbolS *symbol_rootP; - symbolS *ptr; - asymbol **symbol_ptr_vec; - asymbol *symbol_vec; - unsigned int count = 0; - unsigned int index; - - - for (ptr = symbol_rootP; - ptr != (symbolS *)NULL; - ptr = ptr->sy_next) - { - if (SEG_NORMAL(ptr->sy_symbol.seg)) + extern symbolS *symbol_rootP; + symbolS *ptr; + asymbol **symbol_ptr_vec; + asymbol *symbol_vec; + unsigned int count = 0; + unsigned int index; + + + for (ptr = symbol_rootP; + ptr != (symbolS *)NULL; + ptr = ptr->sy_next) { - ptr->sy_symbol.sy.section = - (asection *)(segment_info[ptr->sy_symbol.seg].user_stuff); - ptr->sy_symbol.sy.value += ptr->sy_frag->fr_address; - if (ptr->sy_symbol.sy.flags == 0) { - ptr->sy_symbol.sy.flags = BSF_LOCAL ; - } + if (SEG_NORMAL(ptr->sy_symbol.seg)) + { + ptr->sy_symbol.sy.section = + (asection *)(segment_info[ptr->sy_symbol.seg].user_stuff); + ptr->sy_symbol.sy.value += ptr->sy_frag->fr_address; + if (ptr->sy_symbol.sy.flags == 0) { + ptr->sy_symbol.sy.flags = BSF_LOCAL ; + } + } + else { + switch (ptr->sy_symbol.seg) { + case SEG_ABSOLUTE: + ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE; + ptr->sy_symbol.sy.section = 0; + break; + case SEG_UNKNOWN: + ptr->sy_symbol.sy.flags = BSF_UNDEFINED ; + ptr->sy_symbol.sy.section = 0; + break; + default: + abort(); + } + } + count++; } - else { - switch (ptr->sy_symbol.seg) { - case SEG_ABSOLUTE: - ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE; - ptr->sy_symbol.sy.section = 0; - break; - case SEG_UNKNOWN: - ptr->sy_symbol.sy.flags = BSF_UNDEFINED ; - ptr->sy_symbol.sy.section = 0; - break; - default: - abort(); - } - } - count++; - } - symbol_ptr_vec = (asymbol **)malloc((count+1) * sizeof(asymbol *)); - - index = 0; - for (ptr = symbol_rootP; - ptr != (symbolS *)NULL; - ptr = ptr->sy_next) - { - symbol_ptr_vec[index] = &(ptr->sy_symbol.sy); - index++; - } - symbol_ptr_vec[index] =0; - abfd->outsymbols = symbol_ptr_vec; - abfd->symcount = count; + symbol_ptr_vec = (asymbol **)malloc((count+1) * sizeof(asymbol *)); + + index = 0; + for (ptr = symbol_rootP; + ptr != (symbolS *)NULL; + ptr = ptr->sy_next) + { + symbol_ptr_vec[index] = &(ptr->sy_symbol.sy); + index++; + } + symbol_ptr_vec[index] =0; + abfd->outsymbols = symbol_ptr_vec; + abfd->symcount = count; } /* The generic as->bfd converter. Other backends may have special case @@ -296,21 +296,21 @@ static void DEFUN(do_symbols, (abfd), void DEFUN_VOID(bfd_as_write_hook) { - int i; - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) { - size_section(abfd, i); - } - - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - fill_section(abfd,i); - - do_symbols(abfd); - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - do_relocs_for(i); - + int i; + + for (i = SEG_E0; i < SEG_UNKNOWN; i++) { + size_section(abfd, i); + } + + + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + fill_section(abfd,i); + + do_symbols(abfd); + + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + do_relocs_for(i); + } @@ -318,30 +318,30 @@ void DEFUN_VOID(bfd_as_write_hook) S_GET_VALUE(x) symbolS *x; { - return x->sy_symbol.sy.value; + return x->sy_symbol.sy.value; } S_SET_SEGMENT(x,y) symbolS *x ; int y; { - x->sy_symbol.seg = y; + x->sy_symbol.seg = y; } S_IS_DEFINED(x) symbolS *x; { - if (SEG_NORMAL(x->sy_symbol.seg)) - { - return 1; - } - switch (x->sy_symbol.seg) - { - case SEG_UNKNOWN: - return 0; - default: - abort(); - } + if (SEG_NORMAL(x->sy_symbol.seg)) + { + return 1; + } + switch (x->sy_symbol.seg) + { + case SEG_UNKNOWN: + return 0; + default: + abort(); + } } S_IS_EXTERNAL(x) { abort(); } @@ -349,24 +349,24 @@ S_GET_DESC(x) { abort() ; } S_GET_SEGMENT(x) symbolS *x; - { return x->sy_symbol.seg; } +{ return x->sy_symbol.seg; } S_SET_EXTERNAL(x) symbolS *x; { -x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT; + x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT; } S_SET_NAME(x,y) symbolS*x; char *y; { -x->sy_symbol.sy.name = y; } + x->sy_symbol.sy.name = y; } S_SET_VALUE(s,v) symbolS *s; long v; { - s->sy_symbol.sy.value = v; + s->sy_symbol.sy.value = v; } S_GET_OTHER(x) { abort() ;} @@ -379,39 +379,39 @@ void obj_read_begin_hook() { } static void obj_ieee_section(ignore) int ignore; { - extern char *input_line_pointer; - extern char is_end_of_line[]; - char *p= input_line_pointer; - char *s = p; - int i; - /* Look up the name, if it doesn't exist, make it */ - while (*p &&* p != ' ' && *p != ',' && !is_end_of_line[*p]) { - p++; - } - for (i = SEG_E0; i < SEG_UNKNOWN; i++) { - if (segment_info[i].hadone){ - if (strncmp(segment_info[i].name, s, p-s) ==0) { - goto ok; + extern char *input_line_pointer; + extern char is_end_of_line[]; + char *p= input_line_pointer; + char *s = p; + int i; + /* Look up the name, if it doesn't exist, make it */ + while (*p &&* p != ' ' && *p != ',' && !is_end_of_line[*p]) { + p++; + } + for (i = SEG_E0; i < SEG_UNKNOWN; i++) { + if (segment_info[i].hadone){ + if (strncmp(segment_info[i].name, s, p-s) ==0) { + goto ok; + + } + } + else break; + } + if (i == SEG_UNKNOWN) { + as_bad("too many sections"); + return; + } - } - } - else break; - } - if (i == SEG_UNKNOWN) { - as_bad("too many sections"); - return; - } - - segment_info[i].hadone = 1; - segment_info[i].name = malloc(p-s + 1); - memcpy(segment_info[i].name, s, p-s); - segment_info[i].name[p-s] = 0; + segment_info[i].hadone = 1; + segment_info[i].name = malloc(p-s + 1); + memcpy(segment_info[i].name, s, p-s); + segment_info[i].name[p-s] = 0; ok: - subseg_new(i,0); - while (!is_end_of_line[*p]) - p++; - input_line_pointer = p; - + subseg_new(i,0); + while (!is_end_of_line[*p]) + p++; + input_line_pointer = p; + } @@ -431,17 +431,17 @@ void stringer(); void s_globl(); const pseudo_typeS obj_pseudo_table[] = { - {"section", obj_ieee_section, 0}, - {"data.b", cons, 1}, - {"data.w", cons, 2}, - {"data.l", cons, 4}, - {"export", s_globl, 0}, - {"option", s_ignore, 0}, - {"end", s_ignore, 0}, - {"import", s_ignore, 0}, - {"sdata", stringer, 0}, - 0, - + {"section", obj_ieee_section, 0}, + {"data.b", cons, 1}, + {"data.w", cons, 2}, + {"data.l", cons, 4}, + {"export", s_globl, 0}, + {"option", s_ignore, 0}, + {"end", s_ignore, 0}, + {"import", s_ignore, 0}, + {"sdata", stringer, 0}, + 0, + }; @@ -449,7 +449,7 @@ const pseudo_typeS obj_pseudo_table[] = void obj_symbol_new_hook(symbolP) symbolS *symbolP; { - symbolP->sy_symbol.sy.the_bfd = abfd; + symbolP->sy_symbol.sy.the_bfd = abfd; } @@ -459,70 +459,70 @@ symbolS *symbolP; #if 1 extern void DEFUN_VOID(write_object_file) { - int i; - struct frchain *frchain_ptr; - struct frag *frag_ptr; - - abfd = bfd_openw(out_file_name, "ieee"); - - if (abfd == 0) { - as_perror ("FATAL: Can't create %s", out_file_name); - exit(42); - } - bfd_set_format(abfd, bfd_object); - bfd_set_arch_mach(abfd, bfd_arch_h8300, 0); - subseg_new(1,0); - subseg_new(2,0); - subseg_new(3,0); - for (frchain_ptr = frchain_root; - frchain_ptr != (struct frchain *)NULL; - frchain_ptr = frchain_ptr->frch_next) { - /* Run through all the sub-segments and align them up. Also close any - open frags. We tack a .fill onto the end of the frag chain so - that any .align's size can be worked by looking at the next - frag */ - - subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg); + int i; + struct frchain *frchain_ptr; + struct frag *frag_ptr; + + abfd = bfd_openw(out_file_name, "ieee"); + + if (abfd == 0) { + as_perror ("FATAL: Can't create %s", out_file_name); + exit(42); + } + bfd_set_format(abfd, bfd_object); + bfd_set_arch_mach(abfd, bfd_arch_h8300, 0); + subseg_new(1,0); + subseg_new(2,0); + subseg_new(3,0); + for (frchain_ptr = frchain_root; + frchain_ptr != (struct frchain *)NULL; + frchain_ptr = frchain_ptr->frch_next) { + /* Run through all the sub-segments and align them up. Also close any + open frags. We tack a .fill onto the end of the frag chain so + that any .align's size can be worked by looking at the next + frag */ + + subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg); #define SUB_SEGMENT_ALIGN 2 - frag_align(SUB_SEGMENT_ALIGN,0); - frag_wane(frag_now); - frag_now->fr_fix = 0; - know( frag_now->fr_next == NULL ); - } - - /* Now build one big frag chain for each segment, linked through - fr_next. */ - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - - fragS ** prev_frag_ptr_ptr ; - struct frchain *next_frchain_ptr; - - /* struct frag **head_ptr = segment_info[i].frag_root;*/ - - segment_info[i].frag_root = segment_info[i].frchainP->frch_root; + frag_align(SUB_SEGMENT_ALIGN,0); + frag_wane(frag_now); + frag_now->fr_fix = 0; + know( frag_now->fr_next == NULL ); + } + + /* Now build one big frag chain for each segment, linked through + fr_next. */ + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + { + + fragS ** prev_frag_ptr_ptr ; + struct frchain *next_frchain_ptr; + + /* struct frag **head_ptr = segment_info[i].frag_root;*/ + + segment_info[i].frag_root = segment_info[i].frchainP->frch_root; #if 0 - /* Im not sure what this is for */ - for (frchain_ptr = segment_info[i].frchainP->frch_root; - frchain_ptr != (struct frchain *)NULL; - frchain_ptr = frchain_ptr->frch_next) - { - *head_ptr = frchain_ptr; - head_ptr = &frchain_ptr->next; - } - - + /* Im not sure what this is for */ + for (frchain_ptr = segment_info[i].frchainP->frch_root; + frchain_ptr != (struct frchain *)NULL; + frchain_ptr = frchain_ptr->frch_next) + { + *head_ptr = frchain_ptr; + head_ptr = &frchain_ptr->next; + } + + #endif - } - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) { - relax_segment(segment_info[i].frag_root, i); - } - - /* Now the addresses of the frags are correct within the segment */ - - bfd_as_write_hook(); - bfd_close(abfd); + } + + for (i = SEG_E0; i < SEG_UNKNOWN; i++) { + relax_segment(segment_info[i].frag_root, i); + } + + /* Now the addresses of the frags are correct within the segment */ + + bfd_as_write_hook(); + bfd_close(abfd); } #endif @@ -535,3 +535,5 @@ H_SET_RELOCATION_SIZE() { abort(); } H_SET_MAGIC_NUMBER() { abort(); } H_GET_FILE_SIZE() { abort(); } H_GET_TEXT_RELOCATION_SIZE() { abort(); } + +/* end of obj-ieee.c */ diff --git a/gas/config/signame.h b/gas/config/signame.h index d3d075e..fed0e46 100755 --- a/gas/config/signame.h +++ b/gas/config/signame.h @@ -1,19 +1,19 @@ /* Convert between signal names and numbers. Copyright (C) 1990 Free Software Foundation, Inc. - -This program 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. - -This program 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 this program; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + This program 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. + + This program 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 this program; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Names for signals from 0 to NSIG-1. */ extern char *sys_siglist[]; diff --git a/gas/config/stab.h b/gas/config/stab.h index 77f2d41..237e9a9 100755 --- a/gas/config/stab.h +++ b/gas/config/stab.h @@ -5,8 +5,8 @@ #define __GNU_STAB__ #define __define_stab(NAME, CODE, STRING) NAME=CODE, - -enum __stab_debug_code + + enum __stab_debug_code { #include "stab.def" }; diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c index 79e9d05..c674da8 100644 --- a/gas/config/tc-a29k.c +++ b/gas/config/tc-a29k.c @@ -1,28 +1,28 @@ /* tc-a29k.c -- Assemble for the AMD 29000. Copyright (C) 1989, 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 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. */ /* $Id$ */ /* John Gilmore has reorganized this module somewhat, to make it easier to convert it to new machines' assemblers as desired. There was too much bloody rewriting required before. There still probably is. */ - + #include "as.h" #include "opcode/a29k.h" @@ -44,13 +44,13 @@ const relax_typeS md_relax_table[] = { 0 }; static struct hash_control *op_hash = NULL; struct machine_it { - char *error; - unsigned long opcode; - struct nlist *nlistp; - expressionS exp; - int pcrel; - int reloc_offset; /* Offset of reloc within insn */ - enum reloc_type reloc; + char *error; + unsigned long opcode; + struct nlist *nlistp; + expressionS exp; + int pcrel; + int reloc_offset; /* Offset of reloc within insn */ + enum reloc_type reloc; } the_insn; #ifdef __STDC__ @@ -72,17 +72,17 @@ static void s_use(); #endif /* __STDC__ */ const pseudo_typeS -md_pseudo_table[] = { - { "align", s_align_bytes, 4 }, - { "block", s_space, 0 }, - { "cputype", s_ignore, 0 }, /* CPU as 29000 or 29050 */ - { "reg", s_lsym, 0 }, /* Register equate, same as equ */ - { "space", s_ignore, 0 }, /* Listing control */ - { "sect", s_ignore, 0 }, /* Creation of coff sections */ - { "use", s_use, 0 }, - { "word", cons, 4 }, - { NULL, 0, 0 }, -}; + md_pseudo_table[] = { + { "align", s_align_bytes, 4 }, + { "block", s_space, 0 }, + { "cputype", s_ignore, 0 }, /* CPU as 29000 or 29050 */ + { "reg", s_lsym, 0 }, /* Register equate, same as equ */ + { "space", s_ignore, 0 }, /* Listing control */ + { "sect", s_ignore, 0 }, /* Creation of coff sections */ + { "use", s_use, 0 }, + { "word", cons, 4 }, + { NULL, 0, 0 }, + }; int md_short_jump_size = 4; int md_long_jump_size = 4; @@ -97,7 +97,7 @@ int md_reloc_size = 12; /* Not bfdized*/ #endif /* This array holds the chars that always start a comment. If the - pre-processor is disabled, these aren't very useful */ + pre-processor is disabled, these aren't very useful */ char comment_chars[] = ";"; /* This array holds the chars that only start a comment at the beginning of @@ -124,11 +124,11 @@ char FLT_CHARS[] = "rRsSfFdDxXpP"; /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be changed in read.c . Ideally it shouldn't have to know about it at all, but nothing is ideal around here. - */ + */ static unsigned char octal[256]; #define isoctal(c) octal[c] -static unsigned char toHex[256]; + static unsigned char toHex[256]; /* * anull bit - causes the branch delay slot instructions to not be executed @@ -136,53 +136,53 @@ static unsigned char toHex[256]; #define ANNUL (1 << 29) static void -s_use() + s_use() { - - if (strncmp(input_line_pointer, ".text", 5) == 0) { - input_line_pointer += 5; - s_text(); - return; - } - if (strncmp(input_line_pointer, ".data", 5) == 0) { - input_line_pointer += 5; - s_data(); - return; - } - if (strncmp(input_line_pointer, ".data1", 6) == 0) { - input_line_pointer += 6; - s_data1(); - return; - } - /* Literals can't go in the text segment because you can't read - from instruction memory on some 29k's. So, into initialized data. */ - if (strncmp(input_line_pointer, ".lit", 4) == 0) { - input_line_pointer += 4; - subseg_new(SEG_DATA, 200); + + if (strncmp(input_line_pointer, ".text", 5) == 0) { + input_line_pointer += 5; + s_text(); + return; + } + if (strncmp(input_line_pointer, ".data", 5) == 0) { + input_line_pointer += 5; + s_data(); + return; + } + if (strncmp(input_line_pointer, ".data1", 6) == 0) { + input_line_pointer += 6; + s_data1(); + return; + } + /* Literals can't go in the text segment because you can't read + from instruction memory on some 29k's. So, into initialized data. */ + if (strncmp(input_line_pointer, ".lit", 4) == 0) { + input_line_pointer += 4; + subseg_new(SEG_DATA, 200); + demand_empty_rest_of_line(); + return; + } + + as_bad("Unknown segment type"); demand_empty_rest_of_line(); return; - } - - as_bad("Unknown segment type"); - demand_empty_rest_of_line(); - return; } static void -s_data1() + s_data1() { - subseg_new(SEG_DATA, 1); - demand_empty_rest_of_line(); - return; + subseg_new(SEG_DATA, 1); + demand_empty_rest_of_line(); + return; } /* Install symbol definition that maps REGNAME to REGNO. FIXME-SOON: These are not recognized in mixed case. */ static void -insert_sreg (regname, regnum) - char *regname; - int regnum; + insert_sreg (regname, regnum) +char *regname; +int regnum; { /* FIXME-SOON, put something in these syms so they won't be output to the symbol table of the resulting object file. */ @@ -241,91 +241,91 @@ void define_some_regs() { /* This function is called once, at assembler startup time. It should set up all the tables, etc. that the MD part of the assembler will need. */ void -md_begin() + md_begin() { - register char *retval = NULL; - int lose = 0; - register int skipnext = 0; - register unsigned int i; - register char *strend, *strend2; - - /* Hash up all the opcodes for fast use later. */ - - op_hash = hash_new(); - if (op_hash == NULL) - as_fatal("Virtual memory exhausted"); - - for (i = 0; i < num_opcodes; i++) - { - const char *name = machine_opcodes[i].name; - - if (skipnext) { - skipnext = 0; - continue; - } - - /* Hack to avoid multiple opcode entries. We pre-locate all the - variations (b/i field and P/A field) and handle them. */ - - if (!strcmp (name, machine_opcodes[i+1].name)) { - if ((machine_opcodes[i].opcode ^ machine_opcodes[i+1].opcode) - != 0x01000000) - goto bad_table; - strend = machine_opcodes[i ].args+strlen(machine_opcodes[i ].args)-1; - strend2 = machine_opcodes[i+1].args+strlen(machine_opcodes[i+1].args)-1; - switch (*strend) { - case 'b': - if (*strend2 != 'i') goto bad_table; - break; - case 'i': - if (*strend2 != 'b') goto bad_table; - break; - case 'P': - if (*strend2 != 'A') goto bad_table; - break; - case 'A': - if (*strend2 != 'P') goto bad_table; - break; - default: - bad_table: - fprintf (stderr, "internal error: can't handle opcode %s\n", name); - lose = 1; - } - - /* OK, this is an i/b or A/P pair. We skip the higher-valued one, - and let the code for operand checking handle OR-ing in the bit. */ - if (machine_opcodes[i].opcode & 1) - continue; - else - skipnext = 1; - } - - retval = hash_insert (op_hash, name, &machine_opcodes[i]); - if (retval != NULL && *retval != '\0') - { - fprintf (stderr, "internal error: can't hash `%s': %s\n", - machine_opcodes[i].name, retval); - lose = 1; - } - } - - if (lose) - as_fatal("Broken assembler. No assembly attempted."); - - for (i = '0'; i < '8'; ++i) - octal[i] = 1; - for (i = '0'; i <= '9'; ++i) - toHex[i] = i - '0'; - for (i = 'a'; i <= 'f'; ++i) - toHex[i] = i + 10 - 'a'; - for (i = 'A'; i <= 'F'; ++i) - toHex[i] = i + 10 - 'A'; - - define_some_regs (); + register char *retval = NULL; + int lose = 0; + register int skipnext = 0; + register unsigned int i; + register char *strend, *strend2; + + /* Hash up all the opcodes for fast use later. */ + + op_hash = hash_new(); + if (op_hash == NULL) + as_fatal("Virtual memory exhausted"); + + for (i = 0; i < num_opcodes; i++) + { + const char *name = machine_opcodes[i].name; + + if (skipnext) { + skipnext = 0; + continue; + } + + /* Hack to avoid multiple opcode entries. We pre-locate all the + variations (b/i field and P/A field) and handle them. */ + + if (!strcmp (name, machine_opcodes[i+1].name)) { + if ((machine_opcodes[i].opcode ^ machine_opcodes[i+1].opcode) + != 0x01000000) + goto bad_table; + strend = machine_opcodes[i ].args+strlen(machine_opcodes[i ].args)-1; + strend2 = machine_opcodes[i+1].args+strlen(machine_opcodes[i+1].args)-1; + switch (*strend) { + case 'b': + if (*strend2 != 'i') goto bad_table; + break; + case 'i': + if (*strend2 != 'b') goto bad_table; + break; + case 'P': + if (*strend2 != 'A') goto bad_table; + break; + case 'A': + if (*strend2 != 'P') goto bad_table; + break; + default: + bad_table: + fprintf (stderr, "internal error: can't handle opcode %s\n", name); + lose = 1; + } + + /* OK, this is an i/b or A/P pair. We skip the higher-valued one, + and let the code for operand checking handle OR-ing in the bit. */ + if (machine_opcodes[i].opcode & 1) + continue; + else + skipnext = 1; + } + + retval = hash_insert (op_hash, name, &machine_opcodes[i]); + if (retval != NULL && *retval != '\0') + { + fprintf (stderr, "internal error: can't hash `%s': %s\n", + machine_opcodes[i].name, retval); + lose = 1; + } + } + + if (lose) + as_fatal("Broken assembler. No assembly attempted."); + + for (i = '0'; i < '8'; ++i) + octal[i] = 1; + for (i = '0'; i <= '9'; ++i) + toHex[i] = i - '0'; + for (i = 'a'; i <= 'f'; ++i) + toHex[i] = i + 10 - 'a'; + for (i = 'A'; i <= 'F'; ++i) + toHex[i] = i + 10 - 'A'; + + define_some_regs (); } void md_end() { - return; + return; } /* Assemble a single instruction. Its label has already been handled @@ -333,540 +333,540 @@ void md_end() { produce the bytes of data and relocation. */ void md_assemble(str) - char *str; +char *str; { - char *toP; -/* !!!! int rsd; */ - - know(str); - machine_ip(str); - toP = frag_more(4); - /* put out the opcode */ - md_number_to_chars(toP, the_insn.opcode, 4); - - /* put out the symbol-dependent stuff */ - if (the_insn.reloc != NO_RELOC) { - fix_new( - frag_now, /* which frag */ - (toP - frag_now->fr_literal + the_insn.reloc_offset), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - the_insn.reloc - ); - } + char *toP; + /* !!!! int rsd; */ + + know(str); + machine_ip(str); + toP = frag_more(4); + /* put out the opcode */ + md_number_to_chars(toP, the_insn.opcode, 4); + + /* put out the symbol-dependent stuff */ + if (the_insn.reloc != NO_RELOC) { + fix_new( + frag_now, /* which frag */ + (toP - frag_now->fr_literal + the_insn.reloc_offset), /* where */ + 4, /* size */ + the_insn.exp.X_add_symbol, + the_insn.exp.X_subtract_symbol, + the_insn.exp.X_add_number, + the_insn.pcrel, + the_insn.reloc + ); + } } char * -parse_operand (s, operandp) - char *s; - expressionS *operandp; + parse_operand (s, operandp) +char *s; +expressionS *operandp; { - char *save = input_line_pointer; - char *new; - segT seg; - - input_line_pointer = s; - seg = expr (0, operandp); - new = input_line_pointer; - input_line_pointer = save; - - switch (seg) { - case SEG_ABSOLUTE: - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_REGISTER: - return new; - - case SEG_ABSENT: - as_bad("Missing operand"); - return new; - - default: - as_bad("Don't understand operand of type %s", segment_name (seg)); - return new; - } + char *save = input_line_pointer; + char *new; + segT seg; + + input_line_pointer = s; + seg = expr (0, operandp); + new = input_line_pointer; + input_line_pointer = save; + + switch (seg) { + case SEG_ABSOLUTE: + case SEG_TEXT: + case SEG_DATA: + case SEG_BSS: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + case SEG_BIG: + case SEG_REGISTER: + return new; + + case SEG_ABSENT: + as_bad("Missing operand"); + return new; + + default: + as_bad("Don't understand operand of type %s", segment_name (seg)); + return new; + } } /* Instruction parsing. Takes a string containing the opcode. Operands are at input_line_pointer. Output is in the_insn. Warnings or errors are generated. */ - + static void -machine_ip(str) - char *str; + machine_ip(str) +char *str; { - char *s; - const char *args; -/* !!!! char c; */ -/* !!!! unsigned long i; */ - struct machine_opcode *insn; - char *argsStart; - unsigned long opcode; -/* !!!! unsigned int mask; */ - expressionS the_operand; - expressionS *operand = &the_operand; - unsigned int reg; - - /* Must handle `div0' opcode. */ - s = str; - if (isalpha(*s)) - for (; isalnum(*s); ++s) - if (isupper (*s)) - *s = tolower (*s); - - switch (*s) { - case '\0': - break; - - case ' ': /* FIXME-SOMEDAY more whitespace */ - *s++ = '\0'; - break; - - default: - as_bad("Unknown opcode: `%s'", str); - return; - } - if ((insn = (struct machine_opcode *) hash_find(op_hash, str)) == NULL) { - as_bad("Unknown opcode `%s'.", str); - return; - } - argsStart = s; - opcode = insn->opcode; - bzero(&the_insn, sizeof(the_insn)); - the_insn.reloc = NO_RELOC; - - /* - * Build the opcode, checking as we go to make - * sure that the operands match. - * - * If an operand matches, we modify the_insn or opcode appropriately, - * and do a "continue". If an operand fails to match, we "break". - */ - if (insn->args[0] != '\0') - s = parse_operand (s, operand); /* Prime the pump */ - - for (args = insn->args; ; ++args) { - switch (*args) { - - case '\0': /* end of args */ - if (*s == '\0') { - /* We are truly done. */ - the_insn.opcode = opcode; + char *s; + const char *args; + /* !!!! char c; */ + /* !!!! unsigned long i; */ + struct machine_opcode *insn; + char *argsStart; + unsigned long opcode; + /* !!!! unsigned int mask; */ + expressionS the_operand; + expressionS *operand = &the_operand; + unsigned int reg; + + /* Must handle `div0' opcode. */ + s = str; + if (isalpha(*s)) + for (; isalnum(*s); ++s) + if (isupper (*s)) + *s = tolower (*s); + + switch (*s) { + case '\0': + break; + + case ' ': /* FIXME-SOMEDAY more whitespace */ + *s++ = '\0'; + break; + + default: + as_bad("Unknown opcode: `%s'", str); return; - } - as_bad("Too many operands: %s", s); - break; - - case ',': /* Must match a comma */ - if (*s++ == ',') { - s = parse_operand (s, operand); /* Parse next opnd */ - continue; - } - break; - - case 'v': /* Trap numbers (immediate field) */ - if (operand->X_seg == SEG_ABSOLUTE) { - if (operand->X_add_number < 256) { - opcode |= (operand->X_add_number << 16); - continue; - } else { - as_bad("Immediate value of %d is too large", - operand->X_add_number); - continue; - } - } - the_insn.reloc = RELOC_8; - the_insn.reloc_offset = 1; /* BIG-ENDIAN Byte 1 of insn */ - the_insn.exp = *operand; - continue; - - case 'b': /* A general register or 8-bit immediate */ - case 'i': - /* We treat the two cases identically since we mashed - them together in the opcode table. */ - if (operand->X_seg == SEG_REGISTER) - goto general_reg; - - opcode |= IMMEDIATE_BIT; - if (operand->X_seg == SEG_ABSOLUTE) { - if (operand->X_add_number < 256) { - opcode |= operand->X_add_number; - continue; - } else { - as_bad("Immediate value of %d is too large", - operand->X_add_number); - continue; - } - } - the_insn.reloc = RELOC_8; - the_insn.reloc_offset = 3; /* BIG-ENDIAN Byte 3 of insn */ - the_insn.exp = *operand; - continue; - - case 'a': /* next operand must be a register */ - case 'c': - general_reg: - /* lrNNN or grNNN or %%expr or a user-def register name */ - if (operand->X_seg != SEG_REGISTER) - break; /* Only registers */ - know (operand->X_add_symbol == 0); - know (operand->X_subtract_symbol == 0); - reg = operand->X_add_number; - if (reg >= SREG) - break; /* No special registers */ - - /* - * Got the register, now figure out where - * it goes in the opcode. - */ - switch (*args) { - case 'a': - opcode |= reg << 8; - continue; - - case 'b': - case 'i': - opcode |= reg; - continue; - - case 'c': - opcode |= reg << 16; - continue; - } - as_fatal("failed sanity check."); - break; - - case 'x': /* 16 bit constant, zero-extended */ - case 'X': /* 16 bit constant, one-extended */ - if (operand->X_seg == SEG_ABSOLUTE) { - opcode |= (operand->X_add_number & 0xFF) << 0 | - ((operand->X_add_number & 0xFF00) << 8); - continue; - } - the_insn.reloc = RELOC_CONST; - the_insn.exp = *operand; - continue; - - case 'h': - if (operand->X_seg == SEG_ABSOLUTE) { - opcode |= (operand->X_add_number & 0x00FF0000) >> 16 | - (((unsigned long)operand->X_add_number - /* avoid sign ext */ & 0xFF000000) >> 8); - continue; - } - the_insn.reloc = RELOC_CONSTH; - the_insn.exp = *operand; - continue; - - case 'P': /* PC-relative jump address */ - case 'A': /* Absolute jump address */ - /* These two are treated together since we folded the - opcode table entries together. */ - if (operand->X_seg == SEG_ABSOLUTE) { - opcode |= ABSOLUTE_BIT | - (operand->X_add_number & 0x0003FC00) << 6 | - ((operand->X_add_number & 0x000003FC) >> 2); - continue; - } - the_insn.reloc = RELOC_JUMPTARG; - the_insn.exp = *operand; - the_insn.pcrel = 1; /* Assume PC-relative jump */ - /* FIXME-SOON, Do we figure out whether abs later, after know sym val? */ - continue; - - case 'e': /* Coprocessor enable bit for LOAD/STORE insn */ - if (operand->X_seg == SEG_ABSOLUTE) { - if (operand->X_add_number == 0) - continue; - if (operand->X_add_number == 1) { - opcode |= CE_BIT; - continue; - } - } - break; - - case 'n': /* Control bits for LOAD/STORE instructions */ - if (operand->X_seg == SEG_ABSOLUTE && - operand->X_add_number < 128) { - opcode |= (operand->X_add_number << 16); - continue; - } - break; - - case 's': /* Special register number */ - if (operand->X_seg != SEG_REGISTER) - break; /* Only registers */ - if (operand->X_add_number < SREG) - break; /* Not a special register */ - opcode |= (operand->X_add_number & 0xFF) << 8; - continue; - - case 'u': /* UI bit of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE) { - if (operand->X_add_number == 0) - continue; - if (operand->X_add_number == 1) { - opcode |= UI_BIT; - continue; + } + if ((insn = (struct machine_opcode *) hash_find(op_hash, str)) == NULL) { + as_bad("Unknown opcode `%s'.", str); + return; + } + argsStart = s; + opcode = insn->opcode; + bzero(&the_insn, sizeof(the_insn)); + the_insn.reloc = NO_RELOC; + + /* + * Build the opcode, checking as we go to make + * sure that the operands match. + * + * If an operand matches, we modify the_insn or opcode appropriately, + * and do a "continue". If an operand fails to match, we "break". + */ + if (insn->args[0] != '\0') + s = parse_operand (s, operand); /* Prime the pump */ + + for (args = insn->args; ; ++args) { + switch (*args) { + + case '\0': /* end of args */ + if (*s == '\0') { + /* We are truly done. */ + the_insn.opcode = opcode; + return; + } + as_bad("Too many operands: %s", s); + break; + + case ',': /* Must match a comma */ + if (*s++ == ',') { + s = parse_operand (s, operand); /* Parse next opnd */ + continue; + } + break; + + case 'v': /* Trap numbers (immediate field) */ + if (operand->X_seg == SEG_ABSOLUTE) { + if (operand->X_add_number < 256) { + opcode |= (operand->X_add_number << 16); + continue; + } else { + as_bad("Immediate value of %d is too large", + operand->X_add_number); + continue; + } + } + the_insn.reloc = RELOC_8; + the_insn.reloc_offset = 1; /* BIG-ENDIAN Byte 1 of insn */ + the_insn.exp = *operand; + continue; + + case 'b': /* A general register or 8-bit immediate */ + case 'i': + /* We treat the two cases identically since we mashed + them together in the opcode table. */ + if (operand->X_seg == SEG_REGISTER) + goto general_reg; + + opcode |= IMMEDIATE_BIT; + if (operand->X_seg == SEG_ABSOLUTE) { + if (operand->X_add_number < 256) { + opcode |= operand->X_add_number; + continue; + } else { + as_bad("Immediate value of %d is too large", + operand->X_add_number); + continue; + } + } + the_insn.reloc = RELOC_8; + the_insn.reloc_offset = 3; /* BIG-ENDIAN Byte 3 of insn */ + the_insn.exp = *operand; + continue; + + case 'a': /* next operand must be a register */ + case 'c': + general_reg: + /* lrNNN or grNNN or %%expr or a user-def register name */ + if (operand->X_seg != SEG_REGISTER) + break; /* Only registers */ + know (operand->X_add_symbol == 0); + know (operand->X_subtract_symbol == 0); + reg = operand->X_add_number; + if (reg >= SREG) + break; /* No special registers */ + + /* + * Got the register, now figure out where + * it goes in the opcode. + */ + switch (*args) { + case 'a': + opcode |= reg << 8; + continue; + + case 'b': + case 'i': + opcode |= reg; + continue; + + case 'c': + opcode |= reg << 16; + continue; + } + as_fatal("failed sanity check."); + break; + + case 'x': /* 16 bit constant, zero-extended */ + case 'X': /* 16 bit constant, one-extended */ + if (operand->X_seg == SEG_ABSOLUTE) { + opcode |= (operand->X_add_number & 0xFF) << 0 | + ((operand->X_add_number & 0xFF00) << 8); + continue; + } + the_insn.reloc = RELOC_CONST; + the_insn.exp = *operand; + continue; + + case 'h': + if (operand->X_seg == SEG_ABSOLUTE) { + opcode |= (operand->X_add_number & 0x00FF0000) >> 16 | + (((unsigned long)operand->X_add_number + /* avoid sign ext */ & 0xFF000000) >> 8); + continue; + } + the_insn.reloc = RELOC_CONSTH; + the_insn.exp = *operand; + continue; + + case 'P': /* PC-relative jump address */ + case 'A': /* Absolute jump address */ + /* These two are treated together since we folded the + opcode table entries together. */ + if (operand->X_seg == SEG_ABSOLUTE) { + opcode |= ABSOLUTE_BIT | + (operand->X_add_number & 0x0003FC00) << 6 | + ((operand->X_add_number & 0x000003FC) >> 2); + continue; + } + the_insn.reloc = RELOC_JUMPTARG; + the_insn.exp = *operand; + the_insn.pcrel = 1; /* Assume PC-relative jump */ + /* FIXME-SOON, Do we figure out whether abs later, after know sym val? */ + continue; + + case 'e': /* Coprocessor enable bit for LOAD/STORE insn */ + if (operand->X_seg == SEG_ABSOLUTE) { + if (operand->X_add_number == 0) + continue; + if (operand->X_add_number == 1) { + opcode |= CE_BIT; + continue; + } + } + break; + + case 'n': /* Control bits for LOAD/STORE instructions */ + if (operand->X_seg == SEG_ABSOLUTE && + operand->X_add_number < 128) { + opcode |= (operand->X_add_number << 16); + continue; + } + break; + + case 's': /* Special register number */ + if (operand->X_seg != SEG_REGISTER) + break; /* Only registers */ + if (operand->X_add_number < SREG) + break; /* Not a special register */ + opcode |= (operand->X_add_number & 0xFF) << 8; + continue; + + case 'u': /* UI bit of CONVERT */ + if (operand->X_seg == SEG_ABSOLUTE) { + if (operand->X_add_number == 0) + continue; + if (operand->X_add_number == 1) { + opcode |= UI_BIT; + continue; + } + } + break; + + case 'r': /* RND bits of CONVERT */ + if (operand->X_seg == SEG_ABSOLUTE && + operand->X_add_number < 8) { + opcode |= operand->X_add_number << 4; + continue; + } + break; + + case 'd': /* FD bits of CONVERT */ + if (operand->X_seg == SEG_ABSOLUTE && + operand->X_add_number < 4) { + opcode |= operand->X_add_number << 2; + continue; + } + break; + + + case 'f': /* FS bits of CONVERT */ + if (operand->X_seg == SEG_ABSOLUTE && + operand->X_add_number < 4) { + opcode |= operand->X_add_number << 0; + continue; + } + break; + + case 'C': + if (operand->X_seg == SEG_ABSOLUTE && + operand->X_add_number < 4) { + opcode |= operand->X_add_number << 16; + continue; + } + break; + + case 'F': + if (operand->X_seg == SEG_ABSOLUTE && + operand->X_add_number < 16) { + opcode |= operand->X_add_number << 18; + continue; + } + break; + + default: + BAD_CASE (*args); } - } - break; - - case 'r': /* RND bits of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE && - operand->X_add_number < 8) { - opcode |= operand->X_add_number << 4; - continue; - } - break; - - case 'd': /* FD bits of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE && - operand->X_add_number < 4) { - opcode |= operand->X_add_number << 2; - continue; - } - break; - - - case 'f': /* FS bits of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE && - operand->X_add_number < 4) { - opcode |= operand->X_add_number << 0; - continue; - } - break; - - case 'C': - if (operand->X_seg == SEG_ABSOLUTE && - operand->X_add_number < 4) { - opcode |= operand->X_add_number << 16; - continue; - } - break; - - case 'F': - if (operand->X_seg == SEG_ABSOLUTE && - operand->X_add_number < 16) { - opcode |= operand->X_add_number << 18; - continue; - } - break; - - default: - BAD_CASE (*args); + /* Types or values of args don't match. */ + as_bad("Invalid operands"); + return; } - /* Types or values of args don't match. */ - as_bad("Invalid operands"); - return; - } } /* - This is identical to the md_atof in m68k.c. I think this is right, - but I'm not sure. - - Turn a string in input_line_pointer into a floating point constant of type - type, and store the appropriate bytes in *litP. The number of LITTLENUMS - emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ + This is identical to the md_atof in m68k.c. I think this is right, + but I'm not sure. + + Turn a string in input_line_pointer into a floating point constant of type + type, and store the appropriate bytes in *litP. The number of LITTLENUMS + emitted is stored in *sizeP . An error message is returned, or NULL on OK. + */ /* Equal to MAX_PRECISION in atof-ieee.c */ #define MAX_LITTLENUMS 6 char * -md_atof(type,litP,sizeP) - char type; - char *litP; - int *sizeP; + md_atof(type,litP,sizeP) +char type; +char *litP; +int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - - switch(type) { - - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words;prec--;) { - md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + + switch(type) { + + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words;prec--;) { + md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } /* * Write out big-endian. */ void -md_number_to_chars(buf,val,n) - char *buf; - long val; - int n; + md_number_to_chars(buf,val,n) +char *buf; +long val; +int n; { - - switch(n) { - - case 4: - *buf++ = val >> 24; - *buf++ = val >> 16; - case 2: - *buf++ = val >> 8; - case 1: - *buf = val; - break; - - default: - as_fatal("failed sanity check."); - } - return; + + switch(n) { + + case 4: + *buf++ = val >> 24; + *buf++ = val >> 16; + case 2: + *buf++ = val >> 8; + case 1: + *buf = val; + break; + + default: + as_fatal("failed sanity check."); + } + return; } void md_apply_fix(fixP, val) - fixS *fixP; - long val; +fixS *fixP; +long val; { - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - - fixP->fx_addnumber = val; /* Remember value for emit_reloc */ - - - know(fixP->fx_size == 4); - know(fixP->fx_r_type < NO_RELOC); - - /* - * This is a hack. There should be a better way to - * handle this. - */ - if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) { - val += fixP->fx_where + fixP->fx_frag->fr_address; - } - - switch (fixP->fx_r_type) { - - case RELOC_32: - buf[0] = val >> 24; - buf[1] = val >> 16; - buf[2] = val >> 8; - buf[3] = val; - break; - - case RELOC_8: - buf[0] = val; - break; - - case RELOC_WDISP30: - val = (val >>= 2) + 1; - buf[0] |= (val >> 24) & 0x3f; - buf[1]= (val >> 16); - buf[2] = val >> 8; - buf[3] = val; - break; - - case RELOC_HI22: - buf[1] |= (val >> 26) & 0x3f; - buf[2] = val >> 18; - buf[3] = val >> 10; - break; - - case RELOC_LO10: - buf[2] |= (val >> 8) & 0x03; - buf[3] = val; - break; - - case RELOC_BASE13: - buf[2] |= (val >> 8) & 0x1f; - buf[3] = val; - break; - - case RELOC_WDISP22: - val = (val >>= 2) + 1; - /* FALLTHROUGH */ - case RELOC_BASE22: - buf[1] |= (val >> 16) & 0x3f; - buf[2] = val >> 8; - buf[3] = val; - break; - + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + fixP->fx_addnumber = val; /* Remember value for emit_reloc */ + + + know(fixP->fx_size == 4); + know(fixP->fx_r_type < NO_RELOC); + + /* + * This is a hack. There should be a better way to + * handle this. + */ + if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) { + val += fixP->fx_where + fixP->fx_frag->fr_address; + } + + switch (fixP->fx_r_type) { + + case RELOC_32: + buf[0] = val >> 24; + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; + break; + + case RELOC_8: + buf[0] = val; + break; + + case RELOC_WDISP30: + val = (val >>= 2) + 1; + buf[0] |= (val >> 24) & 0x3f; + buf[1]= (val >> 16); + buf[2] = val >> 8; + buf[3] = val; + break; + + case RELOC_HI22: + buf[1] |= (val >> 26) & 0x3f; + buf[2] = val >> 18; + buf[3] = val >> 10; + break; + + case RELOC_LO10: + buf[2] |= (val >> 8) & 0x03; + buf[3] = val; + break; + + case RELOC_BASE13: + buf[2] |= (val >> 8) & 0x1f; + buf[3] = val; + break; + + case RELOC_WDISP22: + val = (val >>= 2) + 1; + /* FALLTHROUGH */ + case RELOC_BASE22: + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val; + break; + #if 0 - case RELOC_PC10: - case RELOC_PC22: - case RELOC_JMP_TBL: - case RELOC_SEGOFF16: - case RELOC_GLOB_DAT: - case RELOC_JMP_SLOT: - case RELOC_RELATIVE: + case RELOC_PC10: + case RELOC_PC22: + case RELOC_JMP_TBL: + case RELOC_SEGOFF16: + case RELOC_GLOB_DAT: + case RELOC_JMP_SLOT: + case RELOC_RELATIVE: #endif - case RELOC_JUMPTARG: /* 00XX00XX pattern in a word */ - buf[1] = val >> 10; /* Holds bits 0003FFFC of address */ - buf[3] = val >> 2; - break; - - case RELOC_CONST: /* 00XX00XX pattern in a word */ - buf[1] = val >> 8; /* Holds bits 0000XXXX */ - buf[3] = val; - break; - - case RELOC_CONSTH: /* 00XX00XX pattern in a word */ - buf[1] = val >> 24; /* Holds bits XXXX0000 */ - buf[3] = val >> 16; - break; - - case NO_RELOC: - default: - as_bad("bad relocation type: 0x%02x", fixP->fx_r_type); - break; - } - return; + case RELOC_JUMPTARG: /* 00XX00XX pattern in a word */ + buf[1] = val >> 10; /* Holds bits 0003FFFC of address */ + buf[3] = val >> 2; + break; + + case RELOC_CONST: /* 00XX00XX pattern in a word */ + buf[1] = val >> 8; /* Holds bits 0000XXXX */ + buf[3] = val; + break; + + case RELOC_CONSTH: /* 00XX00XX pattern in a word */ + buf[1] = val >> 24; /* Holds bits XXXX0000 */ + buf[3] = val >> 16; + break; + + case NO_RELOC: + default: + as_bad("bad relocation type: 0x%02x", fixP->fx_r_type); + break; + } + return; } #ifdef OBJ_COFF short tc_coff_fix2rtype(fixP) fixS *fixP; { - + /* FIXME-NOW: relocation type handling is not yet written for a29k. */ - - + + switch (fixP->fx_r_type) { case RELOC_32: return(R_WORD); case RELOC_8: return(R_BYTE); @@ -874,107 +874,107 @@ fixS *fixP; case RELOC_CONSTH: return (R_IHIHALF); case RELOC_JUMPTARG: return (R_IREL); default: printf("need %o3\n", fixP->fx_r_type); - abort(0); + abort(0); } /* switch on type */ - + return(0); } /* tc_coff_fix2rtype() */ #endif /* OBJ_COFF */ /* should never be called for sparc */ void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, to_addr; +char *ptr; +long from_addr, to_addr; fragS *frag; symbolS *to_symbol; { - as_fatal("a29k_create_short_jmp\n"); + as_fatal("a29k_create_short_jmp\n"); } /* should never be called for 29k */ void md_convert_frag(headers, fragP) object_headers *headers; - register fragS *fragP; +register fragS *fragP; { - as_fatal("sparc_convert_frag\n"); + as_fatal("sparc_convert_frag\n"); } /* should never be called for 29k */ void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, - to_addr; - fragS *frag; - symbolS *to_symbol; +char *ptr; +long from_addr, + to_addr; +fragS *frag; +symbolS *to_symbol; { as_fatal("sparc_create_long_jump\n"); } /* should never be called for sparc */ int md_estimate_size_before_relax(fragP, segtype) - register fragS *fragP; +register fragS *fragP; segT segtype; { - as_fatal("sparc_estimate_size_before_relax\n"); + as_fatal("sparc_estimate_size_before_relax\n"); } #if 0 /* for debugging only */ static void -print_insn(insn) - struct machine_it *insn; + print_insn(insn) +struct machine_it *insn; { - char *Reloc[] = { - "RELOC_8", - "RELOC_16", - "RELOC_32", - "RELOC_DISP8", - "RELOC_DISP16", - "RELOC_DISP32", - "RELOC_WDISP30", - "RELOC_WDISP22", - "RELOC_HI22", - "RELOC_22", - "RELOC_13", - "RELOC_LO10", - "RELOC_SFA_BASE", - "RELOC_SFA_OFF13", - "RELOC_BASE10", - "RELOC_BASE13", - "RELOC_BASE22", - "RELOC_PC10", - "RELOC_PC22", - "RELOC_JMP_TBL", - "RELOC_SEGOFF16", - "RELOC_GLOB_DAT", - "RELOC_JMP_SLOT", - "RELOC_RELATIVE", - "NO_RELOC" - }; - - if (insn->error) { - fprintf(stderr, "ERROR: %s\n"); - } - fprintf(stderr, "opcode=0x%08x\n", insn->opcode); - fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]); - fprintf(stderr, "exp = {\n"); - fprintf(stderr, "\t\tX_add_symbol = %s\n", - insn->exp.X_add_symbol ? - (S_GET_NAME(insn->exp.X_add_symbol) ? - S_GET_NAME(insn->exp.X_add_symbol) : "???") : "0"); - fprintf(stderr, "\t\tX_sub_symbol = %s\n", - insn->exp.X_subtract_symbol ? - (S_GET_NAME(insn->exp.X_subtract_symbol) ? - S_GET_NAME(insn->exp.X_subtract_symbol) : "???") : "0"); - fprintf(stderr, "\t\tX_add_number = %d\n", - insn->exp.X_add_number); - fprintf(stderr, "}\n"); - return; + char *Reloc[] = { + "RELOC_8", + "RELOC_16", + "RELOC_32", + "RELOC_DISP8", + "RELOC_DISP16", + "RELOC_DISP32", + "RELOC_WDISP30", + "RELOC_WDISP22", + "RELOC_HI22", + "RELOC_22", + "RELOC_13", + "RELOC_LO10", + "RELOC_SFA_BASE", + "RELOC_SFA_OFF13", + "RELOC_BASE10", + "RELOC_BASE13", + "RELOC_BASE22", + "RELOC_PC10", + "RELOC_PC22", + "RELOC_JMP_TBL", + "RELOC_SEGOFF16", + "RELOC_GLOB_DAT", + "RELOC_JMP_SLOT", + "RELOC_RELATIVE", + "NO_RELOC" + }; + + if (insn->error) { + fprintf(stderr, "ERROR: %s\n"); + } + fprintf(stderr, "opcode=0x%08x\n", insn->opcode); + fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]); + fprintf(stderr, "exp = {\n"); + fprintf(stderr, "\t\tX_add_symbol = %s\n", + insn->exp.X_add_symbol ? + (S_GET_NAME(insn->exp.X_add_symbol) ? + S_GET_NAME(insn->exp.X_add_symbol) : "???") : "0"); + fprintf(stderr, "\t\tX_sub_symbol = %s\n", + insn->exp.X_subtract_symbol ? + (S_GET_NAME(insn->exp.X_subtract_symbol) ? + S_GET_NAME(insn->exp.X_subtract_symbol) : "???") : "0"); + fprintf(stderr, "\t\tX_add_number = %d\n", + insn->exp.X_add_number); + fprintf(stderr, "}\n"); + return; } #endif /* Translate internal representation of relocation info to target format. - + On sparc/29k: first 4 bytes are normal unsigned long address, next three bytes are index, most sig. byte first. Byte 7 is broken up with bit 7 as external, bits 6 & 5 unused, and the lower @@ -1009,19 +1009,19 @@ relax_addressT segment_address_in_file; where[7] = (((!S_IS_DEFINED(fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); /* Also easy */ md_number_to_chars(&where[8], fixP->fx_addnumber, 4); - + return; } /* tc_aout_fix_to_chars() */ #endif /* OBJ_AOUT */ int -md_parse_option(argP,cntP,vecP) - char **argP; - int *cntP; - char ***vecP; + md_parse_option(argP,cntP,vecP) +char **argP; +int *cntP; +char ***vecP; { - return(0); + return(0); } @@ -1030,81 +1030,81 @@ md_parse_option(argP,cntP,vecP) are a lot of them. */ symbolS *md_undefined_symbol (name) - char *name; +char *name; { - long regnum; - char testbuf[5+ /*SLOP*/ 5]; - - if (name[0] == 'g' || name[0] == 'G' || name[0] == 'l' || name[0] == 'L') - { - /* Perhaps a global or local register name */ - if (name[1] == 'r' || name[1] == 'R') - { - /* Parse the number, make sure it has no extra zeroes or trailing - chars */ - regnum = atol(&name[2]); - if (regnum > 127) - return 0; - sprintf(testbuf, "%ld", regnum); - if (strcmp (testbuf, &name[2]) != 0) - return 0; /* gr007 or lr7foo or whatever */ - - /* We have a wiener! Define and return a new symbol for it. */ - if (name[0] == 'l' || name[0] == 'L') - regnum += 128; - return(symbol_new(name, SEG_REGISTER, regnum, &zero_address_frag)); - } - } - - return 0; + long regnum; + char testbuf[5+ /*SLOP*/ 5]; + + if (name[0] == 'g' || name[0] == 'G' || name[0] == 'l' || name[0] == 'L') + { + /* Perhaps a global or local register name */ + if (name[1] == 'r' || name[1] == 'R') + { + /* Parse the number, make sure it has no extra zeroes or trailing + chars */ + regnum = atol(&name[2]); + if (regnum > 127) + return 0; + sprintf(testbuf, "%ld", regnum); + if (strcmp (testbuf, &name[2]) != 0) + return 0; /* gr007 or lr7foo or whatever */ + + /* We have a wiener! Define and return a new symbol for it. */ + if (name[0] == 'l' || name[0] == 'L') + regnum += 128; + return(symbol_new(name, SEG_REGISTER, regnum, &zero_address_frag)); + } + } + + return 0; } /* Parse an operand that is machine-specific. */ void md_operand(expressionP) - expressionS *expressionP; +expressionS *expressionP; { - - if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%') - { - /* We have a numeric register expression. No biggy. */ - input_line_pointer += 2; /* Skip %% */ - (void)expression (expressionP); - if (expressionP->X_seg != SEG_ABSOLUTE - || expressionP->X_add_number > 255) - as_bad("Invalid expression after %%%%\n"); - expressionP->X_seg = SEG_REGISTER; - } - else if (input_line_pointer[0] == '&') - { - /* We are taking the 'address' of a register...this one is not - in the manual, but it *is* in traps/fpsymbol.h! What they - seem to want is the register number, as an absolute number. */ - input_line_pointer++; /* Skip & */ - (void)expression (expressionP); - if (expressionP->X_seg != SEG_REGISTER) - as_bad("Invalid register in & expression"); - else - expressionP->X_seg = SEG_ABSOLUTE; - } + + if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%') + { + /* We have a numeric register expression. No biggy. */ + input_line_pointer += 2; /* Skip %% */ + (void)expression (expressionP); + if (expressionP->X_seg != SEG_ABSOLUTE + || expressionP->X_add_number > 255) + as_bad("Invalid expression after %%%%\n"); + expressionP->X_seg = SEG_REGISTER; + } + else if (input_line_pointer[0] == '&') + { + /* We are taking the 'address' of a register...this one is not + in the manual, but it *is* in traps/fpsymbol.h! What they + seem to want is the register number, as an absolute number. */ + input_line_pointer++; /* Skip & */ + (void)expression (expressionP); + if (expressionP->X_seg != SEG_REGISTER) + as_bad("Invalid register in & expression"); + else + expressionP->X_seg = SEG_ABSOLUTE; + } } /* Round up a section size to the appropriate boundary. */ long -md_section_align (segment, size) - segT segment; - long size; + md_section_align (segment, size) +segT segment; +long size; { - return size; /* Byte alignment is fine */ + return size; /* Byte alignment is fine */ } /* Exactly what point is a PC-relative offset relative TO? On the 29000, they're relative to the address of the instruction, which we have set up as the address of the fixup too. */ long md_pcrel_from (fixP) - fixS *fixP; +fixS *fixP; { - return fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_where + fixP->fx_frag->fr_address; } /* diff --git a/gas/config/tc-a29k.h b/gas/config/tc-a29k.h index 8730c2a..086224d 100644 --- a/gas/config/tc-a29k.h +++ b/gas/config/tc-a29k.h @@ -1,21 +1,21 @@ /* tc-a29k.h -- Assemble for the AMD 29000. Copyright (C) 1989, 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 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. */ /* $Id$ */ @@ -25,15 +25,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define tc_headers_hook(a) ; /* not used */ #define tc_crawl_symbol_chain(a) ; /* not used */ #define tc_coff_symbol_emit_hook(a) ; /* not used */ - + #define AOUT_MACHTYPE 101 #define TC_COFF_FIX2RTYPE(fix_ptr) tc_coff_fix2rtype(fix_ptr) #define BFD_ARCH bfd_arch_a29k #define COFF_MAGIC SIPFBOMAGIC /* Should the reloc be output ? - on the 29k, this is true only if there is a symbol attatched. - on the h8, this is allways true, since no fixup is done -*/ + on the 29k, this is true only if there is a symbol attatched. + on the h8, this is allways true, since no fixup is done + */ #define TC_COUNT_RELOC(x) (x->fx_addsy) /* end of tc-a29k.h */ - diff --git a/gas/config/tc-generic.h b/gas/config/tc-generic.h index aa63410..2faab7f 100644 --- a/gas/config/tc-generic.h +++ b/gas/config/tc-generic.h @@ -1,6 +1,8 @@ /* - * This file is tc-generic.h and is intended to be a template for - * target cpu specific header files. + * This file is tc-generic.h and is intended to be a template for target cpu + * specific header files. It is my intent that this file compile. It is also + * my intent that this file grow into something that can be used as both a + * template for porting, and a stub for testing. xoxorich. */ #define TC_GENERIC 1 diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index 6f2e2ff..6533893 100644 --- a/gas/config/tc-h8300.c +++ b/gas/config/tc-h8300.c @@ -1,27 +1,27 @@ -/* tc-h8300.c -- Assemble code for the Hitachi h8/300 +/* tc-h8300.c -- Assemble code for the Hitachi H8/300 Copyright (C) 1991 Free Software Foundation. - -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. */ /* Written By Steve Chamberlain sac@cygnus.com - */ + */ #include <stdio.h> #include "as.h" @@ -38,23 +38,23 @@ char line_separator_chars[] = { '$' ,0}; pseudo-op name without dot function to call to execute this pseudo-op Integer arg to pass to the function - */ + */ void cons(); const pseudo_typeS md_pseudo_table[] = { - { "int", cons, 2 }, - { 0,0,0 } + { "int", cons, 2 }, + { 0,0,0 } }; int md_reloc_size ; - + const char EXP_CHARS[] = "eE"; /* Chars that mean this number is a floating point constant */ /* As in 0f12.456 */ /* or 0d1.2345e12 */ - char FLT_CHARS[] = "rRsSfFdDxXpP"; +char FLT_CHARS[] = "rRsSfFdDxXpP"; const relax_typeS md_relax_table[1]; @@ -64,138 +64,138 @@ static struct hash_control *opcode_hash_control; /* Opcode mnemonics */ /* - This function is called once, at assembler startup time. This should - set up all the tables, etc that the MD part of the assembler needs -*/ - + This function is called once, at assembler startup time. This should + set up all the tables, etc that the MD part of the assembler needs + */ +#if 0 /* encode the size and number into the number field xxnnnn 00 8 bit 01 16 bit 10 ccr - nnnnreg number -*/ + nnnnreg number + */ #define WORD_REG 0x10 #define BYTE_REG 0x00 #define CCR_REG 0x20 - struct reg_entry +struct reg_entry { - char *name; - char number; + char *name; + char number; }; struct reg_entry reg_list[] = { -"r0",WORD_REG +0, -"r1",WORD_REG +1, -"r2",WORD_REG +2, -"r3",WORD_REG +3, -"r4",WORD_REG +4, -"r5",WORD_REG +5, -"r6",WORD_REG +6, -"r7",WORD_REG +7, -"fp",WORD_REG +6, -"sp",WORD_REG +7, -"r0h",BYTE_REG + 0, -"r0l",BYTE_REG + 1, -"r1h",BYTE_REG + 2, -"r1l",BYTE_REG + 3, -"r2h",BYTE_REG + 4, -"r2l",BYTE_REG + 5, -"r3h",BYTE_REG + 6, -"r3l",BYTE_REG + 7, -"r4h",BYTE_REG + 8, -"r4l",BYTE_REG + 9, -"r5h",BYTE_REG + 10, -"r5l",BYTE_REG + 11, -"r6h",BYTE_REG + 12, -"r6l",BYTE_REG + 13, -"r7h",BYTE_REG + 14, -"r7l",BYTE_REG + 15, -"ccr",CCR_REG, -0,0 -} + "r0",WORD_REG +0, + "r1",WORD_REG +1, + "r2",WORD_REG +2, + "r3",WORD_REG +3, + "r4",WORD_REG +4, + "r5",WORD_REG +5, + "r6",WORD_REG +6, + "r7",WORD_REG +7, + "fp",WORD_REG +6, + "sp",WORD_REG +7, + "r0h",BYTE_REG + 0, + "r0l",BYTE_REG + 1, + "r1h",BYTE_REG + 2, + "r1l",BYTE_REG + 3, + "r2h",BYTE_REG + 4, + "r2l",BYTE_REG + 5, + "r3h",BYTE_REG + 6, + "r3l",BYTE_REG + 7, + "r4h",BYTE_REG + 8, + "r4l",BYTE_REG + 9, + "r5h",BYTE_REG + 10, + "r5l",BYTE_REG + 11, + "r6h",BYTE_REG + 12, + "r6l",BYTE_REG + 13, + "r7h",BYTE_REG + 14, + "r7l",BYTE_REG + 15, + "ccr",CCR_REG, + 0,0 + } ; - +#endif void md_begin () { - struct h8_opcode *opcode; - const struct reg_entry *reg; - char prev_buffer[100]; - int idx = 0; - - opcode_hash_control = hash_new(); - prev_buffer[0] = 0; - - for (opcode = h8_opcodes; opcode->name; opcode++) - { - /* Strip off any . part when inserting the opcode and only enter - unique codes into the hash table - */ - char *src= opcode->name; - unsigned int len = strlen(src); - char *dst = malloc(len+1); - char *buffer = dst; - opcode->size = 0; - while (*src) { - if (*src == '.') { - *dst++ = 0; - src++; - opcode->size = *src; - break; - } - *dst++ = *src++; - } - if (strcmp(buffer, prev_buffer)) - { - hash_insert(opcode_hash_control, buffer, (char *)opcode); - strcpy(prev_buffer, buffer); - idx++; - } - opcode->idx = idx; - - - /* Find the number of operands */ - opcode->noperands = 0; - while (opcode->args.nib[opcode->noperands] != E) - opcode->noperands ++; - /* Find the length of the opcode in bytes */ - opcode->length =0; - while (opcode->data.nib[opcode->length*2] != E) - opcode->length++; - } - + struct h8_opcode *opcode; + const struct reg_entry *reg; + char prev_buffer[100]; + int idx = 0; + + opcode_hash_control = hash_new(); + prev_buffer[0] = 0; + + for (opcode = h8_opcodes; opcode->name; opcode++) + { + /* Strip off any . part when inserting the opcode and only enter + unique codes into the hash table + */ + char *src= opcode->name; + unsigned int len = strlen(src); + char *dst = malloc(len+1); + char *buffer = dst; + opcode->size = 0; + while (*src) { + if (*src == '.') { + *dst++ = 0; + src++; + opcode->size = *src; + break; + } + *dst++ = *src++; + } + if (strcmp(buffer, prev_buffer)) + { + hash_insert(opcode_hash_control, buffer, (char *)opcode); + strcpy(prev_buffer, buffer); + idx++; + } + opcode->idx = idx; + + + /* Find the number of operands */ + opcode->noperands = 0; + while (opcode->args.nib[opcode->noperands] != E) + opcode->noperands ++; + /* Find the length of the opcode in bytes */ + opcode->length =0; + while (opcode->data.nib[opcode->length*2] != E) + opcode->length++; + } + } struct h8_exp { - char *e_beg; - char *e_end; - expressionS e_exp; + char *e_beg; + char *e_end; + expressionS e_exp; }; struct h8_op { - unsigned int dispreg; - op_type mode; - unsigned reg; - expressionS exp; + unsigned int dispreg; + op_type mode; + unsigned reg; + expressionS exp; }; /* - parse operands - WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp - r0l,r0h,..r7l,r7h - @WREG - @WREG+ - @-WREG - #const - -*/ + parse operands + WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp + r0l,r0h,..r7l,r7h + @WREG + @WREG+ + @-WREG + #const + + */ op_type r8_sord[] = {RS8, RD8}; op_type r16_sord[] = {RS16, RD16}; @@ -205,2006 +205,873 @@ op_type disp_sord[] = {DISPSRC, DISPDST}; /* try and parse a reg name, returns number of chars consumed */ int -DEFUN(parse_reg,(src, mode, reg, dst), - char *src AND - op_type *mode AND - unsigned int *reg AND - int dst) + DEFUN(parse_reg,(src, mode, reg, dst), + char *src AND + op_type *mode AND + unsigned int *reg AND + int dst) { - if (src[0] == 's' && src[1] == 'p') - { - *mode = r16_sord[dst]; - *reg = 7; - return 2; - } - if (src[0] == 'c' && src[1] == 'c' && src[2] == 'r') - { - *mode = CCR; - *reg = 0; - return 3; - } - if (src[0] == 'f' && src[1] == 'p') - { - *mode = r16_sord[dst]; - *reg = 6; - return 2; - } - if (src[0] == 'r') - { - if (src[1] >= '0' && src[1] <= '7') - { - if(src[2] == 'l') + if (src[0] == 's' && src[1] == 'p') { - *mode = r8_sord[dst]; - *reg = (src[1] - '0') + 8; - return 3; + *mode = r16_sord[dst]; + *reg = 7; + return 2; } - if(src[2] == 'h') + if (src[0] == 'c' && src[1] == 'c' && src[2] == 'r') { - *mode = r8_sord[dst]; - *reg = (src[1] - '0') ; - return 3; + *mode = CCR; + *reg = 0; + return 3; } - *mode = r16_sord[dst]; - *reg = (src[1] - '0'); - return 2; - } - } - return 0; + if (src[0] == 'f' && src[1] == 'p') + { + *mode = r16_sord[dst]; + *reg = 6; + return 2; + } + if (src[0] == 'r') + { + if (src[1] >= '0' && src[1] <= '7') + { + if(src[2] == 'l') + { + *mode = r8_sord[dst]; + *reg = (src[1] - '0') + 8; + return 3; + } + if(src[2] == 'h') + { + *mode = r8_sord[dst]; + *reg = (src[1] - '0') ; + return 3; + } + *mode = r16_sord[dst]; + *reg = (src[1] - '0'); + return 2; + } + } + return 0; } char * -DEFUN(parse_exp,(s, op), - char *s AND - expressionS *op) + DEFUN(parse_exp,(s, op), + char *s AND + expressionS *op) { - char *save = input_line_pointer; - char *new; - segT seg; - input_line_pointer = s; - seg = expr(0,op); - new = input_line_pointer; - input_line_pointer = save; - if (SEG_NORMAL(seg)) - return new; - switch (seg) { - case SEG_ABSOLUTE: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_REGISTER: - return new; - case SEG_ABSENT: - as_bad("Missing operand"); - return new; - default: - as_bad("Don't understand operand of type %s", segment_name (seg)); - return new; - } + char *save = input_line_pointer; + char *new; + segT seg; + input_line_pointer = s; + seg = expr(0,op); + new = input_line_pointer; + input_line_pointer = save; + if (SEG_NORMAL(seg)) + return new; + switch (seg) { + case SEG_ABSOLUTE: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + case SEG_BIG: + case SEG_REGISTER: + return new; + case SEG_ABSENT: + as_bad("Missing operand"); + return new; + default: + as_bad("Don't understand operand of type %s", segment_name (seg)); + return new; + } } static char * -DEFUN(skip_colonthing,(ptr), - char *ptr) + DEFUN(skip_colonthing,(ptr), + char *ptr) { - if (*ptr == ':') { - ptr++; - while (isdigit(*ptr)) - ptr++; - + if (*ptr == ':') { + ptr++; + while (isdigit(*ptr)) + ptr++; + } - return ptr; + return ptr; } /* The many forms of operand: - Rn Register direct - @Rn Register indirect - @(exp[:16], Rn) Register indirect with displacement - @Rn+ - @-Rn - @aa:8 absolute 8 bit - @aa:16 absolute 16 bit - @aa absolute 16 bit - - #xx[:size] immediate data - @(exp:[8], pc) pc rel - @@aa[:8] memory indirect - -*/ + Rn Register direct + @Rn Register indirect + @(exp[:16], Rn) Register indirect with displacement + @Rn+ + @-Rn + @aa:8 absolute 8 bit + @aa:16 absolute 16 bit + @aa absolute 16 bit + + #xx[:size] immediate data + @(exp:[8], pc) pc rel + @@aa[:8] memory indirect + + */ static void -DEFUN(get_operand,(ptr, op, dst), - char **ptr AND - struct h8_op *op AND - unsigned int dst) + DEFUN(get_operand,(ptr, op, dst), + char **ptr AND + struct h8_op *op AND + unsigned int dst) { - char *src = *ptr; - op_type mode; - unsigned int num; - unsigned int len; - unsigned int size; - op->mode = E; - - len = parse_reg(src, &op->mode, &op->reg, dst); - if (len) { - *ptr = src + len; - return ; - } - - if (*src == '@') - { - src++; - if (*src == '@') - { - src++; - src = parse_exp(src,&op->exp); - src = skip_colonthing(src); - - *ptr = src; - - op->mode = MEMIND; - return; - - } + char *src = *ptr; + op_type mode; + unsigned int num; + unsigned int len; + unsigned int size; + op->mode = E; - - if (*src == '-') - { - src++; - len = parse_reg(src, &mode, &num, dst); - if (len == 0 || mode != r16_sord[dst]) - { - as_bad("@- needs word register"); - } - op->mode = RDDEC; - op->reg = num; - *ptr = src + len; - return; - } - if (*src == '(' && ')') - { - /* Disp */ - src++; - src = parse_exp(src, &op->exp); - - if (*src == ')') - { - src++; - op->mode = abs_sord[dst]; - *ptr = src; - return; - } - src = skip_colonthing(src); - - if (*src != ',') - { - as_bad("expected @(exp, reg16)"); - } - src++; - len = parse_reg(src, &mode, &op->reg, dst); - if (len == 0 || mode != r16_sord[dst]) - { - as_bad("expected @(exp, reg16)"); - } - op->mode = disp_sord[dst]; - src += len; - src = skip_colonthing(src); - - if (*src != ')' && '(') - { - as_bad("expected @(exp, reg16)"); - - } - *ptr = src +1; - - return; - } - len = parse_reg(src, &mode, &num, dst); - - if(len) { - src += len; - if (*src == '+') - { - src++; - if (mode != RS16) - { - as_bad("@Rn+ needs src word register"); - } - op->mode = RSINC; - op->reg = num; - *ptr = src; - return; + len = parse_reg(src, &op->mode, &op->reg, dst); + if (len) { + *ptr = src + len; + return ; + } + + if (*src == '@') + { + src++; + if (*src == '@') + { + src++; + src = parse_exp(src,&op->exp); + src = skip_colonthing(src); + + *ptr = src; + + op->mode = MEMIND; + return; + + } + + + if (*src == '-') + { + src++; + len = parse_reg(src, &mode, &num, dst); + if (len == 0) + { + /* Oops, not a reg after all, must be ordinary exp */ + src--; + /* must be a symbol */ + op->mode = abs_sord[dst]; + *ptr = skip_colonthing(parse_exp(src, &op->exp)); + + return; + + + } + + if (mode != r16_sord[dst]) + { + as_bad("@- needs word register"); + } + op->mode = RDDEC; + op->reg = num; + *ptr = src + len; + return; + } + if (*src == '(' && ')') + { + /* Disp */ + src++; + src = parse_exp(src, &op->exp); + + if (*src == ')') + { + src++; + op->mode = abs_sord[dst]; + *ptr = src; + return; + } + src = skip_colonthing(src); + + if (*src != ',') + { + as_bad("expected @(exp, reg16)"); + } + src++; + len = parse_reg(src, &mode, &op->reg, dst); + if (len == 0 || mode != r16_sord[dst]) + { + as_bad("expected @(exp, reg16)"); + } + op->mode = disp_sord[dst]; + src += len; + src = skip_colonthing(src); + + if (*src != ')' && '(') + { + as_bad("expected @(exp, reg16)"); + + } + *ptr = src +1; + + return; + } + len = parse_reg(src, &mode, &num, dst); + + if(len) { + src += len; + if (*src == '+') + { + src++; + if (mode != RS16) + { + as_bad("@Rn+ needs src word register"); + } + op->mode = RSINC; + op->reg = num; + *ptr = src; + return; + } + if (mode != r16_sord[dst]) + { + as_bad("@Rn needs word register"); + } + op->mode =rind_sord[dst]; + op->reg = num; + *ptr = src; + return; + } + else + { + /* must be a symbol */ + op->mode = abs_sord[dst]; + *ptr = skip_colonthing(parse_exp(src, &op->exp)); + + return; + } + } + + + if (*src == '#') { + src++; + op->mode = IMM16; + src = parse_exp(src, &op->exp); + *ptr= skip_colonthing(src); + + return; } - if (mode != r16_sord[dst]) - { - as_bad("@Rn needs word register"); + else { + *ptr = parse_exp(src, &op->exp); + op->mode = DISP8; } - op->mode =rind_sord[dst]; - op->reg = num; - *ptr = src; - return; - } - else - { - /* must be a symbol */ - op->mode = abs_sord[dst]; - *ptr = skip_colonthing(parse_exp(src, &op->exp)); - - return; - } - } - - - if (*src == '#') { - src++; - op->mode = IMM16; - src = parse_exp(src, &op->exp); - *ptr= skip_colonthing(src); - - return; - } - else { - *ptr = parse_exp(src, &op->exp); - op->mode = DISP8; - } } static -char * -DEFUN(get_operands,(noperands,op_end, operand), - unsigned int noperands AND - char *op_end AND - struct h8_op *operand) + char * + DEFUN(get_operands,(noperands,op_end, operand), + unsigned int noperands AND + char *op_end AND + struct h8_op *operand) { - char *ptr = op_end; - switch (noperands) - { - case 0: - operand[0].mode = 0; - operand[1].mode = 0; - break; - - case 1: - ptr++; - get_operand(& ptr, operand +0,0); - operand[1].mode =0; - break; - - case 2: - ptr++; - get_operand(& ptr, operand +0,0); - if (*ptr == ',') ptr++; - get_operand(& ptr, operand +1, 1); - break; - - default: - abort(); - } - - - return ptr; + char *ptr = op_end; + switch (noperands) + { + case 0: + operand[0].mode = 0; + operand[1].mode = 0; + break; + + case 1: + ptr++; + get_operand(& ptr, operand +0,0); + operand[1].mode =0; + break; + + case 2: + ptr++; + get_operand(& ptr, operand +0,0); + if (*ptr == ',') ptr++; + get_operand(& ptr, operand +1, 1); + break; + + default: + abort(); + } + + + return ptr; } /* Passed a pointer to a list of opcodes which use different addressing modes, return the opcode which matches the opcodes provided - */ + */ static -struct h8_opcode * -DEFUN(get_specific,(opcode, operands), - struct h8_opcode *opcode AND - struct h8_op *operands) + struct h8_opcode * + DEFUN(get_specific,(opcode, operands), + struct h8_opcode *opcode AND + struct h8_op *operands) { - struct h8_opcode *this_try = opcode ; - int found = 0; - unsigned int noperands = opcode->noperands; - - unsigned int dispreg; - unsigned int this_index = opcode->idx; - while (this_index == opcode->idx && !found) - { - unsigned int i; - - this_try = opcode ++; - for (i = 0; i < noperands; i++) - { - op_type op = (this_try->args.nib[i]) & ~(B30|B31); - switch (op) - { - case Hex0: - case Hex1: - case Hex2: - case Hex3: - case Hex4: - case Hex5: - case Hex6: - case Hex7: - case Hex8: - case Hex9: - case HexA: - case HexB: - case HexC: - case HexD: - case HexE: - case HexF: - break; - case DISPSRC: - case DISPDST: - operands[0].dispreg = operands[i].reg; - case RD8: - case RS8: - case RDIND: - case RSIND: - case RD16: - case RS16: - case CCR: - case RSINC: - case RDDEC: - if (operands[i].mode != op) goto fail; - break; - case KBIT: - case IMM16: - case IMM3: - case IMM8: - if (operands[i].mode != IMM16) goto fail; - break; - case MEMIND: - if (operands[i].mode != MEMIND) goto fail; - break; - case ABS16SRC: - case ABS8SRC: - case ABS16OR8SRC: - case ABS16ORREL8SRC: - - if (operands[i].mode != ABS16SRC) goto fail; - break; - case ABS16OR8DST: - case ABS16DST: - case ABS8DST: - if (operands[i].mode != ABS16DST) goto fail; - break; - } - } - found =1; - fail: ; - } - if (found) - return this_try; - else - return 0; + struct h8_opcode *this_try = opcode ; + int found = 0; + unsigned int noperands = opcode->noperands; + + unsigned int dispreg; + unsigned int this_index = opcode->idx; + while (this_index == opcode->idx && !found) + { + unsigned int i; + + this_try = opcode ++; + for (i = 0; i < noperands; i++) + { + op_type op = (this_try->args.nib[i]) & ~(B30|B31); + switch (op) + { + case Hex0: + case Hex1: + case Hex2: + case Hex3: + case Hex4: + case Hex5: + case Hex6: + case Hex7: + case Hex8: + case Hex9: + case HexA: + case HexB: + case HexC: + case HexD: + case HexE: + case HexF: + break; + case DISPSRC: + case DISPDST: + operands[0].dispreg = operands[i].reg; + case RD8: + case RS8: + case RDIND: + case RSIND: + case RD16: + case RS16: + case CCR: + case RSINC: + case RDDEC: + if (operands[i].mode != op) goto fail; + break; + case KBIT: + case IMM16: + case IMM3: + case IMM8: + if (operands[i].mode != IMM16) goto fail; + break; + case MEMIND: + if (operands[i].mode != MEMIND) goto fail; + break; + case ABS16SRC: + case ABS8SRC: + case ABS16OR8SRC: + case ABS16ORREL8SRC: + + if (operands[i].mode != ABS16SRC) goto fail; + break; + case ABS16OR8DST: + case ABS16DST: + case ABS8DST: + if (operands[i].mode != ABS16DST) goto fail; + break; + } + } + found =1; + fail: ; + } + if (found) + return this_try; + else + return 0; } static void -DEFUN(check_operand,(operand, width, string), - struct h8_op *operand AND - unsigned int width AND - char *string) + DEFUN(check_operand,(operand, width, string), + struct h8_op *operand AND + unsigned int width AND + char *string) { - if (operand->exp.X_add_symbol == 0 - && operand->exp.X_subtract_symbol == 0) - { - - /* No symbol involved, let's look at offset, it's dangerous if any of - the high bits are not 0 or ff's, find out by oring or anding with - the width and seeing if the answer is 0 or all fs*/ - if ((operand->exp.X_add_number | width) != ~0 && - (operand->exp.X_add_number & ~width)!= 0) - { - as_warn("operand %s0x%x out of range.", string, operand->exp.X_add_number); - } - } - + if (operand->exp.X_add_symbol == 0 + && operand->exp.X_subtract_symbol == 0) + { + + /* No symbol involved, let's look at offset, it's dangerous if any of + the high bits are not 0 or ff's, find out by oring or anding with + the width and seeing if the answer is 0 or all fs*/ + if ((operand->exp.X_add_number | width) != ~0 && + (operand->exp.X_add_number & ~width)!= 0) + { + as_warn("operand %s0x%x out of range.", string, operand->exp.X_add_number); + } + } + } /* Now we know what sort of opcodes it is, lets build the bytes - - */ + */ static void -DEFUN (build_bytes,(this_try, operand), - struct h8_opcode *this_try AND - struct h8_op *operand) + DEFUN (build_bytes,(this_try, operand), + struct h8_opcode *this_try AND + struct h8_op *operand) { - unsigned int i; - - char *output = frag_more(this_try->length); - char *output_ptr = output; - op_type *nibble_ptr = this_try->data.nib; - char part; - op_type c; - char high; - int nib; + unsigned int i; + + char *output = frag_more(this_try->length); + char *output_ptr = output; + op_type *nibble_ptr = this_try->data.nib; + char part; + op_type c; + char high; + int nib; top: ; - while (*nibble_ptr != E) - { - int nibble; - for (nibble = 0; nibble <2; nibble++) - { - c = *nibble_ptr & ~(B30|B31); - switch (c) - { - default: - abort(); - case KBIT: - switch (operand[0].exp.X_add_number) - { - case 1: - nib = 0; - break; - case 2: - nib = 8; - break; - default: - as_bad("Need #1 or #2 here"); - break; - } - /* stop it making a fix */ - operand[0].mode = 0; - break; - case 0: - case 1: - case 2: case 3: case 4: case 5: case 6: - case 7: case 8: case 9: case 10: case 11: - case 12: case 13: case 14: case 15: - nib = c; - break; - case DISPREG: - nib = operand[0].dispreg; - break; - case IMM8: - operand[0].mode = IMM8; - nib = 0; - break; - - case DISPDST: - nib = 0; - break; - case IMM3: - if (operand[0].exp.X_add_symbol == 0) { - operand[0].mode = 0; /* stop it making a fix */ - nib = (operand[0].exp.X_add_number); - } - else as_bad("can't have symbol for bit number"); - if (nib < 0 || nib > 7) - { - as_bad("Bit number out of range %d", nib); - } - - break; - - case ABS16DST: - nib = 0; - break; - case ABS8DST: - operand[1].mode = ABS8DST; - nib = 0; - break; - case ABS8SRC: - operand[0].mode = ABS8SRC; - nib = 0; - break; - case ABS16OR8DST: - operand[1].mode = c; - - nib = 0; - - break; - - case ABS16ORREL8SRC: - operand[0].mode = c; - nib=0; - break; - - case ABS16OR8SRC: - operand[0].mode = ABS16OR8SRC; - nib = 0; - break; - case DISPSRC: - operand[0].mode = ABS16SRC; - nib = 0; - break; - - case DISP8: - operand[0].mode = DISP8; - nib = 0; - break; + while (*nibble_ptr != E) + { + int nibble; + for (nibble = 0; nibble <2; nibble++) + { + c = *nibble_ptr & ~(B30|B31); + switch (c) + { + default: + abort(); + case KBIT: + switch (operand[0].exp.X_add_number) + { + case 1: + nib = 0; + break; + case 2: + nib = 8; + break; + default: + as_bad("Need #1 or #2 here"); + break; + } + /* stop it making a fix */ + operand[0].mode = 0; + break; + case 0: + case 1: + case 2: case 3: case 4: case 5: case 6: + case 7: case 8: case 9: case 10: case 11: + case 12: case 13: case 14: case 15: + nib = c; + break; + case DISPREG: + nib = operand[0].dispreg; + break; + case IMM8: + operand[0].mode = IMM8; + nib = 0; + break; + + case DISPDST: + nib = 0; + break; + case IMM3: + if (operand[0].exp.X_add_symbol == 0) { + operand[0].mode = 0; /* stop it making a fix */ + nib = (operand[0].exp.X_add_number); + } + else as_bad("can't have symbol for bit number"); + if (nib < 0 || nib > 7) + { + as_bad("Bit number out of range %d", nib); + } + + break; + + case ABS16DST: + nib = 0; + break; + case ABS8DST: + operand[1].mode = ABS8DST; + nib = 0; + break; + case ABS8SRC: + operand[0].mode = ABS8SRC; + nib = 0; + break; + case ABS16OR8DST: + operand[1].mode = c; + + nib = 0; + + break; + + case ABS16ORREL8SRC: + operand[0].mode = c; + nib=0; + break; + + case ABS16OR8SRC: + operand[0].mode = ABS16OR8SRC; + nib = 0; + break; + case DISPSRC: + operand[0].mode = ABS16SRC; + nib = 0; + break; + + case DISP8: + operand[0].mode = DISP8; + nib = 0; + break; + + case ABS16SRC: + case IMM16: + case IGNORE: + case MEMIND: + + nib=0; + break; + case RS8: + case RS16: + case RSIND: + case RSINC: + nib = operand[0].reg; + break; + + case RD8: + case RD16: + case RDDEC: + case RDIND: + nib = operand[1].reg; + break; + + case E: + abort(); + break; + } + if (*nibble_ptr & B31) { + nib |=0x8; + } + + if (nibble == 0) { + *output_ptr = nib << 4; + } + else { + *output_ptr |= nib; + output_ptr++; + } + nibble_ptr++; + } + + } - case ABS16SRC: - case IMM16: - case IGNORE: - case MEMIND: - - nib=0; - break; - case RS8: - case RS16: - case RSIND: - case RSINC: - nib = operand[0].reg; - break; - - case RD8: - case RD16: - case RDDEC: - case RDIND: - nib = operand[1].reg; - break; - - case E: - abort(); - break; - } - if (*nibble_ptr & B31) { - nib |=0x8; - } - - if (nibble == 0) { - *output_ptr = nib << 4; - } - else { - *output_ptr |= nib; - output_ptr++; - } - nibble_ptr++; - } - - } - - /* output any fixes */ - for (i = 0; i < 2; i++) - { - switch (operand[i].mode) { - case 0: - break; - - case DISP8: - check_operand(operand+i, 0x7f,"@"); - - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number -1, - 1, - R_PCRBYTE); - break; - case IMM8: - check_operand(operand+i, 0xff,"#"); - /* If there is nothing else going on we can safely - reloc in place */ - if (operand[i].exp.X_add_symbol == 0) - { - output[1] = operand[i].exp.X_add_number; - } - else - { - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELBYTE); - } - - break; - case MEMIND: - check_operand(operand+i, 0xff,"@@"); - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELBYTE); - break; - case ABS8DST: - case ABS8SRC: - check_operand(operand+i, 0xff,"@"); - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELBYTE); - break; - - case ABS16OR8SRC: - case ABS16OR8DST: - check_operand(operand+i, 0xffff,"@"); - - fix_new(frag_now, - output - frag_now->fr_literal + 2, - 2, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_MOVB1); - break; - - case ABS16ORREL8SRC: - check_operand(operand+i, 0xffff,"@"); - - fix_new(frag_now, - output - frag_now->fr_literal + 2, - 2, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_JMP1); - break; - - - case ABS16SRC: - case ABS16DST: - case IMM16: - case DISPSRC: - case DISPDST: - check_operand(operand+i, 0xffff,"@"); - if (operand[i].exp.X_add_symbol == 0) - { - /* This should be done with bfd */ - output[3] = operand[i].exp.X_add_number & 0xff; - output[2] = operand[i].exp.X_add_number >> 8; - - } - else - { - - fix_new(frag_now, - output - frag_now->fr_literal + 2, - 2, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELWORD); - } + /* output any fixes */ + for (i = 0; i < 2; i++) + { + switch (operand[i].mode) { + case 0: + break; + + case DISP8: + check_operand(operand+i, 0x7f,"@"); + + fix_new(frag_now, + output - frag_now->fr_literal + 1, + 1, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number -1, + 1, + R_PCRBYTE); + break; + case IMM8: + check_operand(operand+i, 0xff,"#"); + /* If there is nothing else going on we can safely + reloc in place */ + if (operand[i].exp.X_add_symbol == 0) + { + output[1] = operand[i].exp.X_add_number; + } + else + { + fix_new(frag_now, + output - frag_now->fr_literal + 1, + 1, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + R_RELBYTE); + } + + break; + case MEMIND: + check_operand(operand+i, 0xff,"@@"); + fix_new(frag_now, + output - frag_now->fr_literal + 1, + 1, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + R_RELBYTE); + break; + case ABS8DST: + case ABS8SRC: + check_operand(operand+i, 0xff,"@"); + fix_new(frag_now, + output - frag_now->fr_literal + 1, + 1, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + R_RELBYTE); + break; + + case ABS16OR8SRC: + case ABS16OR8DST: + check_operand(operand+i, 0xffff,"@"); + + fix_new(frag_now, + output - frag_now->fr_literal + 2, + 2, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + R_MOVB1); + break; + + case ABS16ORREL8SRC: + check_operand(operand+i, 0xffff,"@"); + + fix_new(frag_now, + output - frag_now->fr_literal + 2, + 2, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + R_JMP1); + break; + + + case ABS16SRC: + case ABS16DST: + case IMM16: + case DISPSRC: + case DISPDST: + check_operand(operand+i, 0xffff,"@"); + if (operand[i].exp.X_add_symbol == 0) + { + /* This should be done with bfd */ + output[3] = operand[i].exp.X_add_number & 0xff; + output[2] = operand[i].exp.X_add_number >> 8; + + } + else + { + + fix_new(frag_now, + output - frag_now->fr_literal + 2, + 2, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + R_RELWORD); + } + + break; + case RS8: + case RD8: + case RS16: + case RD16: + case RDDEC: + case KBIT: + case RSINC: + case RDIND: + case RSIND: + case CCR: + + break; + default: + abort(); + } + } - break; - case RS8: - case RD8: - case RS16: - case RD16: - case RDDEC: - case KBIT: - case RSINC: - case RDIND: - case RSIND: - case CCR: - - break; - default: - abort(); - } - } +} +/* + try and give an intelligent error message for common and simple to + detect errors + */ +static void + DEFUN(clever_message, (opcode, operand), + struct h8_opcode *opcode AND + struct h8_op *operand) +{ + struct h8_opcode *scan = opcode; + + /* Find out if there was more than one possible opccode */ + + if ((opcode+1)->idx != opcode->idx) + { + unsigned int argn; + + /* Only one opcode of this flavour, try and guess which operand + didn't match */ + for (argn = 0; argn < opcode->noperands; argn++) + { + switch (opcode->args.nib[argn]) + { + case RD16: + if (operand[argn].mode != RD16) + { + as_bad("destination operand must be 16 bit register"); + } + return; + case RS8: + + if (operand[argn].mode != RS8) + { + as_bad("source operand must be 8 bit register"); + } + return; + case ABS16DST: + if (operand[argn].mode != ABS16DST) + { + as_bad("destination operand must be 16bit absolute address"); + return; + } + + case RD8: + if (operand[argn].mode != RD8) + { + as_bad("destination operand must be 8 bit register"); + } + return; + + case ABS16SRC: + if (operand[argn].mode != ABS16SRC) + { + as_bad("source operand must be 16bit absolute address"); + return; + } + } + } + } + as_bad("invalid operands"); } + /* This is the guts of the machine-dependent assembler. STR points to a machine dependent instruction. This funciton is supposed to emit the frags/bytes it assembles to. - */ - - -void -DEFUN(md_assemble,(str), - char *str) -{ - char *op_start; - char *op_end; - unsigned int i; - struct h8_op operand[2]; - struct h8_opcode * opcode; - char *dot = 0; - char c; - /* Drop leading whitespace */ - while (*str == ' ') - str++; - - /* find the op code end */ - for (op_start = op_end = str; - *op_end != 0 && *op_end != ' '; - op_end ++) - { - if (*op_end == '.') { - dot = op_end+1; - *op_end = 0; - op_end+=2; - break; - } - } - - ; - - if (op_end == op_start) - { - as_bad("can't find opcode "); - } - c = *op_end; - - *op_end = 0; - - opcode = (struct h8_opcode *) hash_find(opcode_hash_control, - op_start); - - if (opcode == NULL) - { - as_bad("unknown opcode"); - return; - } - - - input_line_pointer = get_operands(opcode->noperands, op_end, - operand); - *op_end = c; - opcode = get_specific(opcode, operand); - - if (opcode == 0) - { - /* Allocate 2 bytes for the insn anyway */ - char *where =frag_more(2); - where[0] = 0xde; - where[1] = 0xad; - - - as_bad("illegal operands for opcode"); - return; - } - if (opcode->size && dot) - { - if (opcode->size != *dot) - { - as_warn("mismatch between opcode size and operand size"); - } - } - - build_bytes(opcode, operand); - -} + */ -void -DEFUN(tc_crawl_symbol_chain, (headers), -object_headers *headers) -{ - printf("call to tc_crawl_symbol_chain \n"); -} -symbolS *DEFUN(md_undefined_symbol,(name), - char *name) -{ -return 0; -} void -DEFUN(tc_headers_hook,(headers), - object_headers *headers) -{ - printf("call to tc_headers_hook \n"); -} -void -DEFUN_VOID(md_end) -{ -} - -/* Various routines to kill one day */ -/* Equal to MAX_PRECISION in atof-ieee.c */ -#define MAX_LITTLENUMS 6 - -/* Turn a string in input_line_pointer into a floating point constant of type - type, and store the appropriate bytes in *litP. The number of LITTLENUMS - emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ -char * -md_atof(type,litP,sizeP) -char type; -char *litP; -int *sizeP; -{ - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee(); - - switch(type) { - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words;prec--;) { - md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ -} - -int -md_parse_option(argP, cntP, vecP) - char **argP; - int *cntP; - char ***vecP; - - { - return 0; - - } - -int md_short_jump_size; - -void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n"); - abort(); } -void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) -char *ptr; -long from_addr; -long to_addr; -fragS *frag; -symbolS *to_symbol; -{ - as_fatal("failed sanity check."); - } - -void -md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) - char *ptr; - long from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; -{ - as_fatal("failed sanity check."); -} - -void -md_convert_frag(headers, fragP) -object_headers *headers; - fragS * fragP; - - { printf("call to md_convert_frag \n"); abort(); } - -long -DEFUN(md_section_align,(seg, size), - segT seg AND - long size) -{ - return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg])); - -} - -void -md_apply_fix(fixP, val) - fixS *fixP; - long val; -{ - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - - switch(fixP->fx_size) { - case 1: - *buf++=val; - break; - case 2: - *buf++=(val>>8); - *buf++=val; - break; - case 4: - *buf++=(val>>24); - *buf++=(val>>16); - *buf++=(val>>8); - *buf++=val; - break; - default: - abort(); - - } -} - -void DEFUN(md_operand, (expressionP),expressionS *expressionP) -{ } - -int md_long_jump_size; -int -md_estimate_size_before_relax(fragP, segment_type) - register fragS *fragP; - register segT segment_type; -{ -printf("call tomd_estimate_size_before_relax \n"); abort(); } -/* Put number into target byte order */ - -void DEFUN(md_number_to_chars,(ptr, use, nbytes), - char *ptr AND - long use AND - int nbytes) -{ - switch (nbytes) { - case 4: *ptr++ = (use >> 24) & 0xff; - case 3: *ptr++ = (use >> 16) & 0xff; - case 2: *ptr++ = (use >> 8) & 0xff; - case 1: *ptr++ = (use >> 0) & 0xff; - break; - default: - abort(); - } -} -long md_pcrel_from(fixP) -fixS *fixP; { abort(); } - -void tc_coff_symbol_emit_hook() { } - - -void tc_reloc_mangle(fix_ptr, intr, base) -fixS *fix_ptr; -struct internal_reloc *intr; -bfd_vma base; - + DEFUN(md_assemble,(str), + char *str) { - symbolS *symbol_ptr; + char *op_start; + char *op_end; + unsigned int i; + struct h8_op operand[2]; + struct h8_opcode * opcode; + struct h8_opcode * prev_opcode; - symbol_ptr = fix_ptr->fx_addsy; - - /* If this relocation is attached to a symbol then it's ok - to output it */ - if (fix_ptr->fx_r_type == RELOC_32) { - /* cons likes to create reloc32's whatever the size of the reloc.. - */ - switch (fix_ptr->fx_size) - { - - case 2: - intr->r_type = R_RELWORD; - break; - case 1: - intr->r_type = R_RELBYTE; - break; - default: - abort(); - - } - - } - else { - intr->r_type = fix_ptr->fx_r_type; - } - - intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where +base; - intr->r_offset = fix_ptr->fx_offset; - - if (symbol_ptr) - intr->r_symndx = symbol_ptr->sy_number; - else - intr->r_symndx = -1; + char *dot = 0; + char c; + /* Drop leading whitespace */ + while (*str == ' ') + str++; - -} -/* tc-h8300.c -- Assemble code for the Hitachi h8/300 - Copyright (C) 1991 Free Software Foundation. - -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. */ - - -/* - Written By Steve Chamberlain - sac@cygnus.com - */ - -#include <stdio.h> -#include "as.h" -#include "bfd.h" -#include "opcode/h8300.h" -#include <ctype.h> -#include "listing.h" - -char comment_chars[] = { ';',0 }; -char line_separator_chars[] = { '$' ,0}; - -/* This table describes all the machine specific pseudo-ops the assembler - has to support. The fields are: - pseudo-op name without dot - function to call to execute this pseudo-op - Integer arg to pass to the function - */ - -void cons(); - -const pseudo_typeS md_pseudo_table[] = { - { "int", cons, 2 }, - { 0,0,0 } -}; - -int md_reloc_size ; - -const char EXP_CHARS[] = "eE"; - -/* Chars that mean this number is a floating point constant */ -/* As in 0f12.456 */ -/* or 0d1.2345e12 */ - char FLT_CHARS[] = "rRsSfFdDxXpP"; - - -const relax_typeS md_relax_table[1]; - - -static struct hash_control *opcode_hash_control; /* Opcode mnemonics */ - - -/* - This function is called once, at assembler startup time. This should - set up all the tables, etc that the MD part of the assembler needs -*/ - -/* encode the size and number into the number field - xxnnnn - 00 8 bit - 01 16 bit - 10 ccr - nnnnreg number -*/ -#define WORD_REG 0x10 -#define BYTE_REG 0x00 -#define CCR_REG 0x20 - struct reg_entry -{ - char *name; - char number; -}; - -struct reg_entry reg_list[] = { -"r0",WORD_REG +0, -"r1",WORD_REG +1, -"r2",WORD_REG +2, -"r3",WORD_REG +3, -"r4",WORD_REG +4, -"r5",WORD_REG +5, -"r6",WORD_REG +6, -"r7",WORD_REG +7, -"fp",WORD_REG +6, -"sp",WORD_REG +7, -"r0h",BYTE_REG + 0, -"r0l",BYTE_REG + 1, -"r1h",BYTE_REG + 2, -"r1l",BYTE_REG + 3, -"r2h",BYTE_REG + 4, -"r2l",BYTE_REG + 5, -"r3h",BYTE_REG + 6, -"r3l",BYTE_REG + 7, -"r4h",BYTE_REG + 8, -"r4l",BYTE_REG + 9, -"r5h",BYTE_REG + 10, -"r5l",BYTE_REG + 11, -"r6h",BYTE_REG + 12, -"r6l",BYTE_REG + 13, -"r7h",BYTE_REG + 14, -"r7l",BYTE_REG + 15, -"ccr",CCR_REG, -0,0 -} -; - - - - - -void md_begin () -{ - struct h8_opcode *opcode; - const struct reg_entry *reg; - char prev_buffer[100]; - int idx = 0; - - opcode_hash_control = hash_new(); - prev_buffer[0] = 0; - - for (opcode = h8_opcodes; opcode->name; opcode++) - { - /* Strip off any . part when inserting the opcode and only enter - unique codes into the hash table - */ - char *src= opcode->name; - unsigned int len = strlen(src); - char *dst = malloc(len+1); - char *buffer = dst; - opcode->size = 0; - while (*src) { - if (*src == '.') { - *dst++ = 0; - src++; - opcode->size = *src; - break; - } - *dst++ = *src++; - } - if (strcmp(buffer, prev_buffer)) - { - hash_insert(opcode_hash_control, buffer, (char *)opcode); - strcpy(prev_buffer, buffer); - idx++; - } - opcode->idx = idx; - - - /* Find the number of operands */ - opcode->noperands = 0; - while (opcode->args.nib[opcode->noperands] != E) - opcode->noperands ++; - /* Find the length of the opcode in bytes */ - opcode->length =0; - while (opcode->data.nib[opcode->length*2] != E) - opcode->length++; - } - -} - - -struct h8_exp { - char *e_beg; - char *e_end; - expressionS e_exp; -}; -struct h8_op -{ - unsigned int dispreg; - op_type mode; - unsigned reg; - expressionS exp; -}; - - - -/* - parse operands - WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp - r0l,r0h,..r7l,r7h - @WREG - @WREG+ - @-WREG - #const - -*/ - -op_type r8_sord[] = {RS8, RD8}; -op_type r16_sord[] = {RS16, RD16}; -op_type rind_sord[] = {RSIND, RDIND}; -op_type abs_sord[2] = {ABS16SRC, ABS16DST}; -op_type disp_sord[] = {DISPSRC, DISPDST}; - -/* try and parse a reg name, returns number of chars consumed */ -int -DEFUN(parse_reg,(src, mode, reg, dst), - char *src AND - op_type *mode AND - unsigned int *reg AND - int dst) -{ - if (src[0] == 's' && src[1] == 'p') - { - *mode = r16_sord[dst]; - *reg = 7; - return 2; - } - if (src[0] == 'c' && src[1] == 'c' && src[2] == 'r') - { - *mode = CCR; - *reg = 0; - return 3; - } - if (src[0] == 'f' && src[1] == 'p') - { - *mode = r16_sord[dst]; - *reg = 6; - return 2; - } - if (src[0] == 'r') - { - if (src[1] >= '0' && src[1] <= '7') - { - if(src[2] == 'l') + /* find the op code end */ + for (op_start = op_end = str; + *op_end != 0 && *op_end != ' '; + op_end ++) { - *mode = r8_sord[dst]; - *reg = (src[1] - '0') + 8; - return 3; + if (*op_end == '.') { + dot = op_end+1; + *op_end = 0; + op_end+=2; + break; + } } - if(src[2] == 'h') + + ; + + if (op_end == op_start) { - *mode = r8_sord[dst]; - *reg = (src[1] - '0') ; - return 3; + as_bad("can't find opcode "); } - *mode = r16_sord[dst]; - *reg = (src[1] - '0'); - return 2; - } - } - return 0; -} - -char * -DEFUN(parse_exp,(s, op), - char *s AND - expressionS *op) -{ - char *save = input_line_pointer; - char *new; - segT seg; - input_line_pointer = s; - seg = expr(0,op); - new = input_line_pointer; - input_line_pointer = save; - if (SEG_NORMAL(seg)) - return new; - switch (seg) { - case SEG_ABSOLUTE: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_REGISTER: - return new; - case SEG_ABSENT: - as_bad("Missing operand"); - return new; - default: - as_bad("Don't understand operand of type %s", segment_name (seg)); - return new; - } -} - -static char * -DEFUN(skip_colonthing,(ptr), - char *ptr) -{ - if (*ptr == ':') { - ptr++; - while (isdigit(*ptr)) - ptr++; + c = *op_end; - } - return ptr; -} - -/* The many forms of operand: - - Rn Register direct - @Rn Register indirect - @(exp[:16], Rn) Register indirect with displacement - @Rn+ - @-Rn - @aa:8 absolute 8 bit - @aa:16 absolute 16 bit - @aa absolute 16 bit - - #xx[:size] immediate data - @(exp:[8], pc) pc rel - @@aa[:8] memory indirect - -*/ - -static void -DEFUN(get_operand,(ptr, op, dst), - char **ptr AND - struct h8_op *op AND - unsigned int dst) -{ - char *src = *ptr; - op_type mode; - unsigned int num; - unsigned int len; - unsigned int size; - op->mode = E; - - len = parse_reg(src, &op->mode, &op->reg, dst); - if (len) { - *ptr = src + len; - return ; - } - - if (*src == '@') - { - src++; - if (*src == '@') - { - src++; - src = parse_exp(src,&op->exp); - src = skip_colonthing(src); - - *ptr = src; - - op->mode = MEMIND; - return; - - } + *op_end = 0; - - if (*src == '-') - { - src++; - len = parse_reg(src, &mode, &num, dst); - if (len == 0 || mode != r16_sord[dst]) - { - as_bad("@- needs word register"); - } - op->mode = RDDEC; - op->reg = num; - *ptr = src + len; - return; - } - if (*src == '(' && ')') - { - /* Disp */ - src++; - src = parse_exp(src, &op->exp); - - if (*src == ')') - { - src++; - op->mode = abs_sord[dst]; - *ptr = src; - return; - } - src = skip_colonthing(src); - - if (*src != ',') - { - as_bad("expected @(exp, reg16)"); - } - src++; - len = parse_reg(src, &mode, &op->reg, dst); - if (len == 0 || mode != r16_sord[dst]) - { - as_bad("expected @(exp, reg16)"); - } - op->mode = disp_sord[dst]; - src += len; - src = skip_colonthing(src); - - if (*src != ')' && '(') - { - as_bad("expected @(exp, reg16)"); - - } - *ptr = src +1; - - return; - } - len = parse_reg(src, &mode, &num, dst); - - if(len) { - src += len; - if (*src == '+') - { - src++; - if (mode != RS16) - { - as_bad("@Rn+ needs src word register"); - } - op->mode = RSINC; - op->reg = num; - *ptr = src; - return; - } - if (mode != r16_sord[dst]) - { - as_bad("@Rn needs word register"); - } - op->mode =rind_sord[dst]; - op->reg = num; - *ptr = src; - return; - } - else - { - /* must be a symbol */ - op->mode = abs_sord[dst]; - *ptr = skip_colonthing(parse_exp(src, &op->exp)); - - return; - } - } - - - if (*src == '#') { - src++; - op->mode = IMM16; - src = parse_exp(src, &op->exp); - *ptr= skip_colonthing(src); - - return; - } - else { - *ptr = parse_exp(src, &op->exp); - op->mode = DISP8; - } -} - - -static -char * -DEFUN(get_operands,(noperands,op_end, operand), - unsigned int noperands AND - char *op_end AND - struct h8_op *operand) -{ - char *ptr = op_end; - switch (noperands) - { - case 0: - operand[0].mode = 0; - operand[1].mode = 0; - break; - - case 1: - ptr++; - get_operand(& ptr, operand +0,0); - operand[1].mode =0; - break; - - case 2: - ptr++; - get_operand(& ptr, operand +0,0); - if (*ptr == ',') ptr++; - get_operand(& ptr, operand +1, 1); - break; - - default: - abort(); - } - - - return ptr; -} - -/* Passed a pointer to a list of opcodes which use different - addressing modes, return the opcode which matches the opcodes - provided - */ -static -struct h8_opcode * -DEFUN(get_specific,(opcode, operands), - struct h8_opcode *opcode AND - struct h8_op *operands) - -{ - struct h8_opcode *this_try = opcode ; - int found = 0; - unsigned int noperands = opcode->noperands; - - unsigned int dispreg; - unsigned int this_index = opcode->idx; - while (this_index == opcode->idx && !found) - { - unsigned int i; - - this_try = opcode ++; - for (i = 0; i < noperands; i++) - { - op_type op = (this_try->args.nib[i]) & ~(B30|B31); - switch (op) - { - case Hex0: - case Hex1: - case Hex2: - case Hex3: - case Hex4: - case Hex5: - case Hex6: - case Hex7: - case Hex8: - case Hex9: - case HexA: - case HexB: - case HexC: - case HexD: - case HexE: - case HexF: - break; - case DISPSRC: - case DISPDST: - operands[0].dispreg = operands[i].reg; - case RD8: - case RS8: - case RDIND: - case RSIND: - case RD16: - case RS16: - case CCR: - case RSINC: - case RDDEC: - if (operands[i].mode != op) goto fail; - break; - case KBIT: - case IMM16: - case IMM3: - case IMM8: - if (operands[i].mode != IMM16) goto fail; - break; - case MEMIND: - if (operands[i].mode != MEMIND) goto fail; - break; - case ABS16SRC: - case ABS8SRC: - case ABS16OR8SRC: - case ABS16ORREL8SRC: - - if (operands[i].mode != ABS16SRC) goto fail; - break; - case ABS16OR8DST: - case ABS16DST: - case ABS8DST: - if (operands[i].mode != ABS16DST) goto fail; - break; - } - } - found =1; - fail: ; - } - if (found) - return this_try; - else - return 0; -} - -static void -DEFUN(check_operand,(operand, width, string), - struct h8_op *operand AND - unsigned int width AND - char *string) -{ - if (operand->exp.X_add_symbol == 0 - && operand->exp.X_subtract_symbol == 0) - { - - /* No symbol involved, let's look at offset, it's dangerous if any of - the high bits are not 0 or ff's, find out by oring or anding with - the width and seeing if the answer is 0 or all fs*/ - if ((operand->exp.X_add_number | width) != ~0 && - (operand->exp.X_add_number & ~width)!= 0) - { - as_warn("operand %s0x%x out of range.", string, operand->exp.X_add_number); - } - } - -} - -/* Now we know what sort of opcodes it is, lets build the bytes - - */ -static void -DEFUN (build_bytes,(this_try, operand), - struct h8_opcode *this_try AND - struct h8_op *operand) - -{ - unsigned int i; - - char *output = frag_more(this_try->length); - char *output_ptr = output; - op_type *nibble_ptr = this_try->data.nib; - char part; - op_type c; - char high; - int nib; - top: ; - while (*nibble_ptr != E) - { - int nibble; - for (nibble = 0; nibble <2; nibble++) - { - c = *nibble_ptr & ~(B30|B31); - switch (c) - { - default: - abort(); - case KBIT: - switch (operand[0].exp.X_add_number) - { - case 1: - nib = 0; - break; - case 2: - nib = 8; - break; - default: - as_bad("Need #1 or #2 here"); - break; - } - /* stop it making a fix */ - operand[0].mode = 0; - break; - case 0: - case 1: - case 2: case 3: case 4: case 5: case 6: - case 7: case 8: case 9: case 10: case 11: - case 12: case 13: case 14: case 15: - nib = c; - break; - case DISPREG: - nib = operand[0].dispreg; - break; - case IMM8: - operand[0].mode = IMM8; - nib = 0; - break; - - case DISPDST: - nib = 0; - break; - case IMM3: - if (operand[0].exp.X_add_symbol == 0) { - operand[0].mode = 0; /* stop it making a fix */ - nib = (operand[0].exp.X_add_number); - } - else as_bad("can't have symbol for bit number"); - if (nib < 0 || nib > 7) - { - as_bad("Bit number out of range %d", nib); - } - - break; - - case ABS16DST: - nib = 0; - break; - case ABS8DST: - operand[1].mode = ABS8DST; - nib = 0; - break; - case ABS8SRC: - operand[0].mode = ABS8SRC; - nib = 0; - break; - case ABS16OR8DST: - operand[1].mode = c; - - nib = 0; - - break; - - case ABS16ORREL8SRC: - operand[0].mode = c; - nib=0; - break; - - case ABS16OR8SRC: - operand[0].mode = ABS16OR8SRC; - nib = 0; - break; - case DISPSRC: - operand[0].mode = ABS16SRC; - nib = 0; - break; - - case DISP8: - operand[0].mode = DISP8; - nib = 0; - break; + opcode = (struct h8_opcode *) hash_find(opcode_hash_control, + op_start); - case ABS16SRC: - case IMM16: - case IGNORE: - case MEMIND: - - nib=0; - break; - case RS8: - case RS16: - case RSIND: - case RSINC: - nib = operand[0].reg; - break; - - case RD8: - case RD16: - case RDDEC: - case RDIND: - nib = operand[1].reg; - break; - - case E: - abort(); - break; - } - if (*nibble_ptr & B31) { - nib |=0x8; - } - - if (nibble == 0) { - *output_ptr = nib << 4; - } - else { - *output_ptr |= nib; - output_ptr++; - } - nibble_ptr++; - } - - } - - /* output any fixes */ - for (i = 0; i < 2; i++) - { - switch (operand[i].mode) { - case 0: - break; - - case DISP8: - check_operand(operand+i, 0x7f,"@"); - - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number -1, - 1, - R_PCRBYTE); - break; - case IMM8: - check_operand(operand+i, 0xff,"#"); - /* If there is nothing else going on we can safely - reloc in place */ - if (operand[i].exp.X_add_symbol == 0) - { - output[1] = operand[i].exp.X_add_number; - } - else - { - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELBYTE); - } - - break; - case MEMIND: - check_operand(operand+i, 0xff,"@@"); - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELBYTE); - break; - case ABS8DST: - case ABS8SRC: - check_operand(operand+i, 0xff,"@"); - fix_new(frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELBYTE); - break; - - case ABS16OR8SRC: - case ABS16OR8DST: - check_operand(operand+i, 0xffff,"@"); - - fix_new(frag_now, - output - frag_now->fr_literal + 2, - 2, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_MOVB1); - break; - - case ABS16ORREL8SRC: - check_operand(operand+i, 0xffff,"@"); - - fix_new(frag_now, - output - frag_now->fr_literal + 2, - 2, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_JMP1); - break; - - - case ABS16SRC: - case ABS16DST: - case IMM16: - case DISPSRC: - case DISPDST: - check_operand(operand+i, 0xffff,"@"); - if (operand[i].exp.X_add_symbol == 0) - { - /* This should be done with bfd */ - output[3] = operand[i].exp.X_add_number & 0xff; - output[2] = operand[i].exp.X_add_number >> 8; - - } - else - { - - fix_new(frag_now, - output - frag_now->fr_literal + 2, - 2, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELWORD); - } + if (opcode == NULL) + { + as_bad("unknown opcode"); + return; + } + + + input_line_pointer = get_operands(opcode->noperands, op_end, + operand); + *op_end = c; + prev_opcode = opcode; + + opcode = get_specific(opcode, operand); + + if (opcode == 0) + { + /* Couldn't find an opcode which matched the operands */ + char *where =frag_more(2); + where[0] = 0x0; + where[1] = 0x0; + clever_message(prev_opcode, operand); + + return; + } + if (opcode->size && dot) + { + if (opcode->size != *dot) + { + as_warn("mismatch between opcode size and operand size"); + } + } + + build_bytes(opcode, operand); - break; - case RS8: - case RD8: - case RS16: - case RD16: - case RDDEC: - case KBIT: - case RSINC: - case RDIND: - case RSIND: - case CCR: - - break; - default: - abort(); - } - } - -} -/* This is the guts of the machine-dependent assembler. STR points to a - machine dependent instruction. This funciton is supposed to emit - the frags/bytes it assembles to. - */ - - -void -DEFUN(md_assemble,(str), - char *str) -{ - char *op_start; - char *op_end; - unsigned int i; - struct h8_op operand[2]; - struct h8_opcode * opcode; - char *dot = 0; - char c; - /* Drop leading whitespace */ - while (*str == ' ') - str++; - - /* find the op code end */ - for (op_start = op_end = str; - *op_end != 0 && *op_end != ' '; - op_end ++) - { - if (*op_end == '.') { - dot = op_end+1; - *op_end = 0; - op_end+=2; - break; - } - } - - ; - - if (op_end == op_start) - { - as_bad("can't find opcode "); - } - c = *op_end; - - *op_end = 0; - - opcode = (struct h8_opcode *) hash_find(opcode_hash_control, - op_start); - - if (opcode == NULL) - { - as_bad("unknown opcode"); - return; - } - - - input_line_pointer = get_operands(opcode->noperands, op_end, - operand); - *op_end = c; - opcode = get_specific(opcode, operand); - - if (opcode == 0) - { - /* Allocate 2 bytes for the insn anyway */ - char *where =frag_more(2); - where[0] = 0xde; - where[1] = 0xad; - - - as_bad("illegal operands for opcode"); - return; - } - if (opcode->size && dot) - { - if (opcode->size != *dot) - { - as_warn("mismatch between opcode size and operand size"); - } - } - - build_bytes(opcode, operand); - } void -DEFUN(tc_crawl_symbol_chain, (headers), -object_headers *headers) + DEFUN(tc_crawl_symbol_chain, (headers), + object_headers *headers) { - printf("call to tc_crawl_symbol_chain \n"); + printf("call to tc_crawl_symbol_chain \n"); } symbolS *DEFUN(md_undefined_symbol,(name), char *name) { -return 0; + return 0; } void -DEFUN(tc_headers_hook,(headers), - object_headers *headers) + DEFUN(tc_headers_hook,(headers), + object_headers *headers) { - printf("call to tc_headers_hook \n"); + printf("call to tc_headers_hook \n"); } void -DEFUN_VOID(md_end) + DEFUN_VOID(md_end) { } @@ -2215,9 +1082,9 @@ DEFUN_VOID(md_end) /* Turn a string in input_line_pointer into a floating point constant of type type, and store the appropriate bytes in *litP. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ + */ char * -md_atof(type,litP,sizeP) + md_atof(type,litP,sizeP) char type; char *litP; int *sizeP; @@ -2227,7 +1094,7 @@ int *sizeP; LITTLENUM_TYPE *wordP; char *t; char *atof_ieee(); - + switch(type) { case 'f': case 'F': @@ -2235,32 +1102,32 @@ int *sizeP; case 'S': prec = 2; break; - + case 'd': case 'D': case 'r': case 'R': prec = 4; break; - + case 'x': case 'X': prec = 6; break; - + case 'p': case 'P': prec = 6; break; - + default: *sizeP=0; return "Bad call to MD_ATOF()"; } t=atof_ieee(input_line_pointer,type,words); if(t) - input_line_pointer=t; - + input_line_pointer=t; + *sizeP=prec * sizeof(LITTLENUM_TYPE); for(wordP=words;prec--;) { md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); @@ -2270,20 +1137,20 @@ int *sizeP; } int -md_parse_option(argP, cntP, vecP) - char **argP; - int *cntP; - char ***vecP; + md_parse_option(argP, cntP, vecP) +char **argP; +int *cntP; +char ***vecP; - { - return 0; - - } +{ + return 0; + +} int md_short_jump_size; void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n"); - abort(); } + abort(); } void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) char *ptr; long from_addr; @@ -2292,41 +1159,41 @@ fragS *frag; symbolS *to_symbol; { as_fatal("failed sanity check."); - } +} void -md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) - char *ptr; - long from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; + md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) +char *ptr; +long from_addr, to_addr; +fragS *frag; +symbolS *to_symbol; { as_fatal("failed sanity check."); } void -md_convert_frag(headers, fragP) + md_convert_frag(headers, fragP) object_headers *headers; - fragS * fragP; +fragS * fragP; - { printf("call to md_convert_frag \n"); abort(); } +{ printf("call to md_convert_frag \n"); abort(); } long -DEFUN(md_section_align,(seg, size), - segT seg AND - long size) + DEFUN(md_section_align,(seg, size), + segT seg AND + long size) { return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg])); - + } void -md_apply_fix(fixP, val) - fixS *fixP; - long val; + md_apply_fix(fixP, val) +fixS *fixP; +long val; { char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - + switch(fixP->fx_size) { case 1: *buf++=val; @@ -2352,11 +1219,11 @@ void DEFUN(md_operand, (expressionP),expressionS *expressionP) int md_long_jump_size; int -md_estimate_size_before_relax(fragP, segment_type) - register fragS *fragP; - register segT segment_type; + md_estimate_size_before_relax(fragP, segment_type) +register fragS *fragP; +register segT segment_type; { -printf("call tomd_estimate_size_before_relax \n"); abort(); } + printf("call tomd_estimate_size_before_relax \n"); abort(); } /* Put number into target byte order */ void DEFUN(md_number_to_chars,(ptr, use, nbytes), @@ -2364,15 +1231,15 @@ void DEFUN(md_number_to_chars,(ptr, use, nbytes), long use AND int nbytes) { - switch (nbytes) { - case 4: *ptr++ = (use >> 24) & 0xff; - case 3: *ptr++ = (use >> 16) & 0xff; - case 2: *ptr++ = (use >> 8) & 0xff; - case 1: *ptr++ = (use >> 0) & 0xff; - break; - default: - abort(); - } + switch (nbytes) { + case 4: *ptr++ = (use >> 24) & 0xff; + case 3: *ptr++ = (use >> 16) & 0xff; + case 2: *ptr++ = (use >> 8) & 0xff; + case 1: *ptr++ = (use >> 0) & 0xff; + break; + default: + abort(); + } } long md_pcrel_from(fixP) fixS *fixP; { abort(); } @@ -2386,41 +1253,41 @@ struct internal_reloc *intr; bfd_vma base; { - symbolS *symbol_ptr; + symbolS *symbol_ptr; + + symbol_ptr = fix_ptr->fx_addsy; + + /* If this relocation is attached to a symbol then it's ok + to output it */ + if (fix_ptr->fx_r_type == RELOC_32) { + /* cons likes to create reloc32's whatever the size of the reloc.. + */ + switch (fix_ptr->fx_size) + { + + case 2: + intr->r_type = R_RELWORD; + break; + case 1: + intr->r_type = R_RELBYTE; + break; + default: + abort(); + + } + + } + else { + intr->r_type = fix_ptr->fx_r_type; + } + + intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where +base; + intr->r_offset = fix_ptr->fx_offset; + + if (symbol_ptr) + intr->r_symndx = symbol_ptr->sy_number; + else + intr->r_symndx = -1; - symbol_ptr = fix_ptr->fx_addsy; - - /* If this relocation is attached to a symbol then it's ok - to output it */ - if (fix_ptr->fx_r_type == RELOC_32) { - /* cons likes to create reloc32's whatever the size of the reloc.. - */ - switch (fix_ptr->fx_size) - { - - case 2: - intr->r_type = R_RELWORD; - break; - case 1: - intr->r_type = R_RELBYTE; - break; - default: - abort(); - - } - - } - else { - intr->r_type = fix_ptr->fx_r_type; - } - - intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where +base; - intr->r_offset = fix_ptr->fx_offset; - - if (symbol_ptr) - intr->r_symndx = symbol_ptr->sy_number; - else - intr->r_symndx = -1; - } diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h index 2e02b40..5580d69 100644 --- a/gas/config/tc-h8300.h +++ b/gas/config/tc-h8300.h @@ -2,8 +2,15 @@ #define TC_H8300 /* This macro translates between an internal fix and an coff reloc type */ -#define TC_COFF_FIX2RTYPE(fixP) \ - (fixP->fx_pcrel ? (fixP->fx_size == 1 ? R_PCRBYTE : R_PCRWORD ) : \ - (fixP->fx_size == 1 ? R_RELBYTE : R_RELWORD )) +#define TC_COFF_FIX2RTYPE(fixP) abort(); + +#define BFD_ARCH bfd_arch_h8300 +#define COFF_MAGIC 0x8300 +#define TC_COUNT_RELOC(x) (1) +#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle(a,b,c) + +#define DO_NOT_STRIP 1 +#define DO_STRIP 0 +#define LISTING_HEADER "Hitachi H8/300 GAS " diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index cff66a4..7f8c4be 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1,21 +1,21 @@ /* i386.c -- Assemble code for the Intel 80386 Copyright (C) 1989, 1991 Free Software Foundation. - -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. */ + + 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. */ /* $Id$ */ @@ -24,70 +24,87 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Written by Eliot Dresselhaus (eliot@mgm.mit.edu). Bugs & suggestions are completely welcome. This is free software. Please help us make it better. -*/ + */ #include "as.h" #include "obstack.h" -#include "i386-opcode.h" +#include "opcode/i386.h" /* 'md_assemble ()' gathers together information and puts it into a i386_insn. */ typedef struct { - /* TM holds the template for the insn were currently assembling. */ - template tm; - /* SUFFIX holds the opcode suffix (e.g. 'l' for 'movl') if given. */ - char suffix; - /* Operands are coded with OPERANDS, TYPES, DISPS, IMMS, and REGS. */ - - /* OPERANDS gives the number of given operands. */ - unsigned int operands; - - /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number of - given register, displacement, memory operands and immediate operands. */ - unsigned int reg_operands, disp_operands, mem_operands, imm_operands; - - /* TYPES [i] is the type (see above #defines) which tells us how to - search through DISPS [i] & IMMS [i] & REGS [i] for the required - operand. */ - unsigned int types [MAX_OPERANDS]; - - /* Displacements (if given) for each operand. */ - expressionS * disps [MAX_OPERANDS]; - - /* Immediate operands (if given) for each operand. */ - expressionS * imms [MAX_OPERANDS]; - - /* Register operands (if given) for each operand. */ - reg_entry * regs [MAX_OPERANDS]; - - /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode - the base index byte below. */ - reg_entry * base_reg; - reg_entry * index_reg; - unsigned int log2_scale_factor; - - /* SEG gives the seg_entry of this insn. It is equal to zero unless - an explicit segment override is given. */ - seg_entry * seg; /* segment for memory operands (if given) */ + /* TM holds the template for the insn were currently assembling. */ + template tm; + /* SUFFIX holds the opcode suffix (e.g. 'l' for 'movl') if given. */ + char suffix; + /* Operands are coded with OPERANDS, TYPES, DISPS, IMMS, and REGS. */ + + /* OPERANDS gives the number of given operands. */ + unsigned int operands; + + /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number of + given register, displacement, memory operands and immediate operands. */ + unsigned int reg_operands, disp_operands, mem_operands, imm_operands; + + /* TYPES [i] is the type (see above #defines) which tells us how to + search through DISPS [i] & IMMS [i] & REGS [i] for the required + operand. */ + unsigned int types [MAX_OPERANDS]; + + /* Displacements (if given) for each operand. */ + expressionS * disps [MAX_OPERANDS]; + + /* Immediate operands (if given) for each operand. */ + expressionS * imms [MAX_OPERANDS]; + + /* Register operands (if given) for each operand. */ + reg_entry * regs [MAX_OPERANDS]; + + /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode + the base index byte below. */ + reg_entry * base_reg; + reg_entry * index_reg; + unsigned int log2_scale_factor; + + /* SEG gives the seg_entry of this insn. It is equal to zero unless + an explicit segment override is given. */ + seg_entry * seg; /* segment for memory operands (if given) */ + + /* PREFIX holds all the given prefix opcodes (usually null). + PREFIXES is the size of PREFIX. */ + char prefix [MAX_PREFIXES]; + unsigned int prefixes; + + /* RM and IB are the modrm byte and the base index byte where the addressing + modes of this insn are encoded. */ + + modrm_byte rm; + base_index_byte bi; +} i386_insn; - /* PREFIX holds all the given prefix opcodes (usually null). - PREFIXES is the size of PREFIX. */ - char prefix [MAX_PREFIXES]; - unsigned int prefixes; +/* This array holds the chars that always start a comment. If the + pre-processor is disabled, these aren't very useful */ +const char comment_chars[] = "#"; - /* RM and IB are the modrm byte and the base index byte where the addressing - modes of this insn are encoded. */ +/* This array holds the chars that only start a comment at the beginning of + a line. If the line seems to have the form '# 123 filename' + .line and .file directives will appear in the pre-processed output */ +/* Note that input_file.c hand checks for '#' at the beginning of the + first line of the input file. This is because the compiler outputs + #NO_APP at the beginning of its output. */ +/* Also note that comments started like this one will always work if + '/' isn't otherwise defined. */ +const char line_comment_chars[] = "/"; /* removed '#' xoxorich. */ - modrm_byte rm; - base_index_byte bi; -} i386_insn; +/* Chars that can be used to separate mant from exp in floating point nums */ +const char EXP_CHARS[] = "eE"; -char FLT_CHARS[] = "fFdDxX"; -char EXP_CHARS[] = "eE"; -char line_comment_chars[] = "#"; -char comment_chars[] = "#/"; +/* Chars that mean this number is a floating point constant */ +/* As in 0f12.456 */ +/* or 0d1.2345e12 */ +const char FLT_CHARS[] = "fFdDxX"; /* tables for lexical analysis */ static char opcode_chars[256]; @@ -118,9 +135,9 @@ static char save_stack[32]; static char *save_stack_p; /* stack pointer */ #define END_STRING_AND_SAVE(s) *save_stack_p++ = *s; *s = '\0' #define RESTORE_END_STRING(s) *s = *--save_stack_p - -/* The instruction we're assembling. */ -static i386_insn i; + + /* The instruction we're assembling. */ + static i386_insn i; /* Per instruction expressionS buffers: 2 displacements & 2 immediate max. */ static expressionS disp_expressions[2], im_expressions[2]; @@ -131,11 +148,11 @@ static reg_entry *ebp, *esp; static int this_operand; /* current operand we are working on */ /* -Interface to relax_segment. -There are 2 relax states for 386 jump insns: one for conditional & one -for unconditional jumps. This is because the these two types of jumps -add different sizes to frags when we're figuring out what sort of jump -to choose to reach a given label. */ + Interface to relax_segment. + There are 2 relax states for 386 jump insns: one for conditional & one + for unconditional jumps. This is because the these two types of jumps + add different sizes to frags when we're figuring out what sort of jump + to choose to reach a given label. */ /* types */ #define COND_JUMP 1 /* conditional jump */ @@ -148,41 +165,41 @@ to choose to reach a given label. */ #define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size)) #define SIZE_FROM_RELAX_STATE(s) \ - ( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) ) + ( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) ) const relax_typeS md_relax_table[] = { -/* - The fields are: - 1) most positive reach of this state, - 2) most negative reach of this state, - 3) how many bytes this mode will add to the size of the current frag - 4) which index into the table to try if we can't fit into this one. -*/ - {1, 1, 0, 0}, - {1, 1, 0, 0}, - {1, 1, 0, 0}, - {1, 1, 0, 0}, - - /* For now we don't use word displacement jumps: they may be - untrustworthy. */ - {127+1, -128+1, 0, ENCODE_RELAX_STATE(COND_JUMP,DWORD) }, - /* word conditionals add 3 bytes to frag: - 2 opcode prefix; 1 displacement bytes */ - {32767+2, -32768+2, 3, ENCODE_RELAX_STATE(COND_JUMP,DWORD) }, - /* dword conditionals adds 4 bytes to frag: - 1 opcode prefix; 3 displacement bytes */ - {0, 0, 4, 0}, - {1, 1, 0, 0}, - - {127+1, -128+1, 0, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) }, - /* word jmp adds 2 bytes to frag: - 1 opcode prefix; 1 displacement bytes */ - {32767+2, -32768+2, 2, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) }, - /* dword jmp adds 3 bytes to frag: - 0 opcode prefix; 3 displacement bytes */ - {0, 0, 3, 0}, - {1, 1, 0, 0}, - + /* + The fields are: + 1) most positive reach of this state, + 2) most negative reach of this state, + 3) how many bytes this mode will add to the size of the current frag + 4) which index into the table to try if we can't fit into this one. + */ + {1, 1, 0, 0}, + {1, 1, 0, 0}, + {1, 1, 0, 0}, + {1, 1, 0, 0}, + + /* For now we don't use word displacement jumps: they may be + untrustworthy. */ + {127+1, -128+1, 0, ENCODE_RELAX_STATE(COND_JUMP,DWORD) }, + /* word conditionals add 3 bytes to frag: + 2 opcode prefix; 1 displacement bytes */ + {32767+2, -32768+2, 3, ENCODE_RELAX_STATE(COND_JUMP,DWORD) }, + /* dword conditionals adds 4 bytes to frag: + 1 opcode prefix; 3 displacement bytes */ + {0, 0, 4, 0}, + {1, 1, 0, 0}, + + {127+1, -128+1, 0, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) }, + /* word jmp adds 2 bytes to frag: + 1 opcode prefix; 1 displacement bytes */ + {32767+2, -32768+2, 2, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) }, + /* dword jmp adds 3 bytes to frag: + 0 opcode prefix; 3 displacement bytes */ + {0, 0, 3, 0}, + {1, 1, 0, 0}, + }; #ifdef __STDC__ @@ -204,8 +221,8 @@ static reg_entry *parse_register(); not be here. */ void dummy () { - while (*input_line_pointer && *input_line_pointer != '\n') - input_line_pointer++; + while (*input_line_pointer && *input_line_pointer != '\n') + input_line_pointer++; } const pseudo_typeS md_pseudo_table[] = { @@ -213,17 +230,6 @@ const pseudo_typeS md_pseudo_table[] = { { "dfloat", float_cons, 'd' }, { "tfloat", float_cons, 'x' }, { "value", cons, 2 }, - { "ident", dummy, 0 }, /* ignore these directives */ -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) - { "def", dummy, 0 }, -#endif /* OBJ_AOUT or OBJ_BOUT */ - { "def", dummy, 0 }, - { "optim", dummy, 0 }, /* For sun386i cc */ - { "version", dummy, 0 }, -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) - { "ln", dummy, 0 }, -#endif /* OBJ_AOUT or OBJ_BOUT */ - { "ln", dummy, 0 }, { 0, 0, 0 } }; @@ -243,108 +249,108 @@ static struct hash_control *prefix_hash = (struct hash_control *) 0; void md_begin () { - char * hash_err; - - obstack_begin (&o,4096); - - /* initialize op_hash hash table */ - op_hash = hash_new(); /* xmalloc handles error */ - - { - register const template *optab; - register templates *core_optab; - char *prev_name; - - optab = i386_optab; /* setup for loop */ - prev_name = optab->name; - obstack_grow (&o, optab, sizeof(template)); - core_optab = (templates *) xmalloc (sizeof (templates)); - - for (optab++; optab < i386_optab_end; optab++) { - if (! strcmp (optab->name, prev_name)) { - /* same name as before --> append to current template list */ - obstack_grow (&o, optab, sizeof(template)); - } else { - /* different name --> ship out current template list; - add to hash table; & begin anew */ - /* Note: end must be set before start! since obstack_next_free changes - upon opstack_finish */ - core_optab->end = (template *) obstack_next_free(&o); - core_optab->start = (template *) obstack_finish(&o); - hash_err = hash_insert (op_hash, prev_name, (char *) core_optab); - if (hash_err && *hash_err) { - hash_error: - as_fatal("Internal Error: Can't hash %s: %s", prev_name, hash_err); + char * hash_err; + + obstack_begin (&o,4096); + + /* initialize op_hash hash table */ + op_hash = hash_new(); /* xmalloc handles error */ + + { + register const template *optab; + register templates *core_optab; + char *prev_name; + + optab = i386_optab; /* setup for loop */ + prev_name = optab->name; + obstack_grow (&o, optab, sizeof(template)); + core_optab = (templates *) xmalloc (sizeof (templates)); + + for (optab++; optab < i386_optab_end; optab++) { + if (! strcmp (optab->name, prev_name)) { + /* same name as before --> append to current template list */ + obstack_grow (&o, optab, sizeof(template)); + } else { + /* different name --> ship out current template list; + add to hash table; & begin anew */ + /* Note: end must be set before start! since obstack_next_free changes + upon opstack_finish */ + core_optab->end = (template *) obstack_next_free(&o); + core_optab->start = (template *) obstack_finish(&o); + hash_err = hash_insert (op_hash, prev_name, (char *) core_optab); + if (hash_err && *hash_err) { + hash_error: + as_fatal("Internal Error: Can't hash %s: %s", prev_name, hash_err); + } + prev_name = optab->name; + core_optab = (templates *) xmalloc (sizeof(templates)); + obstack_grow (&o, optab, sizeof(template)); + } + } + } + + /* initialize reg_hash hash table */ + reg_hash = hash_new(); + { + register const reg_entry *regtab; + + for (regtab = i386_regtab; regtab < i386_regtab_end; regtab++) { + hash_err = hash_insert (reg_hash, regtab->reg_name, regtab); + if (hash_err && *hash_err) goto hash_error; + } + } + + esp = (reg_entry *) hash_find (reg_hash, "esp"); + ebp = (reg_entry *) hash_find (reg_hash, "ebp"); + + /* initialize reg_hash hash table */ + prefix_hash = hash_new(); + { + register const prefix_entry *prefixtab; + + for (prefixtab = i386_prefixtab; + prefixtab < i386_prefixtab_end; prefixtab++) { + hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, prefixtab); + if (hash_err && *hash_err) goto hash_error; + } + } + + /* fill in lexical tables: opcode_chars, operand_chars, space_chars */ + { + register unsigned int c; + + bzero (opcode_chars, sizeof(opcode_chars)); + bzero (operand_chars, sizeof(operand_chars)); + bzero (space_chars, sizeof(space_chars)); + bzero (identifier_chars, sizeof(identifier_chars)); + bzero (digit_chars, sizeof(digit_chars)); + + for (c = 0; c < 256; c++) { + if (islower(c) || isdigit(c)) { + opcode_chars[c] = c; + register_chars[c] = c; + } else if (isupper(c)) { + opcode_chars[c] = tolower(c); + register_chars[c] = opcode_chars[c]; + } else if (c == PREFIX_SEPERATOR) { + opcode_chars[c] = c; + } else if (c == ')' || c == '(') { + register_chars[c] = c; + } + + if (isupper(c) || islower(c) || isdigit(c)) + operand_chars[c] = c; + else if (c && strchr(operand_special_chars, c)) + operand_chars[c] = c; + + if (isdigit(c) || c == '-') digit_chars[c] = c; + + if (isalpha(c) || c == '_' || c == '.' || isdigit(c)) + identifier_chars[c] = c; + + if (c == ' ' || c == '\t') space_chars[c] = c; + } } - prev_name = optab->name; - core_optab = (templates *) xmalloc (sizeof(templates)); - obstack_grow (&o, optab, sizeof(template)); - } - } - } - - /* initialize reg_hash hash table */ - reg_hash = hash_new(); - { - register const reg_entry *regtab; - - for (regtab = i386_regtab; regtab < i386_regtab_end; regtab++) { - hash_err = hash_insert (reg_hash, regtab->reg_name, regtab); - if (hash_err && *hash_err) goto hash_error; - } - } - - esp = (reg_entry *) hash_find (reg_hash, "esp"); - ebp = (reg_entry *) hash_find (reg_hash, "ebp"); - - /* initialize reg_hash hash table */ - prefix_hash = hash_new(); - { - register const prefix_entry *prefixtab; - - for (prefixtab = i386_prefixtab; - prefixtab < i386_prefixtab_end; prefixtab++) { - hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, prefixtab); - if (hash_err && *hash_err) goto hash_error; - } - } - - /* fill in lexical tables: opcode_chars, operand_chars, space_chars */ - { - register unsigned int c; - - bzero (opcode_chars, sizeof(opcode_chars)); - bzero (operand_chars, sizeof(operand_chars)); - bzero (space_chars, sizeof(space_chars)); - bzero (identifier_chars, sizeof(identifier_chars)); - bzero (digit_chars, sizeof(digit_chars)); - - for (c = 0; c < 256; c++) { - if (islower(c) || isdigit(c)) { - opcode_chars[c] = c; - register_chars[c] = c; - } else if (isupper(c)) { - opcode_chars[c] = tolower(c); - register_chars[c] = opcode_chars[c]; - } else if (c == PREFIX_SEPERATOR) { - opcode_chars[c] = c; - } else if (c == ')' || c == '(') { - register_chars[c] = c; - } - - if (isupper(c) || islower(c) || isdigit(c)) - operand_chars[c] = c; - else if (c && strchr(operand_special_chars, c)) - operand_chars[c] = c; - - if (isdigit(c) || c == '-') digit_chars[c] = c; - - if (isalpha(c) || c == '_' || c == '.' || isdigit(c)) - identifier_chars[c] = c; - - if (c == ' ' || c == '\t') space_chars[c] = c; - } - } } void md_end() {} /* not much to do here. */ @@ -356,106 +362,106 @@ void md_end() {} /* not much to do here. */ /* static void pi (), pte (), pt (), pe (), ps (); */ static void pi (line, x) - char * line; - i386_insn *x; +char * line; +i386_insn *x; { - register template *p; - int i; - - fprintf (stdout, "%s: template ", line); - pte (&x->tm); - fprintf (stdout, " modrm: mode %x reg %x reg/mem %x", - x->rm.mode, x->rm.reg, x->rm.regmem); - fprintf (stdout, " base %x index %x scale %x\n", - x->bi.base, x->bi.index, x->bi.scale); - for (i = 0; i < x->operands; i++) { - fprintf (stdout, " #%d: ", i+1); - pt (x->types[i]); - fprintf (stdout, "\n"); - if (x->types[i] & Reg) fprintf (stdout, "%s\n", x->regs[i]->reg_name); - if (x->types[i] & Imm) pe (x->imms[i]); - if (x->types[i] & (Disp|Abs)) pe (x->disps[i]); - } + register template *p; + int i; + + fprintf (stdout, "%s: template ", line); + pte (&x->tm); + fprintf (stdout, " modrm: mode %x reg %x reg/mem %x", + x->rm.mode, x->rm.reg, x->rm.regmem); + fprintf (stdout, " base %x index %x scale %x\n", + x->bi.base, x->bi.index, x->bi.scale); + for (i = 0; i < x->operands; i++) { + fprintf (stdout, " #%d: ", i+1); + pt (x->types[i]); + fprintf (stdout, "\n"); + if (x->types[i] & Reg) fprintf (stdout, "%s\n", x->regs[i]->reg_name); + if (x->types[i] & Imm) pe (x->imms[i]); + if (x->types[i] & (Disp|Abs)) pe (x->disps[i]); + } } static void pte (t) - template *t; +template *t; { - int i; - fprintf (stdout, " %d operands ", t->operands); - fprintf (stdout, "opcode %x ", - t->base_opcode); - if (t->extension_opcode != None) - fprintf (stdout, "ext %x ", t->extension_opcode); - if (t->opcode_modifier&D) - fprintf (stdout, "D"); - if (t->opcode_modifier&W) - fprintf (stdout, "W"); - fprintf (stdout, "\n"); - for (i = 0; i < t->operands; i++) { - fprintf (stdout, " #%d type ", i+1); - pt (t->operand_types[i]); - fprintf (stdout, "\n"); - } + int i; + fprintf (stdout, " %d operands ", t->operands); + fprintf (stdout, "opcode %x ", + t->base_opcode); + if (t->extension_opcode != None) + fprintf (stdout, "ext %x ", t->extension_opcode); + if (t->opcode_modifier&D) + fprintf (stdout, "D"); + if (t->opcode_modifier&W) + fprintf (stdout, "W"); + fprintf (stdout, "\n"); + for (i = 0; i < t->operands; i++) { + fprintf (stdout, " #%d type ", i+1); + pt (t->operand_types[i]); + fprintf (stdout, "\n"); + } } static void pe (e) - expressionS *e; +expressionS *e; { - fprintf (stdout, " segment %s\n", segment_name (e->X_seg)); - fprintf (stdout, " add_number %d (%x)\n", - e->X_add_number, e->X_add_number); - if (e->X_add_symbol) { - fprintf (stdout, " add_symbol "); - ps (e->X_add_symbol); - fprintf (stdout, "\n"); - } - if (e->X_subtract_symbol) { - fprintf (stdout, " sub_symbol "); - ps (e->X_subtract_symbol); - fprintf (stdout, "\n"); - } + fprintf (stdout, " segment %s\n", segment_name (e->X_seg)); + fprintf (stdout, " add_number %d (%x)\n", + e->X_add_number, e->X_add_number); + if (e->X_add_symbol) { + fprintf (stdout, " add_symbol "); + ps (e->X_add_symbol); + fprintf (stdout, "\n"); + } + if (e->X_subtract_symbol) { + fprintf (stdout, " sub_symbol "); + ps (e->X_subtract_symbol); + fprintf (stdout, "\n"); + } } static void ps (s) - symbolS *s; +symbolS *s; { - fprintf (stdout, "%s type %s%s", - S_GET_NAME(s), - S_IS_EXTERNAL(s) ? "EXTERNAL " : "", - segment_name(S_GET_SEGMENT(s))); + fprintf (stdout, "%s type %s%s", + S_GET_NAME(s), + S_IS_EXTERNAL(s) ? "EXTERNAL " : "", + segment_name(S_GET_SEGMENT(s))); } struct type_name { - unsigned int mask; - char *tname; + unsigned int mask; + char *tname; } type_names[] = { - { Reg8, "r8" }, { Reg16, "r16" }, { Reg32, "r32" }, { Imm8, "i8" }, - { Imm8S, "i8s" }, - { Imm16, "i16" }, { Imm32, "i32" }, { Mem8, "Mem8"}, { Mem16, "Mem16"}, - { Mem32, "Mem32"}, { BaseIndex, "BaseIndex" }, - { Abs8, "Abs8" }, { Abs16, "Abs16" }, { Abs32, "Abs32" }, - { Disp8, "d8" }, { Disp16, "d16" }, - { Disp32, "d32" }, { SReg2, "SReg2" }, { SReg3, "SReg3" }, { Acc, "Acc" }, - { InOutPortReg, "InOutPortReg" }, { ShiftCount, "ShiftCount" }, - { Imm1, "i1" }, { Control, "control reg" }, {Test, "test reg"}, - { FloatReg, "FReg"}, {FloatAcc, "FAcc"}, - { JumpAbsolute, "Jump Absolute"}, - { 0, "" } + { Reg8, "r8" }, { Reg16, "r16" }, { Reg32, "r32" }, { Imm8, "i8" }, + { Imm8S, "i8s" }, + { Imm16, "i16" }, { Imm32, "i32" }, { Mem8, "Mem8"}, { Mem16, "Mem16"}, + { Mem32, "Mem32"}, { BaseIndex, "BaseIndex" }, + { Abs8, "Abs8" }, { Abs16, "Abs16" }, { Abs32, "Abs32" }, + { Disp8, "d8" }, { Disp16, "d16" }, + { Disp32, "d32" }, { SReg2, "SReg2" }, { SReg3, "SReg3" }, { Acc, "Acc" }, + { InOutPortReg, "InOutPortReg" }, { ShiftCount, "ShiftCount" }, + { Imm1, "i1" }, { Control, "control reg" }, {Test, "test reg"}, + { FloatReg, "FReg"}, {FloatAcc, "FAcc"}, + { JumpAbsolute, "Jump Absolute"}, + { 0, "" } }; static void pt (t) - unsigned int t; +unsigned int t; { - register struct type_name *ty; - - if (t == Unknown) { - fprintf (stdout, "Unknown"); - } else { - for (ty = type_names; ty->mask; ty++) - if (t & ty->mask) fprintf (stdout, "%s, ", ty->tname); - } - fflush (stdout); + register struct type_name *ty; + + if (t == Unknown) { + fprintf (stdout, "Unknown"); + } else { + for (ty = type_names; ty->mask; ty++) + if (t & ty->mask) fprintf (stdout, "%s, ", ty->tname); + } + fflush (stdout); } #endif /* DEBUG386 */ @@ -464,1108 +470,1108 @@ static void pt (t) This is the guts of the machine-dependent assembler. LINE points to a machine dependent instruction. This funciton is supposed to emit the frags/bytes it assembles to. - */ + */ void md_assemble (line) - char *line; +char *line; { - /* Holds temlate once we've found it. */ - register template * t; - - /* Possible templates for current insn */ - templates *current_templates = (templates *) 0; - - /* Initialize globals. */ - bzero (&i, sizeof(i)); - bzero (disp_expressions, sizeof(disp_expressions)); - bzero (im_expressions, sizeof(im_expressions)); - save_stack_p = save_stack; /* reset stack pointer */ - - /* Fist parse an opcode & call i386_operand for the operands. - We assume that the scrubber has arranged it so that line[0] is the valid - start of a (possibly prefixed) opcode. */ - { - register char *l = line; /* Fast place to put LINE. */ - - /* 1 if operand is pending after ','. */ - unsigned int expecting_operand = 0; - /* 1 if we found a prefix only acceptable with string insns. */ - unsigned int expecting_string_instruction = 0; - /* Non-zero if operand parens not balenced. */ - unsigned int paren_not_balenced; - char * token_start = l; - - while (! is_space_char(*l) && *l != END_OF_INSN) { - if (! is_opcode_char(*l)) { - as_bad("invalid character %s in opcode", output_invalid(*l)); - return; - } else if (*l != PREFIX_SEPERATOR) { - *l = opcode_chars[(unsigned char) *l]; /* fold case of opcodes */ - l++; - } else { /* this opcode's got a prefix */ - register unsigned int q; - register prefix_entry * prefix; - - if (l == token_start) { - as_bad("expecting prefix; got nothing"); - return; - } - END_STRING_AND_SAVE (l); - prefix = (prefix_entry *) hash_find (prefix_hash, token_start); - if (! prefix) { - as_bad("no such opcode prefix ('%s')", token_start); - return; - } - RESTORE_END_STRING (l); - /* check for repeated prefix */ - for (q = 0; q < i.prefixes; q++) - if (i.prefix[q] == prefix->prefix_code) { - as_bad("same prefix used twice; you don't really want this!"); - return; - } - if (i.prefixes == MAX_PREFIXES) { - as_bad("too many opcode prefixes"); - return; - } - i.prefix[i.prefixes++] = prefix->prefix_code; - if (prefix->prefix_code == REPE || prefix->prefix_code == REPNE) - expecting_string_instruction = 1; - /* skip past PREFIX_SEPERATOR and reset token_start */ - token_start = ++l; - } - } - END_STRING_AND_SAVE (l); - if (token_start == l) { - as_bad("expecting opcode; got nothing"); - return; - } - - /* Lookup insn in hash; try intel & att naming conventions if appropriate; - that is: we only use the opcode suffix 'b' 'w' or 'l' if we need to. */ - current_templates = (templates *) hash_find (op_hash, token_start); - if (! current_templates) { - int last_index = strlen(token_start) - 1; - char last_char = token_start[last_index]; - switch (last_char) { - case DWORD_OPCODE_SUFFIX: - case WORD_OPCODE_SUFFIX: - case BYTE_OPCODE_SUFFIX: - token_start[last_index] = '\0'; - current_templates = (templates *) hash_find (op_hash, token_start); - token_start[last_index] = last_char; - i.suffix = last_char; - } - if (!current_templates) { - as_bad("no such 386 instruction: `%s'", token_start); return; - } - } - RESTORE_END_STRING (l); - - /* check for rep/repne without a string instruction */ - if (expecting_string_instruction && - ! IS_STRING_INSTRUCTION (current_templates-> - start->base_opcode)) { - as_bad("expecting string instruction after rep/repne"); - return; - } - - /* There may be operands to parse. */ - if (*l != END_OF_INSN && - /* For string instructions, we ignore any operands if given. This - kludges, for example, 'rep/movsb %ds:(%esi), %es:(%edi)' where - the operands are always going to be the same, and are not really - encoded in machine code. */ - ! IS_STRING_INSTRUCTION (current_templates-> - start->base_opcode)) { - /* parse operands */ - do { - /* skip optional white space before operand */ - while (! is_operand_char(*l) && *l != END_OF_INSN) { - if (! is_space_char(*l)) { - as_bad("invalid character %s before %s operand", - output_invalid(*l), - ordinal_names[i.operands]); - return; - } - l++; - } - token_start = l; /* after white space */ - paren_not_balenced = 0; - while (paren_not_balenced || *l != ',') { - if (*l == END_OF_INSN) { - if (paren_not_balenced) { - as_bad("unbalenced parenthesis in %s operand.", - ordinal_names[i.operands]); - return; - } else break; /* we are done */ - } else if (! is_operand_char(*l)) { - as_bad("invalid character %s in %s operand", - output_invalid(*l), - ordinal_names[i.operands]); - return; - } - if (*l == '(') ++paren_not_balenced; - if (*l == ')') --paren_not_balenced; - l++; - } - if (l != token_start) { /* yes, we've read in another operand */ - unsigned int operand_ok; - this_operand = i.operands++; - if (i.operands > MAX_OPERANDS) { - as_bad("spurious operands; (%d operands/instruction max)", - MAX_OPERANDS); - return; - } - /* now parse operand adding info to 'i' as we go along */ - END_STRING_AND_SAVE (l); - operand_ok = i386_operand (token_start); - RESTORE_END_STRING (l); /* restore old contents */ - if (!operand_ok) return; - } else { - if (expecting_operand) { - expecting_operand_after_comma: - as_bad("expecting operand after ','; got nothing"); - return; - } - if (*l == ',') { - as_bad("expecting operand before ','; got nothing"); - return; - } - } - - /* now *l must be either ',' or END_OF_INSN */ - if (*l == ',') { - if (*++l == END_OF_INSN) { /* just skip it, if it's \n complain */ - goto expecting_operand_after_comma; - } - expecting_operand = 1; + /* Holds temlate once we've found it. */ + register template * t; + + /* Possible templates for current insn */ + templates *current_templates = (templates *) 0; + + /* Initialize globals. */ + bzero (&i, sizeof(i)); + bzero (disp_expressions, sizeof(disp_expressions)); + bzero (im_expressions, sizeof(im_expressions)); + save_stack_p = save_stack; /* reset stack pointer */ + + /* Fist parse an opcode & call i386_operand for the operands. + We assume that the scrubber has arranged it so that line[0] is the valid + start of a (possibly prefixed) opcode. */ + { + register char *l = line; /* Fast place to put LINE. */ + + /* 1 if operand is pending after ','. */ + unsigned int expecting_operand = 0; + /* 1 if we found a prefix only acceptable with string insns. */ + unsigned int expecting_string_instruction = 0; + /* Non-zero if operand parens not balenced. */ + unsigned int paren_not_balenced; + char * token_start = l; + + while (! is_space_char(*l) && *l != END_OF_INSN) { + if (! is_opcode_char(*l)) { + as_bad("invalid character %s in opcode", output_invalid(*l)); + return; + } else if (*l != PREFIX_SEPERATOR) { + *l = opcode_chars[(unsigned char) *l]; /* fold case of opcodes */ + l++; + } else { /* this opcode's got a prefix */ + register unsigned int q; + register prefix_entry * prefix; + + if (l == token_start) { + as_bad("expecting prefix; got nothing"); + return; + } + END_STRING_AND_SAVE (l); + prefix = (prefix_entry *) hash_find (prefix_hash, token_start); + if (! prefix) { + as_bad("no such opcode prefix ('%s')", token_start); + return; + } + RESTORE_END_STRING (l); + /* check for repeated prefix */ + for (q = 0; q < i.prefixes; q++) + if (i.prefix[q] == prefix->prefix_code) { + as_bad("same prefix used twice; you don't really want this!"); + return; + } + if (i.prefixes == MAX_PREFIXES) { + as_bad("too many opcode prefixes"); + return; + } + i.prefix[i.prefixes++] = prefix->prefix_code; + if (prefix->prefix_code == REPE || prefix->prefix_code == REPNE) + expecting_string_instruction = 1; + /* skip past PREFIX_SEPERATOR and reset token_start */ + token_start = ++l; + } + } + END_STRING_AND_SAVE (l); + if (token_start == l) { + as_bad("expecting opcode; got nothing"); + return; + } + + /* Lookup insn in hash; try intel & att naming conventions if appropriate; + that is: we only use the opcode suffix 'b' 'w' or 'l' if we need to. */ + current_templates = (templates *) hash_find (op_hash, token_start); + if (! current_templates) { + int last_index = strlen(token_start) - 1; + char last_char = token_start[last_index]; + switch (last_char) { + case DWORD_OPCODE_SUFFIX: + case WORD_OPCODE_SUFFIX: + case BYTE_OPCODE_SUFFIX: + token_start[last_index] = '\0'; + current_templates = (templates *) hash_find (op_hash, token_start); + token_start[last_index] = last_char; + i.suffix = last_char; + } + if (!current_templates) { + as_bad("no such 386 instruction: `%s'", token_start); return; + } + } + RESTORE_END_STRING (l); + + /* check for rep/repne without a string instruction */ + if (expecting_string_instruction && + ! IS_STRING_INSTRUCTION (current_templates-> + start->base_opcode)) { + as_bad("expecting string instruction after rep/repne"); + return; + } + + /* There may be operands to parse. */ + if (*l != END_OF_INSN && + /* For string instructions, we ignore any operands if given. This + kludges, for example, 'rep/movsb %ds:(%esi), %es:(%edi)' where + the operands are always going to be the same, and are not really + encoded in machine code. */ + ! IS_STRING_INSTRUCTION (current_templates-> + start->base_opcode)) { + /* parse operands */ + do { + /* skip optional white space before operand */ + while (! is_operand_char(*l) && *l != END_OF_INSN) { + if (! is_space_char(*l)) { + as_bad("invalid character %s before %s operand", + output_invalid(*l), + ordinal_names[i.operands]); + return; + } + l++; + } + token_start = l; /* after white space */ + paren_not_balenced = 0; + while (paren_not_balenced || *l != ',') { + if (*l == END_OF_INSN) { + if (paren_not_balenced) { + as_bad("unbalenced parenthesis in %s operand.", + ordinal_names[i.operands]); + return; + } else break; /* we are done */ + } else if (! is_operand_char(*l)) { + as_bad("invalid character %s in %s operand", + output_invalid(*l), + ordinal_names[i.operands]); + return; + } + if (*l == '(') ++paren_not_balenced; + if (*l == ')') --paren_not_balenced; + l++; + } + if (l != token_start) { /* yes, we've read in another operand */ + unsigned int operand_ok; + this_operand = i.operands++; + if (i.operands > MAX_OPERANDS) { + as_bad("spurious operands; (%d operands/instruction max)", + MAX_OPERANDS); + return; + } + /* now parse operand adding info to 'i' as we go along */ + END_STRING_AND_SAVE (l); + operand_ok = i386_operand (token_start); + RESTORE_END_STRING (l); /* restore old contents */ + if (!operand_ok) return; + } else { + if (expecting_operand) { + expecting_operand_after_comma: + as_bad("expecting operand after ','; got nothing"); + return; + } + if (*l == ',') { + as_bad("expecting operand before ','; got nothing"); + return; + } + } + + /* now *l must be either ',' or END_OF_INSN */ + if (*l == ',') { + if (*++l == END_OF_INSN) { /* just skip it, if it's \n complain */ + goto expecting_operand_after_comma; + } + expecting_operand = 1; + } + } while (*l != END_OF_INSN); /* until we get end of insn */ + } } - } while (*l != END_OF_INSN); /* until we get end of insn */ - } - } - - /* Now we've parsed the opcode into a set of templates, and have the - operands at hand. - Next, we find a template that matches the given insn, - making sure the overlap of the given operands types is consistent - with the template operand types. */ - + + /* Now we've parsed the opcode into a set of templates, and have the + operands at hand. + Next, we find a template that matches the given insn, + making sure the overlap of the given operands types is consistent + with the template operand types. */ + #define MATCH(overlap,given_type) \ - (overlap && \ - (overlap & (JumpAbsolute|BaseIndex|Mem8)) \ - == (given_type & (JumpAbsolute|BaseIndex|Mem8))) - - /* If m0 and m1 are register matches they must be consistent - with the expected operand types t0 and t1. - That is, if both m0 & m1 are register matches - i.e. ( ((m0 & (Reg)) && (m1 & (Reg)) ) ? - then, either 1. or 2. must be true: - 1. the expected operand type register overlap is null: - (t0 & t1 & Reg) == 0 - AND - the given register overlap is null: - (m0 & m1 & Reg) == 0 - 2. the expected operand type register overlap == the given - operand type overlap: (t0 & t1 & m0 & m1 & Reg). - */ -#define CONSISTENT_REGISTER_MATCH(m0, m1, t0, t1) \ - ( ((m0 & (Reg)) && (m1 & (Reg))) ? \ - ( ((t0 & t1 & (Reg)) == 0 && (m0 & m1 & (Reg)) == 0) || \ - ((t0 & t1) & (m0 & m1) & (Reg)) \ - ) : 1) - { - register unsigned int overlap0, overlap1; - expressionS * exp; - unsigned int overlap2; - unsigned int found_reverse_match; - - overlap0 = overlap1 = overlap2 = found_reverse_match = 0; - for (t = current_templates->start; - t < current_templates->end; - t++) { - - /* must have right number of operands */ - if (i.operands != t->operands) continue; - else if (!t->operands) break; /* 0 operands always matches */ - - overlap0 = i.types[0] & t->operand_types[0]; - switch (t->operands) { - case 1: - if (! MATCH (overlap0,i.types[0])) continue; - break; - case 2: case 3: - overlap1 = i.types[1] & t->operand_types[1]; - if (! MATCH (overlap0,i.types[0]) || - ! MATCH (overlap1,i.types[1]) || - ! CONSISTENT_REGISTER_MATCH(overlap0, overlap1, - t->operand_types[0], - t->operand_types[1])) { - - /* check if other direction is valid ... */ - if (! (t->opcode_modifier & COMES_IN_BOTH_DIRECTIONS)) - continue; - - /* try reversing direction of operands */ - overlap0 = i.types[0] & t->operand_types[1]; - overlap1 = i.types[1] & t->operand_types[0]; - if (! MATCH (overlap0,i.types[0]) || - ! MATCH (overlap1,i.types[1]) || - ! CONSISTENT_REGISTER_MATCH (overlap0, overlap1, - t->operand_types[0], - t->operand_types[1])) { - /* does not match either direction */ - continue; - } - /* found a reverse match here -- slip through */ - /* found_reverse_match holds which of D or FloatD we've found */ - found_reverse_match = t->opcode_modifier & COMES_IN_BOTH_DIRECTIONS; - } /* endif: not forward match */ - /* found either forward/reverse 2 operand match here */ - if (t->operands == 3) { - overlap2 = i.types[2] & t->operand_types[2]; - if (! MATCH (overlap2,i.types[2]) || - ! CONSISTENT_REGISTER_MATCH (overlap0, overlap2, - t->operand_types[0], - t->operand_types[2]) || - ! CONSISTENT_REGISTER_MATCH (overlap1, overlap2, - t->operand_types[1], - t->operand_types[2])) - continue; - } - /* found either forward/reverse 2 or 3 operand match here: - slip through to break */ - } - break; /* we've found a match; break out of loop */ - } /* for (t = ... */ - if (t == current_templates->end) { /* we found no match */ - as_bad("operands given don't match any known 386 instruction"); - return; - } - - /* Copy the template we found (we may change it!). */ - bcopy (t, &i.tm, sizeof (template)); - t = &i.tm; /* alter new copy of template */ - - /* If there's no opcode suffix we try to invent one based on register - operands. */ - if (! i.suffix && i.reg_operands) { - /* We take i.suffix from the LAST register operand specified. This - assumes that the last register operands is the destination register - operand. */ - int o; - for (o = 0; o < MAX_OPERANDS; o++) - if (i.types[o] & Reg) { - i.suffix = (i.types[o] == Reg8) ? BYTE_OPCODE_SUFFIX : - (i.types[o] == Reg16) ? WORD_OPCODE_SUFFIX : - DWORD_OPCODE_SUFFIX; - } - } - - /* Make still unresolved immediate matches conform to size of immediate - given in i.suffix. Note: overlap2 cannot be an immediate! - We assume this. */ - if ((overlap0 & (Imm8|Imm8S|Imm16|Imm32)) - && overlap0 != Imm8 && overlap0 != Imm8S - && overlap0 != Imm16 && overlap0 != Imm32) { - if (! i.suffix) { - as_bad("no opcode suffix given; can't determine immediate size"); - return; - } - overlap0 &= (i.suffix == BYTE_OPCODE_SUFFIX ? (Imm8|Imm8S) : - (i.suffix == WORD_OPCODE_SUFFIX ? Imm16 : Imm32)); - } - if ((overlap1 & (Imm8|Imm8S|Imm16|Imm32)) - && overlap1 != Imm8 && overlap1 != Imm8S - && overlap1 != Imm16 && overlap1 != Imm32) { - if (! i.suffix) { - as_bad("no opcode suffix given; can't determine immediate size"); - return; - } - overlap1 &= (i.suffix == BYTE_OPCODE_SUFFIX ? (Imm8|Imm8S) : - (i.suffix == WORD_OPCODE_SUFFIX ? Imm16 : Imm32)); - } - - i.types[0] = overlap0; - i.types[1] = overlap1; - i.types[2] = overlap2; - - if (overlap0 & ImplicitRegister) i.reg_operands--; - if (overlap1 & ImplicitRegister) i.reg_operands--; - if (overlap2 & ImplicitRegister) i.reg_operands--; - if (overlap0 & Imm1) i.imm_operands = 0; /* kludge for shift insns */ - - if (found_reverse_match) { - unsigned int save; - save = t->operand_types[0]; - t->operand_types[0] = t->operand_types[1]; - t->operand_types[1] = save; - } - - /* Finalize opcode. First, we change the opcode based on the operand - size given by i.suffix: we never have to change things for byte insns, - or when no opcode suffix is need to size the operands. */ - - if (! i.suffix && (t->opcode_modifier & W)) { - as_bad("no opcode suffix given and no register operands; can't size instruction"); - return; - } - - if (i.suffix && i.suffix != BYTE_OPCODE_SUFFIX) { - /* Select between byte and word/dword operations. */ - if (t->opcode_modifier & W) - t->base_opcode |= W; - /* Now select between word & dword operations via the - operand size prefix. */ - if (i.suffix == WORD_OPCODE_SUFFIX) { - if (i.prefixes == MAX_PREFIXES) { - as_bad("%d prefixes given and 'w' opcode suffix gives too many prefixes", - MAX_PREFIXES); - return; - } - i.prefix[i.prefixes++] = WORD_PREFIX_OPCODE; - } - } - - /* For insns with operands there are more diddles to do to the opcode. */ - if (i.operands) { - /* If we found a reverse match we must alter the opcode direction bit - found_reverse_match holds bit to set (different for int & - float insns). */ - - if (found_reverse_match) { - t->base_opcode |= found_reverse_match; - } - - /* - The imul $imm, %reg instruction is converted into - imul $imm, %reg, %reg. */ - if (t->opcode_modifier & imulKludge) { - i.regs[2] = i.regs[1]; /* Pretend we saw the 3 operand case. */ - i.reg_operands = 2; - } - - /* Certain instructions expect the destination to be in the i.rm.reg - field. This is by far the exceptional case. For these instructions, - if the source operand is a register, we must reverse the i.rm.reg - and i.rm.regmem fields. We accomplish this by faking that the - two register operands were given in the reverse order. */ - if ((t->opcode_modifier & ReverseRegRegmem) && i.reg_operands == 2) { - unsigned int first_reg_operand = (i.types[0] & Reg) ? 0 : 1; - unsigned int second_reg_operand = first_reg_operand + 1; - reg_entry *tmp = i.regs[first_reg_operand]; - i.regs[first_reg_operand] = i.regs[second_reg_operand]; - i.regs[second_reg_operand] = tmp; - } - - if (t->opcode_modifier & ShortForm) { - /* The register or float register operand is in operand 0 or 1. */ - unsigned int o = (i.types[0] & (Reg|FloatReg)) ? 0 : 1; - /* Register goes in low 3 bits of opcode. */ - t->base_opcode |= i.regs[o]->reg_num; - } else if (t->opcode_modifier & ShortFormW) { - /* Short form with 0x8 width bit. Register is always dest. operand */ - t->base_opcode |= i.regs[1]->reg_num; - if (i.suffix == WORD_OPCODE_SUFFIX || - i.suffix == DWORD_OPCODE_SUFFIX) - t->base_opcode |= 0x8; - } else if (t->opcode_modifier & Seg2ShortForm) { - if (t->base_opcode == POP_SEG_SHORT && i.regs[0]->reg_num == 1) { - as_bad("you can't 'pop cs' on the 386."); - return; - } - t->base_opcode |= (i.regs[0]->reg_num << 3); - } else if (t->opcode_modifier & Seg3ShortForm) { - /* 'push %fs' is 0x0fa0; 'pop %fs' is 0x0fa1. - 'push %gs' is 0x0fa8; 'pop %fs' is 0x0fa9. - So, only if i.regs[0]->reg_num == 5 (%gs) do we need - to change the opcode. */ - if (i.regs[0]->reg_num == 5) - t->base_opcode |= 0x08; - } else if (t->opcode_modifier & Modrm) { - /* The opcode is completed (modulo t->extension_opcode which must - be put into the modrm byte. - Now, we make the modrm & index base bytes based on all the info - we've collected. */ - - /* i.reg_operands MUST be the number of real register operands; - implicit registers do not count. */ - if (i.reg_operands == 2) { - unsigned int source, dest; - source = (i.types[0] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 0 : 1; - dest = source + 1; - i.rm.mode = 3; - /* We must be careful to make sure that all segment/control/test/ - debug registers go into the i.rm.reg field (despite the whether - they are source or destination operands). */ - if (i.regs[dest]->reg_type & (SReg2|SReg3|Control|Debug|Test)) { - i.rm.reg = i.regs[dest]->reg_num; - i.rm.regmem = i.regs[source]->reg_num; - } else { - i.rm.reg = i.regs[source]->reg_num; - i.rm.regmem = i.regs[dest]->reg_num; - } - } else { /* if it's not 2 reg operands... */ - if (i.mem_operands) { - unsigned int fake_zero_displacement = 0; - unsigned int o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2); + (overlap && \ + (overlap & (JumpAbsolute|BaseIndex|Mem8)) \ + == (given_type & (JumpAbsolute|BaseIndex|Mem8))) - /* Encode memory operand into modrm byte and base index byte. */ - - if (i.base_reg == esp && ! i.index_reg) { - /* <disp>(%esp) becomes two byte modrm with no index register. */ - i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); - i.bi.base = ESP_REG_NUM; - i.bi.index = NO_INDEX_REGISTER; - i.bi.scale = 0; /* Must be zero! */ - } else if (i.base_reg == ebp && !i.index_reg) { - if (! (i.types[o] & Disp)) { - /* Must fake a zero byte displacement. - There is no direct way to code '(%ebp)' directly. */ - fake_zero_displacement = 1; - /* fake_zero_displacement code does not set this. */ - i.types[o] |= Disp8; - } - i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); - i.rm.regmem = EBP_REG_NUM; - } else if (! i.base_reg && (i.types[o] & BaseIndex)) { - /* There are three cases here. - Case 1: '<32bit disp>(,1)' -- indirect absolute. - (Same as cases 2 & 3 with NO index register) - Case 2: <32bit disp> (,<index>) -- no base register with disp - Case 3: (, <index>) --- no base register; - no disp (must add 32bit 0 disp). */ - i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - i.rm.mode = 0; /* 32bit mode */ - i.bi.base = NO_BASE_REGISTER; - i.types[o] &= ~Disp; - i.types[o] |= Disp32; /* Must be 32bit! */ - if (i.index_reg) { /* case 2 or case 3 */ - i.bi.index = i.index_reg->reg_num; - i.bi.scale = i.log2_scale_factor; - if (i.disp_operands == 0) - fake_zero_displacement = 1; /* case 3 */ - } else { - i.bi.index = NO_INDEX_REGISTER; - i.bi.scale = 0; - } - } else if (i.disp_operands && !i.base_reg && !i.index_reg) { - /* Operand is just <32bit disp> */ - i.rm.regmem = EBP_REG_NUM; - i.rm.mode = 0; - i.types[o] &= ~Disp; - i.types[o] |= Disp32; - } else { - /* It's not a special case; rev'em up. */ - i.rm.regmem = i.base_reg->reg_num; - i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); - if (i.index_reg) { - i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - i.bi.base = i.base_reg->reg_num; - i.bi.index = i.index_reg->reg_num; - i.bi.scale = i.log2_scale_factor; - if (i.base_reg == ebp && i.disp_operands == 0) { /* pace */ - fake_zero_displacement = 1; - i.types[o] |= Disp8; - i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); - } - } - } - if (fake_zero_displacement) { - /* Fakes a zero displacement assuming that i.types[o] holds - the correct displacement size. */ - exp = &disp_expressions[i.disp_operands++]; - i.disps[o] = exp; - exp->X_seg = SEG_ABSOLUTE; - exp->X_add_number = 0; - exp->X_add_symbol = (symbolS *) 0; - exp->X_subtract_symbol = (symbolS *) 0; - } - - /* Select the correct segment for the memory operand. */ - if (i.seg) { - const unsigned int seg_index; - const seg_entry * default_seg; - - if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING) { - seg_index = (i.rm.mode<<3) | i.bi.base; - default_seg = two_byte_segment_defaults [seg_index]; - } else { - seg_index = (i.rm.mode<<3) | i.rm.regmem; - default_seg = one_byte_segment_defaults [seg_index]; - } - /* If the specified segment is not the default, use an - opcode prefix to select it */ - if (i.seg != default_seg) { - if (i.prefixes == MAX_PREFIXES) { - as_bad("%d prefixes given and %s segment override gives too many prefixes", - MAX_PREFIXES, i.seg->seg_name); - return; + /* If m0 and m1 are register matches they must be consistent + with the expected operand types t0 and t1. + That is, if both m0 & m1 are register matches + i.e. ( ((m0 & (Reg)) && (m1 & (Reg)) ) ? + then, either 1. or 2. must be true: + 1. the expected operand type register overlap is null: + (t0 & t1 & Reg) == 0 + AND + the given register overlap is null: + (m0 & m1 & Reg) == 0 + 2. the expected operand type register overlap == the given + operand type overlap: (t0 & t1 & m0 & m1 & Reg). + */ +#define CONSISTENT_REGISTER_MATCH(m0, m1, t0, t1) \ + ( ((m0 & (Reg)) && (m1 & (Reg))) ? \ + ( ((t0 & t1 & (Reg)) == 0 && (m0 & m1 & (Reg)) == 0) || \ + ((t0 & t1) & (m0 & m1) & (Reg)) \ + ) : 1) + { + register unsigned int overlap0, overlap1; + expressionS * exp; + unsigned int overlap2; + unsigned int found_reverse_match; + + overlap0 = overlap1 = overlap2 = found_reverse_match = 0; + for (t = current_templates->start; + t < current_templates->end; + t++) { + + /* must have right number of operands */ + if (i.operands != t->operands) continue; + else if (!t->operands) break; /* 0 operands always matches */ + + overlap0 = i.types[0] & t->operand_types[0]; + switch (t->operands) { + case 1: + if (! MATCH (overlap0,i.types[0])) continue; + break; + case 2: case 3: + overlap1 = i.types[1] & t->operand_types[1]; + if (! MATCH (overlap0,i.types[0]) || + ! MATCH (overlap1,i.types[1]) || + ! CONSISTENT_REGISTER_MATCH(overlap0, overlap1, + t->operand_types[0], + t->operand_types[1])) { + + /* check if other direction is valid ... */ + if (! (t->opcode_modifier & COMES_IN_BOTH_DIRECTIONS)) + continue; + + /* try reversing direction of operands */ + overlap0 = i.types[0] & t->operand_types[1]; + overlap1 = i.types[1] & t->operand_types[0]; + if (! MATCH (overlap0,i.types[0]) || + ! MATCH (overlap1,i.types[1]) || + ! CONSISTENT_REGISTER_MATCH (overlap0, overlap1, + t->operand_types[0], + t->operand_types[1])) { + /* does not match either direction */ + continue; + } + /* found a reverse match here -- slip through */ + /* found_reverse_match holds which of D or FloatD we've found */ + found_reverse_match = t->opcode_modifier & COMES_IN_BOTH_DIRECTIONS; + } /* endif: not forward match */ + /* found either forward/reverse 2 operand match here */ + if (t->operands == 3) { + overlap2 = i.types[2] & t->operand_types[2]; + if (! MATCH (overlap2,i.types[2]) || + ! CONSISTENT_REGISTER_MATCH (overlap0, overlap2, + t->operand_types[0], + t->operand_types[2]) || + ! CONSISTENT_REGISTER_MATCH (overlap1, overlap2, + t->operand_types[1], + t->operand_types[2])) + continue; + } + /* found either forward/reverse 2 or 3 operand match here: + slip through to break */ + } + break; /* we've found a match; break out of loop */ + } /* for (t = ... */ + if (t == current_templates->end) { /* we found no match */ + as_bad("operands given don't match any known 386 instruction"); + return; + } + + /* Copy the template we found (we may change it!). */ + bcopy (t, &i.tm, sizeof (template)); + t = &i.tm; /* alter new copy of template */ + + /* If there's no opcode suffix we try to invent one based on register + operands. */ + if (! i.suffix && i.reg_operands) { + /* We take i.suffix from the LAST register operand specified. This + assumes that the last register operands is the destination register + operand. */ + int o; + for (o = 0; o < MAX_OPERANDS; o++) + if (i.types[o] & Reg) { + i.suffix = (i.types[o] == Reg8) ? BYTE_OPCODE_SUFFIX : + (i.types[o] == Reg16) ? WORD_OPCODE_SUFFIX : + DWORD_OPCODE_SUFFIX; + } + } + + /* Make still unresolved immediate matches conform to size of immediate + given in i.suffix. Note: overlap2 cannot be an immediate! + We assume this. */ + if ((overlap0 & (Imm8|Imm8S|Imm16|Imm32)) + && overlap0 != Imm8 && overlap0 != Imm8S + && overlap0 != Imm16 && overlap0 != Imm32) { + if (! i.suffix) { + as_bad("no opcode suffix given; can't determine immediate size"); + return; + } + overlap0 &= (i.suffix == BYTE_OPCODE_SUFFIX ? (Imm8|Imm8S) : + (i.suffix == WORD_OPCODE_SUFFIX ? Imm16 : Imm32)); + } + if ((overlap1 & (Imm8|Imm8S|Imm16|Imm32)) + && overlap1 != Imm8 && overlap1 != Imm8S + && overlap1 != Imm16 && overlap1 != Imm32) { + if (! i.suffix) { + as_bad("no opcode suffix given; can't determine immediate size"); + return; + } + overlap1 &= (i.suffix == BYTE_OPCODE_SUFFIX ? (Imm8|Imm8S) : + (i.suffix == WORD_OPCODE_SUFFIX ? Imm16 : Imm32)); + } + + i.types[0] = overlap0; + i.types[1] = overlap1; + i.types[2] = overlap2; + + if (overlap0 & ImplicitRegister) i.reg_operands--; + if (overlap1 & ImplicitRegister) i.reg_operands--; + if (overlap2 & ImplicitRegister) i.reg_operands--; + if (overlap0 & Imm1) i.imm_operands = 0; /* kludge for shift insns */ + + if (found_reverse_match) { + unsigned int save; + save = t->operand_types[0]; + t->operand_types[0] = t->operand_types[1]; + t->operand_types[1] = save; + } + + /* Finalize opcode. First, we change the opcode based on the operand + size given by i.suffix: we never have to change things for byte insns, + or when no opcode suffix is need to size the operands. */ + + if (! i.suffix && (t->opcode_modifier & W)) { + as_bad("no opcode suffix given and no register operands; can't size instruction"); + return; + } + + if (i.suffix && i.suffix != BYTE_OPCODE_SUFFIX) { + /* Select between byte and word/dword operations. */ + if (t->opcode_modifier & W) + t->base_opcode |= W; + /* Now select between word & dword operations via the + operand size prefix. */ + if (i.suffix == WORD_OPCODE_SUFFIX) { + if (i.prefixes == MAX_PREFIXES) { + as_bad("%d prefixes given and 'w' opcode suffix gives too many prefixes", + MAX_PREFIXES); + return; + } + i.prefix[i.prefixes++] = WORD_PREFIX_OPCODE; + } + } + + /* For insns with operands there are more diddles to do to the opcode. */ + if (i.operands) { + /* If we found a reverse match we must alter the opcode direction bit + found_reverse_match holds bit to set (different for int & + float insns). */ + + if (found_reverse_match) { + t->base_opcode |= found_reverse_match; + } + + /* + The imul $imm, %reg instruction is converted into + imul $imm, %reg, %reg. */ + if (t->opcode_modifier & imulKludge) { + i.regs[2] = i.regs[1]; /* Pretend we saw the 3 operand case. */ + i.reg_operands = 2; + } + + /* Certain instructions expect the destination to be in the i.rm.reg + field. This is by far the exceptional case. For these instructions, + if the source operand is a register, we must reverse the i.rm.reg + and i.rm.regmem fields. We accomplish this by faking that the + two register operands were given in the reverse order. */ + if ((t->opcode_modifier & ReverseRegRegmem) && i.reg_operands == 2) { + unsigned int first_reg_operand = (i.types[0] & Reg) ? 0 : 1; + unsigned int second_reg_operand = first_reg_operand + 1; + reg_entry *tmp = i.regs[first_reg_operand]; + i.regs[first_reg_operand] = i.regs[second_reg_operand]; + i.regs[second_reg_operand] = tmp; + } + + if (t->opcode_modifier & ShortForm) { + /* The register or float register operand is in operand 0 or 1. */ + unsigned int o = (i.types[0] & (Reg|FloatReg)) ? 0 : 1; + /* Register goes in low 3 bits of opcode. */ + t->base_opcode |= i.regs[o]->reg_num; + } else if (t->opcode_modifier & ShortFormW) { + /* Short form with 0x8 width bit. Register is always dest. operand */ + t->base_opcode |= i.regs[1]->reg_num; + if (i.suffix == WORD_OPCODE_SUFFIX || + i.suffix == DWORD_OPCODE_SUFFIX) + t->base_opcode |= 0x8; + } else if (t->opcode_modifier & Seg2ShortForm) { + if (t->base_opcode == POP_SEG_SHORT && i.regs[0]->reg_num == 1) { + as_bad("you can't 'pop cs' on the 386."); + return; + } + t->base_opcode |= (i.regs[0]->reg_num << 3); + } else if (t->opcode_modifier & Seg3ShortForm) { + /* 'push %fs' is 0x0fa0; 'pop %fs' is 0x0fa1. + 'push %gs' is 0x0fa8; 'pop %fs' is 0x0fa9. + So, only if i.regs[0]->reg_num == 5 (%gs) do we need + to change the opcode. */ + if (i.regs[0]->reg_num == 5) + t->base_opcode |= 0x08; + } else if (t->opcode_modifier & Modrm) { + /* The opcode is completed (modulo t->extension_opcode which must + be put into the modrm byte. + Now, we make the modrm & index base bytes based on all the info + we've collected. */ + + /* i.reg_operands MUST be the number of real register operands; + implicit registers do not count. */ + if (i.reg_operands == 2) { + unsigned int source, dest; + source = (i.types[0] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 0 : 1; + dest = source + 1; + i.rm.mode = 3; + /* We must be careful to make sure that all segment/control/test/ + debug registers go into the i.rm.reg field (despite the whether + they are source or destination operands). */ + if (i.regs[dest]->reg_type & (SReg2|SReg3|Control|Debug|Test)) { + i.rm.reg = i.regs[dest]->reg_num; + i.rm.regmem = i.regs[source]->reg_num; + } else { + i.rm.reg = i.regs[source]->reg_num; + i.rm.regmem = i.regs[dest]->reg_num; + } + } else { /* if it's not 2 reg operands... */ + if (i.mem_operands) { + unsigned int fake_zero_displacement = 0; + unsigned int o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2); + + /* Encode memory operand into modrm byte and base index byte. */ + + if (i.base_reg == esp && ! i.index_reg) { + /* <disp>(%esp) becomes two byte modrm with no index register. */ + i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; + i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); + i.bi.base = ESP_REG_NUM; + i.bi.index = NO_INDEX_REGISTER; + i.bi.scale = 0; /* Must be zero! */ + } else if (i.base_reg == ebp && !i.index_reg) { + if (! (i.types[o] & Disp)) { + /* Must fake a zero byte displacement. + There is no direct way to code '(%ebp)' directly. */ + fake_zero_displacement = 1; + /* fake_zero_displacement code does not set this. */ + i.types[o] |= Disp8; + } + i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); + i.rm.regmem = EBP_REG_NUM; + } else if (! i.base_reg && (i.types[o] & BaseIndex)) { + /* There are three cases here. + Case 1: '<32bit disp>(,1)' -- indirect absolute. + (Same as cases 2 & 3 with NO index register) + Case 2: <32bit disp> (,<index>) -- no base register with disp + Case 3: (, <index>) --- no base register; + no disp (must add 32bit 0 disp). */ + i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; + i.rm.mode = 0; /* 32bit mode */ + i.bi.base = NO_BASE_REGISTER; + i.types[o] &= ~Disp; + i.types[o] |= Disp32; /* Must be 32bit! */ + if (i.index_reg) { /* case 2 or case 3 */ + i.bi.index = i.index_reg->reg_num; + i.bi.scale = i.log2_scale_factor; + if (i.disp_operands == 0) + fake_zero_displacement = 1; /* case 3 */ + } else { + i.bi.index = NO_INDEX_REGISTER; + i.bi.scale = 0; + } + } else if (i.disp_operands && !i.base_reg && !i.index_reg) { + /* Operand is just <32bit disp> */ + i.rm.regmem = EBP_REG_NUM; + i.rm.mode = 0; + i.types[o] &= ~Disp; + i.types[o] |= Disp32; + } else { + /* It's not a special case; rev'em up. */ + i.rm.regmem = i.base_reg->reg_num; + i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); + if (i.index_reg) { + i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; + i.bi.base = i.base_reg->reg_num; + i.bi.index = i.index_reg->reg_num; + i.bi.scale = i.log2_scale_factor; + if (i.base_reg == ebp && i.disp_operands == 0) { /* pace */ + fake_zero_displacement = 1; + i.types[o] |= Disp8; + i.rm.mode = MODE_FROM_DISP_SIZE (i.types[o]); + } + } + } + if (fake_zero_displacement) { + /* Fakes a zero displacement assuming that i.types[o] holds + the correct displacement size. */ + exp = &disp_expressions[i.disp_operands++]; + i.disps[o] = exp; + exp->X_seg = SEG_ABSOLUTE; + exp->X_add_number = 0; + exp->X_add_symbol = (symbolS *) 0; + exp->X_subtract_symbol = (symbolS *) 0; + } + + /* Select the correct segment for the memory operand. */ + if (i.seg) { + const unsigned int seg_index; + const seg_entry * default_seg; + + if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING) { + seg_index = (i.rm.mode<<3) | i.bi.base; + default_seg = two_byte_segment_defaults [seg_index]; + } else { + seg_index = (i.rm.mode<<3) | i.rm.regmem; + default_seg = one_byte_segment_defaults [seg_index]; + } + /* If the specified segment is not the default, use an + opcode prefix to select it */ + if (i.seg != default_seg) { + if (i.prefixes == MAX_PREFIXES) { + as_bad("%d prefixes given and %s segment override gives too many prefixes", + MAX_PREFIXES, i.seg->seg_name); + return; + } + i.prefix[i.prefixes++] = i.seg->seg_prefix; + } + } + } + + /* Fill in i.rm.reg or i.rm.regmem field with register operand + (if any) based on t->extension_opcode. Again, we must be careful + to make sure that segment/control/debug/test registers are coded + into the i.rm.reg field. */ + if (i.reg_operands) { + unsigned int o = + (i.types[0] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 0 : + (i.types[1] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 1 : 2; + /* If there is an extension opcode to put here, the register number + must be put into the regmem field. */ + if (t->extension_opcode != None) + i.rm.regmem = i.regs[o]->reg_num; + else i.rm.reg = i.regs[o]->reg_num; + + /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 + we must set it to 3 to indicate this is a register operand + int the regmem field */ + if (! i.mem_operands) i.rm.mode = 3; + } + + /* Fill in i.rm.reg field with extension opcode (if any). */ + if (t->extension_opcode != None) + i.rm.reg = t->extension_opcode; + } + } + } } - i.prefix[i.prefixes++] = i.seg->seg_prefix; - } - } - } - - /* Fill in i.rm.reg or i.rm.regmem field with register operand - (if any) based on t->extension_opcode. Again, we must be careful - to make sure that segment/control/debug/test registers are coded - into the i.rm.reg field. */ - if (i.reg_operands) { - unsigned int o = - (i.types[0] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 0 : - (i.types[1] & (Reg|SReg2|SReg3|Control|Debug|Test)) ? 1 : 2; - /* If there is an extension opcode to put here, the register number - must be put into the regmem field. */ - if (t->extension_opcode != None) - i.rm.regmem = i.regs[o]->reg_num; - else i.rm.reg = i.regs[o]->reg_num; - - /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 - we must set it to 3 to indicate this is a register operand - int the regmem field */ - if (! i.mem_operands) i.rm.mode = 3; - } - - /* Fill in i.rm.reg field with extension opcode (if any). */ - if (t->extension_opcode != None) - i.rm.reg = t->extension_opcode; - } - } - } - } - - /* Handle conversion of 'int $3' --> special int3 insn. */ - if (t->base_opcode == INT_OPCODE && i.imms[0]->X_add_number == 3) { - t->base_opcode = INT3_OPCODE; - i.imm_operands = 0; - } - - /* We are ready to output the insn. */ - { - register char * p; - - /* Output jumps. */ - if (t->opcode_modifier & Jump) { - int n = i.disps[0]->X_add_number; - - switch (i.disps[0]->X_seg) { - case SEG_ABSOLUTE: - if (FITS_IN_SIGNED_BYTE (n)) { - p = frag_more (2); - p[0] = t->base_opcode; - p[1] = n; -#if 0 /* leave out 16 bit jumps - pace */ - } else if (FITS_IN_SIGNED_WORD (n)) { - p = frag_more (4); - p[0] = WORD_PREFIX_OPCODE; - p[1] = t->base_opcode; - md_number_to_chars (&p[2], n, 2); -#endif - } else { /* It's an absolute dword displacement. */ - if (t->base_opcode == JUMP_PC_RELATIVE) { /* pace */ - /* unconditional jump */ - p = frag_more (5); - p[0] = 0xe9; - md_number_to_chars (&p[1], n, 4); - } else { - /* conditional jump */ - p = frag_more (6); - p[0] = TWO_BYTE_OPCODE_ESCAPE; - p[1] = t->base_opcode + 0x10; - md_number_to_chars (&p[2], n, 4); - } - } - break; - default: - /* It's a symbol; end frag & setup for relax. - Make sure there are 6 chars left in the current frag; if not - we'll have to start a new one. */ - /* I caught it failing with obstack_room == 6, - so I changed to <= pace */ - if (obstack_room (&frags) <= 6) { - frag_wane(frag_now); - frag_new (0); - } - p = frag_more (1); - p[0] = t->base_opcode; - frag_var (rs_machine_dependent, - 6, /* 2 opcode/prefix + 4 displacement */ - 1, - ((unsigned char) *p == JUMP_PC_RELATIVE - ? ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE) - : ENCODE_RELAX_STATE (COND_JUMP, BYTE)), - i.disps[0]->X_add_symbol, - n, p); - break; - } - } else if (t->opcode_modifier & (JumpByte|JumpDword)) { - int size = (t->opcode_modifier & JumpByte) ? 1 : 4; - int n = i.disps[0]->X_add_number; - - if (FITS_IN_UNSIGNED_BYTE(t->base_opcode)) { - FRAG_APPEND_1_CHAR (t->base_opcode); - } else { - p = frag_more (2); /* opcode can be at most two bytes */ - /* put out high byte first: can't use md_number_to_chars! */ - *p++ = (t->base_opcode >> 8) & 0xff; - *p = t->base_opcode & 0xff; - } - - p = frag_more (size); - switch (i.disps[0]->X_seg) { - case SEG_ABSOLUTE: - md_number_to_chars (p, n, size); - if (size == 1 && ! FITS_IN_SIGNED_BYTE (n)) { - as_bad("loop/jecx only takes byte displacement; %d shortened to %d", - n, *p); - } - break; - default: - fix_new (frag_now, p - frag_now->fr_literal, size, - i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol, - i.disps[0]->X_add_number, 1, NO_RELOC); - break; - } - } else if (t->opcode_modifier & JumpInterSegment) { - p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */ - p[0] = t->base_opcode; - if (i.imms[1]->X_seg == SEG_ABSOLUTE) - md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4); - else - fix_new (frag_now, p + 1 - frag_now->fr_literal, 4, - i.imms[1]->X_add_symbol, - i.imms[1]->X_subtract_symbol, - i.imms[1]->X_add_number, 0, NO_RELOC); - if (i.imms[0]->X_seg != SEG_ABSOLUTE) - as_bad("can't handle non absolute segment in long call/jmp"); - md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2); - } else { - /* Output normal instructions here. */ - register char *q; - - /* First the prefix bytes. */ - for (q = i.prefix; q < i.prefix + i.prefixes; q++) { - p = frag_more (1); - md_number_to_chars (p, (unsigned int) *q, 1); - } - - /* Now the opcode; be careful about word order here! */ - if (FITS_IN_UNSIGNED_BYTE(t->base_opcode)) { - FRAG_APPEND_1_CHAR (t->base_opcode); - } else if (FITS_IN_UNSIGNED_WORD(t->base_opcode)) { - p = frag_more (2); - /* put out high byte first: can't use md_number_to_chars! */ - *p++ = (t->base_opcode >> 8) & 0xff; - *p = t->base_opcode & 0xff; - } else { /* opcode is either 3 or 4 bytes */ - if (t->base_opcode & 0xff000000) { - p = frag_more (4); - *p++ = (t->base_opcode >> 24) & 0xff; - } else p = frag_more (3); - *p++ = (t->base_opcode >> 16) & 0xff; - *p++ = (t->base_opcode >> 8) & 0xff; - *p = (t->base_opcode ) & 0xff; - } - - /* Now the modrm byte and base index byte (if present). */ - if (t->opcode_modifier & Modrm) { - p = frag_more (1); - /* md_number_to_chars (p, i.rm, 1); */ - md_number_to_chars (p, (i.rm.regmem<<0 | i.rm.reg<<3 | i.rm.mode<<6), 1); - /* If i.rm.regmem == ESP (4) && i.rm.mode != Mode 3 (Register mode) - ==> need second modrm byte. */ - if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING && i.rm.mode != 3) { - p = frag_more (1); - /* md_number_to_chars (p, i.bi, 1); */ - md_number_to_chars (p,(i.bi.base<<0 | i.bi.index<<3 | i.bi.scale<<6), 1); - } - } - - if (i.disp_operands) { - register unsigned int n; - for (n = 0; n < i.operands; n++) { - if (i.disps[n]) { - if (i.disps[n]->X_seg == SEG_ABSOLUTE) { - if (i.types[n] & (Disp8|Abs8)) { - p = frag_more (1); - md_number_to_chars (p, i.disps[n]->X_add_number, 1); - } else if (i.types[n] & (Disp16|Abs16)) { - p = frag_more (2); - md_number_to_chars (p, i.disps[n]->X_add_number, 2); - } else { /* Disp32|Abs32 */ - p = frag_more (4); - md_number_to_chars (p, i.disps[n]->X_add_number, 4); - } - } else { /* not SEG_ABSOLUTE */ - /* need a 32-bit fixup (don't support 8bit non-absolute disps) */ - p = frag_more (4); - fix_new (frag_now, p - frag_now->fr_literal, 4, - i.disps[n]->X_add_symbol, i.disps[n]->X_subtract_symbol, - i.disps[n]->X_add_number, 0, NO_RELOC); - } - } + /* Handle conversion of 'int $3' --> special int3 insn. */ + if (t->base_opcode == INT_OPCODE && i.imms[0]->X_add_number == 3) { + t->base_opcode = INT3_OPCODE; + i.imm_operands = 0; } - } /* end displacement output */ - - /* output immediate */ - if (i.imm_operands) { - register unsigned int n; - for (n = 0; n < i.operands; n++) { - if (i.imms[n]) { - if (i.imms[n]->X_seg == SEG_ABSOLUTE) { - if (i.types[n] & (Imm8|Imm8S)) { - p = frag_more (1); - md_number_to_chars (p, i.imms[n]->X_add_number, 1); - } else if (i.types[n] & Imm16) { - p = frag_more (2); - md_number_to_chars (p, i.imms[n]->X_add_number, 2); - } else { - p = frag_more (4); - md_number_to_chars (p, i.imms[n]->X_add_number, 4); - } - } else { /* not SEG_ABSOLUTE */ - /* need a 32-bit fixup (don't support 8bit non-absolute ims) */ - /* try to support other sizes ... */ - int size; - if (i.types[n] & (Imm8|Imm8S)) - size = 1; - else if (i.types[n] & Imm16) - size = 2; - else - size = 4; - p = frag_more (size); - fix_new (frag_now, p - frag_now->fr_literal, size, - i.imms[n]->X_add_symbol, i.imms[n]->X_subtract_symbol, - i.imms[n]->X_add_number, 0, NO_RELOC); - } - } - } - } /* end immediate output */ - } - + /* We are ready to output the insn. */ + { + register char * p; + + /* Output jumps. */ + if (t->opcode_modifier & Jump) { + int n = i.disps[0]->X_add_number; + + switch (i.disps[0]->X_seg) { + case SEG_ABSOLUTE: + if (FITS_IN_SIGNED_BYTE (n)) { + p = frag_more (2); + p[0] = t->base_opcode; + p[1] = n; +#if 0 /* leave out 16 bit jumps - pace */ + } else if (FITS_IN_SIGNED_WORD (n)) { + p = frag_more (4); + p[0] = WORD_PREFIX_OPCODE; + p[1] = t->base_opcode; + md_number_to_chars (&p[2], n, 2); +#endif + } else { /* It's an absolute dword displacement. */ + if (t->base_opcode == JUMP_PC_RELATIVE) { /* pace */ + /* unconditional jump */ + p = frag_more (5); + p[0] = 0xe9; + md_number_to_chars (&p[1], n, 4); + } else { + /* conditional jump */ + p = frag_more (6); + p[0] = TWO_BYTE_OPCODE_ESCAPE; + p[1] = t->base_opcode + 0x10; + md_number_to_chars (&p[2], n, 4); + } + } + break; + default: + /* It's a symbol; end frag & setup for relax. + Make sure there are 6 chars left in the current frag; if not + we'll have to start a new one. */ + /* I caught it failing with obstack_room == 6, + so I changed to <= pace */ + if (obstack_room (&frags) <= 6) { + frag_wane(frag_now); + frag_new (0); + } + p = frag_more (1); + p[0] = t->base_opcode; + frag_var (rs_machine_dependent, + 6, /* 2 opcode/prefix + 4 displacement */ + 1, + ((unsigned char) *p == JUMP_PC_RELATIVE + ? ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE) + : ENCODE_RELAX_STATE (COND_JUMP, BYTE)), + i.disps[0]->X_add_symbol, + n, p); + break; + } + } else if (t->opcode_modifier & (JumpByte|JumpDword)) { + int size = (t->opcode_modifier & JumpByte) ? 1 : 4; + int n = i.disps[0]->X_add_number; + + if (FITS_IN_UNSIGNED_BYTE(t->base_opcode)) { + FRAG_APPEND_1_CHAR (t->base_opcode); + } else { + p = frag_more (2); /* opcode can be at most two bytes */ + /* put out high byte first: can't use md_number_to_chars! */ + *p++ = (t->base_opcode >> 8) & 0xff; + *p = t->base_opcode & 0xff; + } + + p = frag_more (size); + switch (i.disps[0]->X_seg) { + case SEG_ABSOLUTE: + md_number_to_chars (p, n, size); + if (size == 1 && ! FITS_IN_SIGNED_BYTE (n)) { + as_bad("loop/jecx only takes byte displacement; %d shortened to %d", + n, *p); + } + break; + default: + fix_new (frag_now, p - frag_now->fr_literal, size, + i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol, + i.disps[0]->X_add_number, 1, NO_RELOC); + break; + } + } else if (t->opcode_modifier & JumpInterSegment) { + p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */ + p[0] = t->base_opcode; + if (i.imms[1]->X_seg == SEG_ABSOLUTE) + md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4); + else + fix_new (frag_now, p + 1 - frag_now->fr_literal, 4, + i.imms[1]->X_add_symbol, + i.imms[1]->X_subtract_symbol, + i.imms[1]->X_add_number, 0, NO_RELOC); + if (i.imms[0]->X_seg != SEG_ABSOLUTE) + as_bad("can't handle non absolute segment in long call/jmp"); + md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2); + } else { + /* Output normal instructions here. */ + register char *q; + + /* First the prefix bytes. */ + for (q = i.prefix; q < i.prefix + i.prefixes; q++) { + p = frag_more (1); + md_number_to_chars (p, (unsigned int) *q, 1); + } + + /* Now the opcode; be careful about word order here! */ + if (FITS_IN_UNSIGNED_BYTE(t->base_opcode)) { + FRAG_APPEND_1_CHAR (t->base_opcode); + } else if (FITS_IN_UNSIGNED_WORD(t->base_opcode)) { + p = frag_more (2); + /* put out high byte first: can't use md_number_to_chars! */ + *p++ = (t->base_opcode >> 8) & 0xff; + *p = t->base_opcode & 0xff; + } else { /* opcode is either 3 or 4 bytes */ + if (t->base_opcode & 0xff000000) { + p = frag_more (4); + *p++ = (t->base_opcode >> 24) & 0xff; + } else p = frag_more (3); + *p++ = (t->base_opcode >> 16) & 0xff; + *p++ = (t->base_opcode >> 8) & 0xff; + *p = (t->base_opcode ) & 0xff; + } + + /* Now the modrm byte and base index byte (if present). */ + if (t->opcode_modifier & Modrm) { + p = frag_more (1); + /* md_number_to_chars (p, i.rm, 1); */ + md_number_to_chars (p, (i.rm.regmem<<0 | i.rm.reg<<3 | i.rm.mode<<6), 1); + /* If i.rm.regmem == ESP (4) && i.rm.mode != Mode 3 (Register mode) + ==> need second modrm byte. */ + if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING && i.rm.mode != 3) { + p = frag_more (1); + /* md_number_to_chars (p, i.bi, 1); */ + md_number_to_chars (p,(i.bi.base<<0 | i.bi.index<<3 | i.bi.scale<<6), 1); + } + } + + if (i.disp_operands) { + register unsigned int n; + + for (n = 0; n < i.operands; n++) { + if (i.disps[n]) { + if (i.disps[n]->X_seg == SEG_ABSOLUTE) { + if (i.types[n] & (Disp8|Abs8)) { + p = frag_more (1); + md_number_to_chars (p, i.disps[n]->X_add_number, 1); + } else if (i.types[n] & (Disp16|Abs16)) { + p = frag_more (2); + md_number_to_chars (p, i.disps[n]->X_add_number, 2); + } else { /* Disp32|Abs32 */ + p = frag_more (4); + md_number_to_chars (p, i.disps[n]->X_add_number, 4); + } + } else { /* not SEG_ABSOLUTE */ + /* need a 32-bit fixup (don't support 8bit non-absolute disps) */ + p = frag_more (4); + fix_new (frag_now, p - frag_now->fr_literal, 4, + i.disps[n]->X_add_symbol, i.disps[n]->X_subtract_symbol, + i.disps[n]->X_add_number, 0, NO_RELOC); + } + } + } + } /* end displacement output */ + + /* output immediate */ + if (i.imm_operands) { + register unsigned int n; + + for (n = 0; n < i.operands; n++) { + if (i.imms[n]) { + if (i.imms[n]->X_seg == SEG_ABSOLUTE) { + if (i.types[n] & (Imm8|Imm8S)) { + p = frag_more (1); + md_number_to_chars (p, i.imms[n]->X_add_number, 1); + } else if (i.types[n] & Imm16) { + p = frag_more (2); + md_number_to_chars (p, i.imms[n]->X_add_number, 2); + } else { + p = frag_more (4); + md_number_to_chars (p, i.imms[n]->X_add_number, 4); + } + } else { /* not SEG_ABSOLUTE */ + /* need a 32-bit fixup (don't support 8bit non-absolute ims) */ + /* try to support other sizes ... */ + int size; + if (i.types[n] & (Imm8|Imm8S)) + size = 1; + else if (i.types[n] & Imm16) + size = 2; + else + size = 4; + p = frag_more (size); + fix_new (frag_now, p - frag_now->fr_literal, size, + i.imms[n]->X_add_symbol, i.imms[n]->X_subtract_symbol, + i.imms[n]->X_add_number, 0, NO_RELOC); + } + } + } + } /* end immediate output */ + } + #ifdef DEBUG386 - if (flagseen ['D']) { - pi (line, &i); - } + if (flagseen ['D']) { + pi (line, &i); + } #endif /* DEBUG386 */ - - } - return; + + } + return; } /* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero on error. */ static int i386_operand (operand_string) - char *operand_string; +char *operand_string; { - register char *op_string = operand_string; - - /* Address of '\0' at end of operand_string. */ - char * end_of_operand_string = operand_string + strlen(operand_string); - - /* Start and end of displacement string expression (if found). */ - char * displacement_string_start = 0; - char * displacement_string_end; - - /* We check for an absolute prefix (differentiating, - for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */ - if (*op_string == ABSOLUTE_PREFIX) { - op_string++; - i.types[this_operand] |= JumpAbsolute; - } - - /* Check if operand is a register. */ - if (*op_string == REGISTER_PREFIX) { - register reg_entry * r; - if (! (r = parse_register (op_string))) { - as_bad("bad register name ('%s')", op_string); - return 0; - } - /* Check for segment override, rather than segment register by - searching for ':' after %<x>s where <x> = s, c, d, e, f, g. */ - if ((r->reg_type & (SReg2|SReg3)) && op_string[3] == ':') { - switch (r->reg_num) { - case 0: - i.seg = &es; break; - case 1: - i.seg = &cs; break; - case 2: - i.seg = &ss; break; - case 3: - i.seg = &ds; break; - case 4: - i.seg = &fs; break; - case 5: - i.seg = &gs; break; - } - op_string += 4; /* skip % <x> s : */ - operand_string = op_string; /* Pretend given string starts here. */ - if (!is_digit_char(*op_string) && !is_identifier_char(*op_string) - && *op_string != '(' && *op_string != ABSOLUTE_PREFIX) { - as_bad("bad memory operand after segment override"); - return 0; - } - /* Handle case of %es:*foo. */ - if (*op_string == ABSOLUTE_PREFIX) { - op_string++; - i.types[this_operand] |= JumpAbsolute; - } - goto do_memory_reference; - } - i.types[this_operand] |= r->reg_type; - i.regs[this_operand] = r; - i.reg_operands++; - } else if (*op_string == IMMEDIATE_PREFIX) { /* ... or an immediate */ - char * save_input_line_pointer; - register expressionS *exp; - segT exp_seg; - if (i.imm_operands == MAX_IMMEDIATE_OPERANDS) { - as_bad("only 1 or 2 immediate operands are allowed"); - return 0; - } - exp = &im_expressions[i.imm_operands++]; - i.imms [this_operand] = exp; - save_input_line_pointer = input_line_pointer; - input_line_pointer = ++op_string; /* must advance op_string! */ - exp_seg = expression (exp); - input_line_pointer = save_input_line_pointer; - switch (exp_seg) { - case SEG_ABSENT: /* missing or bad expr becomes absolute 0 */ - as_bad("missing or invalid immediate expression '%s' taken as 0", - operand_string); - exp->X_seg = SEG_ABSOLUTE; - exp->X_add_number = 0; - exp->X_add_symbol = (symbolS *) 0; - exp->X_subtract_symbol = (symbolS *) 0; - i.types[this_operand] |= Imm; - break; - case SEG_ABSOLUTE: - i.types[this_operand] |= SMALLEST_IMM_TYPE (exp->X_add_number); - break; - case SEG_TEXT: case SEG_DATA: case SEG_BSS: case SEG_UNKNOWN: - i.types[this_operand] |= Imm32; /* this is an address ==> 32bit */ - break; - default: -seg_unimplemented: - as_bad("Unimplemented segment type %d in parse_operand", exp_seg); - return 0; - } - /* shorten this type of this operand if the instruction wants - * fewer bits than are present in the immediate. The bit field - * code can put out 'andb $0xffffff, %al', for example. pace - * also 'movw $foo,(%eax)' - */ - switch (i.suffix) { - case WORD_OPCODE_SUFFIX: - i.types[this_operand] |= Imm16; - break; - case BYTE_OPCODE_SUFFIX: - i.types[this_operand] |= Imm16 | Imm8 | Imm8S; - break; - } - } else if (is_digit_char(*op_string) || is_identifier_char(*op_string) - || *op_string == '(') { - /* This is a memory reference of some sort. */ - register char * base_string; - unsigned int found_base_index_form; - - do_memory_reference: - if (i.mem_operands == MAX_MEMORY_OPERANDS) { - as_bad("more than 1 memory reference in instruction"); - return 0; - } - i.mem_operands++; - - /* Determine type of memory operand from opcode_suffix; - no opcode suffix implies general memory references. */ - switch (i.suffix) { - case BYTE_OPCODE_SUFFIX: - i.types[this_operand] |= Mem8; - break; - case WORD_OPCODE_SUFFIX: - i.types[this_operand] |= Mem16; - break; - case DWORD_OPCODE_SUFFIX: - default: - i.types[this_operand] |= Mem32; - } - - /* Check for base index form. We detect the base index form by - looking for an ')' at the end of the operand, searching - for the '(' matching it, and finding a REGISTER_PREFIX or ',' - after it. */ - base_string = end_of_operand_string - 1; - found_base_index_form = 0; - if (*base_string == ')') { - unsigned int parens_balenced = 1; - /* We've already checked that the number of left & right ()'s are equal, - so this loop will not be infinite. */ - do { - base_string--; - if (*base_string == ')') parens_balenced++; - if (*base_string == '(') parens_balenced--; - } while (parens_balenced); - base_string++; /* Skip past '('. */ - if (*base_string == REGISTER_PREFIX || *base_string == ',') - found_base_index_form = 1; - } - - /* If we can't parse a base index register expression, we've found - a pure displacement expression. We set up displacement_string_start - and displacement_string_end for the code below. */ - if (! found_base_index_form) { - displacement_string_start = op_string; - displacement_string_end = end_of_operand_string; - } else { - char *base_reg_name, *index_reg_name, *num_string; - int num; - - i.types[this_operand] |= BaseIndex; - - /* If there is a displacement set-up for it to be parsed later. */ - if (base_string != op_string + 1) { - displacement_string_start = op_string; - displacement_string_end = base_string - 1; - } - - /* Find base register (if any). */ - if (*base_string != ',') { - base_reg_name = base_string++; - /* skip past register name & parse it */ - while (isalpha(*base_string)) base_string++; - if (base_string == base_reg_name+1) { - as_bad("can't find base register name after '(%c'", - REGISTER_PREFIX); - return 0; - } - END_STRING_AND_SAVE (base_string); - if (! (i.base_reg = parse_register (base_reg_name))) { - as_bad("bad base register name ('%s')", base_reg_name); - return 0; - } - RESTORE_END_STRING (base_string); - } - - /* Now check seperator; must be ',' ==> index reg - OR num ==> no index reg. just scale factor - OR ')' ==> end. (scale factor = 1) */ - if (*base_string != ',' && *base_string != ')') { - as_bad("expecting ',' or ')' after base register in `%s'", - operand_string); - return 0; - } - - /* There may index reg here; and there may be a scale factor. */ - if (*base_string == ',' && *(base_string+1) == REGISTER_PREFIX) { - index_reg_name = ++base_string; - while (isalpha(*++base_string)); - END_STRING_AND_SAVE (base_string); - if (! (i.index_reg = parse_register(index_reg_name))) { - as_bad("bad index register name ('%s')", index_reg_name); - return 0; - } - RESTORE_END_STRING (base_string); - } - - /* Check for scale factor. */ - if (*base_string == ',' && isdigit(*(base_string+1))) { - num_string = ++base_string; - while (is_digit_char(*base_string)) base_string++; - if (base_string == num_string) { - as_bad("can't find a scale factor after ','"); - return 0; - } - END_STRING_AND_SAVE (base_string); - /* We've got a scale factor. */ - if (! sscanf (num_string, "%d", &num)) { - as_bad("can't parse scale factor from '%s'", num_string); - return 0; - } - RESTORE_END_STRING (base_string); - switch (num) { /* must be 1 digit scale */ - case 1: i.log2_scale_factor = 0; break; - case 2: i.log2_scale_factor = 1; break; - case 4: i.log2_scale_factor = 2; break; - case 8: i.log2_scale_factor = 3; break; - default: - as_bad("expecting scale factor of 1, 2, 4, 8; got %d", num); - return 0; + register char *op_string = operand_string; + + /* Address of '\0' at end of operand_string. */ + char * end_of_operand_string = operand_string + strlen(operand_string); + + /* Start and end of displacement string expression (if found). */ + char * displacement_string_start = 0; + char * displacement_string_end; + + /* We check for an absolute prefix (differentiating, + for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */ + if (*op_string == ABSOLUTE_PREFIX) { + op_string++; + i.types[this_operand] |= JumpAbsolute; } - } else { - if (! i.index_reg && *base_string == ',') { - as_bad("expecting index register or scale factor after ','; got '%c'", - *(base_string+1)); - return 0; + + /* Check if operand is a register. */ + if (*op_string == REGISTER_PREFIX) { + register reg_entry * r; + if (! (r = parse_register (op_string))) { + as_bad("bad register name ('%s')", op_string); + return 0; + } + /* Check for segment override, rather than segment register by + searching for ':' after %<x>s where <x> = s, c, d, e, f, g. */ + if ((r->reg_type & (SReg2|SReg3)) && op_string[3] == ':') { + switch (r->reg_num) { + case 0: + i.seg = &es; break; + case 1: + i.seg = &cs; break; + case 2: + i.seg = &ss; break; + case 3: + i.seg = &ds; break; + case 4: + i.seg = &fs; break; + case 5: + i.seg = &gs; break; + } + op_string += 4; /* skip % <x> s : */ + operand_string = op_string; /* Pretend given string starts here. */ + if (!is_digit_char(*op_string) && !is_identifier_char(*op_string) + && *op_string != '(' && *op_string != ABSOLUTE_PREFIX) { + as_bad("bad memory operand after segment override"); + return 0; + } + /* Handle case of %es:*foo. */ + if (*op_string == ABSOLUTE_PREFIX) { + op_string++; + i.types[this_operand] |= JumpAbsolute; + } + goto do_memory_reference; + } + i.types[this_operand] |= r->reg_type; + i.regs[this_operand] = r; + i.reg_operands++; + } else if (*op_string == IMMEDIATE_PREFIX) { /* ... or an immediate */ + char * save_input_line_pointer; + register expressionS *exp; + segT exp_seg; + if (i.imm_operands == MAX_IMMEDIATE_OPERANDS) { + as_bad("only 1 or 2 immediate operands are allowed"); + return 0; + } + exp = &im_expressions[i.imm_operands++]; + i.imms [this_operand] = exp; + save_input_line_pointer = input_line_pointer; + input_line_pointer = ++op_string; /* must advance op_string! */ + exp_seg = expression (exp); + input_line_pointer = save_input_line_pointer; + switch (exp_seg) { + case SEG_ABSENT: /* missing or bad expr becomes absolute 0 */ + as_bad("missing or invalid immediate expression '%s' taken as 0", + operand_string); + exp->X_seg = SEG_ABSOLUTE; + exp->X_add_number = 0; + exp->X_add_symbol = (symbolS *) 0; + exp->X_subtract_symbol = (symbolS *) 0; + i.types[this_operand] |= Imm; + break; + case SEG_ABSOLUTE: + i.types[this_operand] |= SMALLEST_IMM_TYPE (exp->X_add_number); + break; + case SEG_TEXT: case SEG_DATA: case SEG_BSS: case SEG_UNKNOWN: + i.types[this_operand] |= Imm32; /* this is an address ==> 32bit */ + break; + default: + seg_unimplemented: + as_bad("Unimplemented segment type %d in parse_operand", exp_seg); + return 0; + } + /* shorten this type of this operand if the instruction wants + * fewer bits than are present in the immediate. The bit field + * code can put out 'andb $0xffffff, %al', for example. pace + * also 'movw $foo,(%eax)' + */ + switch (i.suffix) { + case WORD_OPCODE_SUFFIX: + i.types[this_operand] |= Imm16; + break; + case BYTE_OPCODE_SUFFIX: + i.types[this_operand] |= Imm16 | Imm8 | Imm8S; + break; + } + } else if (is_digit_char(*op_string) || is_identifier_char(*op_string) + || *op_string == '(') { + /* This is a memory reference of some sort. */ + register char * base_string; + unsigned int found_base_index_form; + + do_memory_reference: + if (i.mem_operands == MAX_MEMORY_OPERANDS) { + as_bad("more than 1 memory reference in instruction"); + return 0; + } + i.mem_operands++; + + /* Determine type of memory operand from opcode_suffix; + no opcode suffix implies general memory references. */ + switch (i.suffix) { + case BYTE_OPCODE_SUFFIX: + i.types[this_operand] |= Mem8; + break; + case WORD_OPCODE_SUFFIX: + i.types[this_operand] |= Mem16; + break; + case DWORD_OPCODE_SUFFIX: + default: + i.types[this_operand] |= Mem32; + } + + /* Check for base index form. We detect the base index form by + looking for an ')' at the end of the operand, searching + for the '(' matching it, and finding a REGISTER_PREFIX or ',' + after it. */ + base_string = end_of_operand_string - 1; + found_base_index_form = 0; + if (*base_string == ')') { + unsigned int parens_balenced = 1; + /* We've already checked that the number of left & right ()'s are equal, + so this loop will not be infinite. */ + do { + base_string--; + if (*base_string == ')') parens_balenced++; + if (*base_string == '(') parens_balenced--; + } while (parens_balenced); + base_string++; /* Skip past '('. */ + if (*base_string == REGISTER_PREFIX || *base_string == ',') + found_base_index_form = 1; + } + + /* If we can't parse a base index register expression, we've found + a pure displacement expression. We set up displacement_string_start + and displacement_string_end for the code below. */ + if (! found_base_index_form) { + displacement_string_start = op_string; + displacement_string_end = end_of_operand_string; + } else { + char *base_reg_name, *index_reg_name, *num_string; + int num; + + i.types[this_operand] |= BaseIndex; + + /* If there is a displacement set-up for it to be parsed later. */ + if (base_string != op_string + 1) { + displacement_string_start = op_string; + displacement_string_end = base_string - 1; + } + + /* Find base register (if any). */ + if (*base_string != ',') { + base_reg_name = base_string++; + /* skip past register name & parse it */ + while (isalpha(*base_string)) base_string++; + if (base_string == base_reg_name+1) { + as_bad("can't find base register name after '(%c'", + REGISTER_PREFIX); + return 0; + } + END_STRING_AND_SAVE (base_string); + if (! (i.base_reg = parse_register (base_reg_name))) { + as_bad("bad base register name ('%s')", base_reg_name); + return 0; + } + RESTORE_END_STRING (base_string); + } + + /* Now check seperator; must be ',' ==> index reg + OR num ==> no index reg. just scale factor + OR ')' ==> end. (scale factor = 1) */ + if (*base_string != ',' && *base_string != ')') { + as_bad("expecting ',' or ')' after base register in `%s'", + operand_string); + return 0; + } + + /* There may index reg here; and there may be a scale factor. */ + if (*base_string == ',' && *(base_string+1) == REGISTER_PREFIX) { + index_reg_name = ++base_string; + while (isalpha(*++base_string)); + END_STRING_AND_SAVE (base_string); + if (! (i.index_reg = parse_register(index_reg_name))) { + as_bad("bad index register name ('%s')", index_reg_name); + return 0; + } + RESTORE_END_STRING (base_string); + } + + /* Check for scale factor. */ + if (*base_string == ',' && isdigit(*(base_string+1))) { + num_string = ++base_string; + while (is_digit_char(*base_string)) base_string++; + if (base_string == num_string) { + as_bad("can't find a scale factor after ','"); + return 0; + } + END_STRING_AND_SAVE (base_string); + /* We've got a scale factor. */ + if (! sscanf (num_string, "%d", &num)) { + as_bad("can't parse scale factor from '%s'", num_string); + return 0; + } + RESTORE_END_STRING (base_string); + switch (num) { /* must be 1 digit scale */ + case 1: i.log2_scale_factor = 0; break; + case 2: i.log2_scale_factor = 1; break; + case 4: i.log2_scale_factor = 2; break; + case 8: i.log2_scale_factor = 3; break; + default: + as_bad("expecting scale factor of 1, 2, 4, 8; got %d", num); + return 0; + } + } else { + if (! i.index_reg && *base_string == ',') { + as_bad("expecting index register or scale factor after ','; got '%c'", + *(base_string+1)); + return 0; + } + } + } + + /* If there's an expression begining the operand, parse it, + assuming displacement_string_start and displacement_string_end + are meaningful. */ + if (displacement_string_start) { + register expressionS * exp; + segT exp_seg; + char * save_input_line_pointer; + exp = &disp_expressions[i.disp_operands]; + i.disps [this_operand] = exp; + i.disp_operands++; + save_input_line_pointer = input_line_pointer; + input_line_pointer = displacement_string_start; + END_STRING_AND_SAVE (displacement_string_end); + exp_seg = expression (exp); + if(*input_line_pointer) + as_bad("Ignoring junk '%s' after expression",input_line_pointer); + RESTORE_END_STRING (displacement_string_end); + input_line_pointer = save_input_line_pointer; + switch (exp_seg) { + case SEG_ABSENT: + /* missing expr becomes absolute 0 */ + as_bad("missing or invalid displacement '%s' taken as 0", + operand_string); + i.types[this_operand] |= (Disp|Abs); + exp->X_seg = SEG_ABSOLUTE; + exp->X_add_number = 0; + exp->X_add_symbol = (symbolS *) 0; + exp->X_subtract_symbol = (symbolS *) 0; + break; + case SEG_ABSOLUTE: + i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number); + break; + case SEG_TEXT: case SEG_DATA: case SEG_BSS: + case SEG_UNKNOWN: /* must be 32 bit displacement (i.e. address) */ + i.types[this_operand] |= Disp32; + break; + default: + goto seg_unimplemented; + } + } + + /* Make sure the memory operand we've been dealt is valid. */ + if (i.base_reg && i.index_reg && + ! (i.base_reg->reg_type & i.index_reg->reg_type & Reg)) { + as_bad("register size mismatch in (base,index,scale) expression"); + return 0; + } + if ((i.base_reg && (i.base_reg->reg_type & Reg32) == 0) || + (i.index_reg && (i.index_reg->reg_type & Reg32) == 0)) { + as_bad("base/index register must be 32 bit register"); + return 0; + } + if (i.index_reg && i.index_reg == esp) { + as_bad("%s may not be used as an index register", esp->reg_name); + return 0; + } + } else { /* it's not a memory operand; argh! */ + as_bad("invalid char %s begining %s operand '%s'", + output_invalid(*op_string), ordinal_names[this_operand], + op_string); + return 0; } - } - } - - /* If there's an expression begining the operand, parse it, - assuming displacement_string_start and displacement_string_end - are meaningful. */ - if (displacement_string_start) { - register expressionS * exp; - segT exp_seg; - char * save_input_line_pointer; - exp = &disp_expressions[i.disp_operands]; - i.disps [this_operand] = exp; - i.disp_operands++; - save_input_line_pointer = input_line_pointer; - input_line_pointer = displacement_string_start; - END_STRING_AND_SAVE (displacement_string_end); - exp_seg = expression (exp); - if(*input_line_pointer) - as_bad("Ignoring junk '%s' after expression",input_line_pointer); - RESTORE_END_STRING (displacement_string_end); - input_line_pointer = save_input_line_pointer; - switch (exp_seg) { - case SEG_ABSENT: - /* missing expr becomes absolute 0 */ - as_bad("missing or invalid displacement '%s' taken as 0", - operand_string); - i.types[this_operand] |= (Disp|Abs); - exp->X_seg = SEG_ABSOLUTE; - exp->X_add_number = 0; - exp->X_add_symbol = (symbolS *) 0; - exp->X_subtract_symbol = (symbolS *) 0; - break; - case SEG_ABSOLUTE: - i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number); - break; - case SEG_TEXT: case SEG_DATA: case SEG_BSS: - case SEG_UNKNOWN: /* must be 32 bit displacement (i.e. address) */ - i.types[this_operand] |= Disp32; - break; - default: - goto seg_unimplemented; - } - } - - /* Make sure the memory operand we've been dealt is valid. */ - if (i.base_reg && i.index_reg && - ! (i.base_reg->reg_type & i.index_reg->reg_type & Reg)) { - as_bad("register size mismatch in (base,index,scale) expression"); - return 0; - } - if ((i.base_reg && (i.base_reg->reg_type & Reg32) == 0) || - (i.index_reg && (i.index_reg->reg_type & Reg32) == 0)) { - as_bad("base/index register must be 32 bit register"); - return 0; - } - if (i.index_reg && i.index_reg == esp) { - as_bad("%s may not be used as an index register", esp->reg_name); - return 0; - } - } else { /* it's not a memory operand; argh! */ - as_bad("invalid char %s begining %s operand '%s'", - output_invalid(*op_string), ordinal_names[this_operand], - op_string); - return 0; - } - return 1; /* normal return */ + return 1; /* normal return */ } /* @@ -1581,44 +1587,44 @@ seg_unimplemented: * 0 value. */ int -md_estimate_size_before_relax (fragP, segment) - register fragS * fragP; - register segT segment; + md_estimate_size_before_relax (fragP, segment) +register fragS * fragP; +register segT segment; { - register unsigned char * opcode; - register int old_fr_fix; - - old_fr_fix = fragP -> fr_fix; - opcode = (unsigned char *) fragP -> fr_opcode; - /* We've already got fragP->fr_subtype right; all we have to do is check - for un-relaxable symbols. */ - if (S_GET_SEGMENT(fragP -> fr_symbol) != segment) { - /* symbol is undefined in this segment */ - switch (opcode[0]) { - case JUMP_PC_RELATIVE: /* make jmp (0xeb) a dword displacement jump */ - opcode[0] = 0xe9; /* dword disp jmp */ - fragP -> fr_fix += 4; - fix_new (fragP, old_fr_fix, 4, - fragP -> fr_symbol, - (symbolS *) 0, - fragP -> fr_offset, 1, NO_RELOC); - break; - - default: - /* This changes the byte-displacement jump 0x7N --> - the dword-displacement jump 0x0f8N */ - opcode[1] = opcode[0] + 0x10; - opcode[0] = TWO_BYTE_OPCODE_ESCAPE; /* two-byte escape */ - fragP -> fr_fix += 1 + 4; /* we've added an opcode byte */ - fix_new (fragP, old_fr_fix + 1, 4, - fragP -> fr_symbol, - (symbolS *) 0, - fragP -> fr_offset, 1, NO_RELOC); - break; - } - frag_wane (fragP); - } - return (fragP -> fr_var + fragP -> fr_fix - old_fr_fix); + register unsigned char * opcode; + register int old_fr_fix; + + old_fr_fix = fragP -> fr_fix; + opcode = (unsigned char *) fragP -> fr_opcode; + /* We've already got fragP->fr_subtype right; all we have to do is check + for un-relaxable symbols. */ + if (S_GET_SEGMENT(fragP -> fr_symbol) != segment) { + /* symbol is undefined in this segment */ + switch (opcode[0]) { + case JUMP_PC_RELATIVE: /* make jmp (0xeb) a dword displacement jump */ + opcode[0] = 0xe9; /* dword disp jmp */ + fragP -> fr_fix += 4; + fix_new (fragP, old_fr_fix, 4, + fragP -> fr_symbol, + (symbolS *) 0, + fragP -> fr_offset, 1, NO_RELOC); + break; + + default: + /* This changes the byte-displacement jump 0x7N --> + the dword-displacement jump 0x0f8N */ + opcode[1] = opcode[0] + 0x10; + opcode[0] = TWO_BYTE_OPCODE_ESCAPE; /* two-byte escape */ + fragP -> fr_fix += 1 + 4; /* we've added an opcode byte */ + fix_new (fragP, old_fr_fix + 1, 4, + fragP -> fr_symbol, + (symbolS *) 0, + fragP -> fr_offset, 1, NO_RELOC); + break; + } + frag_wane (fragP); + } + return (fragP -> fr_var + fragP -> fr_fix - old_fr_fix); } /* md_estimate_size_before_relax() */ /* @@ -1633,71 +1639,72 @@ md_estimate_size_before_relax (fragP, segment) * Caller will turn frag into a ".space 0". */ void -md_convert_frag (fragP) - register fragS * fragP; + md_convert_frag (headers, fragP) +object_headers *headers; +register fragS * fragP; { - register unsigned char * opcode; - unsigned char * where_to_put_displacement; - unsigned int target_address, opcode_address; - unsigned int extension; - int displacement_from_opcode_start; - - opcode = (unsigned char *) fragP -> fr_opcode; - - /* Address we want to reach in file space. */ - target_address = S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset; - - /* Address opcode resides at in file space. */ - opcode_address = fragP->fr_address + fragP->fr_fix; - - /* Displacement from opcode start to fill into instruction. */ - displacement_from_opcode_start = target_address - opcode_address; - - switch (fragP->fr_subtype) { - case ENCODE_RELAX_STATE (COND_JUMP, BYTE): - case ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE): - /* don't have to change opcode */ - extension = 1; /* 1 opcode + 1 displacement */ - where_to_put_displacement = &opcode[1]; - break; - - case ENCODE_RELAX_STATE (COND_JUMP, WORD): - opcode[1] = TWO_BYTE_OPCODE_ESCAPE; - opcode[2] = opcode[0] + 0x10; - opcode[0] = WORD_PREFIX_OPCODE; - extension = 4; /* 3 opcode + 2 displacement */ - where_to_put_displacement = &opcode[3]; - break; - - case ENCODE_RELAX_STATE (UNCOND_JUMP, WORD): - opcode[1] = 0xe9; - opcode[0] = WORD_PREFIX_OPCODE; - extension = 3; /* 2 opcode + 2 displacement */ - where_to_put_displacement = &opcode[2]; - break; - - case ENCODE_RELAX_STATE (COND_JUMP, DWORD): - opcode[1] = opcode[0] + 0x10; - opcode[0] = TWO_BYTE_OPCODE_ESCAPE; - extension = 5; /* 2 opcode + 4 displacement */ - where_to_put_displacement = &opcode[2]; - break; - - case ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD): - opcode[0] = 0xe9; - extension = 4; /* 1 opcode + 4 displacement */ - where_to_put_displacement = &opcode[1]; - break; - - default: - BAD_CASE(fragP -> fr_subtype); - break; - } - /* now put displacement after opcode */ - md_number_to_chars (where_to_put_displacement, - displacement_from_opcode_start - extension, - SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); - fragP -> fr_fix += extension; + register unsigned char * opcode; + unsigned char * where_to_put_displacement; + unsigned int target_address, opcode_address; + unsigned int extension; + int displacement_from_opcode_start; + + opcode = (unsigned char *) fragP -> fr_opcode; + + /* Address we want to reach in file space. */ + target_address = S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset; + + /* Address opcode resides at in file space. */ + opcode_address = fragP->fr_address + fragP->fr_fix; + + /* Displacement from opcode start to fill into instruction. */ + displacement_from_opcode_start = target_address - opcode_address; + + switch (fragP->fr_subtype) { + case ENCODE_RELAX_STATE (COND_JUMP, BYTE): + case ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE): + /* don't have to change opcode */ + extension = 1; /* 1 opcode + 1 displacement */ + where_to_put_displacement = &opcode[1]; + break; + + case ENCODE_RELAX_STATE (COND_JUMP, WORD): + opcode[1] = TWO_BYTE_OPCODE_ESCAPE; + opcode[2] = opcode[0] + 0x10; + opcode[0] = WORD_PREFIX_OPCODE; + extension = 4; /* 3 opcode + 2 displacement */ + where_to_put_displacement = &opcode[3]; + break; + + case ENCODE_RELAX_STATE (UNCOND_JUMP, WORD): + opcode[1] = 0xe9; + opcode[0] = WORD_PREFIX_OPCODE; + extension = 3; /* 2 opcode + 2 displacement */ + where_to_put_displacement = &opcode[2]; + break; + + case ENCODE_RELAX_STATE (COND_JUMP, DWORD): + opcode[1] = opcode[0] + 0x10; + opcode[0] = TWO_BYTE_OPCODE_ESCAPE; + extension = 5; /* 2 opcode + 4 displacement */ + where_to_put_displacement = &opcode[2]; + break; + + case ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD): + opcode[0] = 0xe9; + extension = 4; /* 1 opcode + 4 displacement */ + where_to_put_displacement = &opcode[1]; + break; + + default: + BAD_CASE(fragP -> fr_subtype); + break; +} + /* now put displacement after opcode */ + md_number_to_chars (where_to_put_displacement, + displacement_from_opcode_start - extension, + SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); + fragP -> fr_fix += extension; } @@ -1706,41 +1713,41 @@ int md_long_jump_size = 5; /* size of dword displacement jmp */ int md_reloc_size = 8; /* Size of relocation record */ void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, to_addr; +char *ptr; +long from_addr, to_addr; fragS *frag; symbolS *to_symbol; { - long offset; - - offset = to_addr - (from_addr + 2); - md_number_to_chars (ptr, (long) 0xeb, 1); /* opcode for byte-disp jump */ - md_number_to_chars (ptr + 1, offset, 1); + long offset; + + offset = to_addr - (from_addr + 2); + md_number_to_chars (ptr, (long) 0xeb, 1); /* opcode for byte-disp jump */ + md_number_to_chars (ptr + 1, offset, 1); } void md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; +char *ptr; +long from_addr, to_addr; +fragS *frag; +symbolS *to_symbol; { - long offset; - - if (flagseen['m']) { - offset = to_addr - S_GET_VALUE(to_symbol); - md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */ - md_number_to_chars (ptr + 1, offset, 4); - fix_new (frag, (ptr+1) - frag->fr_literal, 4, - to_symbol, (symbolS *) 0, (long) 0, 0, NO_RELOC); - } else { - offset = to_addr - (from_addr + 5); - md_number_to_chars(ptr, (long) 0xe9, 1); - md_number_to_chars(ptr + 1, offset, 4); - } + long offset; + + if (flagseen['m']) { + offset = to_addr - S_GET_VALUE(to_symbol); + md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */ + md_number_to_chars (ptr + 1, offset, 4); + fix_new (frag, (ptr+1) - frag->fr_literal, 4, + to_symbol, (symbolS *) 0, (long) 0, 0, NO_RELOC); + } else { + offset = to_addr - (from_addr + 5); + md_number_to_chars(ptr, (long) 0xe9, 1); + md_number_to_chars(ptr + 1, offset, 4); + } } int -md_parse_option(argP,cntP,vecP) + md_parse_option(argP,cntP,vecP) char **argP; int *cntP; char ***vecP; @@ -1749,99 +1756,137 @@ char ***vecP; } void /* Knows about order of bytes in address. */ -md_number_to_chars (con, value, nbytes) - char con []; /* Return 'nbytes' of chars here. */ - long value; /* The value of the bits. */ - int nbytes; /* Number of bytes in the output. */ + md_number_to_chars (con, value, nbytes) +char con []; /* Return 'nbytes' of chars here. */ +long value; /* The value of the bits. */ +int nbytes; /* Number of bytes in the output. */ { - register char * p = con; - - switch (nbytes) { - case 1: - p[0] = value & 0xff; - break; - case 2: - p[0] = value & 0xff; - p[1] = (value >> 8) & 0xff; - break; - case 4: - p[0] = value & 0xff; - p[1] = (value>>8) & 0xff; - p[2] = (value>>16) & 0xff; - p[3] = (value>>24) & 0xff; - break; - default: - BAD_CASE (nbytes); - } + register char * p = con; + + switch (nbytes) { + case 1: + p[0] = value & 0xff; + break; + case 2: + p[0] = value & 0xff; + p[1] = (value >> 8) & 0xff; + break; + case 4: + p[0] = value & 0xff; + p[1] = (value>>8) & 0xff; + p[2] = (value>>16) & 0xff; + p[3] = (value>>24) & 0xff; + break; + default: + BAD_CASE (nbytes); + } } /* Apply a fixup (fixS) to segment data, once it has been determined by our caller that we have all the info we need to fix it up. - + On the 386, immediates, displacements, and data pointers are all in the same (little-endian) format, so we don't need to care about which we are handling. */ void -md_apply_fix (fixP, value) - fixS * fixP; /* The fix we're to put in */ - long value; /* The value of the bits. */ + md_apply_fix (fixP, value) +fixS * fixP; /* The fix we're to put in */ +long value; /* The value of the bits. */ { - register char * p = fixP->fx_where + fixP->fx_frag->fr_literal; - - switch (fixP->fx_size) { - case 1: - *p = value; - break; - case 2: - *p++ = value; - *p = (value>>8); - break; - case 4: - *p++ = value; - *p++ = (value>>8); - *p++ = (value>>16); - *p = (value>>24); - break; - default: - BAD_CASE (fixP->fx_size); - } + register char * p = fixP->fx_where + fixP->fx_frag->fr_literal; + + switch (fixP->fx_size) { + case 1: + *p = value; + break; + case 2: + *p++ = value; + *p = (value>>8); + break; + case 4: + *p++ = value; + *p++ = (value>>8); + *p++ = (value>>16); + *p = (value>>24); + break; + default: + BAD_CASE (fixP->fx_size); + } } long /* Knows about the byte order in a word. */ -md_chars_to_number (con, nbytes) + md_chars_to_number (con, nbytes) unsigned char con[]; /* Low order byte 1st. */ - int nbytes; /* Number of bytes in the input. */ +int nbytes; /* Number of bytes in the input. */ { - long retval; - for (retval=0, con+=nbytes-1; nbytes--; con--) - { - retval <<= BITS_PER_CHAR; - retval |= *con; - } - return retval; + long retval; + for (retval=0, con+=nbytes-1; nbytes--; con--) + { + retval <<= BITS_PER_CHAR; + retval |= *con; + } + return retval; } /* Not needed for coff since relocation structure does not contain bitfields. */ #if defined(OBJ_AOUT) | defined(OBJ_BOUT) +#ifdef comment /* Output relocation information in the target's format. */ void -md_ri_to_chars(the_bytes, ri) - char *the_bytes; - struct reloc_info_generic *ri; + md_ri_to_chars(the_bytes, ri) +char *the_bytes; +struct reloc_info_generic *ri; { - /* this is easy */ - md_number_to_chars(the_bytes, ri->r_address, 4); - /* now the fun stuff */ - the_bytes[6] = (ri->r_symbolnum >> 16) & 0x0ff; - the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff; - the_bytes[4] = ri->r_symbolnum & 0x0ff; - the_bytes[7] = (((ri->r_extern << 3) & 0x08) | ((ri->r_length << 1) & 0x06) | - ((ri->r_pcrel << 0) & 0x01)) & 0x0F; + /* this is easy */ + md_number_to_chars(the_bytes, ri->r_address, 4); + /* now the fun stuff */ + the_bytes[6] = (ri->r_symbolnum >> 16) & 0x0ff; + the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff; + the_bytes[4] = ri->r_symbolnum & 0x0ff; + the_bytes[7] = (((ri->r_extern << 3) & 0x08) | ((ri->r_length << 1) & 0x06) | + ((ri->r_pcrel << 0) & 0x01)) & 0x0F; } -#endif /* OBJ_AOUT or OBJ_BOUT */ +#endif /* comment */ + +void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) +char *where; +fixS *fixP; +relax_addressT segment_address_in_file; +{ + /* + * In: length of relocation (or of address) in chars: 1, 2 or 4. + * Out: GNU LD relocation length code: 0, 1, or 2. + */ + + static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 }; + long r_index; + + know(fixP->fx_addsy != NULL); + + r_index = (S_IS_DEFINED(fixP->fx_addsy) + ? S_GET_TYPE(fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + + /* this is easy */ + md_number_to_chars(where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + /* now the fun stuff */ + where[4] = r_index & 0x0ff; + where[5] = (r_index >> 8) & 0x0ff; + where[6] = (r_index >> 16) & 0x0ff; + where[7] = ((((!S_IS_DEFINED(fixP->fx_addsy)) << 3) & 0x08) + | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06) + | ((fixP->fx_pcrel << 0) & 0x01) & 0x0f); + + return; +} /* tc_aout_fix_to_chars() */ + +#endif /* OBJ_AOUT or OBJ_BOUT */ #define MAX_LITTLENUMS 6 @@ -1849,77 +1894,77 @@ md_ri_to_chars(the_bytes, ri) /* Turn the string pointed to by litP into a floating point constant of type type, and emit the appropriate bytes. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ + */ char * -md_atof(type,litP,sizeP) - char type; - char *litP; - int *sizeP; + md_atof(type,litP,sizeP) +char type; +char *litP; +int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - - switch(type) { - case 'f': - case 'F': - prec = 2; - break; - - case 'd': - case 'D': - prec = 4; - break; - - case 'x': - case 'X': - prec = 5; - break; - - default: - *sizeP=0; - return "Bad call to md_atof ()"; - } - t = atof_ieee (input_line_pointer,type,words); - if(t) - input_line_pointer=t; - - *sizeP = prec * sizeof(LITTLENUM_TYPE); - /* this loops outputs the LITTLENUMs in REVERSE order; in accord with - the bigendian 386 */ - for(wordP = words + prec - 1;prec--;) { - md_number_to_chars (litP, (long) (*wordP--), sizeof(LITTLENUM_TYPE)); - litP += sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + + switch(type) { + case 'f': + case 'F': + prec = 2; + break; + + case 'd': + case 'D': + prec = 4; + break; + + case 'x': + case 'X': + prec = 5; + break; + + default: + *sizeP=0; + return "Bad call to md_atof ()"; + } + t = atof_ieee (input_line_pointer,type,words); + if(t) + input_line_pointer=t; + + *sizeP = prec * sizeof(LITTLENUM_TYPE); + /* this loops outputs the LITTLENUMs in REVERSE order; in accord with + the bigendian 386 */ + for(wordP = words + prec - 1;prec--;) { + md_number_to_chars (litP, (long) (*wordP--), sizeof(LITTLENUM_TYPE)); + litP += sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } char output_invalid_buf[8]; static char * output_invalid (c) - char c; +char c; { - if (isprint(c)) sprintf (output_invalid_buf, "'%c'", c); - else sprintf (output_invalid_buf, "(0x%x)", (unsigned) c); - return output_invalid_buf; + if (isprint(c)) sprintf (output_invalid_buf, "'%c'", c); + else sprintf (output_invalid_buf, "(0x%x)", (unsigned) c); + return output_invalid_buf; } static reg_entry *parse_register (reg_string) - char *reg_string; /* reg_string starts *before* REGISTER_PREFIX */ +char *reg_string; /* reg_string starts *before* REGISTER_PREFIX */ { - register char *s = reg_string; - register char *p; - char reg_name_given[MAX_REG_NAME_SIZE]; - - s++; /* skip REGISTER_PREFIX */ - for (p = reg_name_given; is_register_char (*s); p++, s++) { - *p = register_chars [*s]; - if (p >= reg_name_given + MAX_REG_NAME_SIZE) - return (reg_entry *) 0; - } - *p = '\0'; - return (reg_entry *) hash_find (reg_hash, reg_name_given); + register char *s = reg_string; + register char *p; + char reg_name_given[MAX_REG_NAME_SIZE]; + + s++; /* skip REGISTER_PREFIX */ + for (p = reg_name_given; is_register_char (*s); p++, s++) { + *p = register_chars [*s]; + if (p >= reg_name_given + MAX_REG_NAME_SIZE) + return (reg_entry *) 0; + } + *p = '\0'; + return (reg_entry *) hash_find (reg_hash, reg_name_given); } @@ -1927,10 +1972,10 @@ static reg_entry *parse_register (reg_string) /* ARGSUSED */ symbolS * -md_undefined_symbol (name) - char *name; + md_undefined_symbol (name) +char *name; { - return 0; + return 0; } /* Parse an operand that is machine-specific. @@ -1939,33 +1984,69 @@ md_undefined_symbol (name) /* ARGSUSED */ void -md_operand (expressionP) - expressionS *expressionP; + md_operand (expressionP) +expressionS *expressionP; { } /* Round up a section size to the appropriate boundary. */ long -md_section_align (segment, size) - segT segment; - long size; + md_section_align (segment, size) +segT segment; +long size; { - return size; /* Byte alignment is fine */ + return size; /* Byte alignment is fine */ } /* Exactly what point is a PC-relative offset relative TO? On the i386, they're relative to the address of the offset, plus its size. (??? Is this right? FIXME-SOON!) */ long -md_pcrel_from (fixP) - fixS *fixP; + md_pcrel_from (fixP) +fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } /* * $Log$ - * Revision 1.1 1991/04/04 18:16:41 rich + * Revision 1.9 1992/02/13 08:32:36 rich + * 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. + * + * Revision 1.8 1991/12/01 07:11:28 sac + * More filename renaming. + * + * Revision 1.7 1991/11/04 00:54:41 steve + * Change from bub kukara - puits the index into the right place for a + * reloc + * + * Revision 1.6 1991/08/14 00:25:52 rich + * * no more relocation_info structures. We now squirt directly from + * fixS's. + * + * * i960-bout and i960-coff "tested" against their predecessors. + * + * Revision 1.5 1991/07/27 02:32:37 rich + * Polishing m68k support. + * + * Revision 1.4 1991/06/14 14:02:17 rich + * Version 2 GPL. + * + * Revision 1.3 1991/04/12 05:32:42 rich + * Fixed a comment problem. + * + * Revision 1.2 1991/04/08 15:49:45 rich + * CROSS_ASSEMBLE becomes CROSS_COMPILE to make config simpler. i386 + * support for aout now tested against an installed customers sun4 cross. + * Added REVERSE_SORT_RELOCS. + * + * Revision 1.1.1.1 1991/04/04 18:16:44 rich + * new gas main line + * + * Revision 1.1 1991/04/04 18:16:41 rich * Initial revision * * Revision 1.2 1991/03/30 17:11:30 rich diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index a2b853e..b68f956 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -1,71 +1,74 @@ /* i386.h -- Header file for i386.c Copyright (C) 1989, Free Software Foundation. - -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. */ + 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 TC_I386 1 +#define AOUT_MACHTYPE 100 +#define REVERSE_SORT_RELOCS + #define tc_crawl_symbol_chain(a) ; /* not used */ #define tc_headers_hook(a) ; /* not used */ - + #define MAX_OPERANDS 3 /* max operands per insn */ #define MAX_PREFIXES 4 /* max prefixes per opcode */ #define MAX_IMMEDIATE_OPERANDS 2 /* max immediates per insn */ #define MAX_MEMORY_OPERANDS 2 /* max memory ref per insn * lcall uses 2 */ -/* we define the syntax here (modulo base,index,scale syntax) */ + /* we define the syntax here (modulo base,index,scale syntax) */ #define REGISTER_PREFIX '%' #define IMMEDIATE_PREFIX '$' #define ABSOLUTE_PREFIX '*' #define PREFIX_SEPERATOR '/' - + #define TWO_BYTE_OPCODE_ESCAPE 0x0f - -/* register numbers */ + + /* register numbers */ #define EBP_REG_NUM 5 #define ESP_REG_NUM 4 - -/* modrm_byte.regmem for twobyte escape */ + + /* modrm_byte.regmem for twobyte escape */ #define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM -/* index_base_byte.index for no index register addressing */ + /* index_base_byte.index for no index register addressing */ #define NO_INDEX_REGISTER ESP_REG_NUM -/* index_base_byte.base for no base register addressing */ + /* index_base_byte.base for no base register addressing */ #define NO_BASE_REGISTER EBP_REG_NUM - -/* these are the att as opcode suffixes, making movl --> mov, for example */ + + /* these are the att as opcode suffixes, making movl --> mov, for example */ #define DWORD_OPCODE_SUFFIX 'l' #define WORD_OPCODE_SUFFIX 'w' #define BYTE_OPCODE_SUFFIX 'b' - -/* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */ + + /* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */ #define REGMEM_FIELD_HAS_REG 0x3 /* always = 0x3 */ #define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG) #define END_OF_INSN '\0' /* -When an operand is read in it is classified by its type. This type includes -all the possible ways an operand can be used. Thus, '%eax' is both 'register -# 0' and 'The Accumulator'. In our language this is expressed by OR'ing -'Reg32' (any 32 bit register) and 'Acc' (the accumulator). -Operands are classified so that we can match given operand types with -the opcode table in i386-opcode.h. - */ + When an operand is read in it is classified by its type. This type includes + all the possible ways an operand can be used. Thus, '%eax' is both 'register + # 0' and 'The Accumulator'. In our language this is expressed by OR'ing + 'Reg32' (any 32 bit register) and 'Acc' (the accumulator). + Operands are classified so that we can match given operand types with + the opcode table in i386-opcode.h. + */ #define Unknown 0x0 /* register */ #define Reg8 0x1 /* 8 bit reg */ @@ -113,8 +116,8 @@ the opcode table in i386-opcode.h. #define Abs (Abs8|Abs16|Abs32) #define MODE_FROM_DISP_SIZE(t) \ - ((t&(Disp8)) ? 1 : \ - ((t&(Disp32)) ? 2 : 0)) + ((t&(Disp8)) ? 1 : \ + ((t&(Disp32)) ? 2 : 0)) #define Byte (Reg8|Imm8|Imm8S) #define Word (Reg16|Imm16) @@ -122,8 +125,8 @@ the opcode table in i386-opcode.h. /* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */ #define OPCODE_SUFFIX_TO_TYPE(s) \ - (s == BYTE_OPCODE_SUFFIX ? Byte : \ - (s == WORD_OPCODE_SUFFIX ? Word : DWord)) + (s == BYTE_OPCODE_SUFFIX ? Byte : \ + (s == WORD_OPCODE_SUFFIX ? Word : DWord)) #define FITS_IN_SIGNED_BYTE(num) ((num) >= -128 && (num) <= 127) #define FITS_IN_UNSIGNED_BYTE(num) ((num) >= 0 && (num) <= 255) @@ -131,41 +134,41 @@ the opcode table in i386-opcode.h. #define FITS_IN_SIGNED_WORD(num) ((num) >= -32768 && (num) <= 32767) #define SMALLEST_DISP_TYPE(num) \ - FITS_IN_SIGNED_BYTE(num) ? (Disp8|Disp32|Abs8|Abs32) : (Disp32|Abs32) + FITS_IN_SIGNED_BYTE(num) ? (Disp8|Disp32|Abs8|Abs32) : (Disp32|Abs32) #define SMALLEST_IMM_TYPE(num) \ - (num == 1) ? (Imm1|Imm8|Imm8S|Imm16|Imm32): \ - FITS_IN_SIGNED_BYTE(num) ? (Imm8S|Imm8|Imm16|Imm32) : \ - FITS_IN_UNSIGNED_BYTE(num) ? (Imm8|Imm16|Imm32): \ - (FITS_IN_SIGNED_WORD(num)||FITS_IN_UNSIGNED_WORD(num)) ? (Imm16|Imm32) : \ - (Imm32) + (num == 1) ? (Imm1|Imm8|Imm8S|Imm16|Imm32): \ + FITS_IN_SIGNED_BYTE(num) ? (Imm8S|Imm8|Imm16|Imm32) : \ + FITS_IN_UNSIGNED_BYTE(num) ? (Imm8|Imm16|Imm32): \ + (FITS_IN_SIGNED_WORD(num)||FITS_IN_UNSIGNED_WORD(num)) ? (Imm16|Imm32) : \ + (Imm32) typedef struct { - /* instruction name sans width suffix ("mov" for movl insns) */ - char *name; - - /* how many operands */ - unsigned int operands; - - /* base_opcode is the fundamental opcode byte with a optional prefix(es). */ - unsigned int base_opcode; - - /* extension_opcode is the 3 bit extension for group <n> insns. - If this template has no extension opcode (the usual case) use None */ - unsigned char extension_opcode; + /* instruction name sans width suffix ("mov" for movl insns) */ + char *name; + + /* how many operands */ + unsigned int operands; + + /* base_opcode is the fundamental opcode byte with a optional prefix(es). */ + unsigned int base_opcode; + + /* extension_opcode is the 3 bit extension for group <n> insns. + If this template has no extension opcode (the usual case) use None */ + unsigned char extension_opcode; #define None 0xff /* If no extension_opcode is possible. */ - - /* the bits in opcode_modifier are used to generate the final opcode from - the base_opcode. These bits also are used to detect alternate forms of - the same instruction */ - unsigned int opcode_modifier; - -/* opcode_modifier bits: */ + + /* the bits in opcode_modifier are used to generate the final opcode from + the base_opcode. These bits also are used to detect alternate forms of + the same instruction */ + unsigned int opcode_modifier; + + /* opcode_modifier bits: */ #define W 0x1 /* set if operands are words or dwords */ #define D 0x2 /* D = 0 if Reg --> Regmem; D = 1 if Regmem --> Reg */ -/* direction flag for floating insns: MUST BE 0x400 */ + /* direction flag for floating insns: MUST BE 0x400 */ #define FloatD 0x400 -/* shorthand */ + /* shorthand */ #define DW (D|W) #define ShortForm 0x10 /* register is in low 3 bits of opcode */ #define ShortFormW 0x20 /* ShortForm and W bit is 0x8 */ @@ -173,7 +176,7 @@ typedef struct { #define Seg3ShortForm 0x80 /* fs/gs segment register insns. */ #define Jump 0x100 /* special case for jump insns. */ #define JumpInterSegment 0x200 /* special case for intersegment leaps/calls */ -/* 0x400 CANNOT BE USED since it's already used by FloatD above */ + /* 0x400 CANNOT BE USED since it's already used by FloatD above */ #define DONT_USE 0x400 #define NoModrm 0x800 #define Modrm 0x1000 @@ -181,23 +184,23 @@ typedef struct { #define JumpByte 0x4000 #define JumpDword 0x8000 #define ReverseRegRegmem 0x10000 - - /* (opcode_modifier & COMES_IN_ALL_SIZES) is true if the - instuction comes in byte, word, and dword sizes and is encoded into - machine code in the canonical way. */ + + /* (opcode_modifier & COMES_IN_ALL_SIZES) is true if the + instuction comes in byte, word, and dword sizes and is encoded into + machine code in the canonical way. */ #define COMES_IN_ALL_SIZES (W) - - /* (opcode_modifier & COMES_IN_BOTH_DIRECTIONS) indicates that the - source and destination operands can be reversed by setting either - the D (for integer insns) or the FloatD (for floating insns) bit - in base_opcode. */ + + /* (opcode_modifier & COMES_IN_BOTH_DIRECTIONS) indicates that the + source and destination operands can be reversed by setting either + the D (for integer insns) or the FloatD (for floating insns) bit + in base_opcode. */ #define COMES_IN_BOTH_DIRECTIONS (D|FloatD) - - /* operand_types[i] describes the type of operand i. This is made - by OR'ing together all of the possible type masks. (e.g. - 'operand_types[i] = Reg|Imm' specifies that operand i can be - either a register or an immediate operand */ - unsigned int operand_types[3]; + + /* operand_types[i] describes the type of operand i. This is made + by OR'ing together all of the possible type masks. (e.g. + 'operand_types[i] = Reg|Imm' specifies that operand i can be + either a register or an immediate operand */ + unsigned int operand_types[3]; } template; /* @@ -206,42 +209,42 @@ typedef struct { ole hash table of insns. The templates themselves start at START and range up to (but not including) END. -*/ + */ typedef struct { - template *start; - template *end; + template *start; + template *end; } templates; /* these are for register name --> number & type hash lookup */ typedef struct { - char * reg_name; - unsigned int reg_type; - unsigned int reg_num; + char * reg_name; + unsigned int reg_type; + unsigned int reg_num; } reg_entry; typedef struct { - char * seg_name; - unsigned int seg_prefix; + char * seg_name; + unsigned int seg_prefix; } seg_entry; /* these are for prefix name --> prefix code hash lookup */ typedef struct { - char * prefix_name; - unsigned char prefix_code; + char * prefix_name; + unsigned char prefix_code; } prefix_entry; /* 386 operand encoding bytes: see 386 book for details of this. */ typedef struct { - unsigned regmem:3; /* codes register or memory operand */ - unsigned reg:3; /* codes register operand (or extended opcode) */ - unsigned mode:2; /* how to interpret regmem & reg */ + unsigned regmem:3; /* codes register or memory operand */ + unsigned reg:3; /* codes register operand (or extended opcode) */ + unsigned mode:2; /* how to interpret regmem & reg */ } modrm_byte; /* 386 opcode byte to code indirect addressing. */ typedef struct { - unsigned base:3; - unsigned index:3; - unsigned scale:2; + unsigned base:3; + unsigned index:3; + unsigned scale:2; } base_index_byte; /* end of tc-i386.h */ diff --git a/gas/config/tc-i860.c b/gas/config/tc-i860.c index d9dd84c..d7dda6c 100644 --- a/gas/config/tc-i860.c +++ b/gas/config/tc-i860.c @@ -1,53 +1,53 @@ /* i860.c -- Assemble for the I860 Copyright (C) 1989 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. */ + + 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. */ /* $Id$ */ #include "as.h" -#include "i860-opcode.h" +#include "opcode/i860.h" /* incorporated from i860.h */ enum reloc_type /* NOTE: three bits max, see struct reloc_info_i860.r_type */ { - NO_RELOC = 0, BRADDR, LOW0, LOW1, LOW2, LOW3, LOW4, SPLIT0, SPLIT1, SPLIT2, RELOC_32, + NO_RELOC = 0, BRADDR, LOW0, LOW1, LOW2, LOW3, LOW4, SPLIT0, SPLIT1, SPLIT2, RELOC_32, }; - + enum highlow_type /* NOTE: two bits max, see reloc_info_i860.r_type */ { - NO_SPEC = 0, PAIR, HIGH, HIGHADJ, + NO_SPEC = 0, PAIR, HIGH, HIGHADJ, }; - + struct reloc_info_i860 { - unsigned long r_address; -/* - * Using bit fields here is a bad idea because the order is not portable. :-( - */ - unsigned int r_symbolnum: 24; - unsigned int r_pcrel : 1; - unsigned int r_extern : 1; - /* combining the two field simplifies the argument passing in "new_fix()" */ - /* and is compatible with the existing Sparc #ifdef's */ - /* r_type: highlow_type - bits 5,4; reloc_type - bits 3-0 */ - unsigned int r_type : 6; - long r_addend; + unsigned long r_address; + /* + * Using bit fields here is a bad idea because the order is not portable. :-( + */ + unsigned int r_symbolnum: 24; + unsigned int r_pcrel : 1; + unsigned int r_extern : 1; + /* combining the two field simplifies the argument passing in "new_fix()" */ + /* and is compatible with the existing Sparc #ifdef's */ + /* r_type: highlow_type - bits 5,4; reloc_type - bits 3-0 */ + unsigned int r_type : 6; + long r_addend; }; #define relocation_info reloc_info_i860 @@ -82,18 +82,18 @@ static void s_dual(), s_enddual(); static void s_atmp(); const pseudo_typeS -md_pseudo_table[] = { - { "dual", s_dual, 4 }, - { "enddual", s_enddual, 4 }, - { "atmp", s_atmp, 4 }, - { NULL, 0, 0 }, -}; + md_pseudo_table[] = { + { "dual", s_dual, 4 }, + { "enddual", s_enddual, 4 }, + { "atmp", s_atmp, 4 }, + { NULL, 0, 0 }, + }; int md_short_jump_size = 4; int md_long_jump_size = 4; /* This array holds the chars that always start a comment. If the - pre-processor is disabled, these aren't very useful */ + pre-processor is disabled, these aren't very useful */ char comment_chars[] = "!/"; /* JF removed '|' from comment_chars */ /* This array holds the chars that only start a comment at the beginning of @@ -116,22 +116,22 @@ char FLT_CHARS[] = "rRsSfFdDxXpP"; /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be changed in read.c . Ideally it shouldn't have to know about it at all, but nothing is ideal around here. - */ + */ int size_reloc_info = sizeof(struct relocation_info); static unsigned char octal[256]; #define isoctal(c) octal[c] -static unsigned char toHex[256]; + static unsigned char toHex[256]; struct i860_it { - char *error; - unsigned long opcode; - struct nlist *nlistp; - expressionS exp; - int pcrel; - enum expand_type expand; - enum highlow_type highlow; - enum reloc_type reloc; + char *error; + unsigned long opcode; + struct nlist *nlistp; + expressionS exp; + int pcrel; + enum expand_type expand; + enum highlow_type highlow; + enum reloc_type reloc; } the_insn; #ifdef __STDC__ @@ -146,851 +146,848 @@ static char last_expand; /* error if expansion after branch */ enum dual { - DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT, + DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT, }; static enum dual dual_mode = DUAL_OFF; /* dual-instruction mode */ static void -s_dual() /* floating point instructions have dual set */ + s_dual() /* floating point instructions have dual set */ { - dual_mode = DUAL_ON; + dual_mode = DUAL_ON; } static void -s_enddual() /* floating point instructions have dual set */ + s_enddual() /* floating point instructions have dual set */ { - dual_mode = DUAL_OFF; + dual_mode = DUAL_OFF; } static int atmp = 31; /* temporary register for pseudo's */ static void -s_atmp() + s_atmp() { - register int temp; - if (strncmp(input_line_pointer, "sp", 2) == 0) { - input_line_pointer += 2; - atmp = 2; - } - else if (strncmp(input_line_pointer, "fp", 2) == 0) { - input_line_pointer += 2; - atmp = 3; - } - else if (strncmp(input_line_pointer, "r", 1) == 0) { - input_line_pointer += 1; - temp = get_absolute_expression(); - if (temp >= 0 && temp <= 31) - atmp = temp; - else - as_bad("Unknown temporary pseudo register"); - } - else { - as_bad("Unknown temporary pseudo register"); - } - demand_empty_rest_of_line(); - return; + register int temp; + if (strncmp(input_line_pointer, "sp", 2) == 0) { + input_line_pointer += 2; + atmp = 2; + } + else if (strncmp(input_line_pointer, "fp", 2) == 0) { + input_line_pointer += 2; + atmp = 3; + } + else if (strncmp(input_line_pointer, "r", 1) == 0) { + input_line_pointer += 1; + temp = get_absolute_expression(); + if (temp >= 0 && temp <= 31) + atmp = temp; + else + as_bad("Unknown temporary pseudo register"); + } + else { + as_bad("Unknown temporary pseudo register"); + } + demand_empty_rest_of_line(); + return; } /* This function is called once, at assembler startup time. It should set up all the tables, etc. that the MD part of the assembler will need. */ void -md_begin() + md_begin() { - register char *retval = NULL; - int lose = 0; - register unsigned int i = 0; - - op_hash = hash_new(); - if (op_hash == NULL) - as_fatal("Virtual memory exhausted"); - - while (i < NUMOPCODES) - { - const char *name = i860_opcodes[i].name; - retval = hash_insert(op_hash, name, &i860_opcodes[i]); - if(retval != NULL && *retval != '\0') - { - fprintf (stderr, "internal error: can't hash `%s': %s\n", - i860_opcodes[i].name, retval); - lose = 1; - } - do - { - if (i860_opcodes[i].match & i860_opcodes[i].lose) + register char *retval = NULL; + int lose = 0; + register unsigned int i = 0; + + op_hash = hash_new(); + if (op_hash == NULL) + as_fatal("Virtual memory exhausted"); + + while (i < NUMOPCODES) { - fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n", - i860_opcodes[i].name, i860_opcodes[i].args); - lose = 1; + const char *name = i860_opcodes[i].name; + retval = hash_insert(op_hash, name, &i860_opcodes[i]); + if(retval != NULL && *retval != '\0') + { + fprintf (stderr, "internal error: can't hash `%s': %s\n", + i860_opcodes[i].name, retval); + lose = 1; + } + do + { + if (i860_opcodes[i].match & i860_opcodes[i].lose) + { + fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n", + i860_opcodes[i].name, i860_opcodes[i].args); + lose = 1; + } + ++i; + } while (i < NUMOPCODES + && !strcmp(i860_opcodes[i].name, name)); } - ++i; - } while (i < NUMOPCODES - && !strcmp(i860_opcodes[i].name, name)); - } - - if (lose) - as_fatal("Broken assembler. No assembly attempted."); - - for (i = '0'; i < '8'; ++i) - octal[i] = 1; - for (i = '0'; i <= '9'; ++i) - toHex[i] = i - '0'; - for (i = 'a'; i <= 'f'; ++i) - toHex[i] = i + 10 - 'a'; - for (i = 'A'; i <= 'F'; ++i) - toHex[i] = i + 10 - 'A'; + + if (lose) + as_fatal("Broken assembler. No assembly attempted."); + + for (i = '0'; i < '8'; ++i) + octal[i] = 1; + for (i = '0'; i <= '9'; ++i) + toHex[i] = i - '0'; + for (i = 'a'; i <= 'f'; ++i) + toHex[i] = i + 10 - 'a'; + for (i = 'A'; i <= 'F'; ++i) + toHex[i] = i + 10 - 'A'; } void -md_end() + md_end() { - return; + return; } void -md_assemble(str) - char *str; + md_assemble(str) +char *str; { - char *toP; - int rsd; - int no_opcodes = 1; - int i; - struct i860_it pseudo[3]; - - assert(str); - i860_ip(str); - - /* check for expandable flag to produce pseudo-instructions */ - if (the_insn.expand != 0 && the_insn.highlow == NO_SPEC) { - for (i = 0; i < 3; i++) - pseudo[i] = the_insn; - - switch (the_insn.expand) { - - case E_DELAY: - no_opcodes = 1; - break; - - case E_MOV: - if (the_insn.exp.X_add_symbol == NULL && - the_insn.exp.X_subtract_symbol == NULL && - (the_insn.exp.X_add_number < (1 << 15) && - the_insn.exp.X_add_number >= -(1 << 15))) - break; - /* or l%const,r0,ireg_dest */ - pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000; - pseudo[0].highlow = PAIR; - /* orh h%const,ireg_dest,ireg_dest */ - pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000 | - ((the_insn.opcode & 0x001f0000) << 5); - pseudo[1].highlow = HIGH; - no_opcodes = 2; - break; - - case E_ADDR: - if (the_insn.exp.X_add_symbol == NULL && - the_insn.exp.X_subtract_symbol == NULL) - break; - /* orh ha%addr_expr,r0,r31 */ - pseudo[0].opcode = 0xec000000 | (atmp<<16); - pseudo[0].highlow = HIGHADJ; - pseudo[0].reloc = LOW0; /* must overwrite */ - /* l%addr_expr(r31),ireg_dest */ - pseudo[1].opcode = (the_insn.opcode & ~0x003e0000) | (atmp << 21); - pseudo[1].highlow = PAIR; - no_opcodes = 2; - break; - - case E_U32: /* 2nd version emulates Intel as, not doc. */ - if (the_insn.exp.X_add_symbol == NULL && - the_insn.exp.X_subtract_symbol == NULL && - (the_insn.exp.X_add_number < (1 << 16) && - the_insn.exp.X_add_number >= 0)) - break; - /* $(opcode)h h%const,ireg_src2,ireg_dest - pseudo[0].opcode = (the_insn.opcode & 0xf3ffffff) | 0x0c000000; */ - /* $(opcode)h h%const,ireg_src2,r31 */ - pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000 | - (atmp << 16); - pseudo[0].highlow = HIGH; - /* $(opcode) l%const,ireg_dest,ireg_dest - pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 | - ((the_insn.opcode & 0x001f0000) << 5); */ - /* $(opcode) l%const,r31,ireg_dest */ - pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 | - (atmp << 21); - pseudo[1].highlow = PAIR; - no_opcodes = 2; - break; - - case E_AND: /* 2nd version emulates Intel as, not doc. */ - if (the_insn.exp.X_add_symbol == NULL && - the_insn.exp.X_subtract_symbol == NULL && - (the_insn.exp.X_add_number < (1 << 16) && - the_insn.exp.X_add_number >= 0)) - break; - /* andnot h%const,ireg_src2,ireg_dest - pseudo[0].opcode = (the_insn.opcode & 0x03ffffff) | 0xd4000000; */ - /* andnot h%const,ireg_src2,r31 */ - pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000 | - (atmp << 16); - pseudo[0].highlow = HIGH; - pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number; - /* andnot l%const,ireg_dest,ireg_dest - pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 | - ((the_insn.opcode & 0x001f0000) << 5); */ - /* andnot l%const,r31,ireg_dest */ - pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 | - (atmp << 21); - pseudo[1].highlow = PAIR; - pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number; - no_opcodes = 2; - break; - - case E_S32: - if (the_insn.exp.X_add_symbol == NULL && - the_insn.exp.X_subtract_symbol == NULL && - (the_insn.exp.X_add_number < (1 << 15) && - the_insn.exp.X_add_number >= -(1 << 15))) - break; - /* orh h%const,r0,r31 */ - pseudo[0].opcode = 0xec000000 | (atmp << 16); - pseudo[0].highlow = HIGH; - /* or l%const,r31,r31 */ - pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16); - pseudo[1].highlow = PAIR; - /* r31,ireg_src2,ireg_dest */ - pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11); - pseudo[2].reloc = NO_RELOC; - no_opcodes = 3; - break; - - default: - abort(); + char *toP; + int rsd; + int no_opcodes = 1; + int i; + struct i860_it pseudo[3]; + + assert(str); + i860_ip(str); + + /* check for expandable flag to produce pseudo-instructions */ + if (the_insn.expand != 0 && the_insn.highlow == NO_SPEC) { + for (i = 0; i < 3; i++) + pseudo[i] = the_insn; + + switch (the_insn.expand) { + + case E_DELAY: + no_opcodes = 1; + break; + + case E_MOV: + if (the_insn.exp.X_add_symbol == NULL && + the_insn.exp.X_subtract_symbol == NULL && + (the_insn.exp.X_add_number < (1 << 15) && + the_insn.exp.X_add_number >= -(1 << 15))) + break; + /* or l%const,r0,ireg_dest */ + pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000; + pseudo[0].highlow = PAIR; + /* orh h%const,ireg_dest,ireg_dest */ + pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000 | + ((the_insn.opcode & 0x001f0000) << 5); + pseudo[1].highlow = HIGH; + no_opcodes = 2; + break; + + case E_ADDR: + if (the_insn.exp.X_add_symbol == NULL && + the_insn.exp.X_subtract_symbol == NULL) + break; + /* orh ha%addr_expr,r0,r31 */ + pseudo[0].opcode = 0xec000000 | (atmp<<16); + pseudo[0].highlow = HIGHADJ; + pseudo[0].reloc = LOW0; /* must overwrite */ + /* l%addr_expr(r31),ireg_dest */ + pseudo[1].opcode = (the_insn.opcode & ~0x003e0000) | (atmp << 21); + pseudo[1].highlow = PAIR; + no_opcodes = 2; + break; + + case E_U32: /* 2nd version emulates Intel as, not doc. */ + if (the_insn.exp.X_add_symbol == NULL && + the_insn.exp.X_subtract_symbol == NULL && + (the_insn.exp.X_add_number < (1 << 16) && + the_insn.exp.X_add_number >= 0)) + break; + /* $(opcode)h h%const,ireg_src2,ireg_dest + pseudo[0].opcode = (the_insn.opcode & 0xf3ffffff) | 0x0c000000; */ + /* $(opcode)h h%const,ireg_src2,r31 */ + pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000 | + (atmp << 16); + pseudo[0].highlow = HIGH; + /* $(opcode) l%const,ireg_dest,ireg_dest + pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 | + ((the_insn.opcode & 0x001f0000) << 5); */ + /* $(opcode) l%const,r31,ireg_dest */ + pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 | + (atmp << 21); + pseudo[1].highlow = PAIR; + no_opcodes = 2; + break; + + case E_AND: /* 2nd version emulates Intel as, not doc. */ + if (the_insn.exp.X_add_symbol == NULL && + the_insn.exp.X_subtract_symbol == NULL && + (the_insn.exp.X_add_number < (1 << 16) && + the_insn.exp.X_add_number >= 0)) + break; + /* andnot h%const,ireg_src2,ireg_dest + pseudo[0].opcode = (the_insn.opcode & 0x03ffffff) | 0xd4000000; */ + /* andnot h%const,ireg_src2,r31 */ + pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000 | + (atmp << 16); + pseudo[0].highlow = HIGH; + pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number; + /* andnot l%const,ireg_dest,ireg_dest + pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 | + ((the_insn.opcode & 0x001f0000) << 5); */ + /* andnot l%const,r31,ireg_dest */ + pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 | + (atmp << 21); + pseudo[1].highlow = PAIR; + pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number; + no_opcodes = 2; + break; + + case E_S32: + if (the_insn.exp.X_add_symbol == NULL && + the_insn.exp.X_subtract_symbol == NULL && + (the_insn.exp.X_add_number < (1 << 15) && + the_insn.exp.X_add_number >= -(1 << 15))) + break; + /* orh h%const,r0,r31 */ + pseudo[0].opcode = 0xec000000 | (atmp << 16); + pseudo[0].highlow = HIGH; + /* or l%const,r31,r31 */ + pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16); + pseudo[1].highlow = PAIR; + /* r31,ireg_src2,ireg_dest */ + pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11); + pseudo[2].reloc = NO_RELOC; + no_opcodes = 3; + break; + + default: + as_fatal("failed sanity check."); + } + + the_insn = pseudo[0]; + /* check for expanded opcode after branch or in dual */ + if (no_opcodes > 1 && last_expand == 1) + as_warn("Expanded opcode after delayed branch: `%s'", str); + if (no_opcodes > 1 && dual_mode != DUAL_OFF) + as_warn("Expanded opcode in dual mode: `%s'", str); } - - the_insn = pseudo[0]; - /* check for expanded opcode after branch or in dual */ - if (no_opcodes > 1 && last_expand == 1) - as_warn("Expanded opcode after delayed branch: `%s'", str); - if (no_opcodes > 1 && dual_mode != DUAL_OFF) - as_warn("Expanded opcode in dual mode: `%s'", str); - } - - i = 0; - do { /* always produce at least one opcode */ - toP = frag_more(4); - /* put out the opcode */ - md_number_to_chars(toP, the_insn.opcode, 4); - - /* check for expanded opcode after branch or in dual */ - last_expand = the_insn.pcrel; - - /* put out the symbol-dependent stuff */ - if (the_insn.reloc != NO_RELOC) { - fix_new( - frag_now, /* which frag */ - (toP - frag_now->fr_literal), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - /* merge bit fields into one argument */ - (int)(((the_insn.highlow & 0x3) << 4) | (the_insn.reloc & 0xf)) - ); - } - the_insn = pseudo[++i]; - } while (--no_opcodes > 0); - + + i = 0; + do { /* always produce at least one opcode */ + toP = frag_more(4); + /* put out the opcode */ + md_number_to_chars(toP, the_insn.opcode, 4); + + /* check for expanded opcode after branch or in dual */ + last_expand = the_insn.pcrel; + + /* put out the symbol-dependent stuff */ + if (the_insn.reloc != NO_RELOC) { + fix_new( + frag_now, /* which frag */ + (toP - frag_now->fr_literal), /* where */ + 4, /* size */ + the_insn.exp.X_add_symbol, + the_insn.exp.X_subtract_symbol, + the_insn.exp.X_add_number, + the_insn.pcrel, + /* merge bit fields into one argument */ + (int)(((the_insn.highlow & 0x3) << 4) | (the_insn.reloc & 0xf)) + ); + } + the_insn = pseudo[++i]; + } while (--no_opcodes > 0); + } static void -i860_ip(str) - char *str; + i860_ip(str) +char *str; { - char *s; - const char *args; - char c; - unsigned long i; - struct i860_opcode *insn; - char *argsStart; - unsigned long opcode; - unsigned int mask; - int match = 0; - int comma = 0; - - - for (s = str; islower(*s) || *s == '.' || *s == '3'; ++s) - ; - switch (*s) { - - case '\0': - break; - - case ',': - comma = 1; - - /*FALLTHROUGH*/ - - case ' ': - *s++ = '\0'; - break; - - default: - as_bad("Unknown opcode: `%s'", str); - exit(1); - } - - if (strncmp(str, "d.", 2) == 0) { /* check for d. opcode prefix */ - if (dual_mode == DUAL_ON) - dual_mode = DUAL_ONDDOT; - else - dual_mode = DUAL_DDOT; - str += 2; - } - - if ((insn = (struct i860_opcode *) hash_find(op_hash, str)) == NULL) { - if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT) - str -= 2; - as_bad("Unknown opcode: `%s'", str); - return; - } - if (comma) { - *--s = ','; - } - argsStart = s; - for (;;) { - opcode = insn->match; - bzero(&the_insn, sizeof(the_insn)); - the_insn.reloc = NO_RELOC; - - /* - * Build the opcode, checking as we go to make - * sure that the operands match - */ - for (args = insn->args; ; ++args) { - switch (*args) { - - case '\0': /* end of args */ - if (*s == '\0') { - match = 1; - } - break; - - case '+': - case '(': /* these must match exactly */ - case ')': - case ',': - case ' ': - if (*s++ == *args) - continue; + char *s; + const char *args; + char c; + unsigned long i; + struct i860_opcode *insn; + char *argsStart; + unsigned long opcode; + unsigned int mask; + int match = 0; + int comma = 0; + + + for (s = str; islower(*s) || *s == '.' || *s == '3'; ++s) + ; + switch (*s) { + + case '\0': break; - - case '#': /* must be at least one digit */ - if (isdigit(*s++)) { - while (isdigit(*s)) { - ++s; - } - continue; - } + + case ',': + comma = 1; + + /*FALLTHROUGH*/ + + case ' ': + *s++ = '\0'; break; - - case '1': /* next operand must be a register */ - case '2': - case 'd': - switch (*s) { - - case 'f': /* frame pointer */ - s++; - if (*s++ == 'p') { - mask = 0x3; - break; - } - goto error; - - case 's': /* stack pointer */ - s++; - if (*s++ == 'p') { - mask= 0x2; - break; - } - goto error; - - case 'r': /* any register */ - s++; - if (!isdigit(c = *s++)) { - goto error; - } - if (isdigit(*s)) { - if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) { - goto error; - } - } else { - c -= '0'; - } - mask= c; - break; - - default: /* not this opcode */ - goto error; - } + + default: + as_bad("Unknown opcode: `%s'", str); + exit(1); + } + + if (strncmp(str, "d.", 2) == 0) { /* check for d. opcode prefix */ + if (dual_mode == DUAL_ON) + dual_mode = DUAL_ONDDOT; + else + dual_mode = DUAL_DDOT; + str += 2; + } + + if ((insn = (struct i860_opcode *) hash_find(op_hash, str)) == NULL) { + if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT) + str -= 2; + as_bad("Unknown opcode: `%s'", str); + return; + } + if (comma) { + *--s = ','; + } + argsStart = s; + for (;;) { + opcode = insn->match; + bzero(&the_insn, sizeof(the_insn)); + the_insn.reloc = NO_RELOC; + /* - * Got the register, now figure out where - * it goes in the opcode. + * Build the opcode, checking as we go to make + * sure that the operands match */ - switch (*args) { - - case '1': - opcode |= mask << 11; - continue; - - case '2': - opcode |= mask << 21; - continue; - - case 'd': - opcode |= mask << 16; - continue; - - } - break; - - case 'e': /* next operand is a floating point register */ - case 'f': - case 'g': - if (*s++ == 'f' && isdigit(*s)) { - mask = *s++; - if (isdigit(*s)) { - mask = 10 * (mask - '0') + (*s++ - '0'); - if (mask >= 32) { - break; + for (args = insn->args; ; ++args) { + switch (*args) { + + case '\0': /* end of args */ + if (*s == '\0') { + match = 1; + } + break; + + case '+': + case '(': /* these must match exactly */ + case ')': + case ',': + case ' ': + if (*s++ == *args) + continue; + break; + + case '#': /* must be at least one digit */ + if (isdigit(*s++)) { + while (isdigit(*s)) { + ++s; + } + continue; + } + break; + + case '1': /* next operand must be a register */ + case '2': + case 'd': + switch (*s) { + + case 'f': /* frame pointer */ + s++; + if (*s++ == 'p') { + mask = 0x3; + break; + } + goto error; + + case 's': /* stack pointer */ + s++; + if (*s++ == 'p') { + mask= 0x2; + break; + } + goto error; + + case 'r': /* any register */ + s++; + if (!isdigit(c = *s++)) { + goto error; + } + if (isdigit(*s)) { + if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) { + goto error; + } + } else { + c -= '0'; + } + mask= c; + break; + + default: /* not this opcode */ + goto error; + } + /* + * Got the register, now figure out where + * it goes in the opcode. + */ + switch (*args) { + + case '1': + opcode |= mask << 11; + continue; + + case '2': + opcode |= mask << 21; + continue; + + case 'd': + opcode |= mask << 16; + continue; + + } + break; + + case 'e': /* next operand is a floating point register */ + case 'f': + case 'g': + if (*s++ == 'f' && isdigit(*s)) { + mask = *s++; + if (isdigit(*s)) { + mask = 10 * (mask - '0') + (*s++ - '0'); + if (mask >= 32) { + break; + } + } else { + mask -= '0'; + } + switch (*args) { + + case 'e': + opcode |= mask << 11; + continue; + + case 'f': + opcode |= mask << 21; + continue; + + case 'g': + opcode |= mask << 16; + if (dual_mode != DUAL_OFF) + opcode |= (1 << 9); /* dual mode instruction */ + if (dual_mode == DUAL_DDOT) + dual_mode = DUAL_OFF; + if (dual_mode == DUAL_ONDDOT) + dual_mode = DUAL_ON; + if ((opcode & (1 << 10)) && (mask == ((opcode >> 11) & 0x1f))) + as_warn("Fsr1 equals fdest with Pipelining"); + continue; + } + } + break; + + case 'c': /* next operand must be a control register */ + if (strncmp(s, "fir", 3) == 0) { + opcode |= 0x0 << 21; + s += 3; + continue; + } + if (strncmp(s, "psr", 3) == 0) { + opcode |= 0x1 << 21; + s += 3; + continue; + } + if (strncmp(s, "dirbase", 7) == 0) { + opcode |= 0x2 << 21; + s += 7; + continue; + } + if (strncmp(s, "db", 2) == 0) { + opcode |= 0x3 << 21; + s += 2; + continue; + } + if (strncmp(s, "fsr", 3) == 0) { + opcode |= 0x4 << 21; + s += 3; + continue; + } + if (strncmp(s, "epsr", 4) == 0) { + opcode |= 0x5 << 21; + s += 4; + continue; + } + break; + + case '5': /* 5 bit immediate in src1 */ + bzero(&the_insn, sizeof(the_insn)); + if ( !getExpression(s)) { + s = expr_end; + if (the_insn.exp.X_add_number & ~0x1f) + as_bad("5-bit immediate too large"); + opcode |= (the_insn.exp.X_add_number & 0x1f) << 11; + bzero(&the_insn, sizeof(the_insn)); + the_insn.reloc = NO_RELOC; + continue; + } + break; + + case 'l': /* 26 bit immediate, relative branch */ + the_insn.reloc = BRADDR; + the_insn.pcrel = 1; + goto immediate; + + case 's': /* 16 bit immediate, split relative branch */ + /* upper 5 bits of offset in dest field */ + the_insn.pcrel = 1; + the_insn.reloc = SPLIT0; + goto immediate; + + case 'S': /* 16 bit immediate, split (st), aligned */ + if (opcode & (1 << 28)) + if (opcode & 0x1) + the_insn.reloc = SPLIT2; + else + the_insn.reloc = SPLIT1; + else + the_insn.reloc = SPLIT0; + goto immediate; + + case 'I': /* 16 bit immediate, aligned */ + if (opcode & (1 << 28)) + if (opcode & 0x1) + the_insn.reloc = LOW2; + else + the_insn.reloc = LOW1; + else + the_insn.reloc = LOW0; + goto immediate; + + case 'i': /* 16 bit immediate */ + the_insn.reloc = LOW0; + + /*FALLTHROUGH*/ + + immediate: + if(*s==' ') + s++; + if (strncmp(s, "ha%", 3) == 0) { + the_insn.highlow = HIGHADJ; + s += 3; + } else if (strncmp(s, "h%", 2) == 0) { + the_insn.highlow = HIGH; + s += 2; + } else if (strncmp(s, "l%", 2) == 0) { + the_insn.highlow = PAIR; + s += 2; + } + the_insn.expand = insn->expand; + + /* Note that if the getExpression() fails, we will still have + created U entries in the symbol table for the 'symbols' + in the input string. Try not to create U symbols for + registers, etc. */ + + if ( !getExpression(s)) { + s = expr_end; + continue; + } + break; + + default: + as_fatal("failed sanity check."); } - } else { - mask -= '0'; - } - switch (*args) { - - case 'e': - opcode |= mask << 11; - continue; - - case 'f': - opcode |= mask << 21; - continue; - - case 'g': - opcode |= mask << 16; - if (dual_mode != DUAL_OFF) - opcode |= (1 << 9); /* dual mode instruction */ - if (dual_mode == DUAL_DDOT) - dual_mode = DUAL_OFF; - if (dual_mode == DUAL_ONDDOT) - dual_mode = DUAL_ON; - if ((opcode & (1 << 10)) && (mask == ((opcode >> 11) & 0x1f))) - as_warn("Fsr1 equals fdest with Pipelining"); - continue; - } - } - break; - - case 'c': /* next operand must be a control register */ - if (strncmp(s, "fir", 3) == 0) { - opcode |= 0x0 << 21; - s += 3; - continue; - } - if (strncmp(s, "psr", 3) == 0) { - opcode |= 0x1 << 21; - s += 3; - continue; - } - if (strncmp(s, "dirbase", 7) == 0) { - opcode |= 0x2 << 21; - s += 7; - continue; - } - if (strncmp(s, "db", 2) == 0) { - opcode |= 0x3 << 21; - s += 2; - continue; - } - if (strncmp(s, "fsr", 3) == 0) { - opcode |= 0x4 << 21; - s += 3; - continue; - } - if (strncmp(s, "epsr", 4) == 0) { - opcode |= 0x5 << 21; - s += 4; - continue; - } - break; - - case '5': /* 5 bit immediate in src1 */ - bzero(&the_insn, sizeof(the_insn)); - if ( !getExpression(s)) { - s = expr_end; - if (the_insn.exp.X_add_number & ~0x1f) - as_bad("5-bit immediate too large"); - opcode |= (the_insn.exp.X_add_number & 0x1f) << 11; - bzero(&the_insn, sizeof(the_insn)); - the_insn.reloc = NO_RELOC; - continue; - } - break; - - case 'l': /* 26 bit immediate, relative branch */ - the_insn.reloc = BRADDR; - the_insn.pcrel = 1; - goto immediate; - - case 's': /* 16 bit immediate, split relative branch */ - /* upper 5 bits of offset in dest field */ - the_insn.pcrel = 1; - the_insn.reloc = SPLIT0; - goto immediate; - - case 'S': /* 16 bit immediate, split (st), aligned */ - if (opcode & (1 << 28)) - if (opcode & 0x1) - the_insn.reloc = SPLIT2; - else - the_insn.reloc = SPLIT1; - else - the_insn.reloc = SPLIT0; - goto immediate; - - case 'I': /* 16 bit immediate, aligned */ - if (opcode & (1 << 28)) - if (opcode & 0x1) - the_insn.reloc = LOW2; - else - the_insn.reloc = LOW1; - else - the_insn.reloc = LOW0; - goto immediate; - - case 'i': /* 16 bit immediate */ - the_insn.reloc = LOW0; - - /*FALLTHROUGH*/ - - immediate: - if(*s==' ') - s++; - if (strncmp(s, "ha%", 3) == 0) { - the_insn.highlow = HIGHADJ; - s += 3; - } else if (strncmp(s, "h%", 2) == 0) { - the_insn.highlow = HIGH; - s += 2; - } else if (strncmp(s, "l%", 2) == 0) { - the_insn.highlow = PAIR; - s += 2; - } - the_insn.expand = insn->expand; - - /* Note that if the getExpression() fails, we will still have - created U entries in the symbol table for the 'symbols' - in the input string. Try not to create U symbols for - registers, etc. */ - - if ( !getExpression(s)) { - s = expr_end; - continue; + break; } + error: + if (match == 0) + { + /* Args don't match. */ + if (&insn[1] - i860_opcodes < NUMOPCODES + && !strcmp(insn->name, insn[1].name)) + { + ++insn; + s = argsStart; + continue; + } + else + { + as_bad("Illegal operands"); + return; + } + } break; - - default: - abort(); - } - break; } - error: - if (match == 0) - { - /* Args don't match. */ - if (&insn[1] - i860_opcodes < NUMOPCODES - && !strcmp(insn->name, insn[1].name)) - { - ++insn; - s = argsStart; - continue; - } - else - { - as_bad("Illegal operands"); - return; - } - } - break; - } - - the_insn.opcode = opcode; - return; + + the_insn.opcode = opcode; + return; } static int -getExpression(str) - char *str; + getExpression(str) +char *str; { - char *save_in; - segT seg; - - save_in = input_line_pointer; - input_line_pointer = str; - switch (seg = expression(&the_insn.exp)) { - - case SEG_ABSOLUTE: - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_ABSENT: - break; - - default: - the_insn.error = "bad segment"; + char *save_in; + segT seg; + + save_in = input_line_pointer; + input_line_pointer = str; + switch (seg = expression(&the_insn.exp)) { + + case SEG_ABSOLUTE: + case SEG_TEXT: + case SEG_DATA: + case SEG_BSS: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + case SEG_BIG: + case SEG_ABSENT: + break; + + default: + the_insn.error = "bad segment"; + expr_end = input_line_pointer; + input_line_pointer=save_in; + return 1; + } expr_end = input_line_pointer; - input_line_pointer=save_in; - return 1; - } - expr_end = input_line_pointer; - input_line_pointer = save_in; - return 0; + input_line_pointer = save_in; + return 0; } /* - This is identical to the md_atof in m68k.c. I think this is right, - but I'm not sure. - - Turn a string in input_line_pointer into a floating point constant of type - type, and store the appropriate bytes in *litP. The number of LITTLENUMS - emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ + This is identical to the md_atof in m68k.c. I think this is right, + but I'm not sure. + + Turn a string in input_line_pointer into a floating point constant of type + type, and store the appropriate bytes in *litP. The number of LITTLENUMS + emitted is stored in *sizeP . An error message is returned, or NULL on OK. + */ /* Equal to MAX_PRECISION in atof-ieee.c */ #define MAX_LITTLENUMS 6 char * -md_atof(type,litP,sizeP) - char type; - char *litP; - int *sizeP; + md_atof(type,litP,sizeP) +char type; +char *litP; +int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee(); - - switch(type) { - - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words;prec--;) { - md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee(); + + switch(type) { + + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words;prec--;) { + md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } /* * Write out big-endian. */ void -md_number_to_chars(buf,val,n) - char *buf; - long val; - int n; + md_number_to_chars(buf,val,n) +char *buf; +long val; +int n; { - switch(n) { - - case 4: - *buf++ = val >> 24; - *buf++ = val >> 16; - case 2: - *buf++ = val >> 8; - case 1: - *buf = val; - break; - - default: - abort(); - } - return; + switch(n) { + + case 4: + *buf++ = val >> 24; + *buf++ = val >> 16; + case 2: + *buf++ = val >> 8; + case 1: + *buf = val; + break; + + default: + as_fatal("failed sanity check."); + } + return; } void md_number_to_imm(buf,val,n, fixP) - char *buf; - long val; - int n; - fixS *fixP; +char *buf; +long val; +int n; +fixS *fixP; { - enum reloc_type reloc = fixP->fx_r_type & 0xf; - enum highlow_type highlow = (fixP->fx_r_type >> 4) & 0x3; - - assert(buf); - assert(n == 4); /* always on i860 */ - - switch(highlow) - { - - case HIGHADJ: /* adjusts the high-order 16-bits */ - if (val & (1 << 15)) - val += (1 << 16); - - /*FALLTHROUGH*/ - - case HIGH: /* selects the high-order 16-bits */ - val >>= 16; - break; - - case PAIR: /* selects the low-order 16-bits */ - val = val & 0xffff; - break; - - default: - break; - } - - switch(reloc) - { - - case BRADDR: /* br,call,bc,bc.t,bnc,bnc.t w/26-bit immediate */ - if (fixP->fx_pcrel != 1) - as_bad("26-bit branch w/o pc relative set: 0x%08x", val); - val >>= 2; /* align pcrel offset, see manual */ - - if (val >= (1 << 25) || val < -(1 << 25)) /* check for overflow */ - as_bad("26-bit branch offset overflow: 0x%08x", val); - buf[0] = (buf[0] & 0xfc) | ((val >> 24) & 0x3); - buf[1] = val >> 16; - buf[2] = val >> 8; - buf[3] = val; - break; - - case SPLIT2: /* 16 bit immediate, 4-byte aligned */ - if (val & 0x3) - as_bad("16-bit immediate 4-byte alignment error: 0x%08x", val); - val &= ~0x3; /* 4-byte align value */ - /*FALLTHROUGH*/ - case SPLIT1: /* 16 bit immediate, 2-byte aligned */ - if (val & 0x1) - as_bad("16-bit immediate 2-byte alignment error: 0x%08x", val); - val &= ~0x1; /* 2-byte align value */ - /*FALLTHROUGH*/ - case SPLIT0: /* st,bla,bte,btne w/16-bit immediate */ - if (fixP->fx_pcrel == 1) - val >>= 2; /* align pcrel offset, see manual */ - /* check for bounds */ - if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15))) - as_bad("16-bit branch offset overflow: 0x%08x", val); - buf[1] = (buf[1] & ~0x1f) | ((val >> 11) & 0x1f); - buf[2] = (buf[2] & ~0x7) | ((val >> 8) & 0x7); - buf[3] |= val; /* perserve bottom opcode bits */ - break; - - case LOW4: /* fld,pfld,pst,flush 16-byte aligned */ - if (val & 0xf) - as_bad("16-bit immediate 16-byte alignment error: 0x%08x", val); - val &= ~0xf; /* 16-byte align value */ - /*FALLTHROUGH*/ - case LOW3: /* fld,pfld,pst,flush 8-byte aligned */ - if (val & 0x7) - as_bad("16-bit immediate 8-byte alignment error: 0x%08x", val); - val &= ~0x7; /* 8-byte align value */ - /*FALLTHROUGH*/ - case LOW2: /* 16 bit immediate, 4-byte aligned */ - if (val & 0x3) - as_bad("16-bit immediate 4-byte alignment error: 0x%08x", val); - val &= ~0x3; /* 4-byte align value */ - /*FALLTHROUGH*/ - case LOW1: /* 16 bit immediate, 2-byte aligned */ - if (val & 0x1) - as_bad("16-bit immediate 2-byte alignment error: 0x%08x", val); - val &= ~0x1; /* 2-byte align value */ - /*FALLTHROUGH*/ - case LOW0: /* 16 bit immediate, byte aligned */ - /* check for bounds */ - if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15))) - as_bad("16-bit immediate overflow: 0x%08x", val); - buf[2] = val >> 8; - buf[3] |= val; /* perserve bottom opcode bits */ - break; - - case NO_RELOC: - default: - as_bad("bad relocation type: 0x%02x", reloc); - break; - } - return; + enum reloc_type reloc = fixP->fx_r_type & 0xf; + enum highlow_type highlow = (fixP->fx_r_type >> 4) & 0x3; + + assert(buf); + assert(n == 4); /* always on i860 */ + + switch(highlow) + { + + case HIGHADJ: /* adjusts the high-order 16-bits */ + if (val & (1 << 15)) + val += (1 << 16); + + /*FALLTHROUGH*/ + + case HIGH: /* selects the high-order 16-bits */ + val >>= 16; + break; + + case PAIR: /* selects the low-order 16-bits */ + val = val & 0xffff; + break; + + default: + break; + } + + switch(reloc) + { + + case BRADDR: /* br,call,bc,bc.t,bnc,bnc.t w/26-bit immediate */ + if (fixP->fx_pcrel != 1) + as_bad("26-bit branch w/o pc relative set: 0x%08x", val); + val >>= 2; /* align pcrel offset, see manual */ + + if (val >= (1 << 25) || val < -(1 << 25)) /* check for overflow */ + as_bad("26-bit branch offset overflow: 0x%08x", val); + buf[0] = (buf[0] & 0xfc) | ((val >> 24) & 0x3); + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; + break; + + case SPLIT2: /* 16 bit immediate, 4-byte aligned */ + if (val & 0x3) + as_bad("16-bit immediate 4-byte alignment error: 0x%08x", val); + val &= ~0x3; /* 4-byte align value */ + /*FALLTHROUGH*/ + case SPLIT1: /* 16 bit immediate, 2-byte aligned */ + if (val & 0x1) + as_bad("16-bit immediate 2-byte alignment error: 0x%08x", val); + val &= ~0x1; /* 2-byte align value */ + /*FALLTHROUGH*/ + case SPLIT0: /* st,bla,bte,btne w/16-bit immediate */ + if (fixP->fx_pcrel == 1) + val >>= 2; /* align pcrel offset, see manual */ + /* check for bounds */ + if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15))) + as_bad("16-bit branch offset overflow: 0x%08x", val); + buf[1] = (buf[1] & ~0x1f) | ((val >> 11) & 0x1f); + buf[2] = (buf[2] & ~0x7) | ((val >> 8) & 0x7); + buf[3] |= val; /* perserve bottom opcode bits */ + break; + + case LOW4: /* fld,pfld,pst,flush 16-byte aligned */ + if (val & 0xf) + as_bad("16-bit immediate 16-byte alignment error: 0x%08x", val); + val &= ~0xf; /* 16-byte align value */ + /*FALLTHROUGH*/ + case LOW3: /* fld,pfld,pst,flush 8-byte aligned */ + if (val & 0x7) + as_bad("16-bit immediate 8-byte alignment error: 0x%08x", val); + val &= ~0x7; /* 8-byte align value */ + /*FALLTHROUGH*/ + case LOW2: /* 16 bit immediate, 4-byte aligned */ + if (val & 0x3) + as_bad("16-bit immediate 4-byte alignment error: 0x%08x", val); + val &= ~0x3; /* 4-byte align value */ + /*FALLTHROUGH*/ + case LOW1: /* 16 bit immediate, 2-byte aligned */ + if (val & 0x1) + as_bad("16-bit immediate 2-byte alignment error: 0x%08x", val); + val &= ~0x1; /* 2-byte align value */ + /*FALLTHROUGH*/ + case LOW0: /* 16 bit immediate, byte aligned */ + /* check for bounds */ + if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15))) + as_bad("16-bit immediate overflow: 0x%08x", val); + buf[2] = val >> 8; + buf[3] |= val; /* perserve bottom opcode bits */ + break; + + case NO_RELOC: + default: + as_bad("bad relocation type: 0x%02x", reloc); + break; + } + return; } /* should never be called for i860 */ void -md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, to_addr; + md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) +char *ptr; +long from_addr, to_addr; fragS *frag; symbolS *to_symbol; { - fprintf(stderr, "i860_create_short_jmp\n"); - abort(); + as_fatal("i860_create_short_jmp\n"); } /* should never be called for i860 */ void -md_number_to_disp(buf,val,n) - char *buf; - long val; + md_number_to_disp(buf,val,n) +char *buf; +long val; { - fprintf(stderr, "md_number_to_disp\n"); - abort(); + as_fatal("md_number_to_disp\n"); } /* should never be called for i860 */ void -md_number_to_field(buf,val,fix) - char *buf; - long val; - void *fix; + md_number_to_field(buf,val,fix) +char *buf; +long val; +void *fix; { - fprintf(stderr, "i860_number_to_field\n"); - abort(); + as_fatal("i860_number_to_field\n"); } /* the bit-field entries in the relocation_info struct plays hell @@ -1003,112 +1000,109 @@ md_number_to_field(buf,val,fix) relocation type (highlow 5-4). Next 4 bytes are long addend. */ /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */ void -md_ri_to_chars(ri_p, ri) - struct relocation_info *ri_p, ri; + md_ri_to_chars(ri_p, ri) +struct relocation_info *ri_p, ri; { #if 0 - unsigned char the_bytes[sizeof(*ri_p)]; - - /* this is easy */ - md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address)); - /* now the fun stuff */ - the_bytes[4] = (ri.r_index >> 16) & 0x0ff; - the_bytes[5] = (ri.r_index >> 8) & 0x0ff; - the_bytes[6] = ri.r_index & 0x0ff; - the_bytes[7] = ((ri.r_extern << 7) & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F); - /* Also easy */ - md_number_to_chars(&the_bytes[8], ri.r_addend, sizeof(ri.r_addend)); - /* now put it back where you found it, Junior... */ - bcopy (the_bytes, (char *)ri_p, sizeof(*ri_p)); + unsigned char the_bytes[sizeof(*ri_p)]; + + /* this is easy */ + md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address)); + /* now the fun stuff */ + the_bytes[4] = (ri.r_index >> 16) & 0x0ff; + the_bytes[5] = (ri.r_index >> 8) & 0x0ff; + the_bytes[6] = ri.r_index & 0x0ff; + the_bytes[7] = ((ri.r_extern << 7) & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F); + /* Also easy */ + md_number_to_chars(&the_bytes[8], ri.r_addend, sizeof(ri.r_addend)); + /* now put it back where you found it, Junior... */ + bcopy (the_bytes, (char *)ri_p, sizeof(*ri_p)); #endif } /* should never be called for i860 */ void -md_convert_frag(fragP) - register fragS *fragP; + md_convert_frag(headers, fragP) +object_headers *headers; +register fragS *fragP; { - fprintf(stderr, "i860_convert_frag\n"); - abort(); + as_fatal("i860_convert_frag\n"); } /* should never be called for i860 */ void -md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, - to_addr; - fragS *frag; - symbolS *to_symbol; + md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol) +char *ptr; +long from_addr, + to_addr; +fragS *frag; +symbolS *to_symbol; { - fprintf(stderr, "i860_create_long_jump\n"); - abort(); + as_fatal("i860_create_long_jump\n"); } /* should never be called for i860 */ int -md_estimate_size_before_relax(fragP, segtype) - register fragS *fragP; + md_estimate_size_before_relax(fragP, segtype) +register fragS *fragP; segT segtype; { - fprintf(stderr, "i860_estimate_size_before_relax\n"); - abort(); - return 0; + as_fatal("i860_estimate_size_before_relax\n"); } /* for debugging only, must match enum reloc_type */ static char *Reloc[] = { - "NO_RELOC", - "BRADDR", - "LOW0", - "LOW1", - "LOW2", - "LOW3", - "LOW4", - "SPLIT0", - "SPLIT1", - "SPLIT2", - "RELOC_32", + "NO_RELOC", + "BRADDR", + "LOW0", + "LOW1", + "LOW2", + "LOW3", + "LOW4", + "SPLIT0", + "SPLIT1", + "SPLIT2", + "RELOC_32", }; static char *Highlow[] = { - "NO_SPEC", - "PAIR", - "HIGH", - "HIGHADJ", + "NO_SPEC", + "PAIR", + "HIGH", + "HIGHADJ", }; static void -print_insn(insn) - struct i860_it *insn; + print_insn(insn) +struct i860_it *insn; { - if (insn->error) { - fprintf(stderr, "ERROR: %s\n"); - } - fprintf(stderr, "opcode=0x%08x\t", insn->opcode); - fprintf(stderr, "expand=0x%08x\t", insn->expand); - fprintf(stderr, "reloc = %s\t", Reloc[insn->reloc]); - fprintf(stderr, "highlow = %s\n", Highlow[insn->highlow]); - fprintf(stderr, "exp = {\n"); - fprintf(stderr, "\t\tX_add_symbol = %s\n", - insn->exp.X_add_symbol ? - (S_GET_NAME(insn->exp.X_add_symbol) ? - S_GET_NAME(insn->exp.X_add_symbol) : "???") : "0"); - fprintf(stderr, "\t\tX_sub_symbol = %s\n", - insn->exp.X_subtract_symbol ? - (S_GET_NAME(insn->exp.X_subtract_symbol) ? - S_GET_NAME(insn->exp.X_subtract_symbol) : "???") : "0"); - fprintf(stderr, "\t\tX_add_number = %d\n", - insn->exp.X_add_number); - fprintf(stderr, "}\n"); - return; + if (insn->error) { + fprintf(stderr, "ERROR: %s\n"); + } + fprintf(stderr, "opcode=0x%08x\t", insn->opcode); + fprintf(stderr, "expand=0x%08x\t", insn->expand); + fprintf(stderr, "reloc = %s\t", Reloc[insn->reloc]); + fprintf(stderr, "highlow = %s\n", Highlow[insn->highlow]); + fprintf(stderr, "exp = {\n"); + fprintf(stderr, "\t\tX_add_symbol = %s\n", + insn->exp.X_add_symbol ? + (S_GET_NAME(insn->exp.X_add_symbol) ? + S_GET_NAME(insn->exp.X_add_symbol) : "???") : "0"); + fprintf(stderr, "\t\tX_sub_symbol = %s\n", + insn->exp.X_subtract_symbol ? + (S_GET_NAME(insn->exp.X_subtract_symbol) ? + S_GET_NAME(insn->exp.X_subtract_symbol) : "???") : "0"); + fprintf(stderr, "\t\tX_add_number = %d\n", + insn->exp.X_add_number); + fprintf(stderr, "}\n"); + return; } int -md_parse_option(argP,cntP,vecP) - char **argP; - int *cntP; - char ***vecP; + md_parse_option(argP,cntP,vecP) +char **argP; +int *cntP; +char ***vecP; { - return 1; + return 1; } /* @@ -1116,51 +1110,50 @@ md_parse_option(argP,cntP,vecP) * this machine dependent routine to emit them. */ void -emit_machine_reloc(fixP, segment_address_in_file) - register fixS *fixP; - relax_addressT segment_address_in_file; + emit_machine_reloc(fixP, segment_address_in_file) +register fixS *fixP; +relax_addressT segment_address_in_file; { - struct reloc_info_i860 ri; - register symbolS *symbolP; - extern char *next_object_file_charP; - long add_number; - - bzero((char *) &ri, sizeof(ri)); - for (; fixP; fixP = fixP->fx_next) { - - if (fixP->fx_r_type & ~0x3f) { - fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type); - abort(); - } - ri.r_pcrel = fixP->fx_pcrel; - ri.r_type = fixP->fx_r_type; - - if ((symbolP = fixP->fx_addsy) != NULL) { - ri.r_address = fixP->fx_frag->fr_address + - fixP->fx_where - segment_address_in_file; - if ((symbolP->sy_type & N_TYPE) == N_UNDF) { - ri.r_extern = 1; - ri.r_symbolnum = symbolP->sy_number; - } else { - ri.r_extern = 0; - ri.r_symbolnum = symbolP->sy_type & N_TYPE; - } - if (symbolP && symbolP->sy_frag) { - ri.r_addend = symbolP->sy_frag->fr_address; - } - ri.r_type = fixP->fx_r_type; - if (fixP->fx_pcrel) { - /* preserve actual offset vs. pc + 4 */ - ri.r_addend -= (ri.r_address + 4); - } else { - ri.r_addend = fixP->fx_addnumber; - } - - md_ri_to_chars((char *) &ri, ri); - append(&next_object_file_charP, (char *)& ri, sizeof(ri)); + struct reloc_info_i860 ri; + register symbolS *symbolP; + extern char *next_object_file_charP; + long add_number; + + bzero((char *) &ri, sizeof(ri)); + for (; fixP; fixP = fixP->fx_next) { + + if (fixP->fx_r_type & ~0x3f) { + as_fatal("fixP->fx_r_type = %d\n", fixP->fx_r_type); + } + ri.r_pcrel = fixP->fx_pcrel; + ri.r_type = fixP->fx_r_type; + + if ((symbolP = fixP->fx_addsy) != NULL) { + ri.r_address = fixP->fx_frag->fr_address + + fixP->fx_where - segment_address_in_file; + if ((symbolP->sy_type & N_TYPE) == N_UNDF) { + ri.r_extern = 1; + ri.r_symbolnum = symbolP->sy_number; + } else { + ri.r_extern = 0; + ri.r_symbolnum = symbolP->sy_type & N_TYPE; + } + if (symbolP && symbolP->sy_frag) { + ri.r_addend = symbolP->sy_frag->fr_address; + } + ri.r_type = fixP->fx_r_type; + if (fixP->fx_pcrel) { + /* preserve actual offset vs. pc + 4 */ + ri.r_addend -= (ri.r_address + 4); + } else { + ri.r_addend = fixP->fx_addnumber; + } + + md_ri_to_chars((char *) &ri, ri); + append(&next_object_file_charP, (char *)& ri, sizeof(ri)); + } } - } - return; + return; } /* Parse an operand that is machine-specific. @@ -1169,8 +1162,8 @@ emit_machine_reloc(fixP, segment_address_in_file) /* ARGSUSED */ void -md_operand (expressionP) - expressionS *expressionP; + md_operand (expressionP) +expressionS *expressionP; { } @@ -1178,35 +1171,35 @@ md_operand (expressionP) /* ARGSUSED */ symbolS * -md_undefined_symbol (name) - char *name; + md_undefined_symbol (name) +char *name; { - return 0; + return 0; } /* Round up a section size to the appropriate boundary. */ long -md_section_align (segment, size) - segT segment; - long size; + md_section_align (segment, size) +segT segment; +long size; { - return size; /* Byte alignment is fine */ + return size; /* Byte alignment is fine */ } /* Exactly what point is a PC-relative offset relative TO? On the i860, they're relative to the address of the offset, plus its size. (??? Is this right? FIXME-SOON!) */ long -md_pcrel_from (fixP) - fixS *fixP; + md_pcrel_from (fixP) +fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } void -md_apply_fix(fixP, val) - fixS *fixP; - long val; + md_apply_fix(fixP, val) +fixS *fixP; +long val; { char *place = fixP->fx_where + fixP->fx_frag->fr_literal; @@ -1237,7 +1230,28 @@ md_apply_fix(fixP, val) /* * $Log$ - * Revision 1.1 1991/04/04 18:16:48 rich + * Revision 1.6 1992/02/13 08:32:43 rich + * 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. + * + * Revision 1.5 1991/12/01 07:11:31 sac + * More filename renaming. + * + * Revision 1.4 1991/08/15 19:38:42 rich + * Abort()'s become as_fatal()'s. + * + * Revision 1.3 1991/07/27 02:32:39 rich + * Polishing m68k support. + * + * Revision 1.2 1991/06/14 14:02:20 rich + * Version 2 GPL. + * + * Revision 1.1.1.1 1991/04/04 18:16:49 rich + * new gas main line + * + * Revision 1.1 1991/04/04 18:16:48 rich * Initial revision * * Revision 1.2 1991/03/30 17:11:32 rich diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c index a551376..3f321ec 100644 --- a/gas/config/tc-i960.c +++ b/gas/config/tc-i960.c @@ -1,21 +1,21 @@ /* i960.c - All the i80960-specific stuff Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. - -This file is part of GAS. - -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. + + 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. */ /* $Id$ */ @@ -82,7 +82,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "obstack.h" -#include "i960-opcode.h" +#include "opcode/i960.h" extern char *input_line_pointer; extern struct hash_control *po_hash; @@ -94,13 +94,13 @@ int md_reloc_size = sizeof(struct reloc); int md_reloc_size = sizeof(struct relocation_info); #endif /* OBJ_COFF */ - /*************************** - * Local i80960 routines * - ************************** */ +/*************************** + * Local i80960 routines * + ************************** */ static void brcnt_emit(); /* Emit branch-prediction instrumentation code */ static char * brlab_next(); /* Return next branch local label */ - void brtab_emit(); /* Emit br-predict instrumentation table */ +void brtab_emit(); /* Emit br-predict instrumentation table */ static void cobr_fmt(); /* Generate COBR instruction */ static void ctrl_fmt(); /* Generate CTRL instruction */ static char * emit(); /* Emit (internally) binary */ @@ -117,7 +117,7 @@ static void parse_memop(); /* Parse a memory operand */ static void parse_po(); /* Parse machine-dependent pseudo-op */ static void parse_regop(); /* Parse a register operand */ static void reg_fmt(); /* Generate a REG format instruction */ - void reloc_callj(); /* Relocate a 'callj' instruction */ +void reloc_callj(); /* Relocate a 'callj' instruction */ static void relax_cobr(); /* "De-optimize" cobr into compare/branch */ static void s_leafproc(); /* Process '.leafproc' pseudo-op */ static void s_sysproc(); /* Process '.sysproc' pseudo-op */ @@ -170,11 +170,11 @@ char FLT_CHARS[] = "fFdDtT"; * displacement won't hack it. */ const relax_typeS -md_relax_table[] = { - {0, 0, 0,0}, /* State 0 => no more relaxation possible */ - {4088, -4096, 0,2}, /* State 1: conditional branch (cobr) */ - {0x800000-8,-0x800000,4,0}, /* State 2: compare (reg) & branch (ctrl) */ -}; + md_relax_table[] = { + {0, 0, 0,0}, /* State 0 => no more relaxation possible */ + {4088, -4096, 0,2}, /* State 1: conditional branch (cobr) */ + {0x800000-8,-0x800000,4,0}, /* State 2: compare (reg) & branch (ctrl) */ + }; /* These are the machine dependent pseudo-ops. @@ -189,33 +189,33 @@ md_relax_table[] = { #define S_SYSPROC 2 const pseudo_typeS -md_pseudo_table[] = { - - { "bss", s_lcomm, 1 }, - { "extended", float_cons, 't' }, - { "leafproc", parse_po, S_LEAFPROC }, - { "sysproc", parse_po, S_SYSPROC }, - - { "word", cons, 4 }, - { "quad", big_cons, 16 }, - - { 0, 0, 0 } -}; + md_pseudo_table[] = { + + { "bss", s_lcomm, 1 }, + { "extended", float_cons, 't' }, + { "leafproc", parse_po, S_LEAFPROC }, + { "sysproc", parse_po, S_SYSPROC }, + + { "word", cons, 4 }, + { "quad", big_cons, 16 }, + + { 0, 0, 0 } + }; /* Macros to extract info from an 'expressionS' structure 'e' */ #define adds(e) e.X_add_symbol #define subs(e) e.X_subtract_symbol #define offs(e) e.X_add_number #define segs(e) e.X_seg - - -/* Branch-prediction bits for CTRL/COBR format opcodes */ + + + /* Branch-prediction bits for CTRL/COBR format opcodes */ #define BP_MASK 0x00000002 /* Mask for branch-prediction bit */ #define BP_TAKEN 0x00000000 /* Value to OR in to predict branch */ #define BP_NOT_TAKEN 0x00000002 /* Value to OR in to predict no branch */ - - -/* Some instruction opcodes that we need explicitly */ + + + /* Some instruction opcodes that we need explicitly */ #define BE 0x12000000 #define BG 0x11000000 #define BGE 0x13000000 @@ -227,32 +227,32 @@ md_pseudo_table[] = { #define CHKBIT 0x5a002700 #define CMPI 0x5a002080 #define CMPO 0x5a002000 - + #define B 0x08000000 #define BAL 0x0b000000 #define CALL 0x09000000 #define CALLS 0x66003800 #define RET 0x0a000000 - - -/* These masks are used to build up a set of MEMB mode bits. */ + + + /* These masks are used to build up a set of MEMB mode bits. */ #define A_BIT 0x0400 #define I_BIT 0x0800 #define MEMB_BIT 0x1000 #define D_BIT 0x2000 - - -/* Mask for the only mode bit in a MEMA instruction (if set, abase reg is used) */ + + + /* Mask for the only mode bit in a MEMA instruction (if set, abase reg is used) */ #define MEMA_ABASE 0x2000 - -/* Info from which a MEMA or MEMB format instruction can be generated */ -typedef struct { - long opcode; /* (First) 32 bits of instruction */ - int disp; /* 0-(none), 12- or, 32-bit displacement needed */ - char *e; /* The expression in the source instruction from + + /* Info from which a MEMA or MEMB format instruction can be generated */ + typedef struct { + long opcode; /* (First) 32 bits of instruction */ + int disp; /* 0-(none), 12- or, 32-bit displacement needed */ + char *e; /* The expression in the source instruction from * which the displacement should be determined */ -} memS; + } memS; /* The two pieces of info we need to generate a register operand */ @@ -276,12 +276,12 @@ static struct { { "g4", 20 }, { "g5", 21 }, { "g6", 22 }, { "g7", 23 }, { "g8", 24 }, { "g9", 25 }, { "g10", 26 }, { "g11", 27 }, { "g12", 28 }, { "g13", 29 }, { "g14", 30 }, { "fp", 31 }, - + /* Numbers for special-function registers are for assembler internal * use only: they are scaled back to range [0-31] for binary output. */ # define SF0 32 - + { "sf0", 32 }, { "sf1", 33 }, { "sf2", 34 }, { "sf3", 35 }, { "sf4", 36 }, { "sf5", 37 }, { "sf6", 38 }, { "sf7", 39 }, { "sf8", 40 }, { "sf9", 41 }, { "sf10",42 }, { "sf11",43 }, @@ -290,14 +290,14 @@ static struct { { "sf20",52 }, { "sf21",53 }, { "sf22",54 }, { "sf23",55 }, { "sf24",56 }, { "sf25",57 }, { "sf26",58 }, { "sf27",59 }, { "sf28",60 }, { "sf29",61 }, { "sf30",62 }, { "sf31",63 }, - + /* Numbers for floating point registers are for assembler internal use * only: they are scaled back to [0-3] for binary output. */ # define FP0 64 - + { "fp0", 64 }, { "fp1", 65 }, { "fp2", 66 }, { "fp3", 67 }, - + { NULL, 0 }, /* END OF LIST */ }; @@ -320,13 +320,13 @@ static struct { { "(g4)", 20 }, { "(g5)", 21 }, { "(g6)", 22 }, { "(g7)", 23 }, { "(g8)", 24 }, { "(g9)", 25 }, { "(g10)", 26 }, { "(g11)", 27 }, { "(g12)", 28 }, { "(g13)", 29 }, { "(g14)", 30 }, { "(fp)", 31 }, - + # define IPREL 32 /* for assembler internal use only: this number never appears in binary * output. */ { "(ip)", IPREL }, - + { NULL, 0 }, /* END OF LIST */ }; @@ -392,20 +392,20 @@ static int br_cnt = 0; /* Number of branches instrumented so far. */ #define BR_LABEL_BASE "LBRANCH" - /* Basename of local labels on instrumented - * branches, to avoid conflict with compiler- - * generated local labels. - */ +/* Basename of local labels on instrumented + * branches, to avoid conflict with compiler- + * generated local labels. + */ #define BR_CNT_FUNC "__inc_branch" - /* Name of the external routine that will - * increment (and step over) an inline counter. - */ +/* Name of the external routine that will + * increment (and step over) an inline counter. + */ #define BR_TAB_NAME "__BRANCH_TABLE__" - /* Name of the table of pointers to branches. - * A local (i.e., non-external) symbol. - */ +/* Name of the table of pointers to branches. + * A local (i.e., non-external) symbol. + */ /***************************************************************************** * md_begin: One-time initialization. @@ -414,37 +414,37 @@ static int br_cnt = 0; /* Number of branches instrumented so far. * **************************************************************************** */ void -md_begin() + md_begin() { int i; /* Loop counter */ const struct i960_opcode *oP; /* Pointer into opcode table */ char *retval; /* Value returned by hash functions */ - + if (((op_hash = hash_new()) == 0) || ((reg_hash = hash_new()) == 0) || ((areg_hash = hash_new()) == 0)) { as_fatal("virtual memory exceeded"); } - + retval = ""; /* For some reason, the base assembler uses an empty * string for "no error message", instead of a NULL * pointer. */ - + for (oP=i960_opcodes; oP->name && !*retval; oP++) { retval = hash_insert(op_hash, oP->name, oP); } - + for (i=0; regnames[i].reg_name && !*retval; i++) { retval = hash_insert(reg_hash, regnames[i].reg_name, ®names[i].reg_num); } - + for (i=0; aregs[i].areg_name && !*retval; i++){ retval = hash_insert(areg_hash, aregs[i].areg_name, &aregs[i].areg_num); } - + if (*retval) { as_fatal("Hashing returned \"%s\".", retval); } @@ -457,7 +457,7 @@ md_begin() * **************************************************************************** */ void -md_end() + md_end() { } @@ -472,8 +472,8 @@ md_end() * **************************************************************************** */ void -md_assemble(textP) - char *textP; /* Source text of instruction */ + md_assemble(textP) +char *textP; /* Source text of instruction */ { char *args[4]; /* Parsed instruction text, containing NO whitespace: * arg[0]->opcode mnemonic @@ -481,29 +481,29 @@ md_assemble(textP) * replaced by decimal numbers */ int n_ops; /* Number of instruction operands */ - + struct i960_opcode *oP; - /* Pointer to instruction description */ + /* Pointer to instruction description */ int branch_predict; - /* TRUE iff opcode mnemonic included branch-prediction - * suffix (".f" or ".t") - */ + /* TRUE iff opcode mnemonic included branch-prediction + * suffix (".f" or ".t") + */ long bp_bits; /* Setting of branch-prediction bit(s) to be OR'd * into instruction opcode of CTRL/COBR format * instructions. */ int n; /* Offset of last character in opcode mnemonic */ - + static const char bp_error_msg[] = "branch prediction invalid on this opcode"; - - + + /* Parse instruction into opcode and operands */ bzero(args, sizeof(args)); n_ops = i_scan(textP, args); if (n_ops == -1){ return; /* Error message already issued */ } - + /* Do "macro substitution" (sort of) on 'ldconst' pseudo-instruction */ if (!strcmp(args[0],"ldconst")){ n_ops = parse_ldconst(args); @@ -511,7 +511,7 @@ md_assemble(textP) return; } } - + /* Check for branch-prediction suffix on opcode mnemonic, strip it off */ n = strlen(args[0]) - 1; branch_predict = 0; @@ -525,7 +525,7 @@ md_assemble(textP) bp_bits = (args[0][n] == 't') ? BP_TAKEN : BP_NOT_TAKEN; args[0][n-1] = '\0'; /* Strip suffix from opcode mnemonic */ } - + /* Look up opcode mnemonic in table and check number of operands. * Check that opcode is legal for the target architecture. * If all looks good, assemble instruction. @@ -533,10 +533,10 @@ md_assemble(textP) oP = (struct i960_opcode *) hash_find(op_hash, args[0]); if (!oP || !targ_has_iclass(oP->iclass)) { as_bad("invalid opcode, \"%s\".", args[0]); - + } else if (n_ops != oP->num_ops) { as_bad("improper number of operands. expecting %d, got %d", oP->num_ops, n_ops); - + } else { switch (oP->format){ case FBRA: @@ -590,23 +590,23 @@ md_assemble(textP) * **************************************************************************** */ void -md_number_to_chars(buf, value, n) - char *buf; /* Put output here */ - long value; /* The integer to be converted */ - int n; /* Number of bytes to output (significant bytes - * in 'value') - */ + md_number_to_chars(buf, value, n) +char *buf; /* Put output here */ +long value; /* The integer to be converted */ +int n; /* Number of bytes to output (significant bytes + * in 'value') + */ { while (n--){ *buf++ = value; value >>= 8; } - + /* XXX line number probably botched for this warning message. */ if (value != 0 && value != -1){ as_bad("Displacement too long for instruction field length."); } - + return; } /* md_number_to_chars() */ @@ -615,12 +615,12 @@ md_number_to_chars(buf, value, n) * **************************************************************************** */ int -md_chars_to_number(val, n) - unsigned char *val; /* Value in target byte order */ - int n; /* Number of bytes in the input */ + md_chars_to_number(val, n) +unsigned char *val; /* Value in target byte order */ +int n; /* Number of bytes in the input */ { int retval; - + for (retval=0; n--;){ retval <<= 8; retval |= val[n]; @@ -654,47 +654,47 @@ int *sizeP; int prec; char *t; char *atof_ieee(); - + switch(type) { case 'f': case 'F': prec = 2; break; - + case 'd': case 'D': prec = 4; break; - + case 't': case 'T': prec = 5; type = 'x'; /* That's what atof_ieee() understands */ break; - + default: *sizeP=0; return "Bad call to md_atof()"; } - + t = atof_ieee(input_line_pointer, type, words); if (t){ input_line_pointer = t; } - + *sizeP = prec * LNUM_SIZE; - + /* Output the LITTLENUMs in REVERSE order in accord with i80960 * word-order. (Dunno why atof_ieee doesn't do it in the right * order in the first place -- probably because it's a hack of * atof_m68k.) */ - + for(wordP = words + prec - 1; prec--;){ md_number_to_chars(litP, (long) (*wordP--), LNUM_SIZE); litP += sizeof(LITTLENUM_TYPE); } - + return ""; /* Someone should teach Dean about null pointers */ } @@ -704,10 +704,10 @@ int *sizeP; * **************************************************************************** */ void -md_number_to_imm(buf, val, n) - char *buf; - long val; - int n; + md_number_to_imm(buf, val, n) +char *buf; +long val; +int n; { md_number_to_chars(buf, val, n); } @@ -718,10 +718,10 @@ md_number_to_imm(buf, val, n) * **************************************************************************** */ void -md_number_to_disp(buf, val, n) - char *buf; - long val; - int n; + md_number_to_disp(buf, val, n) +char *buf; +long val; +int n; { md_number_to_chars(buf, val, n); } @@ -734,19 +734,19 @@ md_number_to_disp(buf, val, n) * **************************************************************************** */ void -md_number_to_field(instrP, val, bfixP) - char *instrP; /* Pointer to instruction to be fixed */ - long val; /* Address fixup value */ - bit_fixS *bfixP; /* Description of bit field to be fixed up */ + md_number_to_field(instrP, val, bfixP) +char *instrP; /* Pointer to instruction to be fixed */ +long val; /* Address fixup value */ +bit_fixS *bfixP; /* Description of bit field to be fixed up */ { int numbits; /* Length of bit field to be fixed */ long instr; /* 32-bit instruction to be fixed-up */ long sign; /* 0 or -1, according to sign bit of 'val' */ - + /* Convert instruction back to host byte order */ instr = md_chars_to_number(instrP, 4); - + /* Surprise! -- we stored the number of bits * to be modified rather than a pointer to a structure. */ @@ -755,17 +755,17 @@ md_number_to_field(instrP, val, bfixP) /* This is a no-op, stuck here by reloc_callj() */ return; } - + know ((numbits==13) || (numbits==24)); - + /* Propagate sign bit of 'val' for the given number of bits. * Result should be all 0 or all 1 */ sign = val >> ((int)numbits - 1); if (((val < 0) && (sign != -1)) - || ((val > 0) && (sign != 0))){ - as_bad("Fixup of %d too large for field width of %d", - val, numbits); + || ((val > 0) && (sign != 0))){ + as_bad("Fixup of %d too large for field width of %d", + val, numbits); } else { /* Put bit field into instruction and write back in target * byte order. @@ -817,10 +817,10 @@ md_number_to_field(instrP, val, bfixP) * **************************************************************************** */ int -md_parse_option(argP, cntP, vecP) - char **argP; - int *cntP; - char ***vecP; + md_parse_option(argP, cntP, vecP) +char **argP; +int *cntP; +char ***vecP; { char *p; struct tabentry { char *flag; int arch; }; @@ -833,24 +833,24 @@ md_parse_option(argP, cntP, vecP) "MC", ARCH_MC, "CA", ARCH_CA, NULL, 0 - }; + }; struct tabentry *tp; - + if (!strcmp(*argP,"norelax")){ norelax = 1; - + } else if (**argP == 'b'){ instrument_branches = 1; - + } else if (**argP == 'A'){ p = (*argP) + 1; - + for (tp = arch_tab; tp->flag != NULL; tp++){ if (!strcmp(p,tp->flag)){ break; } } - + if (tp->flag == NULL){ as_bad("unknown architecture: %s", p); } else { @@ -879,12 +879,12 @@ md_parse_option(argP, cntP, vecP) * **************************************************************************** */ void -md_convert_frag(headers, fragP) + md_convert_frag(headers, fragP) object_headers *headers; - fragS * fragP; +fragS * fragP; { fixS *fixP; /* Structure describing needed address fix */ - + switch (fragP->fr_subtype){ case 1: /* LEAVE SINGLE COBR INSTRUCTION */ @@ -896,7 +896,7 @@ object_headers *headers; fragP->fr_offset, 1, 0); - + fixP->fx_bit_fixP = (bit_fixS *) 13; /* size of bit field */ break; case 2: @@ -922,9 +922,9 @@ object_headers *headers; * **************************************************************************** */ int -md_estimate_size_before_relax(fragP, segment_type) - register fragS *fragP; - register segT segment_type; + md_estimate_size_before_relax(fragP, segment_type) +register fragS *fragP; +register segT segment_type; { /* If symbol is undefined in this segment, go to "relaxed" state * (compare and branch instructions instead of cobr) right now. @@ -966,25 +966,25 @@ long to_addr; fragS *frag; symbolS *to_symbol; { - abort(); + as_fatal("failed sanity check."); } void -md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) - char *ptr; - long from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; + md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) +char *ptr; +long from_addr, to_addr; +fragS *frag; +symbolS *to_symbol; { - abort(); + as_fatal("failed sanity check."); } #endif - /************************************************************* - * * - * FOLLOWING ARE THE LOCAL ROUTINES, IN ALPHABETICAL ORDER * - * * - ************************************************************ */ +/************************************************************* + * * + * FOLLOWING ARE THE LOCAL ROUTINES, IN ALPHABETICAL ORDER * + * * + ************************************************************ */ @@ -995,7 +995,7 @@ md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) * branch-prediction instrumentation. **************************************************************************** */ static void -brcnt_emit() + brcnt_emit() { ctrl_fmt(BR_CNT_FUNC,CALL,1);/* Emit call to "increment" routine */ emit(0); /* Emit inline counter to be incremented */ @@ -1008,10 +1008,10 @@ brcnt_emit() * branch-prediction instrumentation. **************************************************************************** */ static char * -brlab_next() + brlab_next() { static char buf[20]; - + sprintf(buf, "%s%d", BR_LABEL_BASE, br_cnt++); return buf; } @@ -1035,24 +1035,24 @@ brlab_next() * .word LBRANCH2 ***************************************************************************** */ void -brtab_emit() + brtab_emit() { int i; char buf[20]; char *p; /* Where the binary was output to */ fixS *fixP; /*->description of deferred address fixup */ - + if (!instrument_branches){ return; } - + subseg_new(SEG_DATA,0); /* .data */ frag_align(2,0); /* .align 2 */ record_alignment(now_seg,2); colon(BR_TAB_NAME); /* BR_TAB_NAME: */ emit(0); /* .word 0 #link to next table */ emit(br_cnt); /* .word n #length of table */ - + for (i=0; i<br_cnt; i++){ sprintf(buf, "%s%d", BR_LABEL_BASE, i); p = emit(0); @@ -1073,14 +1073,14 @@ brtab_emit() * **************************************************************************** */ static -void -cobr_fmt(arg, opcode, oP) - char *arg[]; /* arg[0]->opcode mnemonic, arg[1-3]->operands (ascii) */ - long opcode; /* Opcode, with branch-prediction bits already set - * if necessary. - */ - struct i960_opcode *oP; - /*->description of instruction */ + void + cobr_fmt(arg, opcode, oP) +char *arg[]; /* arg[0]->opcode mnemonic, arg[1-3]->operands (ascii) */ +long opcode; /* Opcode, with branch-prediction bits already set + * if necessary. + */ +struct i960_opcode *oP; +/*->description of instruction */ { long instr; /* 32-bit instruction */ struct regop regop; /* Description of register operand */ @@ -1089,10 +1089,10 @@ cobr_fmt(arg, opcode, oP) * be emitted; 0 if an address fix * should be emitted. */ - + instr = opcode; n = oP->num_ops; - + if (n >= 1) { /* First operand (if any) of a COBR is always a register * operand. Parse it. @@ -1107,17 +1107,17 @@ cobr_fmt(arg, opcode, oP) parse_regop(®op, arg[2], oP->operand[1]); instr |= (regop.n << 14) | regop.special; } - - + + if (n < 3){ emit(instr); - + } else { if (instrument_branches){ brcnt_emit(); colon(brlab_next()); } - + /* A third operand to a COBR is always a displacement. * Parse it; if it's relaxable (a cobr "j" directive, or any * cobr other than bbs/bbc when the "-norelax" option is not in @@ -1126,7 +1126,7 @@ cobr_fmt(arg, opcode, oP) */ var_frag = !norelax || (oP->format == COJ); /* TRUE or FALSE */ get_cdisp(arg[3], "COBR", instr, 13, var_frag, 0); - + if (instrument_branches){ brcnt_emit(); } @@ -1139,39 +1139,39 @@ cobr_fmt(arg, opcode, oP) * **************************************************************************** */ static -void -ctrl_fmt(targP, opcode, num_ops) - char *targP; /* Pointer to text of lone operand (if any) */ - long opcode; /* Template of instruction */ - int num_ops; /* Number of operands */ + void + ctrl_fmt(targP, opcode, num_ops) +char *targP; /* Pointer to text of lone operand (if any) */ +long opcode; /* Template of instruction */ +int num_ops; /* Number of operands */ { int instrument; /* TRUE iff we should add instrumentation to track * how often the branch is taken */ - - + + if (num_ops == 0){ emit(opcode); /* Output opcode */ } else { - + instrument = instrument_branches && (opcode!=CALL) - && (opcode!=B) && (opcode!=RET) && (opcode!=BAL); - + && (opcode!=B) && (opcode!=RET) && (opcode!=BAL); + if (instrument){ brcnt_emit(); colon(brlab_next()); } - + /* The operand MUST be an ip-relative displacment. Parse it * and set up address fix for the instruction we just output. */ get_cdisp(targP, "CTRL", opcode, 24, 0, 0); - + if (instrument){ brcnt_emit(); } } - + } @@ -1183,12 +1183,12 @@ ctrl_fmt(targP, opcode, num_ops) * **************************************************************************** */ static -char * -emit(instr) - long instr; /* Word to be output, host byte order */ + char * + emit(instr) +long instr; /* Word to be output, host byte order */ { char *toP; /* Where to output it */ - + toP = frag_more(4); /* Allocate storage */ md_number_to_chars(toP, instr, 4); /* Convert to target byte order */ return toP; @@ -1213,40 +1213,40 @@ emit(instr) * **************************************************************************** */ static int get_args(p, args) - register char *p; /* Pointer to comma-separated operands; MUCKED BY US */ - char *args[]; /* Output arg: pointers to operands placed in args[1-3]. - * MUST ACCOMMODATE 4 ENTRIES (args[0-3]). - */ +register char *p; /* Pointer to comma-separated operands; MUCKED BY US */ +char *args[]; /* Output arg: pointers to operands placed in args[1-3]. + * MUST ACCOMMODATE 4 ENTRIES (args[0-3]). + */ { register int n; /* Number of operands */ register char *to; -/* char buf[4]; */ -/* int len; */ - - + /* char buf[4]; */ + /* int len; */ + + /* Skip lead white space */ while (*p == ' '){ p++; } - + if (*p == '\0'){ return 0; } - + n = 1; args[1] = p; - + /* Squeze blanks out by moving non-blanks toward start of string. * Isolate operands, whenever comma is found. */ to = p; while (*p != '\0'){ - + if (*p == ' '){ p++; - + } else if (*p == ','){ - + /* Start of operand */ if (n == 3){ as_bad("too many operands"); @@ -1255,7 +1255,7 @@ static int get_args(p, args) *to++ = '\0'; /* Terminate argument */ args[++n] = to; /* Start next argument */ p++; - + } else { *to++ = *p++; } @@ -1280,36 +1280,36 @@ static int get_args(p, args) * **************************************************************************** */ static -void -get_cdisp(dispP, ifmtP, instr, numbits, var_frag, callj) - char *dispP; /*->displacement as specified in source instruction */ - char *ifmtP; /*->"COBR" or "CTRL" (for use in error message) */ - long instr; /* Instruction needing the displacement */ - int numbits; /* # bits of displacement (13 for COBR, 24 for CTRL) */ - int var_frag; /* 1 if varying length code fragment should be emitted; - * 0 if an address fix should be emitted. - */ - int callj; /* 1 if callj relocation should be done; else 0 */ + void + get_cdisp(dispP, ifmtP, instr, numbits, var_frag, callj) +char *dispP; /*->displacement as specified in source instruction */ +char *ifmtP; /*->"COBR" or "CTRL" (for use in error message) */ +long instr; /* Instruction needing the displacement */ +int numbits; /* # bits of displacement (13 for COBR, 24 for CTRL) */ +int var_frag; /* 1 if varying length code fragment should be emitted; + * 0 if an address fix should be emitted. + */ +int callj; /* 1 if callj relocation should be done; else 0 */ { expressionS e; /* Parsed expression */ fixS *fixP; /* Structure describing needed address fix */ char *outP; /* Where instruction binary is output to */ - + fixP = NULL; - + switch (parse_expr(dispP,&e)) { - + case SEG_GOOF: as_bad("expression syntax error"); break; - + case SEG_TEXT: case SEG_UNKNOWN: if (var_frag) { outP = frag_more(8); /* Allocate worst-case storage */ md_number_to_chars(outP, instr, 4); frag_variant(rs_machine_dependent, 4, 4, 1, - adds(e), offs(e), outP, 0, 0); + adds(e), offs(e), outP, 0, 0); } else { /* Set up a new fix structure, so address can be updated * when all symbol values are known. @@ -1323,9 +1323,9 @@ get_cdisp(dispP, ifmtP, instr, numbits, var_frag, callj) offs(e), 1, 0); - + fixP->fx_callj = callj; - + /* We want to modify a bit field when the address is * known. But we don't need all the garbage in the * bit_fix structure. So we're going to lie and store @@ -1334,12 +1334,12 @@ get_cdisp(dispP, ifmtP, instr, numbits, var_frag, callj) fixP->fx_bit_fixP = (bit_fixS *) numbits; } break; - + case SEG_DATA: case SEG_BSS: as_bad("attempt to branch into different segment"); break; - + default: as_bad("target of %s instruction must be a label", ifmtP); break; @@ -1358,27 +1358,27 @@ get_cdisp(dispP, ifmtP, instr, numbits, var_frag, callj) * **************************************************************************** */ static -char * -get_ispec(textP) - char *textP; /*->memory operand from source instruction, no white space */ + char * + get_ispec(textP) +char *textP; /*->memory operand from source instruction, no white space */ { char *start; /*->start of index specification */ char *end; /*->end of index specification */ - + /* Find opening square bracket, if any */ start = strchr(textP, '['); - + if (start != NULL){ - + /* Eliminate '[', detach from rest of operand */ *start++ = '\0'; - + end = strchr(start, ']'); - + if (end == NULL){ as_bad("unmatched '['"); - + } else { /* Eliminate ']' and make sure it was the last thing * in the string. @@ -1400,12 +1400,12 @@ get_ispec(textP) * **************************************************************************** */ static -int -get_regnum(regname) - char *regname; /* Suspected register name */ + int + get_regnum(regname) +char *regname; /* Suspected register name */ { int *rP; - + rP = (int *) hash_find(reg_hash, regname); return (rP == NULL) ? -1 : *rP; } @@ -1430,12 +1430,12 @@ get_regnum(regname) * **************************************************************************** */ static int i_scan(iP, args) - register char *iP; /* Pointer to ascii instruction; MUCKED BY US. */ - char *args[]; /* Output arg: pointers to opcode and operands placed - * here. MUST ACCOMMODATE 4 ENTRIES. - */ +register char *iP; /* Pointer to ascii instruction; MUCKED BY US. */ +char *args[]; /* Output arg: pointers to opcode and operands placed + * here. MUST ACCOMMODATE 4 ENTRIES. + */ { - + /* Isolate opcode */ if (*(iP) == ' ') { iP++; @@ -1462,8 +1462,8 @@ static int i_scan(iP, args) * **************************************************************************** */ static void mem_fmt(args, oP) - char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */ - struct i960_opcode *oP; /* Pointer to description of instruction */ +char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */ +struct i960_opcode *oP; /* Pointer to description of instruction */ { int i; /* Loop counter */ struct regop regop; /* Description of register operand */ @@ -1472,14 +1472,14 @@ static void mem_fmt(args, oP) char *outP; /* Where the binary was output to */ expressionS expr; /* Parsed expression */ fixS *fixP; /*->description of deferred address fixup */ - + bzero(&instr, sizeof(memS)); instr.opcode = oP->opcode; - + /* Process operands. */ for (i = 1; i <= oP->num_ops; i++){ opdesc = oP->operand[i-1]; - + if (MEMOP(opdesc)){ parse_memop(&instr, args[i], oP->format); } else { @@ -1487,21 +1487,21 @@ static void mem_fmt(args, oP) instr.opcode |= regop.n << 19; } } - + /* Output opcode */ outP = emit(instr.opcode); - + if (instr.disp == 0){ return; } - + /* Parse and process the displacement */ switch (parse_expr(instr.e,&expr)){ - + case SEG_GOOF: as_bad("expression syntax error"); break; - + case SEG_ABSOLUTE: if (instr.disp == 32){ (void) emit(offs(expr)); /* Output displacement */ @@ -1523,7 +1523,7 @@ static void mem_fmt(args, oP) } } break; - + case SEG_DIFFERENCE: case SEG_TEXT: case SEG_DATA: @@ -1536,7 +1536,7 @@ static void mem_fmt(args, oP) */ mema_to_memb(outP); } - + /* Output 0 displacement and set up address fixup for when * this symbol's value becomes known. */ @@ -1551,7 +1551,7 @@ static void mem_fmt(args, oP) 0); fixP->fx_im_disp = 2; /* 32-bit displacement fix */ break; - + default: BAD_CASE(segs(expr)); break; @@ -1570,22 +1570,22 @@ static void mem_fmt(args, oP) * **************************************************************************** */ static void mema_to_memb(opcodeP) - char *opcodeP; /* Where to find the opcode, in target byte order */ +char *opcodeP; /* Where to find the opcode, in target byte order */ { long opcode; /* Opcode in host byte order */ long mode; /* Mode bits for MEMB instruction */ - + opcode = md_chars_to_number(opcodeP, 4); know(!(opcode & MEMB_BIT)); - + mode = MEMB_BIT | D_BIT; if (opcode & MEMA_ABASE){ mode |= A_BIT; } - + opcode &= 0xffffc000; /* Clear MEMA offset and mode bits */ opcode |= mode; /* Set MEMB mode bits */ - + md_number_to_chars(opcodeP, opcode, 4); } /* mema_to_memb() */ @@ -1605,27 +1605,27 @@ static void mema_to_memb(opcodeP) * **************************************************************************** */ static -segT -parse_expr(textP, expP) - char *textP; /* Text of expression to be parsed */ - expressionS *expP; /* Where to put the results of parsing */ + segT + parse_expr(textP, expP) +char *textP; /* Text of expression to be parsed */ +expressionS *expP; /* Where to put the results of parsing */ { char *save_in; /* Save global here */ segT seg; /* Segment to which expression evaluates */ symbolS *symP; - + know(textP); - + if (*textP == '\0') { /* Treat empty string as absolute 0 */ expP->X_add_symbol = expP->X_subtract_symbol = NULL; expP->X_add_number = 0; seg = expP->X_seg = SEG_ABSOLUTE; - + } else { save_in = input_line_pointer; /* Save global */ input_line_pointer = textP; /* Make parser work for us */ - + seg = expression(expP); if (input_line_pointer - textP != strlen(textP)) { /* Did not consume all of the input */ @@ -1636,7 +1636,7 @@ parse_expr(textP, expP) /* Register name in an expression */ seg = SEG_GOOF; } - + input_line_pointer = save_in; /* Restore global */ } return seg; @@ -1659,21 +1659,21 @@ parse_expr(textP, expP) * **************************************************************************** */ static -int -parse_ldconst(arg) - char *arg[]; /* See above */ + int + parse_ldconst(arg) +char *arg[]; /* See above */ { int n; /* Constant to be loaded */ int shift; /* Shift count for "shlo" instruction */ static char buf[5]; /* Literal for first operand */ static char buf2[5]; /* Literal for second operand */ expressionS e; /* Parsed expression */ - - + + arg[3] = NULL; /* So we can tell at the end if it got used or not */ - + switch(parse_expr(arg[1],&e)){ - + case SEG_TEXT: case SEG_DATA: case SEG_BSS: @@ -1682,7 +1682,7 @@ parse_ldconst(arg) /* We're dependent on one or more symbols -- use "lda" */ arg[0] = "lda"; break; - + case SEG_ABSOLUTE: /* Try the following mappings: * ldconst 0,<reg> ->mov 0,<reg> @@ -1699,21 +1699,21 @@ parse_ldconst(arg) n = offs(e); if ((0 <= n) && (n <= 31)){ arg[0] = "mov"; - + } else if ((-31 <= n) && (n <= -1)){ arg[0] = "subo"; arg[3] = arg[2]; sprintf(buf, "%d", -n); arg[1] = buf; arg[2] = "0"; - + } else if ((32 <= n) && (n <= 62)){ arg[0] = "addo"; arg[3] = arg[2]; arg[1] = "31"; sprintf(buf, "%d", n-31); arg[2] = buf; - + } else if ((shift = shift_ok(n)) != 0){ arg[0] = "shlo"; arg[3] = arg[2]; @@ -1721,12 +1721,12 @@ parse_ldconst(arg) arg[1] = buf; sprintf(buf2, "%d", n >> shift); arg[2] = buf2; - + } else { arg[0] = "lda"; } break; - + default: as_bad("invalid constant"); return -1; @@ -1767,11 +1767,11 @@ parse_ldconst(arg) * **************************************************************************** */ static -void -parse_memop(memP, argP, optype) - memS *memP; /* Where to put the results */ - char *argP; /* Text of the operand to be parsed */ - int optype; /* MEM1, MEM2, MEM4, MEM8, MEM12, or MEM16 */ + void + parse_memop(memP, argP, optype) +memS *memP; /* Where to put the results */ +char *argP; /* Text of the operand to be parsed */ +int optype; /* MEM1, MEM2, MEM4, MEM8, MEM12, or MEM16 */ { char *indexP; /* Pointer to index specification with "[]" removed */ char *p; /* Temp char pointer */ @@ -1782,7 +1782,7 @@ parse_memop(memP, argP, optype) */ int mode; /* MEMB mode bits */ int *intP; /* Pointer to register number */ - + /* The following table contains the default scale factors for each * type of memory instruction. It is accessed using (optype-MEM1) * as an index -- thus it assumes the 'optype' constants are assigned @@ -1795,11 +1795,11 @@ parse_memop(memP, argP, optype) 8, /* MEM8 */ -1, /* MEM12 -- no valid default */ 16 /* MEM16 */ - }; - - + }; + + iprel_flag = mode = 0; - + /* Any index present? */ indexP = get_ispec(argP); if (indexP) { @@ -1811,11 +1811,11 @@ parse_memop(memP, argP, optype) scale = def_scale[ optype - MEM1 ]; } else { *p++ = '\0'; /* Eliminate '*' */ - + /* Now indexP->a '\0'-terminated register name, * and p->a scale factor. */ - + if (!strcmp(p,"16")){ scale = 16; } else if (strchr("1248",*p) && (p[1] == '\0')){ @@ -1824,13 +1824,13 @@ parse_memop(memP, argP, optype) scale = -1; } } - + regnum = get_regnum(indexP); /* Get index reg. # */ if (!IS_RG_REG(regnum)){ as_bad("invalid index register"); return; } - + /* Convert scale to its binary encoding */ switch (scale){ case 1: scale = 0 << 7; break; @@ -1840,11 +1840,11 @@ parse_memop(memP, argP, optype) case 16: scale = 4 << 7; break; default: as_bad("invalid scale factor"); return; }; - + memP->opcode |= scale | regnum; /* Set index bits in opcode */ mode |= I_BIT; /* Found a valid index spec */ } - + /* Any abase (Register Indirect) specification present? */ if ((p = strrchr(argP,'(')) != NULL) { /* "(" is there -- does it start a legal abase spec? @@ -1864,13 +1864,13 @@ parse_memop(memP, argP, optype) } } } - + /* Any expression present? */ memP->e = argP; if (*argP != '\0'){ mode |= D_BIT; } - + /* Special-case ip-relative addressing */ if (iprel_flag){ if (mode & I_BIT){ @@ -1881,7 +1881,7 @@ parse_memop(memP, argP, optype) } return; } - + /* Handle all other modes */ switch (mode){ case D_BIT | A_BIT: @@ -1893,14 +1893,14 @@ parse_memop(memP, argP, optype) memP->opcode |= MEMA_ABASE; memP->disp = 12; break; - + case D_BIT: /* Go with MEMA instruction format for now (grow to MEMB later * if 12 bits is not enough for the displacement). */ memP->disp = 12; break; - + case A_BIT: /* For some reason, the bit string for this mode is not * consistent: it should be 0 (exclusive of the MEMB bit), @@ -1908,12 +1908,12 @@ parse_memop(memP, argP, optype) */ memP->opcode |= MEMB_BIT; break; - + case A_BIT | I_BIT: /* set MEMB bit in mode, and OR in mode bits */ memP->opcode |= mode | MEMB_BIT; break; - + case I_BIT: /* Treat missing displacement as displacement of 0 */ mode |= D_BIT; @@ -1926,7 +1926,7 @@ parse_memop(memP, argP, optype) memP->opcode |= mode | MEMB_BIT; memP->disp = 32; break; - + default: syntax(); break; @@ -1941,9 +1941,9 @@ parse_memop(memP, argP, optype) * and dispatches them to the correct handler. **************************************************************************** */ static -void -parse_po(po_num) - int po_num; /* Pseudo-op number: currently S_LEAFPROC or S_SYSPROC */ + void + parse_po(po_num) +int po_num; /* Pseudo-op number: currently S_LEAFPROC or S_SYSPROC */ { char *args[4]; /* Pointers operands, with no embedded whitespace. * arg[0] unused. @@ -1952,9 +1952,9 @@ parse_po(po_num) int n_ops; /* Number of operands */ char *p; /* Pointer to beginning of unparsed argument string */ char eol; /* Character that indicated end of line */ - + extern char is_end_of_line[]; - + /* Advance input pointer to end of line. */ p = input_line_pointer; while (!is_end_of_line[ *input_line_pointer ]){ @@ -1962,20 +1962,20 @@ parse_po(po_num) } eol = *input_line_pointer; /* Save end-of-line char */ *input_line_pointer = '\0'; /* Terminate argument list */ - + /* Parse out operands */ n_ops = get_args(p, args); if (n_ops == -1){ return; } - + /* Dispatch to correct handler */ switch(po_num){ case S_SYSPROC: s_sysproc(n_ops, args); break; case S_LEAFPROC: s_leafproc(n_ops, args); break; default: BAD_CASE(po_num); break; } - + /* Restore eol, so line numbers get updated correctly. Base assembler * assumes we leave input pointer pointing at char following the eol. */ @@ -1989,15 +1989,15 @@ parse_po(po_num) * information so instruction processing can continue. **************************************************************************** */ static -void -parse_regop(regopP, optext, opdesc) - struct regop *regopP; /* Where to put description of register operand */ - char *optext; /* Text of operand */ - char opdesc; /* Descriptor byte: what's legal for this operand */ + void + parse_regop(regopP, optext, opdesc) +struct regop *regopP; /* Where to put description of register operand */ +char *optext; /* Text of operand */ +char opdesc; /* Descriptor byte: what's legal for this operand */ { int n; /* Register number */ expressionS e; /* Parsed expression */ - + /* See if operand is a register */ n = get_regnum(optext); if (n >= 0){ @@ -2035,11 +2035,11 @@ parse_regop(regopP, optext, opdesc) if (FP_OK(opdesc)){ /* floating point literal acceptable */ /* Skip over 0f, 0d, or 0e prefix */ if ( (optext[0] == '0') - && (optext[1] >= 'd') - && (optext[1] <= 'f') ){ + && (optext[1] >= 'd') + && (optext[1] <= 'f') ){ optext += 2; } - + if (!strcmp(optext,"0.0") || !strcmp(optext,"0") ){ regopP->n = 0x10; return; @@ -2048,10 +2048,10 @@ parse_regop(regopP, optext, opdesc) regopP->n = 0x16; return; } - + } else { /* fixed point literal acceptable */ if ((parse_expr(optext,&e) != SEG_ABSOLUTE) - || (offs(e) < 0) || (offs(e) > 31)){ + || (offs(e) < 0) || (offs(e) > 31)){ as_bad("illegal literal"); offs(e) = 0; } @@ -2059,7 +2059,7 @@ parse_regop(regopP, optext, opdesc) return; } } - + /* Nothing worked */ syntax(); regopP->mode = 0; /* Register r0 is always a good one */ @@ -2072,20 +2072,20 @@ parse_regop(regopP, optext, opdesc) * **************************************************************************** */ static void reg_fmt(args, oP) - char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */ - struct i960_opcode *oP; /* Pointer to description of instruction */ +char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */ +struct i960_opcode *oP; /* Pointer to description of instruction */ { long instr; /* Binary to be output */ struct regop regop; /* Description of register operand */ int n_ops; /* Number of operands */ - - + + instr = oP->opcode; n_ops = oP->num_ops; - + if (n_ops >= 1){ parse_regop(®op, args[1], oP->operand[0]); - + if ((n_ops == 1) && !(instr & M3)){ /* 1-operand instruction in which the dst field should * be used (instead of src1). @@ -2103,10 +2103,10 @@ static void reg_fmt(args, oP) } instr |= regop.n | regop.mode | regop.special; } - + if (n_ops >= 2) { parse_regop(®op, args[2], oP->operand[1]); - + if ((n_ops == 2) && !(instr & M3)){ /* 2-operand instruction in which the dst field should * be used instead of src2). @@ -2147,43 +2147,43 @@ static void reg_fmt(args, oP) * compare and branch opcodes. */ static -struct { - long compare; - long branch; -} coj[] = { /* COBR OPCODE: */ - CHKBIT, BNO, /* 0x30 - bbc */ - CMPO, BG, /* 0x31 - cmpobg */ - CMPO, BE, /* 0x32 - cmpobe */ - CMPO, BGE, /* 0x33 - cmpobge */ - CMPO, BL, /* 0x34 - cmpobl */ - CMPO, BNE, /* 0x35 - cmpobne */ - CMPO, BLE, /* 0x36 - cmpoble */ - CHKBIT, BO, /* 0x37 - bbs */ - CMPI, BNO, /* 0x38 - cmpibno */ - CMPI, BG, /* 0x39 - cmpibg */ - CMPI, BE, /* 0x3a - cmpibe */ - CMPI, BGE, /* 0x3b - cmpibge */ - CMPI, BL, /* 0x3c - cmpibl */ - CMPI, BNE, /* 0x3d - cmpibne */ - CMPI, BLE, /* 0x3e - cmpible */ - CMPI, BO, /* 0x3f - cmpibo */ -}; + struct { + long compare; + long branch; + } coj[] = { /* COBR OPCODE: */ + CHKBIT, BNO, /* 0x30 - bbc */ + CMPO, BG, /* 0x31 - cmpobg */ + CMPO, BE, /* 0x32 - cmpobe */ + CMPO, BGE, /* 0x33 - cmpobge */ + CMPO, BL, /* 0x34 - cmpobl */ + CMPO, BNE, /* 0x35 - cmpobne */ + CMPO, BLE, /* 0x36 - cmpoble */ + CHKBIT, BO, /* 0x37 - bbs */ + CMPI, BNO, /* 0x38 - cmpibno */ + CMPI, BG, /* 0x39 - cmpibg */ + CMPI, BE, /* 0x3a - cmpibe */ + CMPI, BGE, /* 0x3b - cmpibge */ + CMPI, BL, /* 0x3c - cmpibl */ + CMPI, BNE, /* 0x3d - cmpibne */ + CMPI, BLE, /* 0x3e - cmpible */ + CMPI, BO, /* 0x3f - cmpibo */ + }; static -void -relax_cobr(fragP) - register fragS *fragP; /* fragP->fr_opcode is assumed to point to - * the cobr instruction, which comes at the - * end of the code fragment. - */ + void + relax_cobr(fragP) +register fragS *fragP; /* fragP->fr_opcode is assumed to point to + * the cobr instruction, which comes at the + * end of the code fragment. + */ { int opcode, src1, src2, m1, s2; - /* Bit fields from cobr instruction */ + /* Bit fields from cobr instruction */ long bp_bits; /* Branch prediction bits from cobr instruction */ long instr; /* A single i960 instruction */ char *iP; /*->instruction to be replaced */ fixS *fixP; /* Relocation that can be done at assembly time */ - + /* PICK UP & PARSE COBR INSTRUCTION */ iP = fragP->fr_opcode; instr = md_chars_to_number(iP, 4); @@ -2193,15 +2193,15 @@ relax_cobr(fragP) s2 = instr & 1; src2 = (instr >> 14) & 0x1f; bp_bits= instr & BP_MASK; - + /* GENERATE AND OUTPUT COMPARE INSTRUCTION */ instr = coj[opcode].compare - | src1 | (m1 << 11) | (s2 << 6) | (src2 << 14); + | src1 | (m1 << 11) | (s2 << 6) | (src2 << 14); md_number_to_chars(iP, instr, 4); - + /* OUTPUT BRANCH INSTRUCTION */ md_number_to_chars(iP+4, coj[opcode].branch | bp_bits, 4); - + /* SET UP ADDRESS FIXUP/RELOCATION */ fixP = fix_new(fragP, iP+4 - fragP->fr_literal, @@ -2211,9 +2211,9 @@ relax_cobr(fragP) fragP->fr_offset, 1, 0); - + fixP->fx_bit_fixP = (bit_fixS *) 24; /* Store size of bit field */ - + fragP->fr_fix += 4; frag_wane(fragP); } @@ -2243,28 +2243,28 @@ void reloc_callj(fixP) fixS *fixP; /* Relocation that can be done at assembly time */ { char *where; /*->the binary for the instruction being relocated */ - + if (!fixP->fx_callj) { return; } /* This wasn't a callj instruction in the first place */ - + where = fixP->fx_frag->fr_literal + fixP->fx_where; - + if (TC_S_IS_SYSPROC(fixP->fx_addsy)) { /* Symbol is a .sysproc: replace 'call' with 'calls'. * System procedure number is (other-1). */ md_number_to_chars(where, CALLS|TC_S_GET_SYSPROC(fixP->fx_addsy), 4); - + /* Nothing else needs to be done for this instruction. * Make sure 'md_number_to_field()' will perform a no-op. */ fixP->fx_bit_fixP = (bit_fixS *) 1; - + } else if (TC_S_IS_CALLNAME(fixP->fx_addsy)) { /* Should not happen: see block comment above */ as_fatal("Trying to 'bal' to %s", S_GET_NAME(fixP->fx_addsy)); - + } else if (TC_S_IS_BALNAME(fixP->fx_addsy)) { /* Replace 'call' with 'bal'; both instructions have * the same format, so calling code should complete @@ -2302,38 +2302,38 @@ char *args[]; /* args[1]->1st operand, args[2]->2nd operand */ { symbolS *callP; /* Pointer to leafproc 'call' entry point symbol */ symbolS *balP; /* Pointer to leafproc 'bal' entry point symbol */ - + if ((n_ops != 1) && (n_ops != 2)) { as_bad("should have 1 or 2 operands"); return; } /* Check number of arguments */ - + /* Find or create symbol for 'call' entry point. */ callP = symbol_find_or_make(args[1]); - + if (TC_S_IS_CALLNAME(callP)) { as_warn("Redefining leafproc %s", S_GET_NAME(callP)); } /* is leafproc */ - + /* If that was the only argument, use it as the 'bal' entry point. * Otherwise, mark it as the 'call' entry point and find or create * another symbol for the 'bal' entry point. */ if ((n_ops == 1) || !strcmp(args[1],args[2])) { TC_S_FORCE_TO_BALNAME(callP); - + } else { TC_S_FORCE_TO_CALLNAME(callP); - + balP = symbol_find_or_make(args[2]); if (TC_S_IS_CALLNAME(balP)) { as_warn("Redefining leafproc %s", S_GET_NAME(balP)); } TC_S_FORCE_TO_BALNAME(balP); - + tc_set_bal_of_call(callP, balP); } /* if only one arg, or the args are the same */ - + return; } /* s_leafproc() */ @@ -2356,12 +2356,12 @@ char *args[]; /* args[1]->1st operand, args[2]->2nd operand */ { expressionS exp; symbolS *symP; - + if (n_ops != 2) { as_bad("should have two operands"); return; } /* bad arg count */ - + /* Parse "entry_num" argument and check it for validity. */ if ((parse_expr(args[2],&exp) != SEG_ABSOLUTE) || (offs(exp) < 0) @@ -2369,17 +2369,17 @@ char *args[]; /* args[1]->1st operand, args[2]->2nd operand */ as_bad("'entry_num' must be absolute number in [0,31]"); return; } - + /* Find/make symbol and stick entry number (biased by +1) into it */ symP = symbol_find_or_make(args[1]); - + if (TC_S_IS_SYSPROC(symP)) { as_warn("Redefining entrynum for sysproc %s", S_GET_NAME(symP)); } /* redefining */ - + TC_S_SET_SYSPROC(symP, offs(exp)); /* encode entry number */ TC_S_FORCE_TO_SYSPROC(symP); - + return; } /* s_sysproc() */ @@ -2395,22 +2395,22 @@ char *args[]; /* args[1]->1st operand, args[2]->2nd operand */ * **************************************************************************** */ static -int -shift_ok(n) - int n; /* The constant of interest */ + int + shift_ok(n) +int n; /* The constant of interest */ { int shift; /* The shift count */ - + if (n <= 0){ /* Can't do it for negative numbers */ return 0; } - + /* Shift 'n' right until a 1 is about to be lost */ for (shift = 0; (n & 1) == 0; shift++){ n >>= 1; } - + if (n >= 32){ return 0; } @@ -2434,9 +2434,9 @@ static void syntax() { * **************************************************************************** */ static -int -targ_has_sfr(n) - int n; /* Number (0-31) of sfr */ + int + targ_has_sfr(n) +int n; /* Number (0-31) of sfr */ { switch (architecture){ case ARCH_KA: @@ -2457,11 +2457,11 @@ targ_has_sfr(n) * **************************************************************************** */ static -int -targ_has_iclass(ic) - int ic; /* Instruction class; one of: - * I_BASE, I_CX, I_DEC, I_KX, I_FP, I_MIL, I_CASIM - */ + int + targ_has_iclass(ic) +int ic; /* Instruction class; one of: + * I_BASE, I_CX, I_DEC, I_KX, I_FP, I_MIL, I_CASIM + */ { iclasses_seen |= ic; switch (architecture){ @@ -2471,7 +2471,7 @@ targ_has_iclass(ic) case ARCH_CA: return ic & (I_BASE | I_CX | I_CASIM); default: if ((iclasses_seen & (I_KX|I_FP|I_DEC|I_MIL)) - && (iclasses_seen & I_CX)){ + && (iclasses_seen & I_CX)){ as_warn("architecture of opcode conflicts with that of earlier instruction(s)"); iclasses_seen &= ~ic; } @@ -2486,8 +2486,8 @@ targ_has_iclass(ic) /* ARGSUSED */ void -md_operand (expressionP) - expressionS *expressionP; + md_operand (expressionP) +expressionS *expressionP; { } @@ -2504,21 +2504,21 @@ char *name; On the i960, they're relative to the address of the instruction, which we have set up as the address of the fixup too. */ long -md_pcrel_from (fixP) - fixS *fixP; + md_pcrel_from (fixP) +fixS *fixP; { - return fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_where + fixP->fx_frag->fr_address; } void -md_apply_fix(fixP, val) - fixS *fixP; - long val; + md_apply_fix(fixP, val) +fixS *fixP; +long val; { char *place = fixP->fx_where + fixP->fx_frag->fr_literal; - + if (!fixP->fx_bit_fixP) { - + switch (fixP->fx_im_disp) { case 0: fixP->fx_addnumber = val; @@ -2526,8 +2526,8 @@ md_apply_fix(fixP, val) break; case 1: md_number_to_disp(place, - fixP->fx_pcrel ? val + fixP->fx_pcrel_adjust : val, - fixP->fx_size); + fixP->fx_pcrel ? val + fixP->fx_pcrel_adjust : val, + fixP->fx_size); break; case 2: /* fix requested for .long .word etc */ md_number_to_chars(place, val, fixP->fx_size); @@ -2538,7 +2538,7 @@ md_apply_fix(fixP, val) } else { md_number_to_field(place, val, fixP->fx_bit_fixP); } - + return; } /* md_apply_fix() */ @@ -2593,8 +2593,8 @@ long addr; /* Address to be rounded up */ void tc_headers_hook(headers) object_headers *headers; { - unsigned short arch_flag = 0; - + /* FIXME: remove this line */ /* unsigned short arch_flag = 0; */ + if (iclasses_seen == I_BASE){ headers->filehdr.f_flags |= F_I960CORE; } else if (iclasses_seen & I_CX){ @@ -2606,7 +2606,7 @@ object_headers *headers; } else { headers->filehdr.f_flags |= F_I960KA; } /* set arch flag */ - + if (flagseen['R']) { headers->filehdr.f_magic = I960RWMAGIC; headers->aouthdr.magic = OMAGIC; @@ -2642,7 +2642,7 @@ void tc_crawl_symbol_chain(headers) object_headers *headers; { symbolS *symbolP; - + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { #ifdef OBJ_COFF if (TC_S_IS_SYSPROC(symbolP)) { @@ -2653,15 +2653,15 @@ object_headers *headers; continue; } /* rewrite sysproc */ #endif /* OBJ_COFF */ - + if (!TC_S_IS_BALNAME(symbolP) && !TC_S_IS_CALLNAME(symbolP)) { continue; } /* Not a leafproc symbol */ - + if (!S_IS_DEFINED(symbolP)) { as_bad("leafproc symbol '%s' undefined", S_GET_NAME(symbolP)); } /* undefined leaf */ - + if (TC_S_IS_CALLNAME(symbolP)) { symbolS *balP = tc_get_bal_of_call(symbolP); if (S_IS_EXTERNAL(symbolP) != S_IS_EXTERNAL(balP)) { @@ -2672,7 +2672,7 @@ object_headers *headers; } /* externality mismatch */ } /* if callname */ } /* walk the symbol chain */ - + return; } /* tc_crawl_symbol_chain() */ @@ -2691,12 +2691,12 @@ symbolS *balP; know(TC_S_IS_BALNAME(balP)); #ifdef OBJ_COFF - + callP->sy_symbol.ost_auxent[1].x_bal.x_balntry = (int) balP; S_SET_NUMBER_AUXILIARY(callP,2); - + #elif defined(OBJ_AOUT) || defined(OBJ_BOUT) - + /* If the 'bal' entry doesn't immediately follow the 'call' * symbol, unlink it from the symbol list and re-insert it. */ @@ -2704,7 +2704,7 @@ symbolS *balP; symbol_remove(balP, &symbol_rootP, &symbol_lastP); symbol_append(balP, callP, &symbol_rootP, &symbol_lastP); } /* if not in order */ - + #else (as yet unwritten.); #endif /* switch on OBJ_FORMAT */ @@ -2716,9 +2716,9 @@ char *_tc_get_bal_of_call(callP) symbolS *callP; { symbolS *retval; - + know(TC_S_IS_CALLNAME(callP)); - + #ifdef OBJ_COFF retval = (symbolS *) (callP->sy_symbol.ost_auxent[1].x_bal.x_balntry); #elif defined(OBJ_AOUT) || defined(OBJ_BOUT) @@ -2726,7 +2726,7 @@ symbolS *callP; #else (as yet unwritten.); #endif /* switch on OBJ_FORMAT */ - + know(TC_S_IS_BALNAME(retval)); return((char *) retval); } /* _tc_get_bal_of_call() */ @@ -2739,7 +2739,7 @@ symbolS *symbolP; symbolS *balP = tc_get_bal_of_call(symbolP); /* second aux entry contains the bal entry point */ -/* S_SET_NUMBER_AUXILIARY(symbolP, 2); */ + /* S_SET_NUMBER_AUXILIARY(symbolP, 2); */ symbolP->sy_symbol.ost_auxent[1].x_bal.x_balntry = S_GET_VALUE(balP); S_SET_STORAGE_CLASS(symbolP, (!SF_GET_LOCAL(symbolP) ? C_LEAFEXT : C_LEAFSTAT)); S_SET_DATA_TYPE(symbolP, S_GET_DATA_TYPE(symbolP) | (DT_FCN << N_BTSHFT)); diff --git a/gas/config/tc-i960.h b/gas/config/tc-i960.h index 2b05340..4d6dd75 100644 --- a/gas/config/tc-i960.h +++ b/gas/config/tc-i960.h @@ -1,23 +1,24 @@ /* tc-i960.h - Basic 80960 instruction formats. Copyright (C) 1989, 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. */ - -/* $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. */ + +#ifndef TC_I960 +#define TC_I960 1 /* * The 'COJ' instructions are actually COBR instructions with the 'b' in @@ -38,18 +39,16 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * appropriate. */ -#define TC_I960 1 - - /* tailor gas */ +/* tailor gas */ #define SYMBOLS_NEED_BACKPOINTERS #define LOCAL_LABELS_FB #define WANT_BITFIELDS - /* tailor the coff format */ +/* tailor the coff format */ #define OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT #define OBJ_COFF_MAX_AUXENTRIES (2) - /* other */ +/* other */ #define CTRL 0 #define COBR 1 #define COJ 2 @@ -144,7 +143,7 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define LIT_OK(od) (od & LIT) /* TRUE if literal operand allowed */ #define FP_OK(od) (od & FP) /* TRUE if floating-point op allowed */ #define REG_ALIGN(od,n) ((od & 0x3 & n) == 0) - /* TRUE if reg #n is properly aligned */ +/* TRUE if reg #n is properly aligned */ #define MEMOP(od) (od == M) /* TRUE if operand is a memory operand*/ /* Classes of 960 intructions: @@ -193,33 +192,33 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define N_BALNAME (-2) - /* i960 uses a custom relocation record. */ +/* i960 uses a custom relocation record. */ - /* let obj-aout.h know */ +/* let obj-aout.h know */ #define CUSTOM_RELOC_FORMAT 1 - /* let a.out.gnu.h know */ +/* let a.out.gnu.h know */ #define N_RELOCATION_INFO_DECLARED 1 struct relocation_info { int r_address; /* File address of item to be relocated */ unsigned - r_index:24,/* Index of symbol on which relocation is based*/ - r_pcrel:1, /* 1 => relocate PC-relative; else absolute - * On i960, pc-relative implies 24-bit - * address, absolute implies 32-bit. - */ - r_length:2, /* Number of bytes to relocate: - * 0 => 1 byte - * 1 => 2 bytes - * 2 => 4 bytes -- only value used for i960 - */ - r_extern:1, - r_bsr:1, /* Something for the GNU NS32K assembler */ - r_disp:1, /* Something for the GNU NS32K assembler */ - r_callj:1, /* 1 if relocation target is an i960 'callj' */ - nuthin:1; /* Unused */ + r_index:24,/* Index of symbol on which relocation is based*/ + r_pcrel:1, /* 1 => relocate PC-relative; else absolute + * On i960, pc-relative implies 24-bit + * address, absolute implies 32-bit. + */ + r_length:2, /* Number of bytes to relocate: + * 0 => 1 byte + * 1 => 2 bytes + * 2 => 4 bytes -- only value used for i960 + */ + r_extern:1, + r_bsr:1, /* Something for the GNU NS32K assembler */ + r_disp:1, /* Something for the GNU NS32K assembler */ + r_callj:1, /* 1 if relocation target is an i960 'callj' */ + nuthin:1; /* Unused */ }; - /* hacks for tracking callj's */ +/* hacks for tracking callj's */ #if defined(OBJ_AOUT) | defined(OBJ_BOUT) #define TC_S_IS_SYSPROC(s) ((1<=S_GET_OTHER(s)) && (S_GET_OTHER(s)<=32)) @@ -251,10 +250,10 @@ struct relocation_info { #else /* switch on OBJ */ you lose #endif /* witch on OBJ */ - + #ifdef __STDC__ - -void brtab_emit(void); + + void brtab_emit(void); void reloc_callj(); /* this is really reloc_callj(fixS *fixP) but I don't want to change header inclusion order. */ void tc_set_bal_of_call(); /* this is really tc_set_bal_of_call(symbolS *callP, symbolS *balP) */ @@ -277,3 +276,4 @@ char *_tc_get_bal_of_call(); /* this is really symbolS *tc_get_bal_of_call(symbo */ /* end of tp-i960.h */ +#endif diff --git a/gas/config/tc-m68851.h b/gas/config/tc-m68851.h index ff984fe..b60bdc6 100644 --- a/gas/config/tc-m68851.h +++ b/gas/config/tc-m68851.h @@ -7,61 +7,61 @@ to us as part of the changes for the m68851 Memory Management Unit */ /* Copyright (C) 1987 Free Software Foundation, Inc. - -This file is part of Gas, the GNU Assembler. - -The GNU assembler is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY. No author or distributor -accepts responsibility to anyone for the consequences of using it -or for whether it serves any particular purpose or works at all, -unless he says so in writing. Refer to the GNU Assembler General -Public License for full details. - -Everyone is granted permission to copy, modify and redistribute -the GNU Assembler, but only under the conditions described in the -GNU Assembler General Public License. A copy of this license is -supposed to have been given to you along with the GNU Assembler -so you can know your rights and responsibilities. It should be -in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. */ + + This file is part of Gas, the GNU Assembler. + + The GNU assembler is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the GNU Assembler General + Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + the GNU Assembler, but only under the conditions described in the + GNU Assembler General Public License. A copy of this license is + supposed to have been given to you along with the GNU Assembler + so you can know your rights and responsibilities. It should be + in a file named COPYING. Among other things, the copyright + notice and this notice must be preserved on all copies. */ #ifdef m68851 /* - I didn't use much imagination in choosing the - following codes, so many of them aren't very - mnemonic. -rab - - P pmmu register - Possible values: - 000 TC Translation Control reg - 100 CAL Current Access Level - 101 VAL Validate Access Level - 110 SCC Stack Change Control - 111 AC Access Control - - W wide pmmu registers - Possible values: - 001 DRP Dma Root Pointer - 010 SRP Supervisor Root Pointer - 011 CRP Cpu Root Pointer - - f function code register - 0 SFC - 1 DFC - - V VAL register only - - X BADx, BACx - 100 BAD Breakpoint Acknowledge Data - 101 BAC Breakpoint Acknowledge Control - - Y PSR - Z PCSR - - | memory (modes 2-6, 7.*) - -*/ + I didn't use much imagination in choosing the + following codes, so many of them aren't very + mnemonic. -rab + + P pmmu register + Possible values: + 000 TC Translation Control reg + 100 CAL Current Access Level + 101 VAL Validate Access Level + 110 SCC Stack Change Control + 111 AC Access Control + + W wide pmmu registers + Possible values: + 001 DRP Dma Root Pointer + 010 SRP Supervisor Root Pointer + 011 CRP Cpu Root Pointer + + f function code register + 0 SFC + 1 DFC + + V VAL register only + + X BADx, BACx + 100 BAD Breakpoint Acknowledge Data + 101 BAC Breakpoint Acknowledge Control + + Y PSR + Z PCSR + + | memory (modes 2-6, 7.*) + + */ /* * these defines should be in m68k.c but @@ -83,7 +83,7 @@ notice and this notice must be preserved on all copies. */ #define PSR (BAC+8) /* 72 */ #define PCSR (PSR+1) /* 73 */ - /* name */ /* opcode */ /* match */ /* args */ +/* name */ /* opcode */ /* match */ /* args */ {"pbac", one(0xf0c7), one(0xffbf), "Bc"}, {"pbacw", one(0xf087), one(0xffbf), "Bc"}, @@ -117,8 +117,8 @@ notice and this notice must be preserved on all copies. */ {"pbwcw", one(0xf089), one(0xffbf), "Bc"}, {"pbws", one(0xf0c8), one(0xffbf), "Bc"}, {"pbwsw", one(0xf088), one(0xffbf), "Bc"}, - - + + {"pdbac", two(0xf048, 0x0007), two(0xfff8, 0xffff), "DsBw"}, {"pdbas", two(0xf048, 0x0006), two(0xfff8, 0xffff), "DsBw"}, {"pdbbc", two(0xf048, 0x0001), two(0xfff8, 0xffff), "DsBw"}, @@ -135,53 +135,53 @@ notice and this notice must be preserved on all copies. */ {"pdbss", two(0xf048, 0x0004), two(0xfff8, 0xffff), "DsBw"}, {"pdbwc", two(0xf048, 0x0009), two(0xfff8, 0xffff), "DsBw"}, {"pdbws", two(0xf048, 0x0008), two(0xfff8, 0xffff), "DsBw"}, - + {"pflusha", two(0xf000, 0x2400), two(0xffff, 0xffff), "" }, - + {"pflush", two(0xf000, 0x3010), two(0xffc0, 0xfe10), "T3T9" }, {"pflush", two(0xf000, 0x3810), two(0xffc0, 0xfe10), "T3T9&s" }, {"pflush", two(0xf000, 0x3008), two(0xffc0, 0xfe18), "D3T9" }, {"pflush", two(0xf000, 0x3808), two(0xffc0, 0xfe18), "D3T9&s" }, {"pflush", two(0xf000, 0x3000), two(0xffc0, 0xfe1e), "f3T9" }, {"pflush", two(0xf000, 0x3800), two(0xffc0, 0xfe1e), "f3T9&s" }, - + {"pflushs", two(0xf000, 0x3410), two(0xfff8, 0xfe10), "T3T9" }, {"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe00), "T3T9&s" }, {"pflushs", two(0xf000, 0x3408), two(0xfff8, 0xfe18), "D3T9" }, {"pflushs", two(0xf000, 0x3c08), two(0xfff8, 0xfe18), "D3T9&s" }, {"pflushs", two(0xf000, 0x3400), two(0xfff8, 0xfe1e), "f3T9" }, {"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe1e), "f3T9&s"}, - + {"pflushr", two(0xf000, 0xa000), two(0xffc0, 0xffff), "|s" }, - + {"ploadr", two(0xf000, 0x2210), two(0xffc0, 0xfff0), "T3&s" }, {"ploadr", two(0xf000, 0x2208), two(0xffc0, 0xfff8), "D3&s" }, {"ploadr", two(0xf000, 0x2200), two(0xffc0, 0xfffe), "f3&s" }, {"ploadw", two(0xf000, 0x2010), two(0xffc0, 0xfff0), "T3&s" }, {"ploadw", two(0xf000, 0x2008), two(0xffc0, 0xfff8), "D3&s" }, {"ploadw", two(0xf000, 0x2000), two(0xffc0, 0xfffe), "f3&s" }, - -/* TC, CRP, DRP, SRP, CAL, VAL, SCC, AC */ + + /* TC, CRP, DRP, SRP, CAL, VAL, SCC, AC */ {"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "*sP8" }, {"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "P8%s" }, {"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "|sW8" }, {"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "W8~s" }, - -/* BADx, BACx */ + + /* BADx, BACx */ {"pmove", two(0xf000, 0x6200), two(0xffc0, 0xe3e3), "*sX3" }, {"pmove", two(0xf000, 0x6000), two(0xffc0, 0xe3e3), "X3%s" }, - -/* PSR, PCSR */ -/* {"pmove", two(0xf000, 0x6100), two(oxffc0, oxffff), "*sZ8" }, */ + + /* PSR, PCSR */ + /* {"pmove", two(0xf000, 0x6100), two(oxffc0, oxffff), "*sZ8" }, */ {"pmove", two(0xf000, 0x6000), two(0xffc0, 0xffff), "*sY8" }, {"pmove", two(0xf000, 0x6200), two(0xffc0, 0xffff), "Y8%s" }, {"pmove", two(0xf000, 0x6600), two(0xffc0, 0xffff), "Z8%s" }, - + {"prestore", one(0xf140), one(0xffc0), "&s"}, {"prestore", one(0xf158), one(0xfff8), "+s"}, {"psave", one(0xf100), one(0xffc0), "&s"}, {"psave", one(0xf100), one(0xffc0), "+s"}, - + {"psac", two(0xf040, 0x0007), two(0xffc0, 0xffff), "@s"}, {"psas", two(0xf040, 0x0006), two(0xffc0, 0xffff), "@s"}, {"psbc", two(0xf040, 0x0001), two(0xffc0, 0xffff), "@s"}, @@ -198,87 +198,87 @@ notice and this notice must be preserved on all copies. */ {"psss", two(0xf040, 0x0004), two(0xffc0, 0xffff), "@s"}, {"pswc", two(0xf040, 0x0009), two(0xffc0, 0xffff), "@s"}, {"psws", two(0xf040, 0x0008), two(0xffc0, 0xffff), "@s"}, - + {"ptestr", two(0xf000, 0x8210), two(0xffc0, 0xe3f0), "T3&sQ8" }, {"ptestr", two(0xf000, 0x8310), two(0xffc0, 0xe310), "T3&sQ8A9" }, {"ptestr", two(0xf000, 0x8208), two(0xffc0, 0xe3f8), "D3&sQ8" }, {"ptestr", two(0xf000, 0x8308), two(0xffc0, 0xe318), "D3&sQ8A9" }, {"ptestr", two(0xf000, 0x8200), two(0xffc0, 0xe3fe), "f3&sQ8" }, {"ptestr", two(0xf000, 0x8300), two(0xffc0, 0xe31e), "f3&sQ8A9" }, - + {"ptestw", two(0xf000, 0x8010), two(0xffc0, 0xe3f0), "T3&sQ8" }, {"ptestw", two(0xf000, 0x8110), two(0xffc0, 0xe310), "T3&sQ8A9" }, {"ptestw", two(0xf000, 0x8008), two(0xffc0, 0xe3f8), "D3&sQ8" }, {"ptestw", two(0xf000, 0x8108), two(0xffc0, 0xe318), "D3&sQ8A9" }, {"ptestw", two(0xf000, 0x8000), two(0xffc0, 0xe3fe), "f3&sQ8" }, {"ptestw", two(0xf000, 0x8100), two(0xffc0, 0xe31e), "f3&sQ8A9" }, - + {"ptrapacw", two(0xf07a, 0x0007), two(0xffff, 0xffff), "#w"}, {"ptrapacl", two(0xf07b, 0x0007), two(0xffff, 0xffff), "#l"}, {"ptrapac", two(0xf07c, 0x0007), two(0xffff, 0xffff), ""}, - + {"ptrapasw", two(0xf07a, 0x0006), two(0xffff, 0xffff), "#w"}, {"ptrapasl", two(0xf07b, 0x0006), two(0xffff, 0xffff), "#l"}, {"ptrapas", two(0xf07c, 0x0006), two(0xffff, 0xffff), ""}, - + {"ptrapbcw", two(0xf07a, 0x0001), two(0xffff, 0xffff), "#w"}, {"ptrapbcl", two(0xf07b, 0x0001), two(0xffff, 0xffff), "#l"}, {"ptrapbc", two(0xf07c, 0x0001), two(0xffff, 0xffff), ""}, - + {"ptrapbsw", two(0xf07a, 0x0000), two(0xffff, 0xffff), "#w"}, {"ptrapbsl", two(0xf07b, 0x0000), two(0xffff, 0xffff), "#l"}, {"ptrapbs", two(0xf07c, 0x0000), two(0xffff, 0xffff), ""}, - + {"ptrapccw", two(0xf07a, 0x000f), two(0xffff, 0xffff), "#w"}, {"ptrapccl", two(0xf07b, 0x000f), two(0xffff, 0xffff), "#l"}, {"ptrapcc", two(0xf07c, 0x000f), two(0xffff, 0xffff), ""}, - + {"ptrapcsw", two(0xf07a, 0x000e), two(0xffff, 0xffff), "#w"}, {"ptrapcsl", two(0xf07b, 0x000e), two(0xffff, 0xffff), "#l"}, {"ptrapcs", two(0xf07c, 0x000e), two(0xffff, 0xffff), ""}, - + {"ptrapgcw", two(0xf07a, 0x000d), two(0xffff, 0xffff), "#w"}, {"ptrapgcl", two(0xf07b, 0x000d), two(0xffff, 0xffff), "#l"}, {"ptrapgc", two(0xf07c, 0x000d), two(0xffff, 0xffff), ""}, - + {"ptrapgsw", two(0xf07a, 0x000c), two(0xffff, 0xffff), "#w"}, {"ptrapgsl", two(0xf07b, 0x000c), two(0xffff, 0xffff), "#l"}, {"ptrapgs", two(0xf07c, 0x000c), two(0xffff, 0xffff), ""}, - + {"ptrapicw", two(0xf07a, 0x000b), two(0xffff, 0xffff), "#w"}, {"ptrapicl", two(0xf07b, 0x000b), two(0xffff, 0xffff), "#l"}, {"ptrapic", two(0xf07c, 0x000b), two(0xffff, 0xffff), ""}, - + {"ptrapisw", two(0xf07a, 0x000a), two(0xffff, 0xffff), "#w"}, {"ptrapisl", two(0xf07b, 0x000a), two(0xffff, 0xffff), "#l"}, {"ptrapis", two(0xf07c, 0x000a), two(0xffff, 0xffff), ""}, - + {"ptraplcw", two(0xf07a, 0x0003), two(0xffff, 0xffff), "#w"}, {"ptraplcl", two(0xf07b, 0x0003), two(0xffff, 0xffff), "#l"}, {"ptraplc", two(0xf07c, 0x0003), two(0xffff, 0xffff), ""}, - + {"ptraplsw", two(0xf07a, 0x0002), two(0xffff, 0xffff), "#w"}, {"ptraplsl", two(0xf07b, 0x0002), two(0xffff, 0xffff), "#l"}, {"ptrapls", two(0xf07c, 0x0002), two(0xffff, 0xffff), ""}, - + {"ptrapscw", two(0xf07a, 0x0005), two(0xffff, 0xffff), "#w"}, {"ptrapscl", two(0xf07b, 0x0005), two(0xffff, 0xffff), "#l"}, {"ptrapsc", two(0xf07c, 0x0005), two(0xffff, 0xffff), ""}, - + {"ptrapssw", two(0xf07a, 0x0004), two(0xffff, 0xffff), "#w"}, {"ptrapssl", two(0xf07b, 0x0004), two(0xffff, 0xffff), "#l"}, {"ptrapss", two(0xf07c, 0x0004), two(0xffff, 0xffff), ""}, - + {"ptrapwcw", two(0xf07a, 0x0009), two(0xffff, 0xffff), "#w"}, {"ptrapwcl", two(0xf07b, 0x0009), two(0xffff, 0xffff), "#l"}, {"ptrapwc", two(0xf07c, 0x0009), two(0xffff, 0xffff), ""}, - + {"ptrapwsw", two(0xf07a, 0x0008), two(0xffff, 0xffff), "#w"}, {"ptrapwsl", two(0xf07b, 0x0008), two(0xffff, 0xffff), "#l"}, {"ptrapws", two(0xf07c, 0x0008), two(0xffff, 0xffff), ""}, - + {"pvalid", two(0xf000, 0x2800), two(0xffc0, 0xffff), "Vs&s"}, {"pvalid", two(0xf000, 0x2c00), two(0xffc0, 0xfff8), "A3&s" }, - + #endif /* m68851 */ -/* end pmmu.h */ + /* end pmmu.h */ diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index c7919ce..bcc1a85 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -1,22 +1,22 @@ /* m68k.c All the m68020 specific stuff in one convenient, huge, slow to compile, easy to find file. Copyright (C) 1987, 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 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. */ #include <ctype.h> @@ -24,7 +24,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "obstack.h" - /* note that this file includes real declarations and thus can only be included by one source file per executable. */ +/* note that this file includes real declarations and thus can only be included by one source file per executable. */ #include "opcode/m68k.h" #ifdef TE_SUN /* This variable contains the value to write out at the beginning of @@ -61,7 +61,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXeEpP"; /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be changed in read.c . Ideally it shouldn't have to know about it at all, but nothing is ideal around here. - */ + */ int md_reloc_size = 8; /* Size of relocation record */ @@ -84,56 +84,56 @@ static struct obstack robyn; #define PCLEA 6 /* Operands we can parse: (And associated modes) - -numb: 8 bit num -numw: 16 bit num -numl: 32 bit num -dreg: data reg 0-7 -reg: address or data register -areg: address register -apc: address register, PC, ZPC or empty string -num: 16 or 32 bit num -num2: like num -sz: w or l if omitted, l assumed -scale: 1 2 4 or 8 if omitted, 1 assumed - -7.4 IMMED #num --> NUM -0.? DREG dreg --> dreg -1.? AREG areg --> areg -2.? AINDR areg@ --> *(areg) -3.? AINC areg@+ --> *(areg++) -4.? ADEC areg@- --> *(--areg) -5.? AOFF apc@(numw) --> *(apc+numw) -- empty string and ZPC not allowed here -6.? AINDX apc@(num,reg:sz:scale) --> *(apc+num+reg*scale) -6.? AINDX apc@(reg:sz:scale) --> same, with num=0 -6.? APODX apc@(num)@(num2,reg:sz:scale) --> *(*(apc+num)+num2+reg*scale) -6.? APODX apc@(num)@(reg:sz:scale) --> same, with num2=0 -6.? AMIND apc@(num)@(num2) --> *(*(apc+num)+num2) (previous mode without an index reg) -6.? APRDX apc@(num,reg:sz:scale)@(num2) --> *(*(apc+num+reg*scale)+num2) -6.? APRDX apc@(reg:sz:scale)@(num2) --> same, with num=0 -7.0 ABSL num:sz --> *(num) - num --> *(num) (sz L assumed) -*** MSCR otherreg --> Magic -With -l option -5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still - -examples: - #foo #0x35 #12 - d2 - a4 - a3@ - a5@+ - a6@- - a2@(12) pc@(14) - a1@(5,d2:w:1) @(45,d6:l:4) - pc@(a2) @(d4) - etc . . . - - -#name@(numw) -->turn into PC rel mode -apc@(num8,reg:sz:scale) --> *(apc+num8+reg*scale) - -*/ + + numb: 8 bit num + numw: 16 bit num + numl: 32 bit num + dreg: data reg 0-7 + reg: address or data register + areg: address register + apc: address register, PC, ZPC or empty string + num: 16 or 32 bit num + num2: like num + sz: w or l if omitted, l assumed + scale: 1 2 4 or 8 if omitted, 1 assumed + + 7.4 IMMED #num --> NUM + 0.? DREG dreg --> dreg + 1.? AREG areg --> areg + 2.? AINDR areg@ --> *(areg) + 3.? AINC areg@+ --> *(areg++) + 4.? ADEC areg@- --> *(--areg) + 5.? AOFF apc@(numw) --> *(apc+numw) -- empty string and ZPC not allowed here + 6.? AINDX apc@(num,reg:sz:scale) --> *(apc+num+reg*scale) + 6.? AINDX apc@(reg:sz:scale) --> same, with num=0 + 6.? APODX apc@(num)@(num2,reg:sz:scale) --> *(*(apc+num)+num2+reg*scale) + 6.? APODX apc@(num)@(reg:sz:scale) --> same, with num2=0 + 6.? AMIND apc@(num)@(num2) --> *(*(apc+num)+num2) (previous mode without an index reg) + 6.? APRDX apc@(num,reg:sz:scale)@(num2) --> *(*(apc+num+reg*scale)+num2) + 6.? APRDX apc@(reg:sz:scale)@(num2) --> same, with num=0 + 7.0 ABSL num:sz --> *(num) + num --> *(num) (sz L assumed) + *** MSCR otherreg --> Magic + With -l option + 5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still + + examples: + #foo #0x35 #12 + d2 + a4 + a3@ + a5@+ + a6@- + a2@(12) pc@(14) + a1@(5,d2:w:1) @(45,d6:l:4) + pc@(a2) @(d4) + etc . . . + + + #name@(numw) -->turn into PC rel mode + apc@(num8,reg:sz:scale) --> *(apc+num8+reg*scale) + + */ enum operand_type { IMMED = 1, @@ -154,10 +154,10 @@ enum operand_type { struct m68k_exp { - char *e_beg; - char *e_end; - expressionS e_exp; - short e_siz; /* 0== default 1==short/byte 2==word 3==long */ + char *e_beg; + char *e_end; + expressionS e_exp; + short e_siz; /* 0== default 1==short/byte 2==word 3==long */ }; /* DATA and ADDR have to be contiguous, so that reg-DATA gives 0-7==data reg, @@ -183,12 +183,12 @@ enum _register { ADDR5, ADDR6, ADDR7, - -/* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */ -/* I think. . . */ - + + /* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */ + /* I think. . . */ + SP = ADDR7, - + FPREG, /* Eight FP registers */ FP0 = FPREG, FP1, @@ -211,8 +211,8 @@ enum _register { ZPC, /* Hack for Program space, but 0 addressing */ SR, /* Status Reg */ CCR, /* Condition code Reg */ - -/* These have to be in order for the movec instruction to work. */ + + /* These have to be in order for the movec instruction to work. */ USP, /* User Stack Pointer */ ISP, /* Interrupt stack pointer */ SFC, @@ -229,12 +229,12 @@ enum _register { TC, SRP, URP, -/* end of movec ordering constraints */ - + /* end of movec ordering constraints */ + FPI, FPS, FPC, - + DRP, CRP, CAL, @@ -261,57 +261,57 @@ enum _register { BAC7, PSR, PCSR, - + IC, /* instruction cache token */ DC, /* data cache token */ NC, /* no cache token */ BC, /* both caches token */ - + }; /* Internal form of an operand. */ struct m68k_op { - char *error; /* Couldn't parse it */ - enum operand_type mode; /* What mode this instruction is in. */ - enum _register reg; /* Base register */ - struct m68k_exp *con1; - int ireg; /* Index register */ - int isiz; /* 0==unspec 1==byte(?) 2==short 3==long */ - int imul; /* Multipy ireg by this (1,2,4,or 8) */ - struct m68k_exp *con2; + char *error; /* Couldn't parse it */ + enum operand_type mode; /* What mode this instruction is in. */ + enum _register reg; /* Base register */ + struct m68k_exp *con1; + int ireg; /* Index register */ + int isiz; /* 0==unspec 1==byte(?) 2==short 3==long */ + int imul; /* Multipy ireg by this (1,2,4,or 8) */ + struct m68k_exp *con2; }; /* internal form of a 68020 instruction */ struct m68k_it { - char *error; - char *args; /* list of opcode info */ - int numargs; - - int numo; /* Number of shorts in opcode */ - short opcode[11]; - - struct m68k_op operands[6]; - - int nexp; /* number of exprs in use */ - struct m68k_exp exprs[4]; - - int nfrag; /* Number of frags we have to produce */ - struct { - int fragoff; /* Where in the current opcode[] the frag ends */ - symbolS *fadd; - long foff; - int fragty; - } fragb[4]; - - int nrel; /* Num of reloc strucs in use */ - struct { - int n; - symbolS *add, - *sub; - long off; - char wid; - char pcrel; - } reloc[5]; /* Five is enough??? */ + char *error; + char *args; /* list of opcode info */ + int numargs; + + int numo; /* Number of shorts in opcode */ + short opcode[11]; + + struct m68k_op operands[6]; + + int nexp; /* number of exprs in use */ + struct m68k_exp exprs[4]; + + int nfrag; /* Number of frags we have to produce */ + struct { + int fragoff; /* Where in the current opcode[] the frag ends */ + symbolS *fadd; + long foff; + int fragty; + } fragb[4]; + + int nrel; /* Num of reloc strucs in use */ + struct { + int n; + symbolS *add, + *sub; + long off; + char wid; + char pcrel; + } reloc[5]; /* Five is enough??? */ }; #define cpu_of_arch(x) ((x) & m68000up) @@ -326,39 +326,39 @@ static struct m68k_it the_ins; /* the instruction being assembled */ /* Like addword, but goes BEFORE general operands */ #define insop(w) {int z;\ - for(z=the_ins.numo;z>opcode->m_codenum;--z)\ - the_ins.opcode[z]=the_ins.opcode[z-1];\ - for(z=0;z<the_ins.nrel;z++)\ - the_ins.reloc[z].n+=2;\ - the_ins.opcode[opcode->m_codenum]=w;\ - the_ins.numo++;\ -} + for(z=the_ins.numo;z>opcode->m_codenum;--z)\ + the_ins.opcode[z]=the_ins.opcode[z-1];\ + for(z=0;z<the_ins.nrel;z++)\ + the_ins.reloc[z].n+=2;\ + the_ins.opcode[opcode->m_codenum]=w;\ + the_ins.numo++;\ + } #define add_exp(beg,end) (\ - the_ins.exprs[the_ins.nexp].e_beg=beg,\ - the_ins.exprs[the_ins.nexp].e_end=end,\ - &the_ins.exprs[the_ins.nexp++]\ -) + the_ins.exprs[the_ins.nexp].e_beg=beg,\ + the_ins.exprs[the_ins.nexp].e_end=end,\ + &the_ins.exprs[the_ins.nexp++]\ + ) /* The numo+1 kludge is so we can hit the low order byte of the prev word. Blecch*/ #define add_fix(width,exp,pc_rel) {\ - the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \ - (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\ - the_ins.reloc[the_ins.nrel].add=adds((exp));\ - the_ins.reloc[the_ins.nrel].sub=subs((exp));\ - the_ins.reloc[the_ins.nrel].off=offs((exp));\ - the_ins.reloc[the_ins.nrel].wid=width;\ - the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\ -} + the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \ + (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\ + the_ins.reloc[the_ins.nrel].add=adds((exp));\ + the_ins.reloc[the_ins.nrel].sub=subs((exp));\ + the_ins.reloc[the_ins.nrel].off=offs((exp));\ + the_ins.reloc[the_ins.nrel].wid=width;\ + the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\ + } #define add_frag(add,off,type) {\ - the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\ - the_ins.fragb[the_ins.nfrag].fadd=add;\ - the_ins.fragb[the_ins.nfrag].foff=off;\ - the_ins.fragb[the_ins.nfrag++].fragty=type;\ -} + the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\ + the_ins.fragb[the_ins.nfrag].fadd=add;\ + the_ins.fragb[the_ins.nfrag].foff=off;\ + the_ins.fragb[the_ins.nfrag++].fragty=type;\ + } #define isvar(exp) ((exp) && (adds(exp) || subs(exp))) @@ -369,12 +369,12 @@ static struct m68k_it the_ins; /* the instruction being assembled */ struct m68k_incant { - char *m_operands; - unsigned long m_opcode; - short m_opnum; - short m_codenum; - enum m68k_architecture m_arch; - struct m68k_incant *m_next; + char *m_operands; + unsigned long m_opcode; + short m_opnum; + short m_codenum; + enum m68k_architecture m_arch; + struct m68k_incant *m_next; }; #define getone(x) ((((x)->m_opcode)>>16)&0xffff) @@ -427,69 +427,69 @@ static enum m68k_architecture current_architecture = 0; /* This is currently 10 bytes for DBCC */ /* The fields are: - How far Forward this mode will reach: - How far Backward this mode will reach: - How many bytes this mode will add to the size of the frag - Which mode to go to if the offset won't fit in this one - */ + How far Forward this mode will reach: + How far Backward this mode will reach: + How many bytes this mode will add to the size of the frag + Which mode to go to if the offset won't fit in this one + */ const relax_typeS -md_relax_table[] = { -{ 1, 1, 0, 0 }, /* First entries aren't used */ + md_relax_table[] = { + { 1, 1, 0, 0 }, /* First entries aren't used */ { 1, 1, 0, 0 }, /* For no good reason except */ { 1, 1, 0, 0 }, /* that the VAX doesn't either */ { 1, 1, 0, 0 }, - + { (127), (-128), 0, TAB(BRANCH,SHORT)}, { (32767), (-32768), 2, TAB(BRANCH,LONG) }, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* FBRANCH doesn't come BYTE */ { (32767), (-32768), 2, TAB(FBRANCH,LONG)}, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* PCREL doesn't come BYTE */ { (32767), (-32768), 2, TAB(PCREL,LONG)}, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - + { (127), (-128), 0, TAB(BCC68000,SHORT)}, { (32767), (-32768), 2, TAB(BCC68000,LONG) }, { 0, 0, 6, 0 }, /* jmp long space */ { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE */ { (32767), (-32768), 2, TAB(DBCC,LONG) }, { 0, 0, 10, 0 }, /* bra/jmp long space */ { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* PCLEA doesn't come BYTE */ { 32767, -32768, 2, TAB(PCLEA,LONG) }, { 0, 0, 6, 0 }, { 1, 1, 0, 0 }, - + }; /* These are the machine dependent pseudo-ops. These are included so the assembler can work on the output from the SUN C compiler, which generates these. - */ + */ /* This table describes all the machine specific pseudo-ops the assembler has to support. The fields are: - pseudo-op name without dot - function to call to execute this pseudo-op - Integer arg to pass to the function - */ + pseudo-op name without dot + function to call to execute this pseudo-op + Integer arg to pass to the function + */ const pseudo_typeS md_pseudo_table[] = { - { "data1", s_data1, 0 }, - { "data2", s_data2, 0 }, - { "bss", s_bss, 0 }, - { "even", s_even, 0 }, - { "skip", s_space, 0 }, - { "proc", s_proc, 0 }, - { 0, 0, 0 } +{ "data1", s_data1, 0 }, +{ "data2", s_data2, 0 }, +{ "bss", s_bss, 0 }, +{ "even", s_even, 0 }, +{ "skip", s_space, 0 }, +{ "proc", s_proc, 0 }, +{ 0, 0, 0 } }; @@ -500,12 +500,12 @@ const pseudo_typeS md_pseudo_table[] = { #define isubyte(x) ((x)>=0 && (x)<=255) #define issword(x) ((x)>=-32768 && (x)<=32767) #define isuword(x) ((x)>=0 && (x)<=65535) - + #define isbyte(x) ((x)>=-128 && (x)<=255) #define isword(x) ((x)>=-32768 && (x)<=65535) #define islong(x) (1) - -extern char *input_line_pointer; + + extern char *input_line_pointer; enum { FAIL = 0, @@ -518,273 +518,273 @@ enum { static char mklower_table[256]; #define mklower(c) (mklower_table[(unsigned char)(c)]) -static char notend_table[256]; + static char notend_table[256]; static char alt_notend_table[256]; #define notend(s) ( !(notend_table[(unsigned char)(*s)] || (*s==':' &&\ - alt_notend_table[(unsigned char)(s[1])]))) + alt_notend_table[(unsigned char)(s[1])]))) #if 0 #define mklower(c) (isupper(c) ? tolower(c) : c) #endif - - -/* JF modified this to handle cases where the first part of a symbol name - looks like a register */ - -/* - * m68k_reg_parse() := if it looks like a register, return it's token & - * advance the pointer. - */ - -enum _register m68k_reg_parse(ccp) + + + /* JF modified this to handle cases where the first part of a symbol name + looks like a register */ + + /* + * m68k_reg_parse() := if it looks like a register, return it's token & + * advance the pointer. + */ + + enum _register m68k_reg_parse(ccp) register char **ccp; { #ifndef MAX_REG_NAME_LEN #define MAX_REG_NAME_LEN (6) #endif /* MAX_REG_NAME_LEN */ - register char c[MAX_REG_NAME_LEN]; - char *p, *q; - register int n = 0, - ret = FAIL; - - c[0] = mklower(ccp[0][0]); + register char c[MAX_REG_NAME_LEN]; + char *p, *q; + register int n = 0, + ret = FAIL; + + c[0] = mklower(ccp[0][0]); #ifdef REGISTER_PREFIX - if (c[0] != REGISTER_PREFIX) { - return(FAIL); - } /* need prefix */ + if (c[0] != REGISTER_PREFIX) { + return(FAIL); + } /* need prefix */ #endif - - for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q) - { - if (*q == 0) - { - *p = 0; - break; - } - else - *p = mklower(*q); - } /* downcase */ - - switch(c[0]) { - case 'a': - if(c[1]>='0' && c[1]<='7') { - n=2; - ret=ADDR+c[1]-'0'; - } + + for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q) + { + if (*q == 0) + { + *p = 0; + break; + } + else + *p = mklower(*q); + } /* downcase */ + + switch(c[0]) { + case 'a': + if(c[1]>='0' && c[1]<='7') { + n=2; + ret=ADDR+c[1]-'0'; + } #ifndef NO_68851 - else if (c[1] == 'c') { - n = 2; - ret = AC; - } + else if (c[1] == 'c') { + n = 2; + ret = AC; + } #endif - break; + break; #ifndef NO_68851 - case 'b': - if (c[1] == 'a') { - if (c[2] == 'd') { - if (c[3] >= '0' && c[3] <= '7') { - n = 4; - ret = BAD + c[3] - '0'; - } - } /* BAD */ - if (c[2] == 'c') { - if (c[3] >= '0' && c[3] <= '7') { - n = 4; - ret = BAC + c[3] - '0'; - } - } /* BAC */ - } else if (c[1] == 'c') { - n = 2; - ret = BC; - } /* BC */ - break; + case 'b': + if (c[1] == 'a') { + if (c[2] == 'd') { + if (c[3] >= '0' && c[3] <= '7') { + n = 4; + ret = BAD + c[3] - '0'; + } + } /* BAD */ + if (c[2] == 'c') { + if (c[3] >= '0' && c[3] <= '7') { + n = 4; + ret = BAC + c[3] - '0'; + } + } /* BAC */ + } else if (c[1] == 'c') { + n = 2; + ret = BC; + } /* BC */ + break; #endif - case 'c': + case 'c': #ifndef NO_68851 - if (c[1] == 'a' && c[2] == 'l') { - n = 3; - ret = CAL; - } else + if (c[1] == 'a' && c[2] == 'l') { + n = 3; + ret = CAL; + } else #endif - /* This supports both CCR and CC as the ccr reg. */ - if(c[1]=='c' && c[2]=='r') { - n=3; - ret = CCR; - } else if(c[1]=='c') { - n=2; - ret = CCR; - } else if(c[1]=='a' && (c[2]=='a' || c[2]=='c') && c[3]=='r') { - n=4; - ret = c[2]=='a' ? CAAR : CACR; - } + /* This supports both CCR and CC as the ccr reg. */ + if(c[1]=='c' && c[2]=='r') { + n=3; + ret = CCR; + } else if(c[1]=='c') { + n=2; + ret = CCR; + } else if(c[1]=='a' && (c[2]=='a' || c[2]=='c') && c[3]=='r') { + n=4; + ret = c[2]=='a' ? CAAR : CACR; + } #ifndef NO_68851 - else if (c[1] == 'r' && c[2] == 'p') { - n = 3; - ret = (CRP); - } + else if (c[1] == 'r' && c[2] == 'p') { + n = 3; + ret = (CRP); + } #endif - break; - case 'd': - if (c[1] >= '0' && c[1] <= '7') { - n = 2; - ret = DATA + c[1] - '0'; - } else if (c[1] == 'f' && c[2] == 'c') { - n = 3; - ret = DFC; - } else if (c[1] == 'c') { - n = 2; - ret = DC; - } else if (c[1] == 't' && c[2] == 't') { - if ('0' <= c[3] && c[3] <= '1') { - n = 4; - ret = DTT0 + (c[3] - '0'); - } /* DTT[01] */ - } + break; + case 'd': + if (c[1] >= '0' && c[1] <= '7') { + n = 2; + ret = DATA + c[1] - '0'; + } else if (c[1] == 'f' && c[2] == 'c') { + n = 3; + ret = DFC; + } else if (c[1] == 'c') { + n = 2; + ret = DC; + } else if (c[1] == 't' && c[2] == 't') { + if ('0' <= c[3] && c[3] <= '1') { + n = 4; + ret = DTT0 + (c[3] - '0'); + } /* DTT[01] */ + } #ifndef NO_68851 - else if (c[1] == 'r' && c[2] == 'p') { - n = 3; - ret = (DRP); - } + else if (c[1] == 'r' && c[2] == 'p') { + n = 3; + ret = (DRP); + } #endif - break; - case 'f': - if(c[1]=='p') { - if(c[2]>='0' && c[2]<='7') { - n=3; - ret = FPREG+c[2]-'0'; - if(c[3]==':') - ccp[0][3]=','; - } else if(c[2]=='i') { - n=3; - ret = FPI; - } else if(c[2]=='s') { - n= (c[3] == 'r' ? 4 : 3); - ret = FPS; - } else if(c[2]=='c') { - n= (c[3] == 'r' ? 4 : 3); - ret = FPC; - } - } - break; - case 'i': - if (c[1] == 's' && c[2] == 'p') { - n = 3; - ret = ISP; - } else if (c[1] == 'c') { - n = 2; - ret = IC; - } else if (c[1] == 't' && c[2] == 't') { - if ('0' <= c[3] && c[3] <= '1') { - n = 4; - ret = ITT0 + (c[3] - '0'); - } /* ITT[01] */ - } - break; - case 'm': - if (c[1] == 's' && c[2] == 'p') { - n = 3; - ret = MSP; - } else if (c[1] == 'm' && c[2] == 'u' && c[3] == 's' && c[4] == 'r') { - n = 5; - ret = MMUSR; - } - break; - case 'n': - if (c[1] == 'c') { - n = 2; - ret = NC; - } - break; - case 'p': - if(c[1]=='c') { + break; + case 'f': + if(c[1]=='p') { + if(c[2]>='0' && c[2]<='7') { + n=3; + ret = FPREG+c[2]-'0'; + if(c[3]==':') + ccp[0][3]=','; + } else if(c[2]=='i') { + n=3; + ret = FPI; + } else if(c[2]=='s') { + n= (c[3] == 'r' ? 4 : 3); + ret = FPS; + } else if(c[2]=='c') { + n= (c[3] == 'r' ? 4 : 3); + ret = FPC; + } + } + break; + case 'i': + if (c[1] == 's' && c[2] == 'p') { + n = 3; + ret = ISP; + } else if (c[1] == 'c') { + n = 2; + ret = IC; + } else if (c[1] == 't' && c[2] == 't') { + if ('0' <= c[3] && c[3] <= '1') { + n = 4; + ret = ITT0 + (c[3] - '0'); + } /* ITT[01] */ + } + break; + case 'm': + if (c[1] == 's' && c[2] == 'p') { + n = 3; + ret = MSP; + } else if (c[1] == 'm' && c[2] == 'u' && c[3] == 's' && c[4] == 'r') { + n = 5; + ret = MMUSR; + } + break; + case 'n': + if (c[1] == 'c') { + n = 2; + ret = NC; + } + break; + case 'p': + if(c[1]=='c') { #ifndef NO_68851 - if(c[2] == 's' && c[3]=='r') { - n=4; - ret = (PCSR); - } else + if(c[2] == 's' && c[3]=='r') { + n=4; + ret = (PCSR); + } else #endif - { - n=2; - ret = PC; - } - } + { + n=2; + ret = PC; + } + } #ifndef NO_68851 - else if (c[1] == 's' && c[2] == 'r') { - n = 3; - ret = (PSR); - } + else if (c[1] == 's' && c[2] == 'r') { + n = 3; + ret = (PSR); + } #endif - break; - case 's': + break; + case 's': #ifndef NO_68851 - if (c[1] == 'c' && c[2] == 'c') { - n = 3; - ret = (SCC); - } else + if (c[1] == 'c' && c[2] == 'c') { + n = 3; + ret = (SCC); + } else #endif - if (c[1] == 'r') { - if (c[2] == 'p') { - n = 3; - ret = SRP; - } else { - n = 2; - ret = SR; - } /* srp else sr */ - } else if (c[1] == 'p') { - n = 2; - ret = SP; - } else if (c[1] == 'f' && c[2] == 'c') { - n = 3; - ret = SFC; - } - break; - case 't': - if (c[1] == 'c') { - n = 2; - ret = TC; - } - break; - case 'u': - if (c[1] == 's' && c[2] == 'p') { - n=3; - ret = USP; - } else if (c[1] == 'r' && c[2] == 'p') { - n = 3; - ret = URP; - } - break; - case 'v': + if (c[1] == 'r') { + if (c[2] == 'p') { + n = 3; + ret = SRP; + } else { + n = 2; + ret = SR; + } /* srp else sr */ + } else if (c[1] == 'p') { + n = 2; + ret = SP; + } else if (c[1] == 'f' && c[2] == 'c') { + n = 3; + ret = SFC; + } + break; + case 't': + if (c[1] == 'c') { + n = 2; + ret = TC; + } + break; + case 'u': + if (c[1] == 's' && c[2] == 'p') { + n=3; + ret = USP; + } else if (c[1] == 'r' && c[2] == 'p') { + n = 3; + ret = URP; + } + break; + case 'v': #ifndef NO_68851 - if (c[1] == 'a' && c[2] == 'l') { - n = 3; - ret = (VAL); - } else + if (c[1] == 'a' && c[2] == 'l') { + n = 3; + ret = (VAL); + } else #endif - if(c[1]=='b' && c[2]=='r') { - n=3; - ret = VBR; - } - break; - case 'z': - if(c[1]=='p' && c[2]=='c') { - n=3; - ret = ZPC; - } - break; - default: - break; + if(c[1]=='b' && c[2]=='r') { + n=3; + ret = VBR; + } + break; + case 'z': + if(c[1]=='p' && c[2]=='c') { + n=3; + ret = ZPC; } - if(n) { + break; + default: + break; + } + if(n) { #ifdef REGISTER_PREFIX - n++; + n++; #endif - if(isalnum(ccp[0][n]) || ccp[0][n]=='_') - ret=FAIL; - else - ccp[0]+=n; - } else - ret = FAIL; - return ret; + if(isalnum(ccp[0][n]) || ccp[0][n]=='_') + ret=FAIL; + else + ccp[0]+=n; + } else + ret = FAIL; + return ret; } #define SKIP_WHITE() { str++; if(*str==' ') str++;} @@ -801,241 +801,241 @@ register char **ccp; */ int -m68k_ip_op(str,opP) + m68k_ip_op(str,opP) char *str; register struct m68k_op *opP; { - char *strend; - long i; - char *parse_index(); - - if (*str==' ') { - str++; - } /* Find the beginning of the string */ - - if(!*str) { - opP->error="Missing operand"; - return FAIL; - } /* Out of gas */ - - for(strend = str; *strend; strend++) ;; - - --strend; - - if(*str=='#') { - str++; - opP->con1=add_exp(str,strend); - opP->mode=IMMED; - return OK; - } /* Guess what: A constant. Shar and enjoy */ - - i = m68k_reg_parse(&str); - - /* is a register, is exactly a register, and is followed by '@' */ - - if((i==FAIL || *str!='\0') && *str!='@') { - char *stmp; - - if(i!=FAIL && (*str=='/' || *str=='-')) { - opP->mode=REGLST; - return(get_regs(i,str,opP)); - } - if ((stmp=strchr(str,'@')) != '\0') { - opP->con1=add_exp(str,stmp-1); - if(stmp==strend) { - opP->mode=AINDX; - return(OK); - } - - if ((current_architecture & m68020up) == 0) { - return(FAIL); - } /* if target is not a '20 or better */ - - stmp++; - if(*stmp++!='(' || *strend--!=')') { - opP->error="Malformed operand"; - return(FAIL); - } - i=try_index(&stmp,opP); - opP->con2=add_exp(stmp,strend); - - if (i == FAIL) { - opP->mode=AMIND; - } else { - opP->mode=APODX; - } - return(OK); - } /* if there's an '@' */ - opP->mode = ABSL; - opP->con1 = add_exp(str,strend); - return(OK); - } /* not a register, not exactly a register, or no '@' */ - - opP->reg=i; - - if (*str=='\0') { - if(i>=DATA+0 && i<=DATA+7) - opP->mode=DREG; - else if(i>=ADDR+0 && i<=ADDR+7) - opP->mode=AREG; - else - opP->mode=MSCR; - return OK; - } - - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { /* Can't indirect off non address regs */ - opP->error="Invalid indirect register"; - return FAIL; + char *strend; + long i; + char *parse_index(); + + if (*str==' ') { + str++; + } /* Find the beginning of the string */ + + if(!*str) { + opP->error="Missing operand"; + return FAIL; + } /* Out of gas */ + + for(strend = str; *strend; strend++) ;; + + --strend; + + if(*str=='#') { + str++; + opP->con1=add_exp(str,strend); + opP->mode=IMMED; + return OK; + } /* Guess what: A constant. Shar and enjoy */ + + i = m68k_reg_parse(&str); + + /* is a register, is exactly a register, and is followed by '@' */ + + if((i==FAIL || *str!='\0') && *str!='@') { + char *stmp; + + if(i!=FAIL && (*str=='/' || *str=='-')) { + opP->mode=REGLST; + return(get_regs(i,str,opP)); } - know(*str == '@'); - + if ((stmp=strchr(str,'@')) != '\0') { + opP->con1=add_exp(str,stmp-1); + if(stmp==strend) { + opP->mode=AINDX; + return(OK); + } + + if ((current_architecture & m68020up) == 0) { + return(FAIL); + } /* if target is not a '20 or better */ + + stmp++; + if(*stmp++!='(' || *strend--!=')') { + opP->error="Malformed operand"; + return(FAIL); + } + i=try_index(&stmp,opP); + opP->con2=add_exp(stmp,strend); + + if (i == FAIL) { + opP->mode=AMIND; + } else { + opP->mode=APODX; + } + return(OK); + } /* if there's an '@' */ + opP->mode = ABSL; + opP->con1 = add_exp(str,strend); + return(OK); + } /* not a register, not exactly a register, or no '@' */ + + opP->reg=i; + + if (*str=='\0') { + if(i>=DATA+0 && i<=DATA+7) + opP->mode=DREG; + else if(i>=ADDR+0 && i<=ADDR+7) + opP->mode=AREG; + else + opP->mode=MSCR; + return OK; + } + + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + know(*str == '@'); + + str++; + switch(*str) { + case '\0': + opP->mode=AINDR; + return OK; + case '-': + opP->mode=ADEC; + return OK; + case '+': + opP->mode=AINC; + return OK; + case '(': str++; - switch(*str) { - case '\0': - opP->mode=AINDR; - return OK; - case '-': - opP->mode=ADEC; - return OK; - case '+': - opP->mode=AINC; - return OK; - case '(': - str++; - break; - default: - opP->error="Junk after indirect"; + break; + default: + opP->error="Junk after indirect"; + return FAIL; + } + /* Some kind of indexing involved. Lets find out how bad it is */ + i=try_index(&str,opP); + /* Didn't start with an index reg, maybe its offset or offset,reg */ + if(i==FAIL) { + char *beg_str; + + beg_str=str; + for(i=1;i;) { + switch(*str++) { + case '\0': + opP->error="Missing )"; return FAIL; + case ',': i=0; break; + case '(': i++; break; + case ')': --i; break; + } } - /* Some kind of indexing involved. Lets find out how bad it is */ - i=try_index(&str,opP); - /* Didn't start with an index reg, maybe its offset or offset,reg */ - if(i==FAIL) { - char *beg_str; - - beg_str=str; - for(i=1;i;) { - switch(*str++) { - case '\0': - opP->error="Missing )"; - return FAIL; - case ',': i=0; break; - case '(': i++; break; - case ')': --i; break; - } - } - /* if(str[-3]==':') { - int siz; - - switch(str[-2]) { - case 'b': - case 'B': - siz=1; - break; - case 'w': - case 'W': - siz=2; - break; - case 'l': - case 'L': - siz=3; - break; - default: - opP->error="Specified size isn't :w or :l"; - return FAIL; - } - opP->con1=add_exp(beg_str,str-4); - opP->con1->e_siz=siz; - } else */ - opP->con1=add_exp(beg_str,str-2); - /* Should be offset,reg */ - if(str[-1]==',') { - i=try_index(&str,opP); - if(i==FAIL) { - opP->error="Malformed index reg"; - return FAIL; - } - } + /* if(str[-3]==':') { + int siz; + + switch(str[-2]) { + case 'b': + case 'B': + siz=1; + break; + case 'w': + case 'W': + siz=2; + break; + case 'l': + case 'L': + siz=3; + break; + default: + opP->error="Specified size isn't :w or :l"; + return FAIL; + } + opP->con1=add_exp(beg_str,str-4); + opP->con1->e_siz=siz; + } else */ + opP->con1=add_exp(beg_str,str-2); + /* Should be offset,reg */ + if(str[-1]==',') { + i=try_index(&str,opP); + if(i==FAIL) { + opP->error="Malformed index reg"; + return FAIL; + } } - /* We've now got offset) offset,reg) or reg) */ - - if (*str == '\0') { - /* Th-the-thats all folks */ - if (opP->reg == FAIL) opP->mode = AINDX; /* Other form of indirect */ - else if(opP->ireg == FAIL) opP->mode = AOFF; - else opP->mode = AINDX; - return(OK); + } + /* We've now got offset) offset,reg) or reg) */ + + if (*str == '\0') { + /* Th-the-thats all folks */ + if (opP->reg == FAIL) opP->mode = AINDX; /* Other form of indirect */ + else if(opP->ireg == FAIL) opP->mode = AOFF; + else opP->mode = AINDX; + return(OK); + } + /* Next thing had better be another @ */ + if(*str!='@' || str[1]!='(') { + opP->error = "junk after indirect"; + return(FAIL); + } + + if ((current_architecture & m68020up) == 0) { + return(FAIL); + } /* if target is not a '20 or better */ + + str+=2; + + if(opP->ireg != FAIL) { + opP->mode = APRDX; + + i = try_index(&str, opP); + if (i != FAIL) { + opP->error = "Two index registers! not allowed!"; + return(FAIL); } - /* Next thing had better be another @ */ - if(*str!='@' || str[1]!='(') { - opP->error = "junk after indirect"; + } else { + i = try_index(&str, opP); + } + + if (i == FAIL) { + char *beg_str; + + beg_str = str; + + for (i = 1; i; ) { + switch(*str++) { + case '\0': + opP->error="Missing )"; return(FAIL); + case ',': i=0; break; + case '(': i++; break; + case ')': --i; break; + } } - if ((current_architecture & m68020up) == 0) { + opP->con2=add_exp(beg_str,str-2); + + if (str[-1] == ',') { + if (opP->ireg != FAIL) { + opP->error = "Can't have two index regs"; return(FAIL); - } /* if target is not a '20 or better */ - - str+=2; - - if(opP->ireg != FAIL) { - opP->mode = APRDX; - - i = try_index(&str, opP); - if (i != FAIL) { - opP->error = "Two index registers! not allowed!"; - return(FAIL); - } - } else { - i = try_index(&str, opP); - } - - if (i == FAIL) { - char *beg_str; - - beg_str = str; - - for (i = 1; i; ) { - switch(*str++) { - case '\0': - opP->error="Missing )"; - return(FAIL); - case ',': i=0; break; - case '(': i++; break; - case ')': --i; break; - } - } - - opP->con2=add_exp(beg_str,str-2); - - if (str[-1] == ',') { - if (opP->ireg != FAIL) { - opP->error = "Can't have two index regs"; - return(FAIL); - } - - i = try_index(&str, opP); - - if (i == FAIL) { - opP->error = "malformed index reg"; - return(FAIL); - } - - opP->mode = APODX; - } else if (opP->ireg != FAIL) { - opP->mode = APRDX; - } else { - opP->mode = AMIND; - } + } + + i = try_index(&str, opP); + + if (i == FAIL) { + opP->error = "malformed index reg"; + return(FAIL); + } + + opP->mode = APODX; + } else if (opP->ireg != FAIL) { + opP->mode = APRDX; } else { - opP->mode = APODX; - } - - if(*str!='\0') { - opP->error="Junk after indirect"; - return FAIL; + opP->mode = AMIND; } - return(OK); + } else { + opP->mode = APODX; + } + + if(*str!='\0') { + opP->error="Junk after indirect"; + return FAIL; + } + return(OK); } /* m68k_ip_op() */ /* @@ -1056,106 +1056,106 @@ register struct m68k_op *opP; */ static int try_index(s,opP) -char **s; -struct m68k_op *opP; + char **s; + struct m68k_op *opP; { - register int i; - char *ss; + register int i; + char *ss; #define SKIP_W() { ss++; if (*ss==' ') ss++;} - - ss= *s; - /* SKIP_W(); */ - i=m68k_reg_parse(&ss); - if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ - *s=ss; - return FAIL; - } - opP->ireg=i; - /* SKIP_W(); */ - if(*ss==')') { - opP->isiz=0; - opP->imul=1; - SKIP_W(); - *s=ss; - return OK; - } - if(*ss!=':') { - opP->error="Missing : in index register"; - *s=ss; - return FAIL; - } + + ss= *s; + /* SKIP_W(); */ + i=m68k_reg_parse(&ss); + if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ + *s=ss; + return FAIL; + } + opP->ireg=i; + /* SKIP_W(); */ + if(*ss==')') { + opP->isiz=0; + opP->imul=1; + SKIP_W(); + *s=ss; + return OK; + } + if(*ss!=':') { + opP->error="Missing : in index register"; + *s=ss; + return FAIL; + } + SKIP_W(); + switch(*ss) { + case 'w': + case 'W': + opP->isiz=2; + break; + case 'l': + case 'L': + opP->isiz=3; + break; + default: + opP->error="Index register size spec not :w or :l"; + *s=ss; + return FAIL; + } + SKIP_W(); + if(*ss==':') { SKIP_W(); switch(*ss) { - case 'w': - case 'W': - opP->isiz=2; - break; - case 'l': - case 'L': - opP->isiz=3; - break; + case '1': + case '2': + case '4': + case '8': + opP->imul= *ss-'0'; + break; default: - opP->error="Index register size spec not :w or :l"; - *s=ss; - return FAIL; - } - SKIP_W(); - if(*ss==':') { - SKIP_W(); - switch(*ss) { - case '1': - case '2': - case '4': - case '8': - opP->imul= *ss-'0'; - break; - default: - opP->error="index multiplier not 1, 2, 4 or 8"; - *s=ss; - return FAIL; - } - SKIP_W(); - } else opP->imul=1; - if(*ss!=')') { - opP->error="Missing )"; - *s=ss; - return FAIL; + opP->error="index multiplier not 1, 2, 4 or 8"; + *s=ss; + return FAIL; } SKIP_W(); + } else opP->imul=1; + if(*ss!=')') { + opP->error="Missing )"; *s=ss; - return OK; + return FAIL; + } + SKIP_W(); + *s=ss; + return OK; } /* try_index() */ #ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */ main() { - char buf[128]; - struct m68k_op thark; - - for(;;) { - if(!gets(buf)) - break; - bzero(&thark,sizeof(thark)); - if(!m68k_ip_op(buf,&thark)) printf("FAIL:"); - if(thark.error) - printf("op1 error %s in %s\n",thark.error,buf); - printf("mode %d, reg %d, ",thark.mode,thark.reg); - if(thark.b_const) - printf("Constant: '%.*s',",1+thark.e_const-thark.b_const,thark.b_const); - printf("ireg %d, isiz %d, imul %d ",thark.ireg,thark.isiz,thark.imul); - if(thark.b_iadd) - printf("Iadd: '%.*s'",1+thark.e_iadd-thark.b_iadd,thark.b_iadd); - printf("\n"); - } - exit(0); + char buf[128]; + struct m68k_op thark; + + for(;;) { + if(!gets(buf)) + break; + bzero(&thark,sizeof(thark)); + if(!m68k_ip_op(buf,&thark)) printf("FAIL:"); + if(thark.error) + printf("op1 error %s in %s\n",thark.error,buf); + printf("mode %d, reg %d, ",thark.mode,thark.reg); + if(thark.b_const) + printf("Constant: '%.*s',",1+thark.e_const-thark.b_const,thark.b_const); + printf("ireg %d, isiz %d, imul %d ",thark.ireg,thark.isiz,thark.imul); + if(thark.b_iadd) + printf("Iadd: '%.*s'",1+thark.e_iadd-thark.b_iadd,thark.b_iadd); + printf("\n"); + } + exit(0); } #endif static struct hash_control* op_hash = NULL; /* handle of the OPCODE hash table - NULL means any use before m68k_ip_begin() - will crash */ + NULL means any use before m68k_ip_begin() + will crash */ /* @@ -1184,1191 +1184,1191 @@ static struct hash_control* op_hash = NULL; /* handle of the OPCODE hash table /* JF this function no longer returns a useful value. Sorry */ void m68k_ip (instring) -char *instring; + char *instring; { - register char *p; - register struct m68k_op *opP; - register struct m68k_incant *opcode; - register char *s; - register int tmpreg = 0, - baseo = 0, - outro = 0, - nextword; - int siz1, - siz2; - char c; - int losing; - int opsfound; - char *crack_operand(); - LITTLENUM_TYPE words[6]; - LITTLENUM_TYPE *wordp; - - if (*instring == ' ') - instring++; /* skip leading whitespace */ - - /* Scan up to end of operation-code, which MUST end in end-of-string - or exactly 1 space. */ - for (p = instring; *p != '\0'; p++) - if (*p == ' ') - break; - - - if (p == instring) { - the_ins.error = "No operator"; - the_ins.opcode[0] = NULL; - /* the_ins.numo=1; */ - return; - } - - /* p now points to the end of the opcode name, probably whitespace. - make sure the name is null terminated by clobbering the whitespace, - look it up in the hash table, then fix it back. */ - c = *p; - *p = '\0'; - opcode = (struct m68k_incant *)hash_find (op_hash, instring); - *p = c; - - if (opcode == NULL) { - the_ins.error = "Unknown operator"; - the_ins.opcode[0] = NULL; - /* the_ins.numo=1; */ - return; - } - - /* found a legitimate opcode, start matching operands */ - while (*p == ' ') ++p; - - for(opP = &the_ins.operands[0]; *p; opP++) { - - p = crack_operand(p, opP); - - if (opP->error) { - the_ins.error=opP->error; - return; - } - } + register char *p; + register struct m68k_op *opP; + register struct m68k_incant *opcode; + register char *s; + register int tmpreg = 0, + baseo = 0, + outro = 0, + nextword; + int siz1, + siz2; + char c; + int losing; + int opsfound; + char *crack_operand(); + LITTLENUM_TYPE words[6]; + LITTLENUM_TYPE *wordp; + + if (*instring == ' ') + instring++; /* skip leading whitespace */ + + /* Scan up to end of operation-code, which MUST end in end-of-string + or exactly 1 space. */ + for (p = instring; *p != '\0'; p++) + if (*p == ' ') + break; + + + if (p == instring) { + the_ins.error = "No operator"; + the_ins.opcode[0] = NULL; + /* the_ins.numo=1; */ + return; + } + + /* p now points to the end of the opcode name, probably whitespace. + make sure the name is null terminated by clobbering the whitespace, + look it up in the hash table, then fix it back. */ + c = *p; + *p = '\0'; + opcode = (struct m68k_incant *)hash_find (op_hash, instring); + *p = c; + + if (opcode == NULL) { + the_ins.error = "Unknown operator"; + the_ins.opcode[0] = NULL; + /* the_ins.numo=1; */ + return; + } + + /* found a legitimate opcode, start matching operands */ + while (*p == ' ') ++p; + + for(opP = &the_ins.operands[0]; *p; opP++) { - opsfound = opP - &the_ins.operands[0]; + p = crack_operand(p, opP); - /* This ugly hack is to support the floating pt opcodes in their standard form */ - /* Essentially, we fake a first enty of type COP#1 */ - if (opcode->m_operands[0]=='I') { - int n; - - for(n=opsfound;n>0;--n) - the_ins.operands[n]=the_ins.operands[n-1]; - - /* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */ - bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0])); - the_ins.operands[0].mode=MSCR; - the_ins.operands[0].reg=COPNUM; /* COP #1 */ - opsfound++; + if (opP->error) { + the_ins.error=opP->error; + return; } + } + + opsfound = opP - &the_ins.operands[0]; + + /* This ugly hack is to support the floating pt opcodes in their standard form */ + /* Essentially, we fake a first enty of type COP#1 */ + if (opcode->m_operands[0]=='I') { + int n; - /* We've got the operands. Find an opcode that'll accept them */ - for (losing = 0; ; ) { - /* if we didn't get the right number of ops, - or we have no common model with this pattern - then reject this pattern. */ - - if (opsfound != opcode->m_opnum - || ((opcode->m_arch & current_architecture) == 0)) { - - ++losing; - - } else { - for (s=opcode->m_operands, opP = &the_ins.operands[0]; *s && !losing; s += 2, opP++) { - /* Warning: this switch is huge! */ - /* I've tried to organize the cases into this order: - non-alpha first, then alpha by letter. lower-case goes directly - before uppercase counterpart. */ - /* Code with multiple case ...: gets sorted by the lowest case ... - it belongs to. I hope this makes sense. */ - switch(*s) { - case '!': - if (opP->mode == MSCR || opP->mode == IMMED - || opP->mode == DREG || opP->mode == AREG - || opP->mode == AINC || opP->mode == ADEC - || opP->mode == REGLST) - losing++; - break; - - case '#': - if(opP->mode!=IMMED) - losing++; - else { - long t; - - t=get_num(opP->con1,80); - if(s[1]=='b' && !isbyte(t)) - losing++; - else if(s[1]=='w' && !isword(t)) - losing++; - } - break; - - case '^': - case 'T': - if(opP->mode!=IMMED) - losing++; - break; - - case '$': - if(opP->mode==MSCR || opP->mode==AREG || - opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) - losing++; - break; - - case '%': - if(opP->mode==MSCR || opP->reg==PC || - opP->reg==ZPC || opP->mode==REGLST) - losing++; - break; - - - case '&': - if(opP->mode==MSCR || opP->mode==DREG || - opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || - opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST) - losing++; - break; - - case '*': - if(opP->mode==MSCR || opP->mode==REGLST) - losing++; - break; - - case '+': - if(opP->mode!=AINC) - losing++; - break; - - case '-': - if(opP->mode!=ADEC) - losing++; - break; - - case '/': - if(opP->mode==MSCR || opP->mode==AREG || - opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->mode==REGLST) - losing++; - break; - - case ';': - if(opP->mode==MSCR || opP->mode==AREG || opP->mode==REGLST) - losing++; - break; - - case '?': - if(opP->mode==MSCR || opP->mode==AREG || - opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->reg==PC || - opP->reg==ZPC || opP->mode==REGLST) - losing++; - break; - - case '@': - if(opP->mode==MSCR || opP->mode==AREG || - opP->mode==IMMED || opP->mode==REGLST) - losing++; - break; - - case '~': /* For now! (JF FOO is this right?) */ - if(opP->mode==MSCR || opP->mode==DREG || - opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) - losing++; - break; - - case 'A': - if(opP->mode!=AREG) - losing++; - break; - case 'a': - if (opP->mode != AINDR) { - ++losing; - } /* if not address register indirect */ - break; - case 'B': /* FOO */ - if(opP->mode!=ABSL || (flagseen['S'] && instring[0] == 'j' - && instring[1] == 'b' - && instring[2] == 's' - && instring[3] == 'r')) - losing++; - break; - - case 'C': - if(opP->mode!=MSCR || opP->reg!=CCR) - losing++; - break; - - case 'd': /* FOO This mode is a KLUDGE!! */ - if(opP->mode!=AOFF && (opP->mode!=ABSL || - opP->con1->e_beg[0]!='(' || opP->con1->e_end[0]!=')')) - losing++; - break; - - case 'D': - if(opP->mode!=DREG) - losing++; - break; - - case 'F': - if(opP->mode!=MSCR || opP->reg<(FPREG+0) || opP->reg>(FPREG+7)) - losing++; - break; - - case 'I': - if(opP->mode!=MSCR || opP->reg<COPNUM || - opP->reg>=COPNUM+7) - losing++; - break; - - case 'J': - if (opP->mode != MSCR - || opP->reg < USP - || opP->reg > URP - || cpu_of_arch(current_architecture) < m68010 /* before 68010 had none */ - || (cpu_of_arch(current_architecture) < m68020 - && opP->reg != SFC - && opP->reg != DFC - && opP->reg != USP - && opP->reg != VBR) /* 68010's had only these */ - || (cpu_of_arch(current_architecture) < m68040 - && opP->reg != SFC - && opP->reg != DFC - && opP->reg != USP - && opP->reg != VBR - && opP->reg != CACR - && opP->reg != CAAR - && opP->reg != MSP - && opP->reg != ISP) /* 680[23]0's have only these */ - || (cpu_of_arch(current_architecture) == m68040 /* 68040 has all but this */ - && opP->reg == CAAR)) { - losing++; - } /* doesn't cut it */ - break; - - case 'k': - if(opP->mode!=IMMED) - losing++; - break; - - case 'l': - case 'L': - if(opP->mode==DREG || opP->mode==AREG || opP->mode==FPREG) { - if(s[1]=='8') - losing++; - else { - opP->mode=REGLST; - opP->reg=1<<(opP->reg-DATA); - } - } else if(opP->mode!=REGLST) { - losing++; - } else if(s[1]=='8' && opP->reg&0x0FFffFF) - losing++; - else if(s[1]=='3' && opP->reg&0x7000000) - losing++; - break; - - case 'M': - if(opP->mode!=IMMED) - losing++; - else { - long t; - - t=get_num(opP->con1,80); - if(!issbyte(t) || isvar(opP->con1)) - losing++; - } - break; - - case 'O': - if(opP->mode!=DREG && opP->mode!=IMMED) - losing++; - break; - - case 'Q': - if(opP->mode!=IMMED) - losing++; - else { - long t; - - t=get_num(opP->con1,80); - if(t<1 || t>8 || isvar(opP->con1)) - losing++; - } - break; - - case 'R': - if(opP->mode!=DREG && opP->mode!=AREG) - losing++; - break; - - case 's': - if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC)) - losing++; - break; - - case 'S': - if(opP->mode!=MSCR || opP->reg!=SR) - losing++; - break; - - case 'U': - if(opP->mode!=MSCR || opP->reg!=USP) - losing++; - break; - - /* JF these are out of order. We could put them - in order if we were willing to put up with - bunches of #ifdef m68851s in the code */ -#ifndef NO_68851 - /* Memory addressing mode used by pflushr */ - case '|': - if(opP->mode==MSCR || opP->mode==DREG || - opP->mode==AREG || opP->mode==REGLST) - losing++; - break; - - case 'f': - if (opP->mode != MSCR || (opP->reg != SFC && opP->reg != DFC)) - losing++; - break; - - case 'P': - if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL && - opP->reg != VAL && opP->reg != SCC && opP->reg != AC)) - losing++; - break; - - case 'V': - if (opP->reg != VAL) - losing++; - break; - - case 'W': - if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP && - opP->reg != CRP)) - losing++; - break; - - case 'X': - if (opP->mode != MSCR || - (!(opP->reg >= BAD && opP->reg <= BAD+7) && - !(opP->reg >= BAC && opP->reg <= BAC+7))) - losing++; - break; - - case 'Y': - if (opP->reg != PSR) - losing++; - break; - - case 'Z': - if (opP->reg != PCSR) - losing++; - break; -#endif - case 'c': - if (opP->reg != NC - && opP->reg != IC - && opP->reg != DC - && opP->reg != BC) { - losing++; - } /* not a cache specifier. */ - break; - - case '_': - if (opP->mode != ABSL) { - ++losing; - } /* not absolute */ - break; - - default: - as_fatal("Internal error: Operand mode %c unknown in line %s of file \"%s\"", - *s, __LINE__, __FILE__); - } /* switch on type of operand */ - - if (losing) break; - } /* for each operand */ - } /* if immediately wrong */ - - if (!losing) { - break; - } /* got it. */ - - opcode = opcode->m_next; - - if (!opcode) { - the_ins.error = "instruction/operands mismatch"; - return; - } /* Fell off the end */ - - losing = 0; - } + for(n=opsfound;n>0;--n) + the_ins.operands[n]=the_ins.operands[n-1]; - /* now assemble it */ - - the_ins.args=opcode->m_operands; - the_ins.numargs=opcode->m_opnum; - the_ins.numo=opcode->m_codenum; - the_ins.opcode[0]=getone(opcode); - the_ins.opcode[1]=gettwo(opcode); + /* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */ + bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0])); + the_ins.operands[0].mode=MSCR; + the_ins.operands[0].reg=COPNUM; /* COP #1 */ + opsfound++; + } + + /* We've got the operands. Find an opcode that'll accept them */ + for (losing = 0; ; ) { + /* if we didn't get the right number of ops, + or we have no common model with this pattern + then reject this pattern. */ - for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) { - /* This switch is a doozy. - Watch the first step; its a big one! */ - switch(s[0]) { - - case '*': - case '~': - case '%': - case ';': - case '@': + if (opsfound != opcode->m_opnum + || ((opcode->m_arch & current_architecture) == 0)) { + + ++losing; + + } else { + for (s=opcode->m_operands, opP = &the_ins.operands[0]; *s && !losing; s += 2, opP++) { + /* Warning: this switch is huge! */ + /* I've tried to organize the cases into this order: + non-alpha first, then alpha by letter. lower-case goes directly + before uppercase counterpart. */ + /* Code with multiple case ...: gets sorted by the lowest case ... + it belongs to. I hope this makes sense. */ + switch(*s) { case '!': - case '&': - case '$': - case '?': - case '/': -#ifndef NO_68851 - case '|': -#endif - switch(opP->mode) { - case IMMED: - tmpreg=0x3c; /* 7.4 */ - if (strchr("bwl",s[1])) nextword=get_num(opP->con1,80); - else nextword=nextword=get_num(opP->con1,0); - if(isvar(opP->con1)) - add_fix(s[1],opP->con1,0); - switch(s[1]) { - case 'b': - if(!isbyte(nextword)) - opP->error="operand out of range"; - addword(nextword); - baseo=0; - break; - case 'w': - if(!isword(nextword)) - opP->error="operand out of range"; - addword(nextword); - baseo=0; - break; - case 'l': - addword(nextword>>16); - addword(nextword); - baseo=0; - break; - - case 'f': - baseo=2; - outro=8; - break; - case 'F': - baseo=4; - outro=11; - break; - case 'x': - baseo=6; - outro=15; - break; - case 'p': - baseo=6; - outro= -1; - break; - default: - as_fatal("Internal error: Can't decode %c%c in line %s of file \"%s\"", - *s, s[1], __LINE__, __FILE__); - } - if(!baseo) - break; - - /* We gotta put out some float */ - if(seg(opP->con1)!=SEG_BIG) { - int_to_gen(nextword); - gen_to_words(words,baseo,(long int)outro); - for(wordp=words;baseo--;wordp++) - addword(*wordp); - break; - } /* Its BIG */ - if(offs(opP->con1)>0) { - as_warn("Bignum assumed to be binary bit-pattern"); - if(offs(opP->con1)>baseo) { - as_warn("Bignum too big for %c format; truncated",s[1]); - offs(opP->con1)=baseo; - } - baseo-=offs(opP->con1); - for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp) - addword(*wordp); - while(baseo--) - addword(0); - break; - } - gen_to_words(words,baseo,(long)outro); - for (wordp=words;baseo--;wordp++) - addword(*wordp); - break; - case DREG: - tmpreg=opP->reg-DATA; /* 0.dreg */ - break; - case AREG: - tmpreg=0x08+opP->reg-ADDR; /* 1.areg */ - break; - case AINDR: - tmpreg=0x10+opP->reg-ADDR; /* 2.areg */ - break; - case ADEC: - tmpreg=0x20+opP->reg-ADDR; /* 4.areg */ - break; - case AINC: - tmpreg=0x18+opP->reg-ADDR; /* 3.areg */ - break; - case AOFF: - - nextword=get_num(opP->con1,80); - /* Force into index mode. Hope this works */ - - /* We do the first bit for 32-bit displacements, - and the second bit for 16 bit ones. It is - possible that we should make the default be - WORD instead of LONG, but I think that'd - break GCC, so we put up with a little - inefficiency for the sake of working output. - */ - - if( !issword(nextword) - || ( isvar(opP->con1) - && ( ( opP->con1->e_siz==0 - && flagseen['l']==0) - || opP->con1->e_siz==3))) { - - if(opP->reg==PC) - tmpreg=0x3B; /* 7.3 */ - else - tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ - if(isvar(opP->con1)) { - if(opP->reg==PC) { - add_frag(adds(opP->con1), - offs(opP->con1), - TAB(PCLEA,SZ_UNDEF)); - break; - } else { - addword(0x0170); - add_fix('l',opP->con1,1); - } - } else - addword(0x0170); - addword(nextword>>16); - } else { - if(opP->reg==PC) - tmpreg=0x3A; /* 7.2 */ - else - tmpreg=0x28+opP->reg-ADDR; /* 5.areg */ - - if(isvar(opP->con1)) { - if(opP->reg==PC) { - add_fix('w',opP->con1,1); - } else - add_fix('w',opP->con1,0); - } - } - addword(nextword); - break; - - case APODX: - case AMIND: - case APRDX: - know(current_architecture & m68020up); - /* intentional fall-through */ - case AINDX: - nextword=0; - baseo=get_num(opP->con1,80); - outro=get_num(opP->con2,80); - /* Figure out the 'addressing mode' */ - /* Also turn on the BASE_DISABLE bit, if needed */ - if(opP->reg==PC || opP->reg==ZPC) { - tmpreg=0x3b; /* 7.3 */ - if(opP->reg==ZPC) - nextword|=0x80; - } else if(opP->reg==FAIL) { - nextword|=0x80; - tmpreg=0x30; /* 6.garbage */ - } else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ - - siz1= (opP->con1) ? opP->con1->e_siz : 0; - siz2= (opP->con2) ? opP->con2->e_siz : 0; - - /* Index register stuff */ - if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) { - nextword|=(opP->ireg-DATA)<<12; - - if(opP->isiz==0 || opP->isiz==3) - nextword|=0x800; - switch(opP->imul) { - case 1: break; - case 2: nextword|=0x200; break; - case 4: nextword|=0x400; break; - case 8: nextword|=0x600; break; - default: as_fatal("failed sanity check."); - } - /* IF its simple, - GET US OUT OF HERE! */ - - /* Must be INDEX, with an index - register. Address register - cannot be ZERO-PC, and either - :b was forced, or we know - it will fit */ - if( opP->mode==AINDX - && opP->reg!=FAIL - && opP->reg!=ZPC - && ( siz1==1 - || ( issbyte(baseo) - && !isvar(opP->con1)))) { - nextword +=baseo&0xff; - addword(nextword); - if(isvar(opP->con1)) - add_fix('B',opP->con1,0); - break; - } - } else - nextword|=0x40; /* No index reg */ - - /* It aint simple */ - nextword|=0x100; - /* If the guy specified a width, we assume that - it is wide enough. Maybe it isn't. If so, we lose - */ - switch(siz1) { - case 0: - if(isvar(opP->con1) || !issword(baseo)) { - siz1=3; - nextword|=0x30; - } else if(baseo==0) - nextword|=0x10; - else { - nextword|=0x20; - siz1=2; - } - break; - case 1: - as_warn("Byte dispacement won't work. Defaulting to :w"); - case 2: - nextword|=0x20; - break; - case 3: - nextword|=0x30; - break; - } - - /* Figure out innner displacement stuff */ - if(opP->mode!=AINDX) { - switch(siz2) { - case 0: - if(isvar(opP->con2) || !issword(outro)) { - siz2=3; - nextword|=0x3; - } else if(outro==0) - nextword|=0x1; - else { - nextword|=0x2; - siz2=2; - } - break; - case 1: - as_warn("Byte dispacement won't work. Defaulting to :w"); - case 2: - nextword|=0x2; - break; - case 3: - nextword|=0x3; - break; - } - if(opP->mode==APODX) nextword|=0x04; - else if(opP->mode==AMIND) nextword|=0x40; - } - addword(nextword); - - if(isvar(opP->con1)) { - if(opP->reg==PC || opP->reg==ZPC) { - add_fix(siz1==3 ? 'l' : 'w',opP->con1,1); - opP->con1->e_exp.X_add_number+=6; - } else - add_fix(siz1==3 ? 'l' : 'w',opP->con1,0); - } - if(siz1==3) - addword(baseo>>16); - if(siz1) - addword(baseo); - - if(isvar(opP->con2)) { - if(opP->reg==PC || opP->reg==ZPC) { - add_fix(siz2==3 ? 'l' : 'w',opP->con2,1); - opP->con1->e_exp.X_add_number+=6; - } else - add_fix(siz2==3 ? 'l' : 'w',opP->con2,0); - } - if(siz2==3) - addword(outro>>16); - if(siz2) - addword(outro); - - break; - - case ABSL: - nextword=get_num(opP->con1,80); - switch(opP->con1->e_siz) { - default: - as_warn("Unknown size for absolute reference"); - case 0: - if(!isvar(opP->con1) && issword(offs(opP->con1))) { - tmpreg=0x38; /* 7.0 */ - addword(nextword); - break; - } - /* Don't generate pc relative code - on 68010 and 68000 */ - if(isvar(opP->con1) - && !subs(opP->con1) - && seg(opP->con1) == SEG_TEXT - && now_seg == SEG_TEXT - && cpu_of_arch(current_architecture) < m68020 - && !flagseen['S'] - && !strchr("~%&$?", s[0])) { - tmpreg=0x3A; /* 7.2 */ - add_frag(adds(opP->con1), - offs(opP->con1), - TAB(PCREL,SZ_UNDEF)); - break; - } - case 3: /* Fall through into long */ - if(isvar(opP->con1)) - add_fix('l',opP->con1,0); - - tmpreg=0x39; /* 7.1 mode */ - addword(nextword>>16); - addword(nextword); - break; - - case 2: /* Word */ - if(isvar(opP->con1)) - add_fix('w',opP->con1,0); - - tmpreg=0x38; /* 7.0 mode */ - addword(nextword); - break; - } - break; - case MSCR: - default: - as_bad("unknown/incorrect operand"); - /* abort(); */ - } - install_gen_operand(s[1],tmpreg); - break; - + if (opP->mode == MSCR || opP->mode == IMMED + || opP->mode == DREG || opP->mode == AREG + || opP->mode == AINC || opP->mode == ADEC + || opP->mode == REGLST) + losing++; + break; + case '#': - case '^': - switch(s[1]) { /* JF: I hate floating point! */ - case 'j': - tmpreg=70; - break; - case '8': - tmpreg=20; - break; - case 'C': - tmpreg=50; - break; - case '3': - default: - tmpreg=80; - break; - } - tmpreg=get_num(opP->con1,tmpreg); - if(isvar(opP->con1)) - add_fix(s[1],opP->con1,0); - switch(s[1]) { - case 'b': /* Danger: These do no check for - certain types of overflow. - user beware! */ - if(!isbyte(tmpreg)) - opP->error="out of range"; - insop(tmpreg); - if(isvar(opP->con1)) - the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; - break; - case 'w': - if(!isword(tmpreg)) - opP->error="out of range"; - insop(tmpreg); - if(isvar(opP->con1)) - the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; - break; - case 'l': - insop(tmpreg); /* Because of the way insop works, we put these two out backwards */ - insop(tmpreg>>16); - if(isvar(opP->con1)) - the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; - break; - case '3': - tmpreg&=0xFF; - case '8': - case 'C': - install_operand(s[1],tmpreg); - break; - default: - as_fatal("Internal error: Unknown mode #%c in line %s of file \"%s\"", s[1], __LINE__, __FILE__); - } - break; + if(opP->mode!=IMMED) + losing++; + else { + long t; + t=get_num(opP->con1,80); + if(s[1]=='b' && !isbyte(t)) + losing++; + else if(s[1]=='w' && !isword(t)) + losing++; + } + break; + + case '^': + case 'T': + if(opP->mode!=IMMED) + losing++; + break; + + case '$': + if(opP->mode==MSCR || opP->mode==AREG || + opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) + losing++; + break; + + case '%': + if(opP->mode==MSCR || opP->reg==PC || + opP->reg==ZPC || opP->mode==REGLST) + losing++; + break; + + + case '&': + if(opP->mode==MSCR || opP->mode==DREG || + opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || + opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST) + losing++; + break; + + case '*': + if(opP->mode==MSCR || opP->mode==REGLST) + losing++; + break; + case '+': + if(opP->mode!=AINC) + losing++; + break; + case '-': + if(opP->mode!=ADEC) + losing++; + break; + + case '/': + if(opP->mode==MSCR || opP->mode==AREG || + opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->mode==REGLST) + losing++; + break; + + case ';': + if(opP->mode==MSCR || opP->mode==AREG || opP->mode==REGLST) + losing++; + break; + + case '?': + if(opP->mode==MSCR || opP->mode==AREG || + opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->reg==PC || + opP->reg==ZPC || opP->mode==REGLST) + losing++; + break; + + case '@': + if(opP->mode==MSCR || opP->mode==AREG || + opP->mode==IMMED || opP->mode==REGLST) + losing++; + break; + + case '~': /* For now! (JF FOO is this right?) */ + if(opP->mode==MSCR || opP->mode==DREG || + opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) + losing++; + break; + case 'A': + if(opP->mode!=AREG) + losing++; + break; case 'a': - install_operand(s[1],opP->reg-ADDR); - break; - - case 'B': - tmpreg=get_num(opP->con1,80); - switch(s[1]) { - case 'B': - /* Needs no offsetting */ - add_fix('B',opP->con1,1); - break; - case 'W': - /* Offset the displacement to be relative to byte disp location */ - opP->con1->e_exp.X_add_number+=2; - add_fix('w',opP->con1,1); - addword(0); - break; - case 'L': - long_branch: - if (cpu_of_arch(current_architecture) < m68020) /* 68000 or 010 */ - as_warn("Can't use long branches on 68000/68010"); - the_ins.opcode[the_ins.numo-1]|=0xff; - /* Offset the displacement to be relative to byte disp location */ - opP->con1->e_exp.X_add_number+=4; - add_fix('l',opP->con1,1); - addword(0); - addword(0); - break; - case 'g': - if(subs(opP->con1)) /* We can't relax it */ - goto long_branch; - - /* This could either be a symbol, or an - absolute address. No matter, the - frag hacking will finger it out. - Not quite: it can't switch from - BRANCH to BCC68000 for the case - where opnd is absolute (it needs - to use the 68000 hack since no - conditional abs jumps). */ - if (((cpu_of_arch(current_architecture) < m68020) || (0==adds(opP->con1))) - && (the_ins.opcode[0] >= 0x6200) - && (the_ins.opcode[0] <= 0x6f00)) { - add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF)); - } else { - add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF)); - } - break; - case 'w': - if(isvar(opP->con1)) { - /* check for DBcc instruction */ - if ((the_ins.opcode[0] & 0xf0f8) ==0x50c8) { - /* size varies if patch */ - /* needed for long form */ - add_frag(adds(opP->con1),offs(opP->con1),TAB(DBCC,SZ_UNDEF)); - break; - } - - /* Don't ask! */ - opP->con1->e_exp.X_add_number+=2; - add_fix('w',opP->con1,1); - } - addword(0); - break; - case 'C': /* Fixed size LONG coproc branches */ - the_ins.opcode[the_ins.numo-1]|=0x40; - /* Offset the displacement to be relative to byte disp location */ - /* Coproc branches don't have a byte disp option, but they are - compatible with the ordinary branches, which do... */ - opP->con1->e_exp.X_add_number+=4; - add_fix('l',opP->con1,1); - addword(0); - addword(0); - break; - case 'c': /* Var size Coprocesssor branches */ - if(subs(opP->con1)) { - add_fix('l',opP->con1,1); - add_frag((symbolS *)0,(long)0,TAB(FBRANCH,LONG)); - } else if(adds(opP->con1)) { - add_frag(adds(opP->con1),offs(opP->con1),TAB(FBRANCH,SZ_UNDEF)); - } else { - /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */ - the_ins.opcode[the_ins.numo-1]|=0x40; - add_fix('l',opP->con1,1); - addword(0); - addword(4); - } - break; - default: - as_fatal("Internal error: operand type B%c unknown in line %s of file \"%s\"", - s[1], __LINE__, __FILE__); - } - break; - - case 'C': /* Ignore it */ - break; - - case 'd': /* JF this is a kludge */ - if(opP->mode==AOFF) { - install_operand('s',opP->reg-ADDR); - } else { - char *tmpP; - - tmpP=opP->con1->e_end-2; - opP->con1->e_beg++; - opP->con1->e_end-=4; /* point to the , */ - baseo=m68k_reg_parse(&tmpP); - if(baseo<ADDR+0 || baseo>ADDR+7) { - as_bad("Unknown address reg, using A0"); - baseo=0; - } else baseo-=ADDR; - install_operand('s',baseo); - } - tmpreg=get_num(opP->con1,80); - if(!issword(tmpreg)) { - as_warn("Expression out of range, using 0"); - tmpreg=0; - } - addword(tmpreg); - break; - + if (opP->mode != AINDR) { + ++losing; + } /* if not address register indirect */ + break; + case 'B': /* FOO */ + if(opP->mode!=ABSL || (flagseen['S'] && instring[0] == 'j' + && instring[1] == 'b' + && instring[2] == 's' + && instring[3] == 'r')) + losing++; + break; + + case 'C': + if(opP->mode!=MSCR || opP->reg!=CCR) + losing++; + break; + + case 'd': /* FOO This mode is a KLUDGE!! */ + if(opP->mode!=AOFF && (opP->mode!=ABSL || + opP->con1->e_beg[0]!='(' || opP->con1->e_end[0]!=')')) + losing++; + break; + case 'D': - install_operand(s[1],opP->reg-DATA); - break; - + if(opP->mode!=DREG) + losing++; + break; + case 'F': - install_operand(s[1],opP->reg-FPREG); - break; - + if(opP->mode!=MSCR || opP->reg<(FPREG+0) || opP->reg>(FPREG+7)) + losing++; + break; + case 'I': - tmpreg=1+opP->reg-COPNUM; - if(tmpreg==8) - tmpreg=0; - install_operand(s[1],tmpreg); - break; - - case 'J': /* JF foo */ - switch(opP->reg) { - case SFC: tmpreg=0x000; break; - case DFC: tmpreg=0x001; break; - case CACR: tmpreg=0x002; break; - case TC: tmpreg=0x003; break; - case ITT0: tmpreg=0x004; break; - case ITT1: tmpreg=0x005; break; - case DTT0: tmpreg=0x006; break; - case DTT1: tmpreg=0x007; break; - - case USP: tmpreg=0x800; break; - case VBR: tmpreg=0x801; break; - case CAAR: tmpreg=0x802; break; - case MSP: tmpreg=0x803; break; - case ISP: tmpreg=0x804; break; - case MMUSR: tmpreg=0x805; break; - case URP: tmpreg=0x806; break; - case SRP: tmpreg=0x807; break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - + if(opP->mode!=MSCR || opP->reg<COPNUM || + opP->reg>=COPNUM+7) + losing++; + break; + + case 'J': + if (opP->mode != MSCR + || opP->reg < USP + || opP->reg > URP + || cpu_of_arch(current_architecture) < m68010 /* before 68010 had none */ + || (cpu_of_arch(current_architecture) < m68020 + && opP->reg != SFC + && opP->reg != DFC + && opP->reg != USP + && opP->reg != VBR) /* 68010's had only these */ + || (cpu_of_arch(current_architecture) < m68040 + && opP->reg != SFC + && opP->reg != DFC + && opP->reg != USP + && opP->reg != VBR + && opP->reg != CACR + && opP->reg != CAAR + && opP->reg != MSP + && opP->reg != ISP) /* 680[23]0's have only these */ + || (cpu_of_arch(current_architecture) == m68040 /* 68040 has all but this */ + && opP->reg == CAAR)) { + losing++; + } /* doesn't cut it */ + break; + case 'k': - tmpreg=get_num(opP->con1,55); - install_operand(s[1],tmpreg&0x7f); - break; - + if(opP->mode!=IMMED) + losing++; + break; + case 'l': - tmpreg=opP->reg; - if(s[1]=='w') { - if(tmpreg&0x7FF0000) - as_bad("Floating point register in register list"); - insop(reverse_16_bits(tmpreg)); - } else { - if(tmpreg&0x700FFFF) - as_bad("Wrong register in floating-point reglist"); - install_operand(s[1],reverse_8_bits(tmpreg>>16)); - } - break; - case 'L': - tmpreg=opP->reg; - if(s[1]=='w') { - if(tmpreg&0x7FF0000) - as_bad("Floating point register in register list"); - insop(tmpreg); - } else if(s[1]=='8') { - if(tmpreg&0x0FFFFFF) - as_bad("incorrect register in reglist"); - install_operand(s[1],tmpreg>>24); - } else { - if(tmpreg&0x700FFFF) - as_bad("wrong register in floating-point reglist"); - else - install_operand(s[1],tmpreg>>16); + if(opP->mode==DREG || opP->mode==AREG || opP->mode==FPREG) { + if(s[1]=='8') + losing++; + else { + opP->mode=REGLST; + opP->reg=1<<(opP->reg-DATA); } - break; - + } else if(opP->mode!=REGLST) { + losing++; + } else if(s[1]=='8' && opP->reg&0x0FFffFF) + losing++; + else if(s[1]=='3' && opP->reg&0x7000000) + losing++; + break; + case 'M': - install_operand(s[1],get_num(opP->con1,60)); - break; + if(opP->mode!=IMMED) + losing++; + else { + long t; + t=get_num(opP->con1,80); + if(!issbyte(t) || isvar(opP->con1)) + losing++; + } + break; + case 'O': - tmpreg= (opP->mode==DREG) - ? 0x20+opP->reg-DATA - : (get_num(opP->con1,40)&0x1F); - install_operand(s[1],tmpreg); - break; - + if(opP->mode!=DREG && opP->mode!=IMMED) + losing++; + break; + case 'Q': - tmpreg=get_num(opP->con1,10); - if(tmpreg==8) - tmpreg=0; - install_operand(s[1],tmpreg); - break; + if(opP->mode!=IMMED) + losing++; + else { + long t; + t=get_num(opP->con1,80); + if(t<1 || t>8 || isvar(opP->con1)) + losing++; + } + break; + case 'R': - /* This depends on the fact that ADDR registers are - eight more than their corresponding DATA regs, so - the result will have the ADDR_REG bit set */ - install_operand(s[1],opP->reg-DATA); - break; - + if(opP->mode!=DREG && opP->mode!=AREG) + losing++; + break; + case 's': - if(opP->reg==FPI) tmpreg=0x1; - else if(opP->reg==FPS) tmpreg=0x2; - else if(opP->reg==FPC) tmpreg=0x4; - else as_fatal("failed sanity check."); - install_operand(s[1],tmpreg); - break; - - case 'S': /* Ignore it */ - break; - - case 'T': - install_operand(s[1],get_num(opP->con1,30)); - break; - - case 'U': /* Ignore it */ - break; - - case 'c': - switch (opP->reg) { - case NC: tmpreg = 0; break; - case DC: tmpreg = 1; break; - case IC: tmpreg = 2; break; - case BC: tmpreg = 3; break; - default: - as_fatal("failed sanity check"); - } /* switch on cache token */ - install_operand(s[1], tmpreg); - break; + if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC)) + losing++; + break; + + case 'S': + if(opP->mode!=MSCR || opP->reg!=SR) + losing++; + break; + + case 'U': + if(opP->mode!=MSCR || opP->reg!=USP) + losing++; + break; + + /* JF these are out of order. We could put them + in order if we were willing to put up with + bunches of #ifdef m68851s in the code */ #ifndef NO_68851 - /* JF: These are out of order, I fear. */ + /* Memory addressing mode used by pflushr */ + case '|': + if(opP->mode==MSCR || opP->mode==DREG || + opP->mode==AREG || opP->mode==REGLST) + losing++; + break; + case 'f': - switch (opP->reg) { - case SFC: - tmpreg=0; - break; - case DFC: - tmpreg=1; - break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - + if (opP->mode != MSCR || (opP->reg != SFC && opP->reg != DFC)) + losing++; + break; + case 'P': - switch(opP->reg) { - case TC: - tmpreg=0; - break; - case CAL: - tmpreg=4; - break; - case VAL: - tmpreg=5; - break; - case SCC: - tmpreg=6; - break; - case AC: - tmpreg=7; - break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - + if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL && + opP->reg != VAL && opP->reg != SCC && opP->reg != AC)) + losing++; + break; + case 'V': - if (opP->reg == VAL) - break; - as_fatal("failed sanity check."); - + if (opP->reg != VAL) + losing++; + break; + case 'W': - switch(opP->reg) { - - case DRP: - tmpreg=1; - break; - case SRP: - tmpreg=2; - break; - case CRP: - tmpreg=3; - break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - + if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP && + opP->reg != CRP)) + losing++; + break; + case 'X': - switch (opP->reg) { - case BAD: case BAD+1: case BAD+2: case BAD+3: - case BAD+4: case BAD+5: case BAD+6: case BAD+7: - tmpreg = (4 << 10) | ((opP->reg - BAD) << 2); - break; - - case BAC: case BAC+1: case BAC+2: case BAC+3: - case BAC+4: case BAC+5: case BAC+6: case BAC+7: - tmpreg = (5 << 10) | ((opP->reg - BAC) << 2); - break; - - default: - as_fatal("failed sanity check."); + if (opP->mode != MSCR || + (!(opP->reg >= BAD && opP->reg <= BAD+7) && + !(opP->reg >= BAC && opP->reg <= BAC+7))) + losing++; + break; + + case 'Y': + if (opP->reg != PSR) + losing++; + break; + + case 'Z': + if (opP->reg != PCSR) + losing++; + break; +#endif + case 'c': + if (opP->reg != NC + && opP->reg != IC + && opP->reg != DC + && opP->reg != BC) { + losing++; + } /* not a cache specifier. */ + break; + + case '_': + if (opP->mode != ABSL) { + ++losing; + } /* not absolute */ + break; + + default: + as_fatal("Internal error: Operand mode %c unknown in line %s of file \"%s\"", + *s, __LINE__, __FILE__); + } /* switch on type of operand */ + + if (losing) break; + } /* for each operand */ + } /* if immediately wrong */ + + if (!losing) { + break; + } /* got it. */ + + opcode = opcode->m_next; + + if (!opcode) { + the_ins.error = "instruction/operands mismatch"; + return; + } /* Fell off the end */ + + losing = 0; + } + + /* now assemble it */ + + the_ins.args=opcode->m_operands; + the_ins.numargs=opcode->m_opnum; + the_ins.numo=opcode->m_codenum; + the_ins.opcode[0]=getone(opcode); + the_ins.opcode[1]=gettwo(opcode); + + for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) { + /* This switch is a doozy. + Watch the first step; its a big one! */ + switch(s[0]) { + + case '*': + case '~': + case '%': + case ';': + case '@': + case '!': + case '&': + case '$': + case '?': + case '/': +#ifndef NO_68851 + case '|': +#endif + switch(opP->mode) { + case IMMED: + tmpreg=0x3c; /* 7.4 */ + if (strchr("bwl",s[1])) nextword=get_num(opP->con1,80); + else nextword=nextword=get_num(opP->con1,0); + if(isvar(opP->con1)) + add_fix(s[1],opP->con1,0); + switch(s[1]) { + case 'b': + if(!isbyte(nextword)) + opP->error="operand out of range"; + addword(nextword); + baseo=0; + break; + case 'w': + if(!isword(nextword)) + opP->error="operand out of range"; + addword(nextword); + baseo=0; + break; + case 'l': + addword(nextword>>16); + addword(nextword); + baseo=0; + break; + + case 'f': + baseo=2; + outro=8; + break; + case 'F': + baseo=4; + outro=11; + break; + case 'x': + baseo=6; + outro=15; + break; + case 'p': + baseo=6; + outro= -1; + break; + default: + as_fatal("Internal error: Can't decode %c%c in line %s of file \"%s\"", + *s, s[1], __LINE__, __FILE__); + } + if(!baseo) + break; + + /* We gotta put out some float */ + if(seg(opP->con1)!=SEG_BIG) { + int_to_gen(nextword); + gen_to_words(words,baseo,(long int)outro); + for(wordp=words;baseo--;wordp++) + addword(*wordp); + break; + } /* Its BIG */ + if(offs(opP->con1)>0) { + as_warn("Bignum assumed to be binary bit-pattern"); + if(offs(opP->con1)>baseo) { + as_warn("Bignum too big for %c format; truncated",s[1]); + offs(opP->con1)=baseo; + } + baseo-=offs(opP->con1); + for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp) + addword(*wordp); + while(baseo--) + addword(0); + break; + } + gen_to_words(words,baseo,(long)outro); + for (wordp=words;baseo--;wordp++) + addword(*wordp); + break; + case DREG: + tmpreg=opP->reg-DATA; /* 0.dreg */ + break; + case AREG: + tmpreg=0x08+opP->reg-ADDR; /* 1.areg */ + break; + case AINDR: + tmpreg=0x10+opP->reg-ADDR; /* 2.areg */ + break; + case ADEC: + tmpreg=0x20+opP->reg-ADDR; /* 4.areg */ + break; + case AINC: + tmpreg=0x18+opP->reg-ADDR; /* 3.areg */ + break; + case AOFF: + + nextword=get_num(opP->con1,80); + /* Force into index mode. Hope this works */ + + /* We do the first bit for 32-bit displacements, + and the second bit for 16 bit ones. It is + possible that we should make the default be + WORD instead of LONG, but I think that'd + break GCC, so we put up with a little + inefficiency for the sake of working output. + */ + + if( !issword(nextword) + || ( isvar(opP->con1) + && ( ( opP->con1->e_siz==0 + && flagseen['l']==0) + || opP->con1->e_siz==3))) { + + if(opP->reg==PC) + tmpreg=0x3B; /* 7.3 */ + else + tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ + if(isvar(opP->con1)) { + if(opP->reg==PC) { + add_frag(adds(opP->con1), + offs(opP->con1), + TAB(PCLEA,SZ_UNDEF)); + break; + } else { + addword(0x0170); + add_fix('l',opP->con1,1); } - install_operand(s[1], tmpreg); + } else + addword(0x0170); + addword(nextword>>16); + } else { + if(opP->reg==PC) + tmpreg=0x3A; /* 7.2 */ + else + tmpreg=0x28+opP->reg-ADDR; /* 5.areg */ + + if(isvar(opP->con1)) { + if(opP->reg==PC) { + add_fix('w',opP->con1,1); + } else + add_fix('w',opP->con1,0); + } + } + addword(nextword); + break; + + case APODX: + case AMIND: + case APRDX: + know(current_architecture & m68020up); + /* intentional fall-through */ + case AINDX: + nextword=0; + baseo=get_num(opP->con1,80); + outro=get_num(opP->con2,80); + /* Figure out the 'addressing mode' */ + /* Also turn on the BASE_DISABLE bit, if needed */ + if(opP->reg==PC || opP->reg==ZPC) { + tmpreg=0x3b; /* 7.3 */ + if(opP->reg==ZPC) + nextword|=0x80; + } else if(opP->reg==FAIL) { + nextword|=0x80; + tmpreg=0x30; /* 6.garbage */ + } else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ + + siz1= (opP->con1) ? opP->con1->e_siz : 0; + siz2= (opP->con2) ? opP->con2->e_siz : 0; + + /* Index register stuff */ + if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) { + nextword|=(opP->ireg-DATA)<<12; + + if(opP->isiz==0 || opP->isiz==3) + nextword|=0x800; + switch(opP->imul) { + case 1: break; + case 2: nextword|=0x200; break; + case 4: nextword|=0x400; break; + case 8: nextword|=0x600; break; + default: as_fatal("failed sanity check."); + } + /* IF its simple, + GET US OUT OF HERE! */ + + /* Must be INDEX, with an index + register. Address register + cannot be ZERO-PC, and either + :b was forced, or we know + it will fit */ + if( opP->mode==AINDX + && opP->reg!=FAIL + && opP->reg!=ZPC + && ( siz1==1 + || ( issbyte(baseo) + && !isvar(opP->con1)))) { + nextword +=baseo&0xff; + addword(nextword); + if(isvar(opP->con1)) + add_fix('B',opP->con1,0); break; - case 'Y': - know(opP->reg == PSR); + } + } else + nextword|=0x40; /* No index reg */ + + /* It aint simple */ + nextword|=0x100; + /* If the guy specified a width, we assume that + it is wide enough. Maybe it isn't. If so, we lose + */ + switch(siz1) { + case 0: + if(isvar(opP->con1) || !issword(baseo)) { + siz1=3; + nextword|=0x30; + } else if(baseo==0) + nextword|=0x10; + else { + nextword|=0x20; + siz1=2; + } + break; + case 1: + as_warn("Byte dispacement won't work. Defaulting to :w"); + case 2: + nextword|=0x20; + break; + case 3: + nextword|=0x30; + break; + } + + /* Figure out innner displacement stuff */ + if(opP->mode!=AINDX) { + switch(siz2) { + case 0: + if(isvar(opP->con2) || !issword(outro)) { + siz2=3; + nextword|=0x3; + } else if(outro==0) + nextword|=0x1; + else { + nextword|=0x2; + siz2=2; + } break; - case 'Z': - know(opP->reg == PCSR); + case 1: + as_warn("Byte dispacement won't work. Defaulting to :w"); + case 2: + nextword|=0x2; break; -#endif /* m68851 */ - case '_': - tmpreg=get_num(opP->con1,80); - install_operand(s[1], tmpreg); + case 3: + nextword|=0x3; break; + } + if(opP->mode==APODX) nextword|=0x04; + else if(opP->mode==AMIND) nextword|=0x40; + } + addword(nextword); + + if(isvar(opP->con1)) { + if(opP->reg==PC || opP->reg==ZPC) { + add_fix(siz1==3 ? 'l' : 'w',opP->con1,1); + opP->con1->e_exp.X_add_number+=6; + } else + add_fix(siz1==3 ? 'l' : 'w',opP->con1,0); + } + if(siz1==3) + addword(baseo>>16); + if(siz1) + addword(baseo); + + if(isvar(opP->con2)) { + if(opP->reg==PC || opP->reg==ZPC) { + add_fix(siz2==3 ? 'l' : 'w',opP->con2,1); + opP->con1->e_exp.X_add_number+=6; + } else + add_fix(siz2==3 ? 'l' : 'w',opP->con2,0); + } + if(siz2==3) + addword(outro>>16); + if(siz2) + addword(outro); + + break; + + case ABSL: + nextword=get_num(opP->con1,80); + switch(opP->con1->e_siz) { default: - as_fatal("Internal error: Operand type %c unknown in line %s of file \"%s\"", s[0], __LINE__, __FILE__); + as_warn("Unknown size for absolute reference"); + case 0: + if(!isvar(opP->con1) && issword(offs(opP->con1))) { + tmpreg=0x38; /* 7.0 */ + addword(nextword); + break; + } + /* Don't generate pc relative code + on 68010 and 68000 */ + if(isvar(opP->con1) + && !subs(opP->con1) + && seg(opP->con1) == SEG_TEXT + && now_seg == SEG_TEXT + && cpu_of_arch(current_architecture) < m68020 + && !flagseen['S'] + && !strchr("~%&$?", s[0])) { + tmpreg=0x3A; /* 7.2 */ + add_frag(adds(opP->con1), + offs(opP->con1), + TAB(PCREL,SZ_UNDEF)); + break; + } + case 3: /* Fall through into long */ + if(isvar(opP->con1)) + add_fix('l',opP->con1,0); + + tmpreg=0x39; /* 7.1 mode */ + addword(nextword>>16); + addword(nextword); + break; + + case 2: /* Word */ + if(isvar(opP->con1)) + add_fix('w',opP->con1,0); + + tmpreg=0x38; /* 7.0 mode */ + addword(nextword); + break; + } + break; + case MSCR: + default: + as_bad("unknown/incorrect operand"); + /* abort(); */ + } + install_gen_operand(s[1],tmpreg); + break; + + case '#': + case '^': + switch(s[1]) { /* JF: I hate floating point! */ + case 'j': + tmpreg=70; + break; + case '8': + tmpreg=20; + break; + case 'C': + tmpreg=50; + break; + case '3': + default: + tmpreg=80; + break; + } + tmpreg=get_num(opP->con1,tmpreg); + if(isvar(opP->con1)) + add_fix(s[1],opP->con1,0); + switch(s[1]) { + case 'b': /* Danger: These do no check for + certain types of overflow. + user beware! */ + if(!isbyte(tmpreg)) + opP->error="out of range"; + insop(tmpreg); + if(isvar(opP->con1)) + the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; + break; + case 'w': + if(!isword(tmpreg)) + opP->error="out of range"; + insop(tmpreg); + if(isvar(opP->con1)) + the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; + break; + case 'l': + insop(tmpreg); /* Because of the way insop works, we put these two out backwards */ + insop(tmpreg>>16); + if(isvar(opP->con1)) + the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; + break; + case '3': + tmpreg&=0xFF; + case '8': + case 'C': + install_operand(s[1],tmpreg); + break; + default: + as_fatal("Internal error: Unknown mode #%c in line %s of file \"%s\"", s[1], __LINE__, __FILE__); + } + break; + + case '+': + case '-': + case 'A': + case 'a': + install_operand(s[1],opP->reg-ADDR); + break; + + case 'B': + tmpreg=get_num(opP->con1,80); + switch(s[1]) { + case 'B': + /* Needs no offsetting */ + add_fix('B',opP->con1,1); + break; + case 'W': + /* Offset the displacement to be relative to byte disp location */ + opP->con1->e_exp.X_add_number+=2; + add_fix('w',opP->con1,1); + addword(0); + break; + case 'L': + long_branch: + if (cpu_of_arch(current_architecture) < m68020) /* 68000 or 010 */ + as_warn("Can't use long branches on 68000/68010"); + the_ins.opcode[the_ins.numo-1]|=0xff; + /* Offset the displacement to be relative to byte disp location */ + opP->con1->e_exp.X_add_number+=4; + add_fix('l',opP->con1,1); + addword(0); + addword(0); + break; + case 'g': + if(subs(opP->con1)) /* We can't relax it */ + goto long_branch; + + /* This could either be a symbol, or an + absolute address. No matter, the + frag hacking will finger it out. + Not quite: it can't switch from + BRANCH to BCC68000 for the case + where opnd is absolute (it needs + to use the 68000 hack since no + conditional abs jumps). */ + if (((cpu_of_arch(current_architecture) < m68020) || (0==adds(opP->con1))) + && (the_ins.opcode[0] >= 0x6200) + && (the_ins.opcode[0] <= 0x6f00)) { + add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF)); + } else { + add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF)); + } + break; + case 'w': + if(isvar(opP->con1)) { + /* check for DBcc instruction */ + if ((the_ins.opcode[0] & 0xf0f8) ==0x50c8) { + /* size varies if patch */ + /* needed for long form */ + add_frag(adds(opP->con1),offs(opP->con1),TAB(DBCC,SZ_UNDEF)); + break; + } + + /* Don't ask! */ + opP->con1->e_exp.X_add_number+=2; + add_fix('w',opP->con1,1); + } + addword(0); + break; + case 'C': /* Fixed size LONG coproc branches */ + the_ins.opcode[the_ins.numo-1]|=0x40; + /* Offset the displacement to be relative to byte disp location */ + /* Coproc branches don't have a byte disp option, but they are + compatible with the ordinary branches, which do... */ + opP->con1->e_exp.X_add_number+=4; + add_fix('l',opP->con1,1); + addword(0); + addword(0); + break; + case 'c': /* Var size Coprocesssor branches */ + if(subs(opP->con1)) { + add_fix('l',opP->con1,1); + add_frag((symbolS *)0,(long)0,TAB(FBRANCH,LONG)); + } else if(adds(opP->con1)) { + add_frag(adds(opP->con1),offs(opP->con1),TAB(FBRANCH,SZ_UNDEF)); + } else { + /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */ + the_ins.opcode[the_ins.numo-1]|=0x40; + add_fix('l',opP->con1,1); + addword(0); + addword(4); } + break; + default: + as_fatal("Internal error: operand type B%c unknown in line %s of file \"%s\"", + s[1], __LINE__, __FILE__); + } + break; + + case 'C': /* Ignore it */ + break; + + case 'd': /* JF this is a kludge */ + if(opP->mode==AOFF) { + install_operand('s',opP->reg-ADDR); + } else { + char *tmpP; + + tmpP=opP->con1->e_end-2; + opP->con1->e_beg++; + opP->con1->e_end-=4; /* point to the , */ + baseo=m68k_reg_parse(&tmpP); + if(baseo<ADDR+0 || baseo>ADDR+7) { + as_bad("Unknown address reg, using A0"); + baseo=0; + } else baseo-=ADDR; + install_operand('s',baseo); + } + tmpreg=get_num(opP->con1,80); + if(!issword(tmpreg)) { + as_warn("Expression out of range, using 0"); + tmpreg=0; + } + addword(tmpreg); + break; + + case 'D': + install_operand(s[1],opP->reg-DATA); + break; + + case 'F': + install_operand(s[1],opP->reg-FPREG); + break; + + case 'I': + tmpreg=1+opP->reg-COPNUM; + if(tmpreg==8) + tmpreg=0; + install_operand(s[1],tmpreg); + break; + + case 'J': /* JF foo */ + switch(opP->reg) { + case SFC: tmpreg=0x000; break; + case DFC: tmpreg=0x001; break; + case CACR: tmpreg=0x002; break; + case TC: tmpreg=0x003; break; + case ITT0: tmpreg=0x004; break; + case ITT1: tmpreg=0x005; break; + case DTT0: tmpreg=0x006; break; + case DTT1: tmpreg=0x007; break; + + case USP: tmpreg=0x800; break; + case VBR: tmpreg=0x801; break; + case CAAR: tmpreg=0x802; break; + case MSP: tmpreg=0x803; break; + case ISP: tmpreg=0x804; break; + case MMUSR: tmpreg=0x805; break; + case URP: tmpreg=0x806; break; + case SRP: tmpreg=0x807; break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'k': + tmpreg=get_num(opP->con1,55); + install_operand(s[1],tmpreg&0x7f); + break; + + case 'l': + tmpreg=opP->reg; + if(s[1]=='w') { + if(tmpreg&0x7FF0000) + as_bad("Floating point register in register list"); + insop(reverse_16_bits(tmpreg)); + } else { + if(tmpreg&0x700FFFF) + as_bad("Wrong register in floating-point reglist"); + install_operand(s[1],reverse_8_bits(tmpreg>>16)); + } + break; + + case 'L': + tmpreg=opP->reg; + if(s[1]=='w') { + if(tmpreg&0x7FF0000) + as_bad("Floating point register in register list"); + insop(tmpreg); + } else if(s[1]=='8') { + if(tmpreg&0x0FFFFFF) + as_bad("incorrect register in reglist"); + install_operand(s[1],tmpreg>>24); + } else { + if(tmpreg&0x700FFFF) + as_bad("wrong register in floating-point reglist"); + else + install_operand(s[1],tmpreg>>16); + } + break; + + case 'M': + install_operand(s[1],get_num(opP->con1,60)); + break; + + case 'O': + tmpreg= (opP->mode==DREG) + ? 0x20+opP->reg-DATA + : (get_num(opP->con1,40)&0x1F); + install_operand(s[1],tmpreg); + break; + + case 'Q': + tmpreg=get_num(opP->con1,10); + if(tmpreg==8) + tmpreg=0; + install_operand(s[1],tmpreg); + break; + + case 'R': + /* This depends on the fact that ADDR registers are + eight more than their corresponding DATA regs, so + the result will have the ADDR_REG bit set */ + install_operand(s[1],opP->reg-DATA); + break; + + case 's': + if(opP->reg==FPI) tmpreg=0x1; + else if(opP->reg==FPS) tmpreg=0x2; + else if(opP->reg==FPC) tmpreg=0x4; + else as_fatal("failed sanity check."); + install_operand(s[1],tmpreg); + break; + + case 'S': /* Ignore it */ + break; + + case 'T': + install_operand(s[1],get_num(opP->con1,30)); + break; + + case 'U': /* Ignore it */ + break; + + case 'c': + switch (opP->reg) { + case NC: tmpreg = 0; break; + case DC: tmpreg = 1; break; + case IC: tmpreg = 2; break; + case BC: tmpreg = 3; break; + default: + as_fatal("failed sanity check"); + } /* switch on cache token */ + install_operand(s[1], tmpreg); + break; +#ifndef NO_68851 + /* JF: These are out of order, I fear. */ + case 'f': + switch (opP->reg) { + case SFC: + tmpreg=0; + break; + case DFC: + tmpreg=1; + break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'P': + switch(opP->reg) { + case TC: + tmpreg=0; + break; + case CAL: + tmpreg=4; + break; + case VAL: + tmpreg=5; + break; + case SCC: + tmpreg=6; + break; + case AC: + tmpreg=7; + break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'V': + if (opP->reg == VAL) + break; + as_fatal("failed sanity check."); + + case 'W': + switch(opP->reg) { + + case DRP: + tmpreg=1; + break; + case SRP: + tmpreg=2; + break; + case CRP: + tmpreg=3; + break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'X': + switch (opP->reg) { + case BAD: case BAD+1: case BAD+2: case BAD+3: + case BAD+4: case BAD+5: case BAD+6: case BAD+7: + tmpreg = (4 << 10) | ((opP->reg - BAD) << 2); + break; + + case BAC: case BAC+1: case BAC+2: case BAC+3: + case BAC+4: case BAC+5: case BAC+6: case BAC+7: + tmpreg = (5 << 10) | ((opP->reg - BAC) << 2); + break; + + default: + as_fatal("failed sanity check."); + } + install_operand(s[1], tmpreg); + break; + case 'Y': + know(opP->reg == PSR); + break; + case 'Z': + know(opP->reg == PCSR); + break; +#endif /* m68851 */ + case '_': + tmpreg=get_num(opP->con1,80); + install_operand(s[1], tmpreg); + break; + default: + as_fatal("Internal error: Operand type %c unknown in line %s of file \"%s\"", s[0], __LINE__, __FILE__); } - /* By the time whe get here (FINALLY) the_ins contains the complete - instruction, ready to be emitted. . . */ + } + /* By the time whe get here (FINALLY) the_ins contains the complete + instruction, ready to be emitted. . . */ } /* m68k_ip() */ /* @@ -2378,211 +2378,211 @@ char *instring; * | <empty> * ; * - + * The idea here must be to scan in a set of registers but I don't * understand it. Looks awfully sloppy to me but I don't have any doc on * this format so... - + * * */ static int get_regs(i,str,opP) -int i; -struct m68k_op *opP; -char *str; + int i; + struct m68k_op *opP; + char *str; { - /* 26, 25, 24, 23-16, 15-8, 0-7 */ - /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */ - unsigned long cur_regs = 0; - int reg1, - reg2; - + /* 26, 25, 24, 23-16, 15-8, 0-7 */ + /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */ + unsigned long cur_regs = 0; + int reg1, + reg2; + #define ADD_REG(x) { if(x==FPI) cur_regs|=(1<<24);\ - else if(x==FPS) cur_regs|=(1<<25);\ - else if(x==FPC) cur_regs|=(1<<26);\ - else cur_regs|=(1<<(x-1)); } - - reg1=i; - for(;;) { - if(*str=='/') { - ADD_REG(reg1); - str++; - } else if(*str=='-') { - str++; - reg2=m68k_reg_parse(&str); - if(reg2<DATA || reg2>=FPREG+8 || reg1==FPI || reg1==FPS || reg1==FPC) { - opP->error="unknown register in register list"; - return FAIL; - } - while(reg1<=reg2) { - ADD_REG(reg1); - reg1++; - } - if(*str=='\0') - break; - } else if(*str=='\0') { - ADD_REG(reg1); - break; - } else { - opP->error="unknow character in register list"; - return FAIL; - } -/* DJA -- Bug Fix. Did't handle d1-d2/a1 until the following instruction was added */ - if (*str=='/') - str ++; - reg1=m68k_reg_parse(&str); - if((reg1<DATA || reg1>=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) { - opP->error="unknown register in register list"; - return FAIL; - } +else if(x==FPS) cur_regs|=(1<<25);\ +else if(x==FPC) cur_regs|=(1<<26);\ +else cur_regs|=(1<<(x-1)); } + + reg1=i; + for(;;) { + if(*str=='/') { + ADD_REG(reg1); + str++; + } else if(*str=='-') { + str++; + reg2=m68k_reg_parse(&str); + if(reg2<DATA || reg2>=FPREG+8 || reg1==FPI || reg1==FPS || reg1==FPC) { + opP->error="unknown register in register list"; + return FAIL; + } + while(reg1<=reg2) { + ADD_REG(reg1); + reg1++; + } + if(*str=='\0') + break; + } else if(*str=='\0') { + ADD_REG(reg1); + break; + } else { + opP->error="unknow character in register list"; + return FAIL; } - opP->reg=cur_regs; - return OK; + /* DJA -- Bug Fix. Did't handle d1-d2/a1 until the following instruction was added */ + if (*str=='/') + str ++; + reg1=m68k_reg_parse(&str); + if((reg1<DATA || reg1>=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) { + opP->error="unknown register in register list"; + return FAIL; + } + } + opP->reg=cur_regs; + return OK; } /* get_regs() */ static int reverse_16_bits(in) -int in; + int in; { - int out=0; - int n; - - static int mask[16] = { -0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, -0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000 + int out=0; + int n; + + static int mask[16] = { + 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, + 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000 }; - for(n=0;n<16;n++) { - if(in&mask[n]) - out|=mask[15-n]; - } - return out; + for(n=0;n<16;n++) { + if(in&mask[n]) + out|=mask[15-n]; + } + return out; } /* reverse_16_bits() */ static int reverse_8_bits(in) -int in; + int in; { - int out=0; - int n; - - static int mask[8] = { -0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, - }; - - for(n=0;n<8;n++) { - if(in&mask[n]) - out|=mask[7-n]; - } - return out; + int out=0; + int n; + + static int mask[8] = { + 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, + }; + + for(n=0;n<8;n++) { + if(in&mask[n]) + out|=mask[7-n]; + } + return out; } /* reverse_8_bits() */ static void install_operand(mode,val) -int mode; -int val; + int mode; + int val; { - switch(mode) { - case 's': - the_ins.opcode[0]|=val & 0xFF; /* JF FF is for M kludge */ - break; - case 'd': - the_ins.opcode[0]|=val<<9; - break; - case '1': - the_ins.opcode[1]|=val<<12; - break; - case '2': - the_ins.opcode[1]|=val<<6; - break; - case '3': - the_ins.opcode[1]|=val; - break; - case '4': - the_ins.opcode[2]|=val<<12; - break; - case '5': - the_ins.opcode[2]|=val<<6; - break; - case '6': - /* DANGER! This is a hack to force cas2l and cas2w cmds - to be three words long! */ - the_ins.numo++; - the_ins.opcode[2]|=val; - break; - case '7': - the_ins.opcode[1]|=val<<7; - break; - case '8': - the_ins.opcode[1]|=val<<10; - break; + switch(mode) { + case 's': + the_ins.opcode[0]|=val & 0xFF; /* JF FF is for M kludge */ + break; + case 'd': + the_ins.opcode[0]|=val<<9; + break; + case '1': + the_ins.opcode[1]|=val<<12; + break; + case '2': + the_ins.opcode[1]|=val<<6; + break; + case '3': + the_ins.opcode[1]|=val; + break; + case '4': + the_ins.opcode[2]|=val<<12; + break; + case '5': + the_ins.opcode[2]|=val<<6; + break; + case '6': + /* DANGER! This is a hack to force cas2l and cas2w cmds + to be three words long! */ + the_ins.numo++; + the_ins.opcode[2]|=val; + break; + case '7': + the_ins.opcode[1]|=val<<7; + break; + case '8': + the_ins.opcode[1]|=val<<10; + break; #ifndef NO_68851 - case '9': - the_ins.opcode[1]|=val<<5; - break; + case '9': + the_ins.opcode[1]|=val<<5; + break; #endif - - case 't': - the_ins.opcode[1]|=(val<<10)|(val<<7); - break; - case 'D': - the_ins.opcode[1]|=(val<<12)|val; - break; - case 'g': - the_ins.opcode[0]|=val=0xff; - break; - case 'i': - the_ins.opcode[0]|=val<<9; - break; - case 'C': - the_ins.opcode[1]|=val; - break; - case 'j': - the_ins.opcode[1]|=val; - the_ins.numo++; /* What a hack */ - break; - case 'k': - the_ins.opcode[1]|=val<<4; - break; - case 'b': - case 'w': - case 'l': - break; - case 'e': - the_ins.opcode[0] |= (val << 6); - break; - case 'L': - the_ins.opcode[1] = (val >> 16); - the_ins.opcode[2] = val & 0xffff; - break; - case 'c': - default: - as_fatal("failed sanity check."); - } + + case 't': + the_ins.opcode[1]|=(val<<10)|(val<<7); + break; + case 'D': + the_ins.opcode[1]|=(val<<12)|val; + break; + case 'g': + the_ins.opcode[0]|=val=0xff; + break; + case 'i': + the_ins.opcode[0]|=val<<9; + break; + case 'C': + the_ins.opcode[1]|=val; + break; + case 'j': + the_ins.opcode[1]|=val; + the_ins.numo++; /* What a hack */ + break; + case 'k': + the_ins.opcode[1]|=val<<4; + break; + case 'b': + case 'w': + case 'l': + break; + case 'e': + the_ins.opcode[0] |= (val << 6); + break; + case 'L': + the_ins.opcode[1] = (val >> 16); + the_ins.opcode[2] = val & 0xffff; + break; + case 'c': + default: + as_fatal("failed sanity check."); + } } /* install_operand() */ static void install_gen_operand(mode,val) -int mode; -int val; + int mode; + int val; { - switch(mode) { - case 's': - the_ins.opcode[0]|=val; - break; - case 'd': - /* This is a kludge!!! */ - the_ins.opcode[0]|=(val&0x07)<<9|(val&0x38)<<3; - break; - case 'b': - case 'w': - case 'l': - case 'f': - case 'F': - case 'x': - case 'p': - the_ins.opcode[0]|=val; - break; - /* more stuff goes here */ - default: - as_fatal("failed sanity check."); - } + switch(mode) { + case 's': + the_ins.opcode[0]|=val; + break; + case 'd': + /* This is a kludge!!! */ + the_ins.opcode[0]|=(val&0x07)<<9|(val&0x38)<<3; + break; + case 'b': + case 'w': + case 'l': + case 'f': + case 'F': + case 'x': + case 'p': + the_ins.opcode[0]|=val; + break; + /* more stuff goes here */ + default: + as_fatal("failed sanity check."); + } } /* install_gen_operand() */ /* @@ -2591,304 +2591,304 @@ int val; */ static char *crack_operand(str,opP) -register char *str; -register struct m68k_op *opP; + register char *str; + register struct m68k_op *opP; { - register int parens; - register int c; - register char *beg_str; - - if(!str) { - return str; - } - beg_str=str; - for(parens=0;*str && (parens>0 || notend(str));str++) { - if(*str=='(') parens++; - else if(*str==')') { - if(!parens) { /* ERROR */ - opP->error="Extra )"; - return str; - } - --parens; - } - } - if(!*str && parens) { /* ERROR */ - opP->error="Missing )"; - return str; - } - c= *str; - *str='\0'; - if(m68k_ip_op(beg_str,opP)==FAIL) { - *str=c; + register int parens; + register int c; + register char *beg_str; + + if(!str) { + return str; + } + beg_str=str; + for(parens=0;*str && (parens>0 || notend(str));str++) { + if(*str=='(') parens++; + else if(*str==')') { + if(!parens) { /* ERROR */ + opP->error="Extra )"; return str; + } + --parens; } + } + if(!*str && parens) { /* ERROR */ + opP->error="Missing )"; + return str; + } + c= *str; + *str='\0'; + if(m68k_ip_op(beg_str,opP)==FAIL) { *str=c; - if(c=='}') - c= *++str; /* JF bitfield hack */ - if(c) { - c= *++str; - if(!c) - as_bad("Missing operand"); - } return str; + } + *str=c; + if(c=='}') + c= *++str; /* JF bitfield hack */ + if(c) { + c= *++str; + if(!c) + as_bad("Missing operand"); + } + return str; } /* See the comment up above where the #define notend(... is */ #if 0 notend(s) -char *s; + char *s; { - if(*s==',') return 0; - if(*s=='{' || *s=='}') - return 0; - if(*s!=':') return 1; - /* This kludge here is for the division cmd, which is a kludge */ - if(index("aAdD#",s[1])) return 0; - return 1; + if(*s==',') return 0; + if(*s=='{' || *s=='}') + return 0; + if(*s!=':') return 1; + /* This kludge here is for the division cmd, which is a kludge */ + if(index("aAdD#",s[1])) return 0; + return 1; } #endif /* This is the guts of the machine-dependent assembler. STR points to a machine dependent instruction. This function is supposed to emit the frags/bytes it assembles to. - */ + */ void -md_assemble(str) + md_assemble(str) char *str; { - char *er; - short *fromP; - char *toP = NULL; - int m,n = 0; - char *to_beg_P; - int shorts_this_frag; - - - if (current_architecture == 0) { - current_architecture = (m68020 + char *er; + short *fromP; + char *toP = NULL; + int m,n = 0; + char *to_beg_P; + int shorts_this_frag; + + + if (current_architecture == 0) { + current_architecture = (m68020 #ifndef NO_68881 - | m68881 + | m68881 #endif #ifndef NO_68851 - | m68851 + | m68851 #endif - ); - } /* default current_architecture */ - - bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */ - m68k_ip(str); - er=the_ins.error; - if(!er) { - for(n=the_ins.numargs;n;--n) - if(the_ins.operands[n].error) { - er=the_ins.operands[n].error; - break; - } - } - if(er) { - as_bad("\"%s\" -- Statement '%s' ignored",er,str); - return; - } - - if(the_ins.nfrag==0) { /* No frag hacking involved; just put it out */ - toP=frag_more(2*the_ins.numo); - fromP= &the_ins.opcode[0]; - for(m=the_ins.numo;m;--m) { - md_number_to_chars(toP,(long)(*fromP),2); - toP+=2; - fromP++; - } - /* put out symbol-dependent info */ - for(m=0;m<the_ins.nrel;m++) { - switch(the_ins.reloc[m].wid) { - case 'B': - n=1; - break; - case 'b': - n=1; - break; - case '3': - n=2; - break; - case 'w': - n=2; - break; - case 'l': - n=4; - break; - default: - as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins.reloc[m].wid); - } - - fix_new(frag_now, - (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, - n, - the_ins.reloc[m].add, - the_ins.reloc[m].sub, - the_ins.reloc[m].off, - the_ins.reloc[m].pcrel, - NO_RELOC); - } - return; + ); + } /* default current_architecture */ + + bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */ + m68k_ip(str); + er=the_ins.error; + if(!er) { + for(n=the_ins.numargs;n;--n) + if(the_ins.operands[n].error) { + er=the_ins.operands[n].error; + break; + } + } + if(er) { + as_bad("\"%s\" -- Statement '%s' ignored",er,str); + return; + } + + if(the_ins.nfrag==0) { /* No frag hacking involved; just put it out */ + toP=frag_more(2*the_ins.numo); + fromP= &the_ins.opcode[0]; + for(m=the_ins.numo;m;--m) { + md_number_to_chars(toP,(long)(*fromP),2); + toP+=2; + fromP++; } - - /* There's some frag hacking */ - for(n=0,fromP= &the_ins.opcode[0];n<the_ins.nfrag;n++) { - int wid; - - if(n==0) wid=2*the_ins.fragb[n].fragoff; - else wid=2*(the_ins.numo-the_ins.fragb[n-1].fragoff); - toP=frag_more(wid); - to_beg_P=toP; - shorts_this_frag=0; - for(m=wid/2;m;--m) { - md_number_to_chars(toP,(long)(*fromP),2); - toP+=2; - fromP++; - shorts_this_frag++; - } - for(m=0;m<the_ins.nrel;m++) { - if((the_ins.reloc[m].n)>= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */) { - the_ins.reloc[m].n-= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */; - break; - } - wid=the_ins.reloc[m].wid; - if(wid==0) - continue; - the_ins.reloc[m].wid=0; - wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; - - fix_new(frag_now, - (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, - wid, - the_ins.reloc[m].add, - the_ins.reloc[m].sub, - the_ins.reloc[m].off, - the_ins.reloc[m].pcrel, - NO_RELOC); - } - /* know(the_ins.fragb[n].fadd); */ - (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty), - the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P); + /* put out symbol-dependent info */ + for(m=0;m<the_ins.nrel;m++) { + switch(the_ins.reloc[m].wid) { + case 'B': + n=1; + break; + case 'b': + n=1; + break; + case '3': + n=2; + break; + case 'w': + n=2; + break; + case 'l': + n=4; + break; + default: + as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins.reloc[m].wid); + } + + fix_new(frag_now, + (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, + n, + the_ins.reloc[m].add, + the_ins.reloc[m].sub, + the_ins.reloc[m].off, + the_ins.reloc[m].pcrel, + NO_RELOC); } - n=(the_ins.numo-the_ins.fragb[n-1].fragoff); + return; + } + + /* There's some frag hacking */ + for(n=0,fromP= &the_ins.opcode[0];n<the_ins.nfrag;n++) { + int wid; + + if(n==0) wid=2*the_ins.fragb[n].fragoff; + else wid=2*(the_ins.numo-the_ins.fragb[n-1].fragoff); + toP=frag_more(wid); + to_beg_P=toP; shorts_this_frag=0; - if(n) { - toP=frag_more(n*sizeof(short)); - while(n--) { - md_number_to_chars(toP,(long)(*fromP),2); - toP+=2; - fromP++; - shorts_this_frag++; - } + for(m=wid/2;m;--m) { + md_number_to_chars(toP,(long)(*fromP),2); + toP+=2; + fromP++; + shorts_this_frag++; } for(m=0;m<the_ins.nrel;m++) { - int wid; - - wid=the_ins.reloc[m].wid; - if(wid==0) - continue; - the_ins.reloc[m].wid=0; - wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; - - fix_new(frag_now, - (the_ins.reloc[m].n + toP-frag_now->fr_literal)-/* the_ins.numo */ shorts_this_frag*2, + if((the_ins.reloc[m].n)>= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */) { + the_ins.reloc[m].n-= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */; + break; + } + wid=the_ins.reloc[m].wid; + if(wid==0) + continue; + the_ins.reloc[m].wid=0; + wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; + + fix_new(frag_now, + (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, wid, the_ins.reloc[m].add, the_ins.reloc[m].sub, the_ins.reloc[m].off, the_ins.reloc[m].pcrel, - NO_RELOC); + NO_RELOC); } + /* know(the_ins.fragb[n].fadd); */ + (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty), + the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P); + } + n=(the_ins.numo-the_ins.fragb[n-1].fragoff); + shorts_this_frag=0; + if(n) { + toP=frag_more(n*sizeof(short)); + while(n--) { + md_number_to_chars(toP,(long)(*fromP),2); + toP+=2; + fromP++; + shorts_this_frag++; + } + } + for(m=0;m<the_ins.nrel;m++) { + int wid; + + wid=the_ins.reloc[m].wid; + if(wid==0) + continue; + the_ins.reloc[m].wid=0; + wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; + + fix_new(frag_now, + (the_ins.reloc[m].n + toP-frag_now->fr_literal)-/* the_ins.numo */ shorts_this_frag*2, + wid, + the_ins.reloc[m].add, + the_ins.reloc[m].sub, + the_ins.reloc[m].off, + the_ins.reloc[m].pcrel, + NO_RELOC); + } } /* This function is called once, at assembler startup time. This should set up all the tables, etc that the MD part of the assembler needs - */ + */ void -md_begin() + md_begin() { -/* - * md_begin -- set up hash tables with 68000 instructions. - * similar to what the vax assembler does. ---phr - */ - /* RMS claims the thing to do is take the m68k-opcode.h table, and make - a copy of it at runtime, adding in the information we want but isn't - there. I think it'd be better to have an awk script hack the table - at compile time. Or even just xstr the table and use it as-is. But - my lord ghod hath spoken, so we do it this way. Excuse the ugly var - names. */ - - register const struct m68k_opcode *ins; - register struct m68k_incant *hack, - *slak; - register char *retval = 0; /* empty string, or error msg text */ - register unsigned int i; - register char c; - - if ((op_hash = hash_new()) == NULL) - as_fatal("Virtual memory exhausted"); - - obstack_begin(&robyn,4000); - for (ins = m68k_opcodes; ins < endop; ins++) { - hack=slak=(struct m68k_incant *)obstack_alloc(&robyn,sizeof(struct m68k_incant)); - do { - /* we *could* ignore insns that don't match our - arch here but just leaving them out of the - hash. */ - slak->m_operands=ins->args; - slak->m_opnum=strlen(slak->m_operands)/2; - slak->m_arch = ins->arch; - slak->m_opcode=ins->opcode; - /* This is kludgey */ - slak->m_codenum=((ins->match)&0xffffL) ? 2 : 1; - if((ins+1)!=endop && !strcmp(ins->name,(ins+1)->name)) { - slak->m_next=(struct m68k_incant *) obstack_alloc(&robyn,sizeof(struct m68k_incant)); - ins++; - } else - slak->m_next=0; - slak=slak->m_next; - } while(slak); - - retval = hash_insert (op_hash, ins->name,(char *)hack); - /* Didn't his mommy tell him about null pointers? */ - if(retval && *retval) - as_fatal("Internal Error: Can't hash %s: %s",ins->name,retval); - } - - for (i = 0; i < sizeof(mklower_table) ; i++) - mklower_table[i] = (isupper(c = (char) i)) ? tolower(c) : c; - - for (i = 0 ; i < sizeof(notend_table) ; i++) { - notend_table[i] = 0; - alt_notend_table[i] = 0; - } - notend_table[','] = 1; - notend_table['{'] = 1; - notend_table['}'] = 1; - alt_notend_table['a'] = 1; - alt_notend_table['A'] = 1; - alt_notend_table['d'] = 1; - alt_notend_table['D'] = 1; - alt_notend_table['#'] = 1; - alt_notend_table['f'] = 1; - alt_notend_table['F'] = 1; + /* + * md_begin -- set up hash tables with 68000 instructions. + * similar to what the vax assembler does. ---phr + */ + /* RMS claims the thing to do is take the m68k-opcode.h table, and make + a copy of it at runtime, adding in the information we want but isn't + there. I think it'd be better to have an awk script hack the table + at compile time. Or even just xstr the table and use it as-is. But + my lord ghod hath spoken, so we do it this way. Excuse the ugly var + names. */ + + register const struct m68k_opcode *ins; + register struct m68k_incant *hack, + *slak; + register char *retval = 0; /* empty string, or error msg text */ + register unsigned int i; + register char c; + + if ((op_hash = hash_new()) == NULL) + as_fatal("Virtual memory exhausted"); + + obstack_begin(&robyn,4000); + for (ins = m68k_opcodes; ins < endop; ins++) { + hack=slak=(struct m68k_incant *)obstack_alloc(&robyn,sizeof(struct m68k_incant)); + do { + /* we *could* ignore insns that don't match our + arch here but just leaving them out of the + hash. */ + slak->m_operands=ins->args; + slak->m_opnum=strlen(slak->m_operands)/2; + slak->m_arch = ins->arch; + slak->m_opcode=ins->opcode; + /* This is kludgey */ + slak->m_codenum=((ins->match)&0xffffL) ? 2 : 1; + if((ins+1)!=endop && !strcmp(ins->name,(ins+1)->name)) { + slak->m_next=(struct m68k_incant *) obstack_alloc(&robyn,sizeof(struct m68k_incant)); + ins++; + } else + slak->m_next=0; + slak=slak->m_next; + } while(slak); + + retval = hash_insert (op_hash, ins->name,(char *)hack); + /* Didn't his mommy tell him about null pointers? */ + if(retval && *retval) + as_fatal("Internal Error: Can't hash %s: %s",ins->name,retval); + } + + for (i = 0; i < sizeof(mklower_table) ; i++) + mklower_table[i] = (isupper(c = (char) i)) ? tolower(c) : c; + + for (i = 0 ; i < sizeof(notend_table) ; i++) { + notend_table[i] = 0; + alt_notend_table[i] = 0; + } + notend_table[','] = 1; + notend_table['{'] = 1; + notend_table['}'] = 1; + alt_notend_table['a'] = 1; + alt_notend_table['A'] = 1; + alt_notend_table['d'] = 1; + alt_notend_table['D'] = 1; + alt_notend_table['#'] = 1; + alt_notend_table['f'] = 1; + alt_notend_table['F'] = 1; #ifdef REGISTER_PREFIX - alt_notend_table[REGISTER_PREFIX] = 1; + alt_notend_table[REGISTER_PREFIX] = 1; #endif } #if 0 #define notend(s) ((*s == ',' || *s == '}' || *s == '{' \ - || (*s == ':' && strchr("aAdD#", s[1]))) \ - ? 0 : 1) + || (*s == ':' && strchr("aAdD#", s[1]))) \ + ? 0 : 1) #endif /* This funciton is called once, before the assembler exits. It is supposed to do any final cleanup for this part of the assembler. - */ + */ void -md_end() + md_end() { } @@ -2898,58 +2898,58 @@ md_end() /* Turn a string in input_line_pointer into a floating point constant of type type, and store the appropriate bytes in *litP. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ + */ char * -md_atof(type,litP,sizeP) + md_atof(type,litP,sizeP) char type; char *litP; int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee(); - - switch(type) { - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words;prec--;) { - md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee(); + + switch(type) { + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words;prec--;) { + md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } /* Turn an integer of n bytes (in val) into a stream of bytes appropriate @@ -2958,149 +2958,149 @@ int *sizeP; THE RIGHT THING, whatever it is. Possible values for n are 1 (byte) 2 (short) and 4 (long) Floating numbers are put out as a series of LITTLENUMS (shorts, here at least) - */ + */ void -md_number_to_chars(buf,val,n) + md_number_to_chars(buf,val,n) char *buf; long val; int n; { - switch(n) { - case 1: - *buf++=val; - break; - case 2: - *buf++=(val>>8); - *buf++=val; - break; - case 4: - *buf++=(val>>24); - *buf++=(val>>16); - *buf++=(val>>8); - *buf++=val; - break; - default: - as_fatal("failed sanity check."); - } + switch(n) { + case 1: + *buf++=val; + break; + case 2: + *buf++=(val>>8); + *buf++=val; + break; + case 4: + *buf++=(val>>24); + *buf++=(val>>16); + *buf++=(val>>8); + *buf++=val; + break; + default: + as_fatal("failed sanity check."); + } } void -md_apply_fix(fixP, val) - fixS *fixP; - long val; + md_apply_fix(fixP, val) +fixS *fixP; +long val; { - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - - switch(fixP->fx_size) { - case 1: - *buf++=val; - break; - case 2: - *buf++=(val>>8); - *buf++=val; - break; - case 4: - *buf++=(val>>24); - *buf++=(val>>16); - *buf++=(val>>8); - *buf++=val; - break; - default: - BAD_CASE (fixP->fx_size); - } + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + switch(fixP->fx_size) { + case 1: + *buf++=val; + break; + case 2: + *buf++=(val>>8); + *buf++=val; + break; + case 4: + *buf++=(val>>24); + *buf++=(val>>16); + *buf++=(val>>8); + *buf++=val; + break; + default: + BAD_CASE (fixP->fx_size); + } } /* *fragP has been relaxed to its final size, and now needs to have the bytes inside it modified to conform to the new size There is UGLY MAGIC here. .. - */ + */ void -md_convert_frag(headers, fragP) + md_convert_frag(headers, fragP) object_headers *headers; register fragS *fragP; { - long disp; - long ext = 0; - - /* Address in object code of the displacement. */ - register int object_address = fragP -> fr_fix + fragP -> fr_address; - + long disp; + long ext = 0; + + /* Address in object code of the displacement. */ + register int object_address = fragP -> fr_fix + fragP -> fr_address; + #ifdef IBM_COMPILER_SUX - /* This is wrong but it convinces the native rs6000 compiler to - generate the code we want. */ - register char *buffer_address = fragP -> fr_literal; - buffer_address += fragP -> fr_fix; + /* This is wrong but it convinces the native rs6000 compiler to + generate the code we want. */ + register char *buffer_address = fragP -> fr_literal; + buffer_address += fragP -> fr_fix; #else /* IBM_COMPILER_SUX */ - /* Address in gas core of the place to store the displacement. */ - register char *buffer_address = fragP->fr_fix + fragP->fr_literal; + /* Address in gas core of the place to store the displacement. */ + register char *buffer_address = fragP->fr_fix + fragP->fr_literal; #endif /* IBM_COMPILER_SUX */ - - /* No longer true: know(fragP->fr_symbol); */ - - /* The displacement of the address, from current location. */ - disp = fragP->fr_symbol ? S_GET_VALUE(fragP->fr_symbol) : 0; - disp = (disp + fragP->fr_offset) - object_address; - - switch(fragP->fr_subtype) { - case TAB(BCC68000,BYTE): - case TAB(BRANCH,BYTE): - know(issbyte(disp)); - if(disp==0) - as_bad("short branch with zero offset: use :w"); - fragP->fr_opcode[1]=disp; - ext=0; - break; - case TAB(DBCC,SHORT): - know(issword(disp)); - ext=2; - break; - case TAB(BCC68000,SHORT): - case TAB(BRANCH,SHORT): - know(issword(disp)); - fragP->fr_opcode[1]=0x00; - ext=2; - break; - case TAB(BRANCH,LONG): - if (cpu_of_arch(current_architecture) < m68020) { - if (fragP->fr_opcode[0]==0x61) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - - fix_new(fragP, - fragP->fr_fix, - 4, - fragP->fr_symbol, - 0, - fragP->fr_offset, - 0, - NO_RELOC); - - fragP->fr_fix+=4; + + /* No longer true: know(fragP->fr_symbol); */ + + /* The displacement of the address, from current location. */ + disp = fragP->fr_symbol ? S_GET_VALUE(fragP->fr_symbol) : 0; + disp = (disp + fragP->fr_offset) - object_address; + + switch(fragP->fr_subtype) { + case TAB(BCC68000,BYTE): + case TAB(BRANCH,BYTE): + know(issbyte(disp)); + if(disp==0) + as_bad("short branch with zero offset: use :w"); + fragP->fr_opcode[1]=disp; ext=0; - } else if (fragP->fr_opcode[0]==0x60) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,0, - NO_RELOC); - fragP->fr_fix+=4; - ext=0; - } else { - as_bad("Long branch offset not supported."); - } - } else { - fragP->fr_opcode[1]=0xff; - ext=4; - } - break; - case TAB(BCC68000,LONG): + break; + case TAB(DBCC,SHORT): + know(issword(disp)); + ext=2; + break; + case TAB(BCC68000,SHORT): + case TAB(BRANCH,SHORT): + know(issword(disp)); + fragP->fr_opcode[1]=0x00; + ext=2; + break; + case TAB(BRANCH,LONG): + if (cpu_of_arch(current_architecture) < m68020) { + if (fragP->fr_opcode[0]==0x61) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + + fix_new(fragP, + fragP->fr_fix, + 4, + fragP->fr_symbol, + 0, + fragP->fr_offset, + 0, + NO_RELOC); + + fragP->fr_fix+=4; + ext=0; + } else if (fragP->fr_opcode[0]==0x60) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,0, + NO_RELOC); + fragP->fr_fix+=4; + ext=0; + } else { + as_bad("Long branch offset not supported."); + } + } else { + fragP->fr_opcode[1]=0xff; + ext=4; + } + break; + case TAB(BCC68000,LONG): /* only Bcc 68000 instructions can come here */ /* change bcc into b!cc/jmp absl long */ fragP->fr_opcode[0] ^= 0x01; /* invert bcc */ fragP->fr_opcode[1] = 0x6; /* branch offset = 6 */ - + /* JF: these used to be fr_opcode[2,3], but they may be in a different frag, in which case refering to them is a no-no. Only fr_opcode[0,1] are guaranteed to work. */ @@ -3109,12 +3109,12 @@ register fragS *fragP; fragP->fr_fix += 2; /* account for jmp instruction */ subseg_change(SEG_TEXT,0); fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset,0, - NO_RELOC); + fragP->fr_offset,0, + NO_RELOC); fragP->fr_fix += 4; ext=0; break; - case TAB(DBCC,LONG): + case TAB(DBCC,LONG): /* only DBcc 68000 instructions can come here */ /* change dbcc into dbcc/jmp absl long */ /* JF: these used to be fr_opcode[2-7], but that's wrong */ @@ -3124,254 +3124,254 @@ register fragS *fragP; *buffer_address++ = 0x06; *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */ *buffer_address++ = 0xf9; - + fragP->fr_fix += 6; /* account for bra/jmp instructions */ subseg_change(SEG_TEXT,0); fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset,0, - NO_RELOC); + fragP->fr_offset,0, + NO_RELOC); fragP->fr_fix += 4; ext=0; - break; - case TAB(FBRANCH,SHORT): - know((fragP->fr_opcode[1]&0x40)==0); - ext=2; - break; - case TAB(FBRANCH,LONG): - fragP->fr_opcode[1]|=0x40; /* Turn on LONG bit */ - ext=4; - break; - case TAB(PCREL,SHORT): - ext=2; - break; - case TAB(PCREL,LONG): - /* The thing to do here is force it to ABSOLUTE LONG, since - PCREL is really trying to shorten an ABSOLUTE address anyway */ - /* JF FOO This code has not been tested */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); - if((fragP->fr_opcode[1] & 0x3F) != 0x3A) - as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx", - fragP->fr_opcode[0],fragP->fr_address); - fragP->fr_opcode[1]&= ~0x3F; - fragP->fr_opcode[1]|=0x39; /* Mode 7.1 */ - fragP->fr_fix+=4; - /* md_number_to_chars(buffer_address, - (long)(fragP->fr_symbol->sy_value + fragP->fr_offset), - 4); */ - ext=0; - break; - case TAB(PCLEA,SHORT): - subseg_change(SEG_TEXT,0); - fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset,1, - NO_RELOC); - fragP->fr_opcode[1] &= ~0x3F; - fragP->fr_opcode[1] |= 0x3A; - ext=2; - break; - case TAB(PCLEA,LONG): - subseg_change(SEG_TEXT,0); - fix_new(fragP,(int)(fragP->fr_fix)+2,4,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset+2,1, - NO_RELOC); - *buffer_address++ = 0x01; - *buffer_address++ = 0x70; - fragP->fr_fix+=2; - /* buffer_address+=2; */ - ext=4; - break; - - } /* switch on subtype */ - - if (ext) { - md_number_to_chars(buffer_address, (long) disp, (int) ext); - fragP->fr_fix += ext; -/* H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */ - } /* if extending */ - - return; + break; + case TAB(FBRANCH,SHORT): + know((fragP->fr_opcode[1]&0x40)==0); + ext=2; + break; + case TAB(FBRANCH,LONG): + fragP->fr_opcode[1]|=0x40; /* Turn on LONG bit */ + ext=4; + break; + case TAB(PCREL,SHORT): + ext=2; + break; + case TAB(PCREL,LONG): + /* The thing to do here is force it to ABSOLUTE LONG, since + PCREL is really trying to shorten an ABSOLUTE address anyway */ + /* JF FOO This code has not been tested */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); + if((fragP->fr_opcode[1] & 0x3F) != 0x3A) + as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx", + fragP->fr_opcode[0],fragP->fr_address); + fragP->fr_opcode[1]&= ~0x3F; + fragP->fr_opcode[1]|=0x39; /* Mode 7.1 */ + fragP->fr_fix+=4; + /* md_number_to_chars(buffer_address, + (long)(fragP->fr_symbol->sy_value + fragP->fr_offset), + 4); */ + ext=0; + break; + case TAB(PCLEA,SHORT): + subseg_change(SEG_TEXT,0); + fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset,1, + NO_RELOC); + fragP->fr_opcode[1] &= ~0x3F; + fragP->fr_opcode[1] |= 0x3A; + ext=2; + break; + case TAB(PCLEA,LONG): + subseg_change(SEG_TEXT,0); + fix_new(fragP,(int)(fragP->fr_fix)+2,4,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset+2,1, + NO_RELOC); + *buffer_address++ = 0x01; + *buffer_address++ = 0x70; + fragP->fr_fix+=2; + /* buffer_address+=2; */ + ext=4; + break; + + } /* switch on subtype */ + + if (ext) { + md_number_to_chars(buffer_address, (long) disp, (int) ext); + fragP->fr_fix += ext; + /* H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */ + } /* if extending */ + + return; } /* md_convert_frag() */ /* Force truly undefined symbols to their maximum size, and generally set up the frag list to be relaxed - */ + */ int md_estimate_size_before_relax(fragP, segment) -register fragS *fragP; -segT segment; + register fragS *fragP; + segT segment; { - int old_fix; - register char *buffer_address = fragP->fr_fix + fragP->fr_literal; - - old_fix = fragP->fr_fix; - - /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ - switch(fragP->fr_subtype) { - - case TAB(BRANCH,SZ_UNDEF): { - if((fragP->fr_symbol != NULL) /* Not absolute */ - && S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); - break; - } else if((fragP->fr_symbol == 0) || (cpu_of_arch(current_architecture) < m68020)) { - /* On 68000, or for absolute value, switch to abs long */ - /* FIXME, we should check abs val, pick short or long */ - if(fragP->fr_opcode[0]==0x61) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - fix_new(fragP, fragP->fr_fix, 4, - fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix+=4; - frag_wane(fragP); - } else if(fragP->fr_opcode[0]==0x60) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - fix_new(fragP, fragP->fr_fix, 4, - fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix+=4; - frag_wane(fragP); - } else { - as_warn("Long branch offset to extern symbol not supported."); - } - } else { /* Symbol is still undefined. Make it simple */ - fix_new(fragP, (int)(fragP->fr_fix), 4, fragP->fr_symbol, - (symbolS *)0, fragP->fr_offset+4, 1, NO_RELOC); - fragP->fr_fix+=4; - fragP->fr_opcode[1]=0xff; - frag_wane(fragP); - break; - } - - break; - } /* case TAB(BRANCH,SZ_UNDEF) */ - - case TAB(FBRANCH,SZ_UNDEF): { - if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { - fragP->fr_subtype = TAB(FBRANCH,SHORT); - fragP->fr_var += 2; - } else { - fragP->fr_subtype = TAB(FBRANCH,LONG); - fragP->fr_var += 4; - } - break; - } /* TAB(FBRANCH,SZ_UNDEF) */ - - case TAB(PCREL,SZ_UNDEF): { - if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { - fragP->fr_subtype = TAB(PCREL,SHORT); - fragP->fr_var += 2; - } else { - fragP->fr_subtype = TAB(PCREL,LONG); - fragP->fr_var += 4; - } - break; - } /* TAB(PCREL,SZ_UNDEF) */ - - case TAB(BCC68000,SZ_UNDEF): { - if((fragP->fr_symbol != NULL) - && S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype=TAB(BCC68000,BYTE); - break; - } - /* only Bcc 68000 instructions can come here */ - /* change bcc into b!cc/jmp absl long */ - fragP->fr_opcode[0] ^= 0x01; /* invert bcc */ - if(flagseen['l']) { - fragP->fr_opcode[1] = 0x04; /* branch offset = 6 */ - /* JF: these were fr_opcode[2,3] */ - buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */ - buffer_address[1] = 0xf8; - fragP->fr_fix += 2; /* account for jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 2; - } else { - fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */ - /* JF: these were fr_opcode[2,3] */ - buffer_address[2] = 0x4e; /* put in jmp long (0x4ef9) */ - buffer_address[3] = 0xf9; - fragP->fr_fix += 2; /* account for jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 4; - } + int old_fix; + register char *buffer_address = fragP->fr_fix + fragP->fr_literal; + + old_fix = fragP->fr_fix; + + /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ + switch(fragP->fr_subtype) { + + case TAB(BRANCH,SZ_UNDEF): { + if((fragP->fr_symbol != NULL) /* Not absolute */ + && S_GET_SEGMENT(fragP->fr_symbol) == segment) { + fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); + break; + } else if((fragP->fr_symbol == 0) || (cpu_of_arch(current_architecture) < m68020)) { + /* On 68000, or for absolute value, switch to abs long */ + /* FIXME, we should check abs val, pick short or long */ + if(fragP->fr_opcode[0]==0x61) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + fix_new(fragP, fragP->fr_fix, 4, + fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix+=4; frag_wane(fragP); - break; - } /* case TAB(BCC68000,SZ_UNDEF) */ - - case TAB(DBCC,SZ_UNDEF): { - if (fragP->fr_symbol != NULL && S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype=TAB(DBCC,SHORT); - fragP->fr_var+=2; - break; - } - /* only DBcc 68000 instructions can come here */ - /* change dbcc into dbcc/jmp absl long */ - /* JF: these used to be fr_opcode[2-4], which is wrong. */ - buffer_address[0] = 0x00; /* branch offset = 4 */ - buffer_address[1] = 0x04; - buffer_address[2] = 0x60; /* put in bra pc + ... */ - - if(flagseen['l']) { - /* JF: these were fr_opcode[5-7] */ - buffer_address[3] = 0x04; /* plus 4 */ - buffer_address[4] = 0x4e;/* Put in Jump Word */ - buffer_address[5] = 0xf8; - fragP->fr_fix += 6; /* account for bra/jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 2; - } else { - /* JF: these were fr_opcode[5-7] */ - buffer_address[3] = 0x06; /* Plus 6 */ - buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */ - buffer_address[5] = 0xf9; - fragP->fr_fix += 6; /* account for bra/jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 4; - } - + } else if(fragP->fr_opcode[0]==0x60) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + fix_new(fragP, fragP->fr_fix, 4, + fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix+=4; frag_wane(fragP); - break; - } /* case TAB(DBCC,SZ_UNDEF) */ - - case TAB(PCLEA,SZ_UNDEF): { - if ((S_GET_SEGMENT(fragP->fr_symbol))==segment || flagseen['l']) { - fragP->fr_subtype=TAB(PCLEA,SHORT); - fragP->fr_var+=2; - } else { - fragP->fr_subtype=TAB(PCLEA,LONG); - fragP->fr_var+=6; - } - break; - } /* TAB(PCLEA,SZ_UNDEF) */ - - default: - break; - - } /* switch on subtype looking for SZ_UNDEF's. */ - - /* now that SZ_UNDEF are taken care of, check others */ - switch(fragP->fr_subtype) { - case TAB(BCC68000,BYTE): - case TAB(BRANCH,BYTE): - /* We can't do a short jump to the next instruction, - so we force word mode. */ - if (fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 && - fragP->fr_symbol->sy_frag==fragP->fr_next) { - fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); - fragP->fr_var+=2; - } - break; - default: - break; + } else { + as_warn("Long branch offset to extern symbol not supported."); + } + } else { /* Symbol is still undefined. Make it simple */ + fix_new(fragP, (int)(fragP->fr_fix), 4, fragP->fr_symbol, + (symbolS *)0, fragP->fr_offset+4, 1, NO_RELOC); + fragP->fr_fix+=4; + fragP->fr_opcode[1]=0xff; + frag_wane(fragP); + break; + } + + break; + } /* case TAB(BRANCH,SZ_UNDEF) */ + + case TAB(FBRANCH,SZ_UNDEF): { + if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { + fragP->fr_subtype = TAB(FBRANCH,SHORT); + fragP->fr_var += 2; + } else { + fragP->fr_subtype = TAB(FBRANCH,LONG); + fragP->fr_var += 4; } - return fragP->fr_var + fragP->fr_fix - old_fix; + break; + } /* TAB(FBRANCH,SZ_UNDEF) */ + + case TAB(PCREL,SZ_UNDEF): { + if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { + fragP->fr_subtype = TAB(PCREL,SHORT); + fragP->fr_var += 2; + } else { + fragP->fr_subtype = TAB(PCREL,LONG); + fragP->fr_var += 4; + } + break; + } /* TAB(PCREL,SZ_UNDEF) */ + + case TAB(BCC68000,SZ_UNDEF): { + if((fragP->fr_symbol != NULL) + && S_GET_SEGMENT(fragP->fr_symbol) == segment) { + fragP->fr_subtype=TAB(BCC68000,BYTE); + break; + } + /* only Bcc 68000 instructions can come here */ + /* change bcc into b!cc/jmp absl long */ + fragP->fr_opcode[0] ^= 0x01; /* invert bcc */ + if(flagseen['l']) { + fragP->fr_opcode[1] = 0x04; /* branch offset = 6 */ + /* JF: these were fr_opcode[2,3] */ + buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */ + buffer_address[1] = 0xf8; + fragP->fr_fix += 2; /* account for jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 2; + } else { + fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */ + /* JF: these were fr_opcode[2,3] */ + buffer_address[2] = 0x4e; /* put in jmp long (0x4ef9) */ + buffer_address[3] = 0xf9; + fragP->fr_fix += 2; /* account for jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 4; + } + frag_wane(fragP); + break; + } /* case TAB(BCC68000,SZ_UNDEF) */ + + case TAB(DBCC,SZ_UNDEF): { + if (fragP->fr_symbol != NULL && S_GET_SEGMENT(fragP->fr_symbol) == segment) { + fragP->fr_subtype=TAB(DBCC,SHORT); + fragP->fr_var+=2; + break; + } + /* only DBcc 68000 instructions can come here */ + /* change dbcc into dbcc/jmp absl long */ + /* JF: these used to be fr_opcode[2-4], which is wrong. */ + buffer_address[0] = 0x00; /* branch offset = 4 */ + buffer_address[1] = 0x04; + buffer_address[2] = 0x60; /* put in bra pc + ... */ + + if(flagseen['l']) { + /* JF: these were fr_opcode[5-7] */ + buffer_address[3] = 0x04; /* plus 4 */ + buffer_address[4] = 0x4e;/* Put in Jump Word */ + buffer_address[5] = 0xf8; + fragP->fr_fix += 6; /* account for bra/jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 2; + } else { + /* JF: these were fr_opcode[5-7] */ + buffer_address[3] = 0x06; /* Plus 6 */ + buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */ + buffer_address[5] = 0xf9; + fragP->fr_fix += 6; /* account for bra/jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 4; + } + + frag_wane(fragP); + break; + } /* case TAB(DBCC,SZ_UNDEF) */ + + case TAB(PCLEA,SZ_UNDEF): { + if ((S_GET_SEGMENT(fragP->fr_symbol))==segment || flagseen['l']) { + fragP->fr_subtype=TAB(PCLEA,SHORT); + fragP->fr_var+=2; + } else { + fragP->fr_subtype=TAB(PCLEA,LONG); + fragP->fr_var+=6; + } + break; + } /* TAB(PCLEA,SZ_UNDEF) */ + + default: + break; + + } /* switch on subtype looking for SZ_UNDEF's. */ + + /* now that SZ_UNDEF are taken care of, check others */ + switch(fragP->fr_subtype) { + case TAB(BCC68000,BYTE): + case TAB(BRANCH,BYTE): + /* We can't do a short jump to the next instruction, + so we force word mode. */ + if (fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 && + fragP->fr_symbol->sy_frag==fragP->fr_next) { + fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); + fragP->fr_var+=2; + } + break; + default: + break; + } + return fragP->fr_var + fragP->fr_fix - old_fix; } #if defined(OBJ_AOUT) | defined(OBJ_BOUT) @@ -3380,64 +3380,64 @@ segT segment; I added this mach. dependent ri twiddler. Ugly, but it gets you there. -KWK */ /* on m68k: first 4 bytes are normal unsigned long, next three bytes -are symbolnum, most sig. byte first. Last byte is broken up with -bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower -nibble as nuthin. (on Sun 3 at least) */ + are symbolnum, most sig. byte first. Last byte is broken up with + bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower + nibble as nuthin. (on Sun 3 at least) */ /* Translate the internal relocation information into target-specific format. */ #ifdef comment void -md_ri_to_chars(the_bytes, ri) - char *the_bytes; - struct reloc_info_generic *ri; + md_ri_to_chars(the_bytes, ri) +char *the_bytes; +struct reloc_info_generic *ri; { - /* this is easy */ - md_number_to_chars(the_bytes, ri->r_address, 4); - /* now the fun stuff */ - the_bytes[4] = (ri->r_symbolnum >> 16) & 0x0ff; - the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff; - the_bytes[6] = ri->r_symbolnum & 0x0ff; - the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) | - ((ri->r_extern << 4) & 0x10)); + /* this is easy */ + md_number_to_chars(the_bytes, ri->r_address, 4); + /* now the fun stuff */ + the_bytes[4] = (ri->r_symbolnum >> 16) & 0x0ff; + the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff; + the_bytes[6] = ri->r_symbolnum & 0x0ff; + the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) | + ((ri->r_extern << 4) & 0x10)); } #endif /* comment */ void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) -char *where; -fixS *fixP; -relax_addressT segment_address_in_file; + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; { - /* - * In: length of relocation (or of address) in chars: 1, 2 or 4. - * Out: GNU LD relocation length code: 0, 1, or 2. - */ - - static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 }; - - long r_extern; - long r_symbolnum; - - /* this is easy */ - md_number_to_chars(where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); - - /* now the fun stuff */ - if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) { - r_extern = 1; - r_symbolnum = fixP->fx_addsy->sy_number; - } else { - r_extern = 0; - r_symbolnum = S_GET_TYPE(fixP->fx_addsy); - } - - where[4] = (r_symbolnum >> 16) & 0x0ff; - where[5] = (r_symbolnum >> 8) & 0x0ff; - where[6] = r_symbolnum & 0x0ff; - where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) | - ((r_extern << 4) & 0x10)); - - return; + /* + * In: length of relocation (or of address) in chars: 1, 2 or 4. + * Out: GNU LD relocation length code: 0, 1, or 2. + */ + + static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 }; + + long r_extern; + long r_symbolnum; + + /* this is easy */ + md_number_to_chars(where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + /* now the fun stuff */ + if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) { + r_extern = 1; + r_symbolnum = fixP->fx_addsy->sy_number; + } else { + r_extern = 0; + r_symbolnum = S_GET_TYPE(fixP->fx_addsy); + } + + where[4] = (r_symbolnum >> 16) & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[6] = r_symbolnum & 0x0ff; + where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) | + ((r_extern << 4) & 0x10)); + + return; } /* tc_aout_fix_to_chars() */ #endif /* OBJ_AOUT or OBJ_BOUT */ @@ -3447,233 +3447,233 @@ const int md_short_jump_size = 4; const int md_long_jump_size = 6; void -md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol) + md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol) char *ptr; long from_addr, - to_addr; + to_addr; fragS *frag; symbolS *to_symbol; { - long offset; - - offset = to_addr - (from_addr+2); - - md_number_to_chars(ptr ,(long)0x6000,2); - md_number_to_chars(ptr+2,(long)offset,2); + long offset; + + offset = to_addr - (from_addr+2); + + md_number_to_chars(ptr ,(long)0x6000,2); + md_number_to_chars(ptr+2,(long)offset,2); } void -md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) + md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) char *ptr; long from_addr, - to_addr; + to_addr; fragS *frag; symbolS *to_symbol; { - long offset; - - if (cpu_of_arch(current_architecture) < m68020) { - offset=to_addr-S_GET_VALUE(to_symbol); - md_number_to_chars(ptr ,(long)0x4EF9,2); - md_number_to_chars(ptr+2,(long)offset,4); - fix_new(frag,(ptr+2)-frag->fr_literal,4,to_symbol,(symbolS *)0,(long)0,0, - NO_RELOC); - } else { - offset=to_addr - (from_addr+2); - md_number_to_chars(ptr ,(long)0x60ff,2); - md_number_to_chars(ptr+2,(long)offset,4); - } + long offset; + + if (cpu_of_arch(current_architecture) < m68020) { + offset=to_addr-S_GET_VALUE(to_symbol); + md_number_to_chars(ptr ,(long)0x4EF9,2); + md_number_to_chars(ptr+2,(long)offset,4); + fix_new(frag,(ptr+2)-frag->fr_literal,4,to_symbol,(symbolS *)0,(long)0,0, + NO_RELOC); + } else { + offset=to_addr - (from_addr+2); + md_number_to_chars(ptr ,(long)0x60ff,2); + md_number_to_chars(ptr+2,(long)offset,4); + } } #endif /* Different values of OK tell what its OK to return. Things that aren't OK are an error (what a shock, no?) - - 0: Everything is OK - 10: Absolute 1:8 only - 20: Absolute 0:7 only - 30: absolute 0:15 only - 40: Absolute 0:31 only - 50: absolute 0:127 only - 55: absolute -64:63 only - 60: absolute -128:127 only - 70: absolute 0:4095 only - 80: No bignums - -*/ + + 0: Everything is OK + 10: Absolute 1:8 only + 20: Absolute 0:7 only + 30: absolute 0:15 only + 40: Absolute 0:31 only + 50: absolute 0:127 only + 55: absolute -64:63 only + 60: absolute -128:127 only + 70: absolute 0:4095 only + 80: No bignums + + */ static int get_num(exp,ok) -struct m68k_exp *exp; -int ok; + struct m68k_exp *exp; + int ok; { #ifdef TEST2 - long l = 0; - - if(!exp->e_beg) - return 0; - if(*exp->e_beg=='0') { - if(exp->e_beg[1]=='x') - sscanf(exp->e_beg+2,"%x",&l); - else - sscanf(exp->e_beg+1,"%O",&l); - return l; - } - return atol(exp->e_beg); + long l = 0; + + if(!exp->e_beg) + return 0; + if(*exp->e_beg=='0') { + if(exp->e_beg[1]=='x') + sscanf(exp->e_beg+2,"%x",&l); + else + sscanf(exp->e_beg+1,"%O",&l); + return l; + } + return atol(exp->e_beg); #else - char *save_in; - char c_save; - - if(!exp) { - /* Can't do anything */ - return 0; - } - if(!exp->e_beg || !exp->e_end) { - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Null expression defaults to %ld",offs(exp)); - return 0; + char *save_in; + char c_save; + + if(!exp) { + /* Can't do anything */ + return 0; + } + if(!exp->e_beg || !exp->e_end) { + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Null expression defaults to %ld",offs(exp)); + return 0; + } + + exp->e_siz=0; + if(/* ok!=80 && */exp->e_end[-1]==':' && (exp->e_end-exp->e_beg)>=2) { + switch(exp->e_end[0]) { + case 's': + case 'S': + case 'b': + case 'B': + exp->e_siz=1; + break; + case 'w': + case 'W': + exp->e_siz=2; + break; + case 'l': + case 'L': + exp->e_siz=3; + break; + default: + as_bad("Unknown size for expression \"%c\"",exp->e_end[0]); } - - exp->e_siz=0; - if(/* ok!=80 && */exp->e_end[-1]==':' && (exp->e_end-exp->e_beg)>=2) { - switch(exp->e_end[0]) { - case 's': - case 'S': - case 'b': - case 'B': - exp->e_siz=1; - break; - case 'w': - case 'W': - exp->e_siz=2; - break; - case 'l': - case 'L': - exp->e_siz=3; - break; - default: - as_bad("Unknown size for expression \"%c\"",exp->e_end[0]); - } - exp->e_end-=2; + exp->e_end-=2; + } + c_save=exp->e_end[1]; + exp->e_end[1]='\0'; + save_in=input_line_pointer; + input_line_pointer=exp->e_beg; + switch(expression(&(exp->e_exp))) { + case SEG_PASS1: + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp)); + break; + + case SEG_ABSENT: + /* Do the same thing the VAX asm does */ + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)=0; + if(ok==10) { + as_warn("expression out of range: defaulting to 1"); + offs(exp)=1; } - c_save=exp->e_end[1]; - exp->e_end[1]='\0'; - save_in=input_line_pointer; - input_line_pointer=exp->e_beg; - switch(expression(&(exp->e_exp))) { - case SEG_PASS1: - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp)); - break; - - case SEG_ABSENT: - /* Do the same thing the VAX asm does */ - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; + break; + case SEG_ABSOLUTE: + switch(ok) { + case 10: + if(offs(exp)<1 || offs(exp)>8) { + as_warn("expression out of range: defaulting to 1"); + offs(exp)=1; + } + break; + case 20: + if(offs(exp)<0 || offs(exp)>7) + goto outrange; + break; + case 30: + if(offs(exp)<0 || offs(exp)>15) + goto outrange; + break; + case 40: + if(offs(exp)<0 || offs(exp)>32) + goto outrange; + break; + case 50: + if(offs(exp)<0 || offs(exp)>127) + goto outrange; + break; + case 55: + if(offs(exp)<-64 || offs(exp)>63) + goto outrange; + break; + case 60: + if(offs(exp)<-128 || offs(exp)>127) + goto outrange; + break; + case 70: + if(offs(exp)<0 || offs(exp)>4095) { + outrange: + as_warn("expression out of range: defaulting to 0"); offs(exp)=0; - if(ok==10) { - as_warn("expression out of range: defaulting to 1"); - offs(exp)=1; - } - break; - case SEG_ABSOLUTE: - switch(ok) { - case 10: - if(offs(exp)<1 || offs(exp)>8) { - as_warn("expression out of range: defaulting to 1"); - offs(exp)=1; - } - break; - case 20: - if(offs(exp)<0 || offs(exp)>7) - goto outrange; - break; - case 30: - if(offs(exp)<0 || offs(exp)>15) - goto outrange; - break; - case 40: - if(offs(exp)<0 || offs(exp)>32) - goto outrange; - break; - case 50: - if(offs(exp)<0 || offs(exp)>127) - goto outrange; - break; - case 55: - if(offs(exp)<-64 || offs(exp)>63) - goto outrange; - break; - case 60: - if(offs(exp)<-128 || offs(exp)>127) - goto outrange; - break; - case 70: - if(offs(exp)<0 || offs(exp)>4095) { - outrange: - as_warn("expression out of range: defaulting to 0"); - offs(exp)=0; - } - break; - default: - break; - } - break; - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - if(ok>=10 && ok<=70) { - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); - } - break; - case SEG_BIG: - if(ok==80 && offs(exp)<0) { /* HACK! Turn it into a long */ - LITTLENUM_TYPE words[6]; - - gen_to_words(words,2,8L);/* These numbers are magic! */ - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)=words[1]|(words[0]<<16); - } else if(ok!=0) { - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); - } - break; + } + break; default: - as_fatal("failed sanity check."); + break; } - if(input_line_pointer!=exp->e_end+1) - as_bad("Ignoring junk after expression"); - exp->e_end[1]=c_save; - input_line_pointer=save_in; - if(exp->e_siz) { - switch(exp->e_siz) { - case 1: - if(!isbyte(offs(exp))) - as_warn("expression doesn't fit in BYTE"); - break; - case 2: - if(!isword(offs(exp))) - as_warn("expression doesn't fit in WORD"); - break; - } + break; + case SEG_TEXT: + case SEG_DATA: + case SEG_BSS: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + if(ok>=10 && ok<=70) { + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); + } + break; + case SEG_BIG: + if(ok==80 && offs(exp)<0) { /* HACK! Turn it into a long */ + LITTLENUM_TYPE words[6]; + + gen_to_words(words,2,8L);/* These numbers are magic! */ + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)=words[1]|(words[0]<<16); + } else if(ok!=0) { + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); } - return offs(exp); + break; + default: + as_fatal("failed sanity check."); + } + if(input_line_pointer!=exp->e_end+1) + as_bad("Ignoring junk after expression"); + exp->e_end[1]=c_save; + input_line_pointer=save_in; + if(exp->e_siz) { + switch(exp->e_siz) { + case 1: + if(!isbyte(offs(exp))) + as_warn("expression doesn't fit in BYTE"); + break; + case 2: + if(!isword(offs(exp))) + as_warn("expression doesn't fit in WORD"); + break; + } + } + return offs(exp); #endif } /* get_num() */ @@ -3681,35 +3681,35 @@ int ok; void demand_empty_rest_of_line(); /* Hate those extra verbose names */ static void s_data1() { - subseg_new(SEG_DATA,1); - demand_empty_rest_of_line(); + subseg_new(SEG_DATA,1); + demand_empty_rest_of_line(); } /* s_data1() */ static void s_data2() { - subseg_new(SEG_DATA,2); - demand_empty_rest_of_line(); + subseg_new(SEG_DATA,2); + demand_empty_rest_of_line(); } /* s_data2() */ static void s_bss() { - /* We don't support putting frags in the BSS segment, but we - can put them into initialized data for now... */ - subseg_new(SEG_DATA,255); /* FIXME-SOON */ - demand_empty_rest_of_line(); + /* We don't support putting frags in the BSS segment, but we + can put them into initialized data for now... */ + subseg_new(SEG_DATA,255); /* FIXME-SOON */ + demand_empty_rest_of_line(); } /* s_bss() */ static void s_even() { - register int temp; - register long temp_fill; - - temp = 1; /* JF should be 2? */ - temp_fill = get_absolute_expression (); - if ( ! need_pass_2 ) /* Never make frag if expect extra pass. */ - frag_align (temp, (int)temp_fill); - demand_empty_rest_of_line(); + register int temp; + register long temp_fill; + + temp = 1; /* JF should be 2? */ + temp_fill = get_absolute_expression (); + if ( ! need_pass_2 ) /* Never make frag if expect extra pass. */ + frag_align (temp, (int)temp_fill); + demand_empty_rest_of_line(); } /* s_even() */ static void s_proc() { - demand_empty_rest_of_line(); + demand_empty_rest_of_line(); } /* s_proc() */ /* s_space is defined in read.c .skip is simply an alias to it. */ @@ -3727,82 +3727,91 @@ static void s_proc() { * -m68020 -m68851 -m68881. Note that -m68008 is a synonym * for -m68000, and -m68882 is a synonym for -m68881. * + * MAYBE_FLOAT_TOO is defined below so that specifying a processor type + * (e.g. m68020) also requests that float instructions be included. This + * is the default setup, mostly to avoid hassling users. A better + * rearrangement of this structure would be to add an option to DENY + * floating point opcodes, for people who want to really know there's none + * of that funny floaty stuff going on. FIXME-later. */ +#ifndef MAYBE_FLOAT_TOO +#define MAYBE_FLOAT_TOO m68881 +#endif int md_parse_option(argP,cntP,vecP) -char **argP; -int *cntP; -char ***vecP; + char **argP; + int *cntP; + char ***vecP; { - switch(**argP) { - case 'l': /* -l means keep external to 2 bit offset - rather than 16 bit one */ - break; - - case 'S': /* -S means that jbsr's always turn into jsr's. */ - break; - - case 'A': - (*argP)++; - /* intentional fall-through */ - case 'm': - (*argP)++; - - if (**argP=='c') { - (*argP)++; - } /* allow an optional "c" */ - - if (!strcmp(*argP, "68000") - || !strcmp(*argP, "68008")) { - current_architecture |= m68000; - } else if (!strcmp(*argP, "68010")) { + switch(**argP) { + case 'l': /* -l means keep external to 2 bit offset + rather than 16 bit one */ + break; + + case 'S': /* -S means that jbsr's always turn into jsr's. */ + break; + + case 'A': + (*argP)++; + /* intentional fall-through */ + case 'm': + (*argP)++; + + if (**argP=='c') { + (*argP)++; + } /* allow an optional "c" */ + + if (!strcmp(*argP, "68000") + || !strcmp(*argP, "68008")) { + current_architecture |= m68000; + } else if (!strcmp(*argP, "68010")) { #ifdef TE_SUN - omagic= 1<<16|OMAGIC; + omagic= 1<<16|OMAGIC; #endif - current_architecture |= m68010; - - } else if (!strcmp(*argP, "68020")) { - current_architecture |= m68020; - - } else if (!strcmp(*argP, "68030")) { - current_architecture |= m68030; - - } else if (!strcmp(*argP, "68040")) { - current_architecture |= m68040; - + current_architecture |= m68010; + + } else if (!strcmp(*argP, "68020")) { + current_architecture |= m68020 | MAYBE_FLOAT_TOO; + + } else if (!strcmp(*argP, "68030")) { + current_architecture |= m68030 | MAYBE_FLOAT_TOO; + + } else if (!strcmp(*argP, "68040")) { + current_architecture |= m68040 | MAYBE_FLOAT_TOO; + #ifndef NO_68881 - } else if (!strcmp(*argP, "68881")) { - current_architecture |= m68881; - - } else if (!strcmp(*argP, "68882")) { - current_architecture |= m68882; - + } else if (!strcmp(*argP, "68881")) { + current_architecture |= m68881; + + } else if (!strcmp(*argP, "68882")) { + current_architecture |= m68882; + #endif /* NO_68881 */ #ifndef NO_68851 - } else if (!strcmp(*argP,"68851")) { - current_architecture |= m68851; - + } else if (!strcmp(*argP,"68851")) { + current_architecture |= m68851; + #endif /* NO_68851 */ - } else { - as_warn("Unknown architecture, \"%s\". option ignored", *argP); - } /* switch on architecture */ - - while(**argP) (*argP)++; - - break; - - case 'p': - if (!strcmp(*argP,"pic")) { - (*argP) += 3; - break; /* -pic, Position Independent Code */ - } else { - return(0); - } /* pic or not */ - - default: - return 0; - } - return 1; + } else { + as_warn("Unknown architecture, \"%s\". option ignored", *argP); + } /* switch on architecture */ + + while(**argP) (*argP)++; + + break; + + case 'p': + if (!strcmp(*argP,"pic")) { + (*argP) += 3; + break; /* -pic, Position Independent Code */ + } else { + return(0); + } /* pic or not */ + + default: + return 0; + } + return 1; } @@ -3813,134 +3822,134 @@ char ***vecP; main() { - struct m68k_it the_ins; - char buf[120]; - char *cp; - int n; - - m68k_ip_begin(); - for(;;) { - if(!gets(buf) || !*buf) - break; - if(buf[0]=='|' || buf[1]=='.') - continue; - for(cp=buf;*cp;cp++) - if(*cp=='\t') - *cp=' '; - if(is_label(buf)) - continue; - bzero(&the_ins,sizeof(the_ins)); - m68k_ip(&the_ins,buf); - if(the_ins.error) { - printf("Error %s in %s\n",the_ins.error,buf); - } else { - printf("Opcode(%d.%s): ",the_ins.numo,the_ins.args); - for(n=0;n<the_ins.numo;n++) - printf(" 0x%x",the_ins.opcode[n]&0xffff); - printf(" "); - print_the_insn(&the_ins.opcode[0],stdout); - (void)putchar('\n'); - } - for(n=0;n<strlen(the_ins.args)/2;n++) { - if(the_ins.operands[n].error) { - printf("op%d Error %s in %s\n",n,the_ins.operands[n].error,buf); - continue; - } - printf("mode %d, reg %d, ",the_ins.operands[n].mode,the_ins.operands[n].reg); - if(the_ins.operands[n].b_const) - printf("Constant: '%.*s', ",1+the_ins.operands[n].e_const-the_ins.operands[n].b_const,the_ins.operands[n].b_const); - printf("ireg %d, isiz %d, imul %d, ",the_ins.operands[n].ireg,the_ins.operands[n].isiz,the_ins.operands[n].imul); - if(the_ins.operands[n].b_iadd) - printf("Iadd: '%.*s',",1+the_ins.operands[n].e_iadd-the_ins.operands[n].b_iadd,the_ins.operands[n].b_iadd); - (void)putchar('\n'); - } + struct m68k_it the_ins; + char buf[120]; + char *cp; + int n; + + m68k_ip_begin(); + for(;;) { + if(!gets(buf) || !*buf) + break; + if(buf[0]=='|' || buf[1]=='.') + continue; + for(cp=buf;*cp;cp++) + if(*cp=='\t') + *cp=' '; + if(is_label(buf)) + continue; + bzero(&the_ins,sizeof(the_ins)); + m68k_ip(&the_ins,buf); + if(the_ins.error) { + printf("Error %s in %s\n",the_ins.error,buf); + } else { + printf("Opcode(%d.%s): ",the_ins.numo,the_ins.args); + for(n=0;n<the_ins.numo;n++) + printf(" 0x%x",the_ins.opcode[n]&0xffff); + printf(" "); + print_the_insn(&the_ins.opcode[0],stdout); + (void)putchar('\n'); } - m68k_ip_end(); - return 0; + for(n=0;n<strlen(the_ins.args)/2;n++) { + if(the_ins.operands[n].error) { + printf("op%d Error %s in %s\n",n,the_ins.operands[n].error,buf); + continue; + } + printf("mode %d, reg %d, ",the_ins.operands[n].mode,the_ins.operands[n].reg); + if(the_ins.operands[n].b_const) + printf("Constant: '%.*s', ",1+the_ins.operands[n].e_const-the_ins.operands[n].b_const,the_ins.operands[n].b_const); + printf("ireg %d, isiz %d, imul %d, ",the_ins.operands[n].ireg,the_ins.operands[n].isiz,the_ins.operands[n].imul); + if(the_ins.operands[n].b_iadd) + printf("Iadd: '%.*s',",1+the_ins.operands[n].e_iadd-the_ins.operands[n].b_iadd,the_ins.operands[n].b_iadd); + (void)putchar('\n'); + } + } + m68k_ip_end(); + return 0; } is_label(str) -char *str; + char *str; { - while(*str==' ') - str++; - while(*str && *str!=' ') - str++; - if(str[-1]==':' || str[1]=='=') - return 1; - return 0; + while(*str==' ') + str++; + while(*str && *str!=' ') + str++; + if(str[-1]==':' || str[1]=='=') + return 1; + return 0; } #endif /* Possible states for relaxation: - -0 0 branch offset byte (bra, etc) -0 1 word -0 2 long - -1 0 indexed offsets byte a0@(32,d4:w:1) etc -1 1 word -1 2 long - -2 0 two-offset index word-word a0@(32,d4)@(45) etc -2 1 word-long -2 2 long-word -2 3 long-long - -*/ + + 0 0 branch offset byte (bra, etc) + 0 1 word + 0 2 long + + 1 0 indexed offsets byte a0@(32,d4:w:1) etc + 1 1 word + 1 2 long + + 2 0 two-offset index word-word a0@(32,d4)@(45) etc + 2 1 word-long + 2 2 long-word + 2 3 long-long + + */ #ifdef DONTDEF abort() { - printf("ABORT!\n"); - exit(12); + printf("ABORT!\n"); + exit(12); } char *index(s,c) -char *s; + char *s; { - while(*s!=c) { - if(!*s) return 0; - s++; - } - return s; + while(*s!=c) { + if(!*s) return 0; + s++; + } + return s; } bzero(s,n) -char *s; + char *s; { - while(n--) - *s++=0; + while(n--) + *s++=0; } print_frags() { - fragS *fragP; - extern fragS *text_frag_root; - - for(fragP=text_frag_root;fragP;fragP=fragP->fr_next) { - printf("addr %lu next 0x%x fix %ld var %ld symbol 0x%x offset %ld\n", - fragP->fr_address,fragP->fr_next,fragP->fr_fix,fragP->fr_var,fragP->fr_symbol,fragP->fr_offset); - printf("opcode 0x%x type %d subtype %d\n\n",fragP->fr_opcode,fragP->fr_type,fragP->fr_subtype); - } - fflush(stdout); - return 0; + fragS *fragP; + extern fragS *text_frag_root; + + for(fragP=text_frag_root;fragP;fragP=fragP->fr_next) { + printf("addr %lu next 0x%x fix %ld var %ld symbol 0x%x offset %ld\n", + fragP->fr_address,fragP->fr_next,fragP->fr_fix,fragP->fr_var,fragP->fr_symbol,fragP->fr_offset); + printf("opcode 0x%x type %d subtype %d\n\n",fragP->fr_opcode,fragP->fr_type,fragP->fr_subtype); + } + fflush(stdout); + return 0; } #endif #ifdef DONTDEF /*VARARGS1*/ panic(format,args) -char *format; + char *format; { - fputs("Internal error:",stderr); - _doprnt(format,&args,stderr); - (void)putc('\n',stderr); - as_where(); - abort(); + fputs("Internal error:",stderr); + _doprnt(format,&args,stderr); + (void)putc('\n',stderr); + as_where(); + abort(); } #endif @@ -3948,10 +3957,10 @@ char *format; /* ARGSUSED */ symbolS * -md_undefined_symbol (name) - char *name; + md_undefined_symbol (name) +char *name; { - return 0; + return 0; } /* Parse an operand that is machine-specific. @@ -3960,28 +3969,28 @@ md_undefined_symbol (name) /* ARGSUSED */ void -md_operand (expressionP) - expressionS *expressionP; + md_operand (expressionP) +expressionS *expressionP; { } /* Round up a section size to the appropriate boundary. */ long -md_section_align (segment, size) - segT segment; - long size; + md_section_align (segment, size) +segT segment; +long size; { - return size; /* Byte alignment is fine */ + return size; /* Byte alignment is fine */ } /* Exactly what point is a PC-relative offset relative TO? On the 68k, they're relative to the address of the offset, plus its size. (??? Is this right? FIXME-SOON!) */ long -md_pcrel_from (fixP) - fixS *fixP; + md_pcrel_from (fixP) +fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } /* diff --git a/gas/config/tc-m68k.h b/gas/config/tc-m68k.h index 4fa516c..0a7aa50 100644 --- a/gas/config/tc-m68k.h +++ b/gas/config/tc-m68k.h @@ -12,9 +12,26 @@ #define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (2<<16|OMAGIC); /* Magic byte for file header */ #endif /* TE_SUN3 */ + +#define AOUT_MACHTYPE 0x2 +#define REVERSE_SORT_RELOCS /* FIXME-NOW: this line can be removed. */ +#define LOCAL_LABELS_FB + +#define tc_crawl_symbol_chain(a) {;} /* not used */ +#define tc_headers_hook(a) {;} /* not used */ +#define tc_aout_pre_write_hook(x) {;} /* not used */ -#define tc_crawl_symbol_chain(a) ; /* not used */ -#define tc_headers_hook(a) ; /* not used */ +#define LISTING_WORD_SIZE 2 /* A word is 2 bytes */ +#define LISTING_LHS_WIDTH 2 /* One word on the first line */ +#define LISTING_LHS_WIDTH_SECOND 2 /* One word on the second line */ +#define LISTING_LHS_CONT_LINES 4 /* And 4 lines max */ +#define LISTING_HEADER "68K GAS " + +/* Copied from write.c */ +#define M68K_AIM_KLUDGE(aim, this_state,this_type) \ + if (aim==0 && this_state== 4) { /* hard encoded from tc-m68k.c */ \ + aim=this_type->rlx_forward+1; /* Force relaxation into word mode */ \ + } /* * Local Variables: diff --git a/gas/config/tc-m68kmote.c b/gas/config/tc-m68kmote.c index 9d32caa..ce54a73 100644 --- a/gas/config/tc-m68kmote.c +++ b/gas/config/tc-m68kmote.c @@ -2,22 +2,22 @@ /* m68k.c All the m68020 specific stuff in one convenient, huge, slow to compile, easy to find file. Copyright (C) 1987, 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 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. */ #include <ctype.h> @@ -25,7 +25,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "obstack.h" - /* note that this file includes real declarations and thus can only be included by one source file per executable. */ +/* note that this file includes real declarations and thus can only be included by one source file per executable. */ #include "opcode/m68k.h" #ifdef TE_SUN /* This variable contains the value to write out at the beginning of @@ -66,7 +66,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXeEpP"; /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be changed in read.c . Ideally it shouldn't have to know about it at all, but nothing is ideal around here. - */ + */ int md_reloc_size = 8; /* Size of relocation record */ @@ -89,56 +89,56 @@ static struct obstack robyn; #define PCLEA 6 /* Operands we can parse: (And associated modes) - -numb: 8 bit num -numw: 16 bit num -numl: 32 bit num -dreg: data reg 0-7 -reg: address or data register -areg: address register -apc: address register, PC, ZPC or empty string -num: 16 or 32 bit num -num2: like num -sz: w or l if omitted, l assumed -scale: 1 2 4 or 8 if omitted, 1 assumed - -7.4 IMMED #num --> NUM -0.? DREG dreg --> dreg -1.? AREG areg --> areg -2.? AINDR areg@ --> *(areg) -3.? AINC areg@+ --> *(areg++) -4.? ADEC areg@- --> *(--areg) -5.? AOFF apc@(numw) --> *(apc+numw) -- empty string and ZPC not allowed here -6.? AINDX apc@(num,reg:sz:scale) --> *(apc+num+reg*scale) -6.? AINDX apc@(reg:sz:scale) --> same, with num=0 -6.? APODX apc@(num)@(num2,reg:sz:scale) --> *(*(apc+num)+num2+reg*scale) -6.? APODX apc@(num)@(reg:sz:scale) --> same, with num2=0 -6.? AMIND apc@(num)@(num2) --> *(*(apc+num)+num2) (previous mode without an index reg) -6.? APRDX apc@(num,reg:sz:scale)@(num2) --> *(*(apc+num+reg*scale)+num2) -6.? APRDX apc@(reg:sz:scale)@(num2) --> same, with num=0 -7.0 ABSL num:sz --> *(num) - num --> *(num) (sz L assumed) -*** MSCR otherreg --> Magic -With -l option -5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still - -examples: - #foo #0x35 #12 - d2 - a4 - a3@ - a5@+ - a6@- - a2@(12) pc@(14) - a1@(5,d2:w:1) @(45,d6:l:4) - pc@(a2) @(d4) - etc . . . - - -#name@(numw) -->turn into PC rel mode -apc@(num8,reg:sz:scale) --> *(apc+num8+reg*scale) - -*/ + + numb: 8 bit num + numw: 16 bit num + numl: 32 bit num + dreg: data reg 0-7 + reg: address or data register + areg: address register + apc: address register, PC, ZPC or empty string + num: 16 or 32 bit num + num2: like num + sz: w or l if omitted, l assumed + scale: 1 2 4 or 8 if omitted, 1 assumed + + 7.4 IMMED #num --> NUM + 0.? DREG dreg --> dreg + 1.? AREG areg --> areg + 2.? AINDR areg@ --> *(areg) + 3.? AINC areg@+ --> *(areg++) + 4.? ADEC areg@- --> *(--areg) + 5.? AOFF apc@(numw) --> *(apc+numw) -- empty string and ZPC not allowed here + 6.? AINDX apc@(num,reg:sz:scale) --> *(apc+num+reg*scale) + 6.? AINDX apc@(reg:sz:scale) --> same, with num=0 + 6.? APODX apc@(num)@(num2,reg:sz:scale) --> *(*(apc+num)+num2+reg*scale) + 6.? APODX apc@(num)@(reg:sz:scale) --> same, with num2=0 + 6.? AMIND apc@(num)@(num2) --> *(*(apc+num)+num2) (previous mode without an index reg) + 6.? APRDX apc@(num,reg:sz:scale)@(num2) --> *(*(apc+num+reg*scale)+num2) + 6.? APRDX apc@(reg:sz:scale)@(num2) --> same, with num=0 + 7.0 ABSL num:sz --> *(num) + num --> *(num) (sz L assumed) + *** MSCR otherreg --> Magic + With -l option + 5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still + + examples: + #foo #0x35 #12 + d2 + a4 + a3@ + a5@+ + a6@- + a2@(12) pc@(14) + a1@(5,d2:w:1) @(45,d6:l:4) + pc@(a2) @(d4) + etc . . . + + + #name@(numw) -->turn into PC rel mode + apc@(num8,reg:sz:scale) --> *(apc+num8+reg*scale) + + */ enum operand_type { IMMED = 1, @@ -159,10 +159,10 @@ enum operand_type { struct m68k_exp { - char *e_beg; - char *e_end; - expressionS e_exp; - short e_siz; /* 0== default 1==short/byte 2==word 3==long */ + char *e_beg; + char *e_end; + expressionS e_exp; + short e_siz; /* 0== default 1==short/byte 2==word 3==long */ }; /* DATA and ADDR have to be contiguous, so that reg-DATA gives 0-7==data reg, @@ -188,12 +188,12 @@ enum _register { ADDR5, ADDR6, ADDR7, - -/* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */ -/* I think. . . */ - + + /* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */ + /* I think. . . */ + SP = ADDR7, - + FPREG, /* Eight FP registers */ FP0 = FPREG, FP1, @@ -216,8 +216,8 @@ enum _register { ZPC, /* Hack for Program space, but 0 addressing */ SR, /* Status Reg */ CCR, /* Condition code Reg */ - -/* These have to be in order for the movec instruction to work. */ + + /* These have to be in order for the movec instruction to work. */ USP, /* User Stack Pointer */ ISP, /* Interrupt stack pointer */ SFC, @@ -234,12 +234,12 @@ enum _register { TC, SRP, URP, -/* end of movec ordering constraints */ - + /* end of movec ordering constraints */ + FPI, FPS, FPC, - + DRP, CRP, CAL, @@ -266,57 +266,57 @@ enum _register { BAC7, PSR, PCSR, - + IC, /* instruction cache token */ DC, /* data cache token */ NC, /* no cache token */ BC, /* both caches token */ - + }; /* Internal form of an operand. */ struct m68k_op { - char *error; /* Couldn't parse it */ - enum operand_type mode; /* What mode this instruction is in. */ - enum _register reg; /* Base register */ - struct m68k_exp *con1; - int ireg; /* Index register */ - int isiz; /* 0==unspec 1==byte(?) 2==short 3==long */ - int imul; /* Multipy ireg by this (1,2,4,or 8) */ - struct m68k_exp *con2; + char *error; /* Couldn't parse it */ + enum operand_type mode; /* What mode this instruction is in. */ + enum _register reg; /* Base register */ + struct m68k_exp *con1; + int ireg; /* Index register */ + int isiz; /* 0==unspec 1==byte(?) 2==short 3==long */ + int imul; /* Multipy ireg by this (1,2,4,or 8) */ + struct m68k_exp *con2; }; /* internal form of a 68020 instruction */ struct m68k_it { - char *error; - char *args; /* list of opcode info */ - int numargs; - - int numo; /* Number of shorts in opcode */ - short opcode[11]; - - struct m68k_op operands[6]; - - int nexp; /* number of exprs in use */ - struct m68k_exp exprs[4]; - - int nfrag; /* Number of frags we have to produce */ - struct { - int fragoff; /* Where in the current opcode[] the frag ends */ - symbolS *fadd; - long foff; - int fragty; - } fragb[4]; - - int nrel; /* Num of reloc strucs in use */ - struct { - int n; - symbolS *add, - *sub; - long off; - char wid; - char pcrel; - } reloc[5]; /* Five is enough??? */ + char *error; + char *args; /* list of opcode info */ + int numargs; + + int numo; /* Number of shorts in opcode */ + short opcode[11]; + + struct m68k_op operands[6]; + + int nexp; /* number of exprs in use */ + struct m68k_exp exprs[4]; + + int nfrag; /* Number of frags we have to produce */ + struct { + int fragoff; /* Where in the current opcode[] the frag ends */ + symbolS *fadd; + long foff; + int fragty; + } fragb[4]; + + int nrel; /* Num of reloc strucs in use */ + struct { + int n; + symbolS *add, + *sub; + long off; + char wid; + char pcrel; + } reloc[5]; /* Five is enough??? */ }; #define cpu_of_arch(x) ((x) & m68000up) @@ -331,39 +331,39 @@ static struct m68k_it the_ins; /* the instruction being assembled */ /* Like addword, but goes BEFORE general operands */ #define insop(w) {int z;\ - for(z=the_ins.numo;z>opcode->m_codenum;--z)\ - the_ins.opcode[z]=the_ins.opcode[z-1];\ - for(z=0;z<the_ins.nrel;z++)\ - the_ins.reloc[z].n+=2;\ - the_ins.opcode[opcode->m_codenum]=w;\ - the_ins.numo++;\ -} + for(z=the_ins.numo;z>opcode->m_codenum;--z)\ + the_ins.opcode[z]=the_ins.opcode[z-1];\ + for(z=0;z<the_ins.nrel;z++)\ + the_ins.reloc[z].n+=2;\ + the_ins.opcode[opcode->m_codenum]=w;\ + the_ins.numo++;\ + } #define add_exp(beg,end) (\ - the_ins.exprs[the_ins.nexp].e_beg=beg,\ - the_ins.exprs[the_ins.nexp].e_end=end,\ - &the_ins.exprs[the_ins.nexp++]\ -) + the_ins.exprs[the_ins.nexp].e_beg=beg,\ + the_ins.exprs[the_ins.nexp].e_end=end,\ + &the_ins.exprs[the_ins.nexp++]\ + ) /* The numo+1 kludge is so we can hit the low order byte of the prev word. Blecch*/ #define add_fix(width,exp,pc_rel) {\ - the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \ - (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\ - the_ins.reloc[the_ins.nrel].add=adds((exp));\ - the_ins.reloc[the_ins.nrel].sub=subs((exp));\ - the_ins.reloc[the_ins.nrel].off=offs((exp));\ - the_ins.reloc[the_ins.nrel].wid=width;\ - the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\ -} + the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \ + (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\ + the_ins.reloc[the_ins.nrel].add=adds((exp));\ + the_ins.reloc[the_ins.nrel].sub=subs((exp));\ + the_ins.reloc[the_ins.nrel].off=offs((exp));\ + the_ins.reloc[the_ins.nrel].wid=width;\ + the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\ + } #define add_frag(add,off,type) {\ - the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\ - the_ins.fragb[the_ins.nfrag].fadd=add;\ - the_ins.fragb[the_ins.nfrag].foff=off;\ - the_ins.fragb[the_ins.nfrag++].fragty=type;\ -} + the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\ + the_ins.fragb[the_ins.nfrag].fadd=add;\ + the_ins.fragb[the_ins.nfrag].foff=off;\ + the_ins.fragb[the_ins.nfrag++].fragty=type;\ + } #define isvar(exp) ((exp) && (adds(exp) || subs(exp))) @@ -374,12 +374,12 @@ static struct m68k_it the_ins; /* the instruction being assembled */ struct m68k_incant { - char *m_operands; - unsigned long m_opcode; - short m_opnum; - short m_codenum; - enum m68k_architecture m_arch; - struct m68k_incant *m_next; + char *m_operands; + unsigned long m_opcode; + short m_opnum; + short m_codenum; + enum m68k_architecture m_arch; + struct m68k_incant *m_next; }; #define getone(x) ((((x)->m_opcode)>>16)&0xffff) @@ -432,61 +432,61 @@ static enum m68k_architecture current_architecture = 0; /* This is currently 10 bytes for DBCC */ /* The fields are: - How far Forward this mode will reach: - How far Backward this mode will reach: - How many bytes this mode will add to the size of the frag - Which mode to go to if the offset won't fit in this one - */ + How far Forward this mode will reach: + How far Backward this mode will reach: + How many bytes this mode will add to the size of the frag + Which mode to go to if the offset won't fit in this one + */ const relax_typeS -md_relax_table[] = { -{ 1, 1, 0, 0 }, /* First entries aren't used */ + md_relax_table[] = { + { 1, 1, 0, 0 }, /* First entries aren't used */ { 1, 1, 0, 0 }, /* For no good reason except */ { 1, 1, 0, 0 }, /* that the VAX doesn't either */ { 1, 1, 0, 0 }, - + { (127), (-128), 0, TAB(BRANCH,SHORT)}, { (32767), (-32768), 2, TAB(BRANCH,LONG) }, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* FBRANCH doesn't come BYTE */ { (32767), (-32768), 2, TAB(FBRANCH,LONG)}, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* PCREL doesn't come BYTE */ { (32767), (-32768), 2, TAB(PCREL,LONG)}, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - + { (127), (-128), 0, TAB(BCC68000,SHORT)}, { (32767), (-32768), 2, TAB(BCC68000,LONG) }, { 0, 0, 6, 0 }, /* jmp long space */ { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE */ { (32767), (-32768), 2, TAB(DBCC,LONG) }, { 0, 0, 10, 0 }, /* bra/jmp long space */ { 1, 1, 0, 0 }, - + { 1, 1, 0, 0 }, /* PCLEA doesn't come BYTE */ { 32767, -32768, 2, TAB(PCLEA,LONG) }, { 0, 0, 6, 0 }, { 1, 1, 0, 0 }, - + }; /* These are the machine dependent pseudo-ops. These are included so the assembler can work on the output from the SUN C compiler, which generates these. - */ + */ /* This table describes all the machine specific pseudo-ops the assembler has to support. The fields are: - pseudo-op name without dot - function to call to execute this pseudo-op - Integer arg to pass to the function - */ + pseudo-op name without dot + function to call to execute this pseudo-op + Integer arg to pass to the function + */ #ifdef MRI void cons(); @@ -498,40 +498,40 @@ void s_ds(); void s_dcb(); void s_dc(); const pseudo_typeS md_pseudo_table[] = { - { "xdef", s_globl, 0 }, - { "sect", s_sect, 0 }, - { "dc", s_dc, 2 }, - { "dc.d", float_cons, 'd' }, - { "dc.s", float_cons, 'f' }, - { "dc.l", s_dc, 4 }, - { "dc.w", s_dc, 2 }, - { "dc.b", s_dc, 1 }, - { "comline", s_ds, 1 }, - { "ds.b", s_ds, 1 }, - { "ds.w", s_ds, 2 }, - { "ds", s_ds, 2 }, - { "ds.l", s_ds, 4 }, - { "ds.d", s_ds, 8 }, - { "ds.s", s_ds, 4 }, - { "dcb", s_dcb, 2 }, - { "dcb.b", s_dcb, 1 }, - { "dcb.w", s_dcb, 2 }, - { "dcb.l", s_dcb, 4 }, - { "xcom", s_comm, 0 }, - { "align", s_align_bytes, 0 }, - { "chip", s_chip, 0 }, - { 0, 0, 0 } +{ "xdef", s_globl, 0 }, +{ "sect", s_sect, 0 }, +{ "dc", s_dc, 2 }, +{ "dc.d", float_cons, 'd' }, +{ "dc.s", float_cons, 'f' }, +{ "dc.l", s_dc, 4 }, +{ "dc.w", s_dc, 2 }, +{ "dc.b", s_dc, 1 }, +{ "comline", s_ds, 1 }, +{ "ds.b", s_ds, 1 }, +{ "ds.w", s_ds, 2 }, +{ "ds", s_ds, 2 }, +{ "ds.l", s_ds, 4 }, +{ "ds.d", s_ds, 8 }, +{ "ds.s", s_ds, 4 }, +{ "dcb", s_dcb, 2 }, +{ "dcb.b", s_dcb, 1 }, +{ "dcb.w", s_dcb, 2 }, +{ "dcb.l", s_dcb, 4 }, +{ "xcom", s_comm, 0 }, +{ "align", s_align_bytes, 0 }, +{ "chip", s_chip, 0 }, +{ 0, 0, 0 } }; #else const pseudo_typeS md_pseudo_table[] = { - { "data1", s_data1, 0 }, - { "data2", s_data2, 0 }, - { "bss", s_bss, 0 }, - { "even", s_even, 0 }, - { "skip", s_space, 0 }, - { "proc", s_proc, 0 }, - { 0, 0, 0 } +{ "data1", s_data1, 0 }, +{ "data2", s_data2, 0 }, +{ "bss", s_bss, 0 }, +{ "even", s_even, 0 }, +{ "skip", s_space, 0 }, +{ "proc", s_proc, 0 }, +{ 0, 0, 0 } } @@ -546,12 +546,12 @@ const pseudo_typeS md_pseudo_table[] = { #define isubyte(x) ((x)>=0 && (x)<=255) #define issword(x) ((x)>=-32768 && (x)<=32767) #define isuword(x) ((x)>=0 && (x)<=65535) - + #define isbyte(x) ((x)>=-128 && (x)<=255) #define isword(x) ((x)>=-32768 && (x)<=65535) #define islong(x) (1) - -extern char *input_line_pointer; + + extern char *input_line_pointer; enum { FAIL = 0, @@ -564,15 +564,15 @@ enum { static char mklower_table[256]; #define mklower(c) (mklower_table[(unsigned char)(c)]) -static char notend_table[256]; + static char notend_table[256]; static char alt_notend_table[256]; #define notend(s) ( !(notend_table[(unsigned char)(*s)] || (*s==':' &&\ - alt_notend_table[(unsigned char)(s[1])]))) + alt_notend_table[(unsigned char)(s[1])]))) #if 0 #define mklower(c) (isupper(c) ? tolower(c) : c) #endif - + #define ISSPACE(x) ((x) == ' ' || (x) == '\t') #ifdef MRI #define MULTIPLIER '*' @@ -581,270 +581,270 @@ static char alt_notend_table[256]; #define MULTIPLIER ':' #define SIZER ':' #endif - - -/* JF modified this to handle cases where the first part of a symbol name - looks like a register */ - -/* - * m68k_reg_parse() := if it looks like a register, return it's token & - * advance the pointer. - */ - -enum _register m68k_reg_parse(ccp) + + + /* JF modified this to handle cases where the first part of a symbol name + looks like a register */ + + /* + * m68k_reg_parse() := if it looks like a register, return it's token & + * advance the pointer. + */ + + enum _register m68k_reg_parse(ccp) register char **ccp; { #ifndef MAX_REG_NAME_LEN #define MAX_REG_NAME_LEN (6) #endif /* MAX_REG_NAME_LEN */ - register char c[MAX_REG_NAME_LEN]; - char *p, *q; - register int n = 0, - ret = FAIL; - - c[0] = mklower(ccp[0][0]); + register char c[MAX_REG_NAME_LEN]; + char *p, *q; + register int n = 0, + ret = FAIL; + + c[0] = mklower(ccp[0][0]); #ifdef REGISTER_PREFIX - if (c[0] != REGISTER_PREFIX) { - return(FAIL); + if (c[0] != REGISTER_PREFIX) { + return(FAIL); } /* need prefix */ #endif - - for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q) - { - if (*q == 0) + + for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q) { - *p = 0; - break; - } - else - *p = mklower(*q); - } /* downcase */ - - switch(c[0]) { + if (*q == 0) + { + *p = 0; + break; + } + else + *p = mklower(*q); + } /* downcase */ + + switch(c[0]) { case 'a': - if(c[1]>='0' && c[1]<='7') { - n=2; - ret=ADDR+c[1]-'0'; + if(c[1]>='0' && c[1]<='7') { + n=2; + ret=ADDR+c[1]-'0'; } #ifndef NO_68851 - else if (c[1] == 'c') { - n = 2; - ret = AC; + else if (c[1] == 'c') { + n = 2; + ret = AC; } #endif - break; + break; #ifndef NO_68851 case 'b': - if (c[1] == 'a') { - if (c[2] == 'd') { - if (c[3] >= '0' && c[3] <= '7') { - n = 4; - ret = BAD + c[3] - '0'; + if (c[1] == 'a') { + if (c[2] == 'd') { + if (c[3] >= '0' && c[3] <= '7') { + n = 4; + ret = BAD + c[3] - '0'; } } /* BAD */ - if (c[2] == 'c') { - if (c[3] >= '0' && c[3] <= '7') { - n = 4; - ret = BAC + c[3] - '0'; + if (c[2] == 'c') { + if (c[3] >= '0' && c[3] <= '7') { + n = 4; + ret = BAC + c[3] - '0'; } } /* BAC */ } else if (c[1] == 'c') { n = 2; ret = BC; - } /* BC */ - break; + } /* BC */ + break; #endif case 'c': #ifndef NO_68851 - if (c[1] == 'a' && c[2] == 'l') { - n = 3; - ret = CAL; + if (c[1] == 'a' && c[2] == 'l') { + n = 3; + ret = CAL; } else #endif - /* This supports both CCR and CC as the ccr reg. */ - if(c[1]=='c' && c[2]=='r') { - n=3; - ret = CCR; - } else if(c[1]=='c') { - n=2; - ret = CCR; - } else if(c[1]=='a' && (c[2]=='a' || c[2]=='c') && c[3]=='r') { - n=4; - ret = c[2]=='a' ? CAAR : CACR; - } + /* This supports both CCR and CC as the ccr reg. */ + if(c[1]=='c' && c[2]=='r') { + n=3; + ret = CCR; + } else if(c[1]=='c') { + n=2; + ret = CCR; + } else if(c[1]=='a' && (c[2]=='a' || c[2]=='c') && c[3]=='r') { + n=4; + ret = c[2]=='a' ? CAAR : CACR; + } #ifndef NO_68851 - else if (c[1] == 'r' && c[2] == 'p') { - n = 3; - ret = (CRP); - } + else if (c[1] == 'r' && c[2] == 'p') { + n = 3; + ret = (CRP); + } #endif - break; + break; case 'd': - if (c[1] >= '0' && c[1] <= '7') { - n = 2; - ret = DATA + c[1] - '0'; + if (c[1] >= '0' && c[1] <= '7') { + n = 2; + ret = DATA + c[1] - '0'; } else if (c[1] == 'f' && c[2] == 'c') { n = 3; ret = DFC; - } else if (c[1] == 'c') { - n = 2; - ret = DC; - } else if (c[1] == 't' && c[2] == 't') { - if ('0' <= c[3] && c[3] <= '1') { - n = 4; - ret = DTT0 + (c[3] - '0'); - } /* DTT[01] */ - } + } else if (c[1] == 'c') { + n = 2; + ret = DC; + } else if (c[1] == 't' && c[2] == 't') { + if ('0' <= c[3] && c[3] <= '1') { + n = 4; + ret = DTT0 + (c[3] - '0'); + } /* DTT[01] */ + } #ifndef NO_68851 - else if (c[1] == 'r' && c[2] == 'p') { - n = 3; - ret = (DRP); - } + else if (c[1] == 'r' && c[2] == 'p') { + n = 3; + ret = (DRP); + } #endif - break; + break; case 'f': - if(c[1]=='p') { - if(c[2]>='0' && c[2]<='7') { - n=3; - ret = FPREG+c[2]-'0'; - if(c[3]==':') - ccp[0][3]=','; + if(c[1]=='p') { + if(c[2]>='0' && c[2]<='7') { + n=3; + ret = FPREG+c[2]-'0'; + if(c[3]==':') + ccp[0][3]=','; } else if(c[2]=='i') { n=3; ret = FPI; - } else if(c[2]=='s') { - n= (c[3] == 'r' ? 4 : 3); - ret = FPS; - } else if(c[2]=='c') { - n= (c[3] == 'r' ? 4 : 3); - ret = FPC; - } else if (!isalpha(c[2]) && !isdigit(c[2])) { - n = 2; - ret = ADDR + 6; - } - - + } else if(c[2]=='s') { + n= (c[3] == 'r' ? 4 : 3); + ret = FPS; + } else if(c[2]=='c') { + n= (c[3] == 'r' ? 4 : 3); + ret = FPC; + } else if (!isalpha(c[2]) && !isdigit(c[2])) { + n = 2; + ret = ADDR + 6; + } + + } - break; + break; case 'i': - if (c[1] == 's' && c[2] == 'p') { - n = 3; - ret = ISP; + if (c[1] == 's' && c[2] == 'p') { + n = 3; + ret = ISP; } else if (c[1] == 'c') { n = 2; ret = IC; - } else if (c[1] == 't' && c[2] == 't') { - if ('0' <= c[3] && c[3] <= '1') { - n = 4; - ret = ITT0 + (c[3] - '0'); - } /* ITT[01] */ - } - break; + } else if (c[1] == 't' && c[2] == 't') { + if ('0' <= c[3] && c[3] <= '1') { + n = 4; + ret = ITT0 + (c[3] - '0'); + } /* ITT[01] */ + } + break; case 'm': - if (c[1] == 's' && c[2] == 'p') { - n = 3; - ret = MSP; + if (c[1] == 's' && c[2] == 'p') { + n = 3; + ret = MSP; } else if (c[1] == 'm' && c[2] == 'u' && c[3] == 's' && c[4] == 'r') { n = 5; ret = MMUSR; - } - break; + } + break; case 'n': - if (c[1] == 'c') { - n = 2; - ret = NC; + if (c[1] == 'c') { + n = 2; + ret = NC; } - break; + break; case 'p': - if(c[1]=='c') { + if(c[1]=='c') { #ifndef NO_68851 - if(c[2] == 's' && c[3]=='r') { - n=4; - ret = (PCSR); + if(c[2] == 's' && c[3]=='r') { + n=4; + ret = (PCSR); } else #endif { - n=2; - ret = PC; + n=2; + ret = PC; } } #ifndef NO_68851 - else if (c[1] == 's' && c[2] == 'r') { - n = 3; - ret = (PSR); + else if (c[1] == 's' && c[2] == 'r') { + n = 3; + ret = (PSR); } #endif - break; + break; case 's': #ifndef NO_68851 - if (c[1] == 'c' && c[2] == 'c') { - n = 3; - ret = (SCC); + if (c[1] == 'c' && c[2] == 'c') { + n = 3; + ret = (SCC); } else #endif - if (c[1] == 'r') { - if (c[2] == 'p') { - n = 3; - ret = SRP; - } else { - n = 2; - ret = SR; - } /* srp else sr */ - } else if (c[1] == 'p') { - n = 2; - ret = SP; - } else if (c[1] == 'f' && c[2] == 'c') { - n = 3; - ret = SFC; - } - break; + if (c[1] == 'r') { + if (c[2] == 'p') { + n = 3; + ret = SRP; + } else { + n = 2; + ret = SR; + } /* srp else sr */ + } else if (c[1] == 'p') { + n = 2; + ret = SP; + } else if (c[1] == 'f' && c[2] == 'c') { + n = 3; + ret = SFC; + } + break; case 't': - if (c[1] == 'c') { - n = 2; - ret = TC; + if (c[1] == 'c') { + n = 2; + ret = TC; } - break; + break; case 'u': - if (c[1] == 's' && c[2] == 'p') { - n=3; - ret = USP; + if (c[1] == 's' && c[2] == 'p') { + n=3; + ret = USP; } else if (c[1] == 'r' && c[2] == 'p') { n = 3; ret = URP; - } - break; + } + break; case 'v': #ifndef NO_68851 - if (c[1] == 'a' && c[2] == 'l') { - n = 3; - ret = (VAL); + if (c[1] == 'a' && c[2] == 'l') { + n = 3; + ret = (VAL); } else #endif - if(c[1]=='b' && c[2]=='r') { - n=3; - ret = VBR; - } - break; + if(c[1]=='b' && c[2]=='r') { + n=3; + ret = VBR; + } + break; case 'z': - if(c[1]=='p' && c[2]=='c') { - n=3; - ret = ZPC; + if(c[1]=='p' && c[2]=='c') { + n=3; + ret = ZPC; } - break; + break; default: - break; + break; } - if(n) { + if(n) { #ifdef REGISTER_PREFIX - n++; + n++; #endif - if(isalnum(ccp[0][n]) || ccp[0][n]=='_') - ret=FAIL; - else - ccp[0]+=n; + if(isalnum(ccp[0][n]) || ccp[0][n]=='_') + ret=FAIL; + else + ccp[0]+=n; } else - ret = FAIL; - return ret; + ret = FAIL; + return ret; } #define SKIP_WHITE() { str++; if(ISSPACE(*str)) str++;} @@ -854,262 +854,262 @@ register char **ccp; /* Parse an operand from the text *str into the operand struct *opP. */ int - m68k_ip_op(str,opP) + m68k_ip_op(str,opP) char *str; register struct m68k_op *opP; { - char *strend; - long i; - char *parse_index(); - - /* Skip leading blank */ - if(ISSPACE(*str)) - str++; - if(!*str) { - opP->error="Missing operand"; - return FAIL; - } - /* *strend = last character of string */ - for(strend=str;*strend;strend++) - ; - --strend; - - /* Logic of the parsing switch(*str): - case opP->mode = - ---- ----------- - #anything IMMED 1 - REG AREG or DREG or MSCR 3 or 2 or 13 - REG- or REG/ REGLST 14 - (REG) AINDR 4 - (REG)+ AINC 6 - (REG,INDX) AINDX 8 - (EXPR,REG) AOFF 7 - (EXPR,REG,INDX) AINDX 8 - -(REG) ADEC 5 - EXP2(REG) AOFF 7 - EXP2(REG,INDX) AINDX 8 - EXP2 ABSL 12 - - REG means truth(m68k_reg_parse(&str)) - INDX means truth(try_index(&str,opP)) - EXPR means not REG - EXP2 means not REG and not '(' and not '-(' - */ - - if(*str=='#') { - /* "#<expression>" Immediate mode */ - str++; - opP->con1=add_exp(str,strend); - opP->mode=IMMED; - return OK; - } - - i=m68k_reg_parse(&str); - if (i!=FAIL) { - if(*str=='\0') { - /* "Rn" Register Direct mode */ - opP->reg=i; - if(i>=DATA+0 && i<=DATA+7) - opP->mode=DREG; - else if(i>=ADDR+0 && i<=ADDR+7) - opP->mode=AREG; - else - opP->mode=MSCR; - return OK; - } - else if(*str=='/' || *str=='-') { - /* "Rm-Rn/Ro-Rp" Register list for MOVEM instruction */ - opP->mode=REGLST; - return get_regs(i,str,opP); - } - else { - opP->error="Junk after register name"; - return FAIL; - } - } - - if(*str=='(') { - str++; - i=m68k_reg_parse(&str); - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { - /* Can't indirect off non address regs */ - opP->error="Invalid indirect register"; - return FAIL; - } - if(i!=FAIL) { - opP->reg=i; - if(*str==')') { - str++; - if(*str=='\0') { - /* "(An)" Address Register Indirect mode */ - opP->mode=AINDR; - return OK; - } - if(*str=='+') { - if(str[1]=='\0') { - /* "(An)+" Register Indirect w Postincrement */ - opP->mode=AINC; - return OK; - } - } - opP->error="Junk after indirect"; - return FAIL; - } - if(*str==',') { - str++; - i=try_index(&str,opP); - if(i==FAIL) return FAIL; - /* "(An,Rn)" Register Indirect with Index mode*/ - opP->mode=AINDX; + char *strend; + long i; + char *parse_index(); + + /* Skip leading blank */ + if(ISSPACE(*str)) + str++; + if(!*str) { + opP->error="Missing operand"; + return FAIL; + } + /* *strend = last character of string */ + for(strend=str;*strend;strend++) + ; + --strend; + + /* Logic of the parsing switch(*str): + case opP->mode = + ---- ----------- + #anything IMMED 1 + REG AREG or DREG or MSCR 3 or 2 or 13 + REG- or REG/ REGLST 14 + (REG) AINDR 4 + (REG)+ AINC 6 + (REG,INDX) AINDX 8 + (EXPR,REG) AOFF 7 + (EXPR,REG,INDX) AINDX 8 + -(REG) ADEC 5 + EXP2(REG) AOFF 7 + EXP2(REG,INDX) AINDX 8 + EXP2 ABSL 12 + + REG means truth(m68k_reg_parse(&str)) + INDX means truth(try_index(&str,opP)) + EXPR means not REG + EXP2 means not REG and not '(' and not '-(' + */ + + if(*str=='#') { + /* "#<expression>" Immediate mode */ + str++; + opP->con1=add_exp(str,strend); + opP->mode=IMMED; + return OK; + } + + i=m68k_reg_parse(&str); + if (i!=FAIL) { + if(*str=='\0') { + /* "Rn" Register Direct mode */ + opP->reg=i; + if(i>=DATA+0 && i<=DATA+7) + opP->mode=DREG; + else if(i>=ADDR+0 && i<=ADDR+7) + opP->mode=AREG; + else + opP->mode=MSCR; + return OK; + } + else if(*str=='/' || *str=='-') { + /* "Rm-Rn/Ro-Rp" Register list for MOVEM instruction */ + opP->mode=REGLST; + return get_regs(i,str,opP); + } + else { + opP->error="Junk after register name"; + return FAIL; + } + } + + if(*str=='(') { + str++; + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { + /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + if(i!=FAIL) { + opP->reg=i; + if(*str==')') { + str++; + if(*str=='\0') { + /* "(An)" Address Register Indirect mode */ + opP->mode=AINDR; return OK; - } - else { - opP->error="Bad indirect syntax"; - return FAIL; - } - } - else { - /* "(EXPR,..." , a displacement */ - char *stmp; - char *index(); - - if(stmp=index(str,',')) { - opP->con1=add_exp(str,stmp-1); - str=stmp; - SKIP_WHITE(); - i=m68k_reg_parse(&str); - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC) { - /* Can't indirect off non address regs */ - opP->error="Invalid indirect register"; - return FAIL; - } - if(i!=FAIL) { - opP->reg=i; - if(*str==')') { - /* "(d,An)" Register Indirect w Displacement */ - opP->mode=AOFF; - return OK; - } - if(*str==',') { - str++; - i=try_index(&str,opP); - if(i==FAIL) return FAIL; - /* "(d,An,Rn)" Register Indirect with Index */ - opP->mode=AINDX; - return OK; - } - else { - opP->error="Bad indirect syntax"; - return FAIL; - } - } - else { - opP->error="Invalid register"; - return FAIL; - } - } - else { - opP->error="Missing register for indirect"; - return FAIL; - } - } - } - - if(*str=='-') { - if(str[1]=='(') { - str = str+2; - i=m68k_reg_parse(&str); - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { - /* Can't indirect off non address regs */ - opP->error="Invalid indirect register"; - return FAIL; - } - if(i!=FAIL) { - opP->reg=i; - if(*str==')') { - str++; - if(*str=='\0') { - /* "-(An)" Register Indirect with Predecrement */ - opP->mode=ADEC; - return OK; - } - opP->error="Junk after indirect"; - return FAIL; + } + if(*str=='+') { + if(str[1]=='\0') { + /* "(An)+" Register Indirect w Postincrement */ + opP->mode=AINC; + return OK; } - opP->error="Bad indirect syntax"; - return FAIL; - } - opP->error="Invalid register"; - return FAIL; - } - /* if '-' but not "-(', do nothing */ - } - - /* whether *str=='-' or not */ - { - /* "EXP2" or "EXP2(REG..." */ - char *stmp; - char *index(); - if(stmp=index(str,'(')) { - opP->con1=add_exp(str,stmp-1); - str=stmp+1; - i=m68k_reg_parse(&str); - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC) { + } + opP->error="Junk after indirect"; + return FAIL; + } + if(*str==',') { + str++; + i=try_index(&str,opP); + if(i==FAIL) return FAIL; + /* "(An,Rn)" Register Indirect with Index mode*/ + opP->mode=AINDX; + return OK; + } + else { + opP->error="Bad indirect syntax"; + return FAIL; + } + } + else { + /* "(EXPR,..." , a displacement */ + char *stmp; + char *index(); + + if(stmp=index(str,',')) { + opP->con1=add_exp(str,stmp-1); + str=stmp; + SKIP_WHITE(); + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC) { /* Can't indirect off non address regs */ opP->error="Invalid indirect register"; return FAIL; - } - if(i!=FAIL) { + } + if(i!=FAIL) { opP->reg=i; if(*str==')') { - /* "d(An)" Register Indirect w Displacement */ - opP->mode=AOFF; - return OK; + /* "(d,An)" Register Indirect w Displacement */ + opP->mode=AOFF; + return OK; } if(*str==',') { - str++; - i=try_index(&str,opP); - if(i==FAIL) return FAIL; - /* "d(An,Rn)" Register Indirect with Index */ - opP->mode=AINDX; - return OK; + str++; + i=try_index(&str,opP); + if(i==FAIL) return FAIL; + /* "(d,An,Rn)" Register Indirect with Index */ + opP->mode=AINDX; + return OK; } else { - opP->error="Bad indirect syntax"; - return FAIL; + opP->error="Bad indirect syntax"; + return FAIL; } - } - else { + } + else { opP->error="Invalid register"; return FAIL; - } - } - else { - /* "EXP2" Absolute */ - opP->mode=ABSL; - if(strend[-1]=='.') { /* mode ==foo.[wl] */ - switch(*strend) { - case 'w': - case 'W': - opP->isiz=2; - break; - case 'l': - case 'L': - opP->isiz=3; - break; - default: - opP->error="Size spec not .W or .L"; - return FAIL; + } + } + else { + opP->error="Missing register for indirect"; + return FAIL; + } + } + } + + if(*str=='-') { + if(str[1]=='(') { + str = str+2; + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { + /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + if(i!=FAIL) { + opP->reg=i; + if(*str==')') { + str++; + if(*str=='\0') { + /* "-(An)" Register Indirect with Predecrement */ + opP->mode=ADEC; + return OK; } - strend-=2; - } - else opP->isiz=0; - - - opP->con1=add_exp(str,strend); - return OK; - } - } + opP->error="Junk after indirect"; + return FAIL; + } + opP->error="Bad indirect syntax"; + return FAIL; + } + opP->error="Invalid register"; + return FAIL; + } + /* if '-' but not "-(', do nothing */ + } + + /* whether *str=='-' or not */ +{ + /* "EXP2" or "EXP2(REG..." */ + char *stmp; + char *index(); + if(stmp=index(str,'(')) { + opP->con1=add_exp(str,stmp-1); + str=stmp+1; + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC) { + /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + if(i!=FAIL) { + opP->reg=i; + if(*str==')') { + /* "d(An)" Register Indirect w Displacement */ + opP->mode=AOFF; + return OK; + } + if(*str==',') { + str++; + i=try_index(&str,opP); + if(i==FAIL) return FAIL; + /* "d(An,Rn)" Register Indirect with Index */ + opP->mode=AINDX; + return OK; + } + else { + opP->error="Bad indirect syntax"; + return FAIL; + } + } + else { + opP->error="Invalid register"; + return FAIL; + } + } + else { + /* "EXP2" Absolute */ + opP->mode=ABSL; + if(strend[-1]=='.') { /* mode ==foo.[wl] */ + switch(*strend) { + case 'w': + case 'W': + opP->isiz=2; + break; + case 'l': + case 'L': + opP->isiz=3; + break; + default: + opP->error="Size spec not .W or .L"; + return FAIL; + } + strend-=2; + } + else opP->isiz=0; + + + opP->con1=add_exp(str,strend); + return OK; + } +} } /* end of m68k_ip_op () */ #else @@ -1125,241 +1125,241 @@ register struct m68k_op *opP; */ int -m68k_ip_op(str,opP) + m68k_ip_op(str,opP) char *str; register struct m68k_op *opP; { - char *strend; - long i; - char *parse_index(); - - if (ISSPACE(*str)) { - str++; - } /* Find the beginning of the string */ - - if(!*str) { - opP->error="Missing operand"; - return FAIL; - } /* Out of gas */ - - for(strend = str; *strend; strend++) ;; - - --strend; - - if(*str=='#') { - str++; - opP->con1=add_exp(str,strend); - opP->mode=IMMED; - return OK; - } /* Guess what: A constant. Shar and enjoy */ - - i = m68k_reg_parse(&str); - - /* is a register, is exactly a register, and is followed by '@' */ - - if((i==FAIL || *str!='\0') && *str!='@') { - char *stmp; - - if(i!=FAIL && (*str=='/' || *str=='-')) { - opP->mode=REGLST; - return(get_regs(i,str,opP)); - } - if ((stmp=strchr(str,'@')) != '\0') { - opP->con1=add_exp(str,stmp-1); - if(stmp==strend) { - opP->mode=AINDX; - return(OK); - } - - if ((current_architecture & m68020up) == 0) { - return(FAIL); - } /* if target is not a '20 or better */ - - stmp++; - if(*stmp++!='(' || *strend--!=')') { - opP->error="Malformed operand"; - return(FAIL); - } - i=try_index(&stmp,opP); - opP->con2=add_exp(stmp,strend); - - if (i == FAIL) { - opP->mode=AMIND; - } else { - opP->mode=APODX; - } - return(OK); - } /* if there's an '@' */ - opP->mode = ABSL; - opP->con1 = add_exp(str,strend); - return(OK); - } /* not a register, not exactly a register, or no '@' */ - - opP->reg=i; - - if (*str=='\0') { - if(i>=DATA+0 && i<=DATA+7) - opP->mode=DREG; - else if(i>=ADDR+0 && i<=ADDR+7) - opP->mode=AREG; - else - opP->mode=MSCR; - return OK; - } - - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { /* Can't indirect off non address regs */ - opP->error="Invalid indirect register"; - return FAIL; + char *strend; + long i; + char *parse_index(); + + if (ISSPACE(*str)) { + str++; + } /* Find the beginning of the string */ + + if(!*str) { + opP->error="Missing operand"; + return FAIL; + } /* Out of gas */ + + for(strend = str; *strend; strend++) ;; + + --strend; + + if(*str=='#') { + str++; + opP->con1=add_exp(str,strend); + opP->mode=IMMED; + return OK; + } /* Guess what: A constant. Shar and enjoy */ + + i = m68k_reg_parse(&str); + + /* is a register, is exactly a register, and is followed by '@' */ + + if((i==FAIL || *str!='\0') && *str!='@') { + char *stmp; + + if(i!=FAIL && (*str=='/' || *str=='-')) { + opP->mode=REGLST; + return(get_regs(i,str,opP)); } - know(*str == '@'); - + if ((stmp=strchr(str,'@')) != '\0') { + opP->con1=add_exp(str,stmp-1); + if(stmp==strend) { + opP->mode=AINDX; + return(OK); + } + + if ((current_architecture & m68020up) == 0) { + return(FAIL); + } /* if target is not a '20 or better */ + + stmp++; + if(*stmp++!='(' || *strend--!=')') { + opP->error="Malformed operand"; + return(FAIL); + } + i=try_index(&stmp,opP); + opP->con2=add_exp(stmp,strend); + + if (i == FAIL) { + opP->mode=AMIND; + } else { + opP->mode=APODX; + } + return(OK); + } /* if there's an '@' */ + opP->mode = ABSL; + opP->con1 = add_exp(str,strend); + return(OK); + } /* not a register, not exactly a register, or no '@' */ + + opP->reg=i; + + if (*str=='\0') { + if(i>=DATA+0 && i<=DATA+7) + opP->mode=DREG; + else if(i>=ADDR+0 && i<=ADDR+7) + opP->mode=AREG; + else + opP->mode=MSCR; + return OK; + } + + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + know(*str == '@'); + + str++; + switch(*str) { + case '\0': + opP->mode=AINDR; + return OK; + case '-': + opP->mode=ADEC; + return OK; + case '+': + opP->mode=AINC; + return OK; + case '(': str++; - switch(*str) { - case '\0': - opP->mode=AINDR; - return OK; - case '-': - opP->mode=ADEC; - return OK; - case '+': - opP->mode=AINC; - return OK; - case '(': - str++; - break; - default: - opP->error="Junk after indirect"; + break; + default: + opP->error="Junk after indirect"; + return FAIL; + } + /* Some kind of indexing involved. Lets find out how bad it is */ + i=try_index(&str,opP); + /* Didn't start with an index reg, maybe its offset or offset,reg */ + if(i==FAIL) { + char *beg_str; + + beg_str=str; + for(i=1;i;) { + switch(*str++) { + case '\0': + opP->error="Missing )"; return FAIL; + case ',': i=0; break; + case '(': i++; break; + case ')': --i; break; + } } - /* Some kind of indexing involved. Lets find out how bad it is */ - i=try_index(&str,opP); - /* Didn't start with an index reg, maybe its offset or offset,reg */ - if(i==FAIL) { - char *beg_str; - - beg_str=str; - for(i=1;i;) { - switch(*str++) { - case '\0': - opP->error="Missing )"; - return FAIL; - case ',': i=0; break; - case '(': i++; break; - case ')': --i; break; - } - } - /* if(str[-3]==':') { - int siz; - - switch(str[-2]) { - case 'b': - case 'B': - siz=1; - break; - case 'w': - case 'W': - siz=2; - break; - case 'l': - case 'L': - siz=3; - break; - default: - opP->error="Specified size isn't :w or :l"; - return FAIL; - } - opP->con1=add_exp(beg_str,str-4); - opP->con1->e_siz=siz; - } else */ - opP->con1=add_exp(beg_str,str-2); - /* Should be offset,reg */ - if(str[-1]==',') { - i=try_index(&str,opP); - if(i==FAIL) { - opP->error="Malformed index reg"; - return FAIL; - } - } + /* if(str[-3]==':') { + int siz; + + switch(str[-2]) { + case 'b': + case 'B': + siz=1; + break; + case 'w': + case 'W': + siz=2; + break; + case 'l': + case 'L': + siz=3; + break; + default: + opP->error="Specified size isn't :w or :l"; + return FAIL; + } + opP->con1=add_exp(beg_str,str-4); + opP->con1->e_siz=siz; + } else */ + opP->con1=add_exp(beg_str,str-2); + /* Should be offset,reg */ + if(str[-1]==',') { + i=try_index(&str,opP); + if(i==FAIL) { + opP->error="Malformed index reg"; + return FAIL; + } } - /* We've now got offset) offset,reg) or reg) */ - - if (*str == '\0') { - /* Th-the-thats all folks */ - if (opP->reg == FAIL) opP->mode = AINDX; /* Other form of indirect */ - else if(opP->ireg == FAIL) opP->mode = AOFF; - else opP->mode = AINDX; - return(OK); + } + /* We've now got offset) offset,reg) or reg) */ + + if (*str == '\0') { + /* Th-the-thats all folks */ + if (opP->reg == FAIL) opP->mode = AINDX; /* Other form of indirect */ + else if(opP->ireg == FAIL) opP->mode = AOFF; + else opP->mode = AINDX; + return(OK); + } + /* Next thing had better be another @ */ + if(*str!='@' || str[1]!='(') { + opP->error = "junk after indirect"; + return(FAIL); + } + + if ((current_architecture & m68020up) == 0) { + return(FAIL); + } /* if target is not a '20 or better */ + + str+=2; + + if(opP->ireg != FAIL) { + opP->mode = APRDX; + + i = try_index(&str, opP); + if (i != FAIL) { + opP->error = "Two index registers! not allowed!"; + return(FAIL); } - /* Next thing had better be another @ */ - if(*str!='@' || str[1]!='(') { - opP->error = "junk after indirect"; + } else { + i = try_index(&str, opP); + } + + if (i == FAIL) { + char *beg_str; + + beg_str = str; + + for (i = 1; i; ) { + switch(*str++) { + case '\0': + opP->error="Missing )"; return(FAIL); + case ',': i=0; break; + case '(': i++; break; + case ')': --i; break; + } } - if ((current_architecture & m68020up) == 0) { + opP->con2=add_exp(beg_str,str-2); + + if (str[-1] == ',') { + if (opP->ireg != FAIL) { + opP->error = "Can't have two index regs"; return(FAIL); - } /* if target is not a '20 or better */ - - str+=2; - - if(opP->ireg != FAIL) { - opP->mode = APRDX; - - i = try_index(&str, opP); - if (i != FAIL) { - opP->error = "Two index registers! not allowed!"; - return(FAIL); - } - } else { - i = try_index(&str, opP); - } - - if (i == FAIL) { - char *beg_str; - - beg_str = str; - - for (i = 1; i; ) { - switch(*str++) { - case '\0': - opP->error="Missing )"; - return(FAIL); - case ',': i=0; break; - case '(': i++; break; - case ')': --i; break; - } - } - - opP->con2=add_exp(beg_str,str-2); - - if (str[-1] == ',') { - if (opP->ireg != FAIL) { - opP->error = "Can't have two index regs"; - return(FAIL); - } - - i = try_index(&str, opP); - - if (i == FAIL) { - opP->error = "malformed index reg"; - return(FAIL); - } - - opP->mode = APODX; - } else if (opP->ireg != FAIL) { - opP->mode = APRDX; - } else { - opP->mode = AMIND; - } + } + + i = try_index(&str, opP); + + if (i == FAIL) { + opP->error = "malformed index reg"; + return(FAIL); + } + + opP->mode = APODX; + } else if (opP->ireg != FAIL) { + opP->mode = APRDX; } else { - opP->mode = APODX; - } - - if(*str!='\0') { - opP->error="Junk after indirect"; - return FAIL; + opP->mode = AMIND; } - return(OK); + } else { + opP->mode = APODX; + } + + if(*str!='\0') { + opP->error="Junk after indirect"; + return FAIL; + } + return(OK); } /* m68k_ip_op() */ #endif /* @@ -1380,108 +1380,108 @@ register struct m68k_op *opP; */ static int try_index(s,opP) -char **s; -struct m68k_op *opP; + char **s; + struct m68k_op *opP; { - register int i; - char *ss; + register int i; + char *ss; #define SKIP_W() { ss++; if (ISSPACE(*ss)) ss++;} - - ss= *s; - /* SKIP_W(); */ - i=m68k_reg_parse(&ss); - if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ - *s=ss; - return FAIL; - } - opP->ireg=i; - /* SKIP_W(); */ - if(*ss==')') { - opP->isiz=0; - opP->imul=1; - SKIP_W(); - *s=ss; - return OK; - } - if(*ss!=SIZER) - { - opP->error="Missing : in index register"; - *s=ss; - return FAIL; - } + + ss= *s; + /* SKIP_W(); */ + i=m68k_reg_parse(&ss); + if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ + *s=ss; + return FAIL; + } + opP->ireg=i; + /* SKIP_W(); */ + if(*ss==')') { + opP->isiz=0; + opP->imul=1; + SKIP_W(); + *s=ss; + return OK; + } + if(*ss!=SIZER) + { + opP->error="Missing : in index register"; + *s=ss; + return FAIL; + } + SKIP_W(); + switch(*ss) { + case 'w': + case 'W': + opP->isiz=2; + break; + case 'l': + case 'L': + opP->isiz=3; + break; + default: + opP->error="Index register size spec not :w or :l"; + *s=ss; + return FAIL; + } + SKIP_W(); + if(*ss==MULTIPLIER) + { SKIP_W(); switch(*ss) { - case 'w': - case 'W': - opP->isiz=2; - break; - case 'l': - case 'L': - opP->isiz=3; - break; + case '1': + case '2': + case '4': + case '8': + opP->imul= *ss-'0'; + break; default: - opP->error="Index register size spec not :w or :l"; - *s=ss; - return FAIL; - } - SKIP_W(); - if(*ss==MULTIPLIER) - { - SKIP_W(); - switch(*ss) { - case '1': - case '2': - case '4': - case '8': - opP->imul= *ss-'0'; - break; - default: - opP->error="index multiplier not 1, 2, 4 or 8"; - *s=ss; - return FAIL; - } - SKIP_W(); - } else opP->imul=1; - if(*ss!=')') { - opP->error="Missing )"; - *s=ss; - return FAIL; + opP->error="index multiplier not 1, 2, 4 or 8"; + *s=ss; + return FAIL; } SKIP_W(); + } else opP->imul=1; + if(*ss!=')') { + opP->error="Missing )"; *s=ss; - return OK; + return FAIL; + } + SKIP_W(); + *s=ss; + return OK; } /* try_index() */ #ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */ main() { - char buf[128]; - struct m68k_op thark; - - for(;;) { - if(!gets(buf)) - break; - bzero(&thark,sizeof(thark)); - if(!m68k_ip_op(buf,&thark)) printf("FAIL:"); - if(thark.error) - printf("op1 error %s in %s\n",thark.error,buf); - printf("mode %d, reg %d, ",thark.mode,thark.reg); - if(thark.b_const) - printf("Constant: '%.*s',",1+thark.e_const-thark.b_const,thark.b_const); - printf("ireg %d, isiz %d, imul %d ",thark.ireg,thark.isiz,thark.imul); - if(thark.b_iadd) - printf("Iadd: '%.*s'",1+thark.e_iadd-thark.b_iadd,thark.b_iadd); - printf("\n"); - } - exit(0); + char buf[128]; + struct m68k_op thark; + + for(;;) { + if(!gets(buf)) + break; + bzero(&thark,sizeof(thark)); + if(!m68k_ip_op(buf,&thark)) printf("FAIL:"); + if(thark.error) + printf("op1 error %s in %s\n",thark.error,buf); + printf("mode %d, reg %d, ",thark.mode,thark.reg); + if(thark.b_const) + printf("Constant: '%.*s',",1+thark.e_const-thark.b_const,thark.b_const); + printf("ireg %d, isiz %d, imul %d ",thark.ireg,thark.isiz,thark.imul); + if(thark.b_iadd) + printf("Iadd: '%.*s'",1+thark.e_iadd-thark.b_iadd,thark.b_iadd); + printf("\n"); + } + exit(0); } #endif static struct hash_control* op_hash = NULL; /* handle of the OPCODE hash table - NULL means any use before m68k_ip_begin() - will crash */ + NULL means any use before m68k_ip_begin() + will crash */ /* @@ -1510,130 +1510,130 @@ static struct hash_control* op_hash = NULL; /* handle of the OPCODE hash table /* JF this function no longer returns a useful value. Sorry */ void m68k_ip (instring) -char *instring; + char *instring; { - register char *p; - register struct m68k_op *opP; - register struct m68k_incant *opcode, prev_opcode; - register char *s; - register int tmpreg = 0, - baseo = 0, - outro = 0, - nextword; - int siz1, - siz2; - char c; - int losing; - int opsfound; - char *crack_operand(); - - LITTLENUM_TYPE words[6]; - LITTLENUM_TYPE *wordp; - - if (ISSPACE(*instring)) - instring++; /* skip leading whitespace */ - - /* Scan up to end of operation-code, which MUST end in end-of-string - or exactly 1 space. */ - for (p = instring; *p != '\0'; p++) - if (ISSPACE(*p)) - break; - - - if (p == instring) { - the_ins.error = "No operator"; - the_ins.opcode[0] = NULL; - /* the_ins.numo=1; */ - return; + register char *p; + register struct m68k_op *opP; + register struct m68k_incant *opcode, prev_opcode; + register char *s; + register int tmpreg = 0, + baseo = 0, + outro = 0, + nextword; + int siz1, + siz2; + char c; + int losing; + int opsfound; + char *crack_operand(); + + LITTLENUM_TYPE words[6]; + LITTLENUM_TYPE *wordp; + + if (ISSPACE(*instring)) + instring++; /* skip leading whitespace */ + + /* Scan up to end of operation-code, which MUST end in end-of-string + or exactly 1 space. */ + for (p = instring; *p != '\0'; p++) + if (ISSPACE(*p)) + break; + + + if (p == instring) { + the_ins.error = "No operator"; + the_ins.opcode[0] = NULL; + /* the_ins.numo=1; */ + return; } - - /* p now points to the end of the opcode name, probably whitespace. - make sure the name is null terminated by clobbering the whitespace, - look it up in the hash table, then fix it back. */ - c = *p; - *p = '\0'; + + /* p now points to the end of the opcode name, probably whitespace. + make sure the name is null terminated by clobbering the whitespace, + look it up in the hash table, then fix it back. */ + c = *p; + *p = '\0'; #ifdef MRI - /* Copy from input line to our private buffer, and drop any dots */ + /* Copy from input line to our private buffer, and drop any dots */ { - char our_copy[100]; - char *dst = our_copy; - char *src = instring; - while (*src) - { - if (*src != '.') - *dst++ = *src; - src++; - } - *dst = 0; - - - opcode = (struct m68k_incant *)hash_find (op_hash, our_copy); - - /* If no match, try again with a w suffix */ - if (!opcode) - { - *dst++ = 'w'; + char our_copy[100]; + char *dst = our_copy; + char *src = instring; + while (*src) + { + if (*src != '.') + *dst++ = *src; + src++; + } *dst = 0; + + opcode = (struct m68k_incant *)hash_find (op_hash, our_copy); - } - + + /* If no match, try again with a w suffix */ + if (!opcode) + { + *dst++ = 'w'; + *dst = 0; + opcode = (struct m68k_incant *)hash_find (op_hash, our_copy); + } + } - + #else - opcode = (struct m68k_incant *)hash_find (op_hash, instring); +opcode = (struct m68k_incant *)hash_find (op_hash, instring); #endif - *p = c; - - if (opcode == NULL) { - the_ins.error = "Unknown opcode"; - the_ins.opcode[0] = NULL; - /* the_ins.numo=1; */ - return; - } +*p = c; + +if (opcode == NULL) { + the_ins.error = "Unknown opcode"; + the_ins.opcode[0] = NULL; + /* the_ins.numo=1; */ + return; +} + +/* found a legitimate opcode, start matching operands */ +while (ISSPACE(*p)) ++p; + + for(opP = &the_ins.operands[0]; *p; opP++) { - /* found a legitimate opcode, start matching operands */ - while (ISSPACE(*p)) ++p; + p = crack_operand(p, opP); - for(opP = &the_ins.operands[0]; *p; opP++) { - - p = crack_operand(p, opP); - - if (opP->error) { - the_ins.error=opP->error; - return; + if (opP->error) { + the_ins.error=opP->error; + return; } } + + opsfound = opP - &the_ins.operands[0]; + + /* This ugly hack is to support the floating pt opcodes in their standard form */ + /* Essentially, we fake a first enty of type COP#1 */ + if (opcode->m_operands[0]=='I') { + int n; - opsfound = opP - &the_ins.operands[0]; + for(n=opsfound;n>0;--n) + the_ins.operands[n]=the_ins.operands[n-1]; - /* This ugly hack is to support the floating pt opcodes in their standard form */ - /* Essentially, we fake a first enty of type COP#1 */ - if (opcode->m_operands[0]=='I') { - int n; - - for(n=opsfound;n>0;--n) - the_ins.operands[n]=the_ins.operands[n-1]; - - /* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */ - bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0])); - the_ins.operands[0].mode=MSCR; - the_ins.operands[0].reg=COPNUM; /* COP #1 */ - opsfound++; + /* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */ + bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0])); + the_ins.operands[0].mode=MSCR; + the_ins.operands[0].reg=COPNUM; /* COP #1 */ + opsfound++; } + + /* We've got the operands. Find an opcode that'll accept them */ + for (losing = 0; ; ) { + /* if we didn't get the right number of ops, + or we have no common model with this pattern + then reject this pattern. */ - /* We've got the operands. Find an opcode that'll accept them */ - for (losing = 0; ; ) { - /* if we didn't get the right number of ops, - or we have no common model with this pattern - then reject this pattern. */ - - if (opsfound != opcode->m_opnum - || ((opcode->m_arch & current_architecture) == 0)) { - - ++losing; - + if (opsfound != opcode->m_opnum + || ((opcode->m_arch & current_architecture) == 0)) { + + ++losing; + } else { for (s=opcode->m_operands, opP = &the_ins.operands[0]; *s && !losing; s += 2, opP++) { /* Warning: this switch is huge! */ @@ -1643,144 +1643,144 @@ char *instring; /* Code with multiple case ...: gets sorted by the lowest case ... it belongs to. I hope this makes sense. */ switch(*s) { - case '!': + case '!': if (opP->mode == MSCR || opP->mode == IMMED || opP->mode == DREG || opP->mode == AREG || opP->mode == AINC || opP->mode == ADEC || opP->mode == REGLST) - losing++; + losing++; break; - - case '#': + + case '#': if(opP->mode!=IMMED) - losing++; + losing++; else { long t; - + t=get_num(opP->con1,80); if(s[1]=='b' && !isbyte(t)) - losing++; + losing++; else if(s[1]=='w' && !isword(t)) - losing++; - } + losing++; + } break; - - case '^': - case 'T': + + case '^': + case 'T': if(opP->mode!=IMMED) - losing++; + losing++; break; - - case '$': + + case '$': if(opP->mode==MSCR || opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) - losing++; + losing++; break; - - case '%': + + case '%': if(opP->mode==MSCR || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) - losing++; + losing++; break; - - - case '&': + + + case '&': if(opP->mode==MSCR || opP->mode==DREG || opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST) - losing++; + losing++; break; - - case '*': + + case '*': if(opP->mode==MSCR || opP->mode==REGLST) - losing++; + losing++; break; - - case '+': + + case '+': if(opP->mode!=AINC) - losing++; + losing++; break; - - case '-': + + case '-': if(opP->mode!=ADEC) - losing++; + losing++; break; - - case '/': + + case '/': if(opP->mode==MSCR || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->mode==REGLST) - losing++; + losing++; break; - - case ';': + + case ';': if(opP->mode==MSCR || opP->mode==AREG || opP->mode==REGLST) - losing++; + losing++; break; - - case '?': + + case '?': if(opP->mode==MSCR || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) - losing++; + losing++; break; - - case '@': + + case '@': if(opP->mode==MSCR || opP->mode==AREG || opP->mode==IMMED || opP->mode==REGLST) - losing++; + losing++; break; - - case '~': /* For now! (JF FOO is this right?) */ + + case '~': /* For now! (JF FOO is this right?) */ if(opP->mode==MSCR || opP->mode==DREG || opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST) - losing++; + losing++; break; - - case 'A': + + case 'A': if(opP->mode!=AREG) - losing++; + losing++; break; - case 'a': + case 'a': if (opP->mode != AINDR) { ++losing; - } /* if not address register indirect */ + } /* if not address register indirect */ break; - case 'B': /* FOO */ + case 'B': /* FOO */ if(opP->mode!=ABSL || (flagseen['S'] && instring[0] == 'j' && instring[1] == 'b' && instring[2] == 's' && instring[3] == 'r')) - losing++; + losing++; break; - - case 'C': + + case 'C': if(opP->mode!=MSCR || opP->reg!=CCR) - losing++; + losing++; break; - - case 'd': /* FOO This mode is a KLUDGE!! */ + + case 'd': /* FOO This mode is a KLUDGE!! */ if(opP->mode!=AOFF && (opP->mode!=ABSL || opP->con1->e_beg[0]!='(' || opP->con1->e_end[0]!=')')) - losing++; + losing++; break; - - case 'D': + + case 'D': if(opP->mode!=DREG) - losing++; + losing++; break; - - case 'F': + + case 'F': if(opP->mode!=MSCR || opP->reg<(FPREG+0) || opP->reg>(FPREG+7)) - losing++; + losing++; break; - - case 'I': + + case 'I': if(opP->mode!=MSCR || opP->reg<COPNUM || opP->reg>=COPNUM+7) - losing++; + losing++; break; - - case 'J': + + case 'J': if (opP->mode != MSCR || opP->reg < USP || opP->reg > URP @@ -1802,191 +1802,191 @@ char *instring; || (cpu_of_arch(current_architecture) == m68040 /* 68040 has all but this */ && opP->reg == CAAR)) { losing++; - } /* doesn't cut it */ + } /* doesn't cut it */ break; - - case 'k': + + case 'k': if(opP->mode!=IMMED) - losing++; + losing++; break; - - case 'l': - case 'L': + + case 'l': + case 'L': if(opP->mode==DREG || opP->mode==AREG || opP->mode==FPREG) { if(s[1]=='8') - losing++; + losing++; else { opP->mode=REGLST; opP->reg=1<<(opP->reg-DATA); - } - } else if(opP->mode!=REGLST) { - losing++; - } else if(s[1]=='8' && opP->reg&0x0FFffFF) - losing++; - else if(s[1]=='3' && opP->reg&0x7000000) - losing++; + } + } else if(opP->mode!=REGLST) { + losing++; + } else if(s[1]=='8' && opP->reg&0x0FFffFF) + losing++; + else if(s[1]=='3' && opP->reg&0x7000000) + losing++; break; - - case 'M': + + case 'M': if(opP->mode!=IMMED) - losing++; + losing++; else { long t; - + t=get_num(opP->con1,80); if(!issbyte(t) || isvar(opP->con1)) - losing++; - } + losing++; + } break; - - case 'O': + + case 'O': if(opP->mode!=DREG && opP->mode!=IMMED) - losing++; + losing++; break; - - case 'Q': + + case 'Q': if(opP->mode!=IMMED) - losing++; + losing++; else { long t; - + t=get_num(opP->con1,80); if(t<1 || t>8 || isvar(opP->con1)) - losing++; - } + losing++; + } break; - - case 'R': + + case 'R': if(opP->mode!=DREG && opP->mode!=AREG) - losing++; + losing++; break; - - case 's': + + case 's': if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC)) - losing++; + losing++; break; - - case 'S': + + case 'S': if(opP->mode!=MSCR || opP->reg!=SR) - losing++; + losing++; break; - - case 'U': + + case 'U': if(opP->mode!=MSCR || opP->reg!=USP) - losing++; + losing++; break; - + /* JF these are out of order. We could put them in order if we were willing to put up with bunches of #ifdef m68851s in the code */ #ifndef NO_68851 /* Memory addressing mode used by pflushr */ - case '|': + case '|': if(opP->mode==MSCR || opP->mode==DREG || opP->mode==AREG || opP->mode==REGLST) - losing++; + losing++; break; - - case 'f': + + case 'f': if (opP->mode != MSCR || (opP->reg != SFC && opP->reg != DFC)) - losing++; + losing++; break; - - case 'P': + + case 'P': if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL && opP->reg != VAL && opP->reg != SCC && opP->reg != AC)) - losing++; + losing++; break; - - case 'V': + + case 'V': if (opP->reg != VAL) - losing++; + losing++; break; - - case 'W': + + case 'W': if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP && opP->reg != CRP)) - losing++; + losing++; break; - - case 'X': + + case 'X': if (opP->mode != MSCR || (!(opP->reg >= BAD && opP->reg <= BAD+7) && !(opP->reg >= BAC && opP->reg <= BAC+7))) - losing++; + losing++; break; - - case 'Y': + + case 'Y': if (opP->reg != PSR) - losing++; + losing++; break; - - case 'Z': + + case 'Z': if (opP->reg != PCSR) - losing++; + losing++; break; #endif - case 'c': + case 'c': if (opP->reg != NC && opP->reg != IC && opP->reg != DC && opP->reg != BC) { losing++; - } /* not a cache specifier. */ + } /* not a cache specifier. */ break; - - case '_': + + case '_': if (opP->mode != ABSL) { ++losing; - } /* not absolute */ + } /* not absolute */ break; - - default: + + default: as_fatal("Internal error: Operand mode %c unknown in line %s of file \"%s\"", *s, __LINE__, __FILE__); - } /* switch on type of operand */ - - if (losing) break; - } /* for each operand */ - } /* if immediately wrong */ + } /* switch on type of operand */ - if (!losing) { - break; - } /* got it. */ - - - if (!opcode->m_next) - { - if ((opcode->m_arch & current_architecture) == 0) - { - the_ins.error = "Opcode not available on architecture specified"; - addword(0); - - } - else - { - the_ins.error = "instruction/operands mismatch"; - } + if (losing) break; + } /* for each operand */ + } /* if immediately wrong */ - return; - } /* Fell off the end */ - opcode = opcode->m_next; - losing = 0; - } + if (!losing) { + break; + } /* got it. */ - /* now assemble it */ - - the_ins.args=opcode->m_operands; - the_ins.numargs=opcode->m_opnum; - the_ins.numo=opcode->m_codenum; - the_ins.opcode[0]=getone(opcode); - the_ins.opcode[1]=gettwo(opcode); - for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) { - /* This switch is a doozy. - Watch the first step; its a big one! */ - switch(s[0]) { - + if (!opcode->m_next) + { + if ((opcode->m_arch & current_architecture) == 0) + { + the_ins.error = "Opcode not available on architecture specified"; + addword(0); + + } + else + { + the_ins.error = "instruction/operands mismatch"; + } + + return; + } /* Fell off the end */ + opcode = opcode->m_next; + losing = 0; + } + + /* now assemble it */ + + the_ins.args=opcode->m_operands; + the_ins.numargs=opcode->m_opnum; + the_ins.numo=opcode->m_codenum; + the_ins.opcode[0]=getone(opcode); + the_ins.opcode[1]=gettwo(opcode); + + for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) { + /* This switch is a doozy. + Watch the first step; its a big one! */ + switch(s[0]) { + case '*': case '~': case '%': @@ -2000,743 +2000,743 @@ char *instring; #ifndef NO_68851 case '|': #endif - switch(opP->mode) { + switch(opP->mode) { case IMMED: - tmpreg=0x3c; /* 7.4 */ - if (strchr("bwl",s[1])) nextword=get_num(opP->con1,80); - else nextword=nextword=get_num(opP->con1,0); - if(isvar(opP->con1)) - add_fix(s[1],opP->con1,0); - switch(s[1]) { + tmpreg=0x3c; /* 7.4 */ + if (strchr("bwl",s[1])) nextword=get_num(opP->con1,80); + else nextword=nextword=get_num(opP->con1,0); + if(isvar(opP->con1)) + add_fix(s[1],opP->con1,0); + switch(s[1]) { case 'b': - if(!isbyte(nextword)) - opP->error="operand out of range"; - addword(nextword); - baseo=0; - break; + if(!isbyte(nextword)) + opP->error="operand out of range"; + addword(nextword); + baseo=0; + break; case 'w': - if(!isword(nextword)) - opP->error="operand out of range"; - addword(nextword); - baseo=0; - break; + if(!isword(nextword)) + opP->error="operand out of range"; + addword(nextword); + baseo=0; + break; case 'l': - addword(nextword>>16); - addword(nextword); - baseo=0; - break; - + addword(nextword>>16); + addword(nextword); + baseo=0; + break; + case 'f': - baseo=2; - outro=8; - break; + baseo=2; + outro=8; + break; case 'F': - baseo=4; - outro=11; - break; + baseo=4; + outro=11; + break; case 'x': - baseo=6; - outro=15; - break; + baseo=6; + outro=15; + break; case 'p': - baseo=6; - outro= -1; - break; + baseo=6; + outro= -1; + break; default: - as_fatal("Internal error: Can't decode %c%c in line %s of file \"%s\"", - *s, s[1], __LINE__, __FILE__); + as_fatal("Internal error: Can't decode %c%c in line %s of file \"%s\"", + *s, s[1], __LINE__, __FILE__); } - if(!baseo) - break; - - /* We gotta put out some float */ - if(seg(opP->con1)!=SEG_BIG) { - int_to_gen(nextword); - gen_to_words(words,baseo,(long int)outro); - for(wordp=words;baseo--;wordp++) - addword(*wordp); - break; + if(!baseo) + break; + + /* We gotta put out some float */ + if(seg(opP->con1)!=SEG_BIG) { + int_to_gen(nextword); + gen_to_words(words,baseo,(long int)outro); + for(wordp=words;baseo--;wordp++) + addword(*wordp); + break; } /* Its BIG */ - if(offs(opP->con1)>0) { - as_warn("Bignum assumed to be binary bit-pattern"); - if(offs(opP->con1)>baseo) { - as_warn("Bignum too big for %c format; truncated",s[1]); - offs(opP->con1)=baseo; + if(offs(opP->con1)>0) { + as_warn("Bignum assumed to be binary bit-pattern"); + if(offs(opP->con1)>baseo) { + as_warn("Bignum too big for %c format; truncated",s[1]); + offs(opP->con1)=baseo; } - baseo-=offs(opP->con1); - for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp) - addword(*wordp); - while(baseo--) - addword(0); - break; + baseo-=offs(opP->con1); + for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp) + addword(*wordp); + while(baseo--) + addword(0); + break; } - gen_to_words(words,baseo,(long)outro); - for (wordp=words;baseo--;wordp++) - addword(*wordp); - break; + gen_to_words(words,baseo,(long)outro); + for (wordp=words;baseo--;wordp++) + addword(*wordp); + break; case DREG: - tmpreg=opP->reg-DATA; /* 0.dreg */ - break; + tmpreg=opP->reg-DATA; /* 0.dreg */ + break; case AREG: - tmpreg=0x08+opP->reg-ADDR; /* 1.areg */ - break; + tmpreg=0x08+opP->reg-ADDR; /* 1.areg */ + break; case AINDR: - tmpreg=0x10+opP->reg-ADDR; /* 2.areg */ - break; + tmpreg=0x10+opP->reg-ADDR; /* 2.areg */ + break; case ADEC: - tmpreg=0x20+opP->reg-ADDR; /* 4.areg */ - break; + tmpreg=0x20+opP->reg-ADDR; /* 4.areg */ + break; case AINC: - tmpreg=0x18+opP->reg-ADDR; /* 3.areg */ - break; + tmpreg=0x18+opP->reg-ADDR; /* 3.areg */ + break; case AOFF: - - nextword=get_num(opP->con1,80); - /* Force into index mode. Hope this works */ - - /* We do the first bit for 32-bit displacements, - and the second bit for 16 bit ones. It is - possible that we should make the default be - WORD instead of LONG, but I think that'd - break GCC, so we put up with a little - inefficiency for the sake of working output. - */ - - if( !issword(nextword) - || ( isvar(opP->con1) - && ( ( opP->con1->e_siz==0 - && flagseen['l']==0) - || opP->con1->e_siz==3))) { - - if(opP->reg==PC) - tmpreg=0x3B; /* 7.3 */ - else - tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ - if(isvar(opP->con1)) { - if(opP->reg==PC) { - add_frag(adds(opP->con1), - offs(opP->con1), - TAB(PCLEA,SZ_UNDEF)); - break; + + nextword=get_num(opP->con1,80); + /* Force into index mode. Hope this works */ + + /* We do the first bit for 32-bit displacements, + and the second bit for 16 bit ones. It is + possible that we should make the default be + WORD instead of LONG, but I think that'd + break GCC, so we put up with a little + inefficiency for the sake of working output. + */ + + if( !issword(nextword) + || ( isvar(opP->con1) + && ( ( opP->con1->e_siz==0 + && flagseen['l']==0) + || opP->con1->e_siz==3))) { + + if(opP->reg==PC) + tmpreg=0x3B; /* 7.3 */ + else + tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ + if(isvar(opP->con1)) { + if(opP->reg==PC) { + add_frag(adds(opP->con1), + offs(opP->con1), + TAB(PCLEA,SZ_UNDEF)); + break; } else { addword(0x0170); add_fix('l',opP->con1,1); - } + } } else - addword(0x0170); - addword(nextword>>16); + addword(0x0170); + addword(nextword>>16); } else { if(opP->reg==PC) - tmpreg=0x3A; /* 7.2 */ + tmpreg=0x3A; /* 7.2 */ else - tmpreg=0x28+opP->reg-ADDR; /* 5.areg */ - + tmpreg=0x28+opP->reg-ADDR; /* 5.areg */ + if(isvar(opP->con1)) { if(opP->reg==PC) { add_fix('w',opP->con1,1); - } else - add_fix('w',opP->con1,0); - } - } - addword(nextword); - break; - + } else + add_fix('w',opP->con1,0); + } + } + addword(nextword); + break; + case APODX: case AMIND: case APRDX: - know(current_architecture & m68020up); - /* intentional fall-through */ + know(current_architecture & m68020up); + /* intentional fall-through */ case AINDX: - nextword=0; - baseo=get_num(opP->con1,80); - outro=get_num(opP->con2,80); - /* Figure out the 'addressing mode' */ - /* Also turn on the BASE_DISABLE bit, if needed */ - if(opP->reg==PC || opP->reg==ZPC) { - tmpreg=0x3b; /* 7.3 */ - if(opP->reg==ZPC) - nextword|=0x80; + nextword=0; + baseo=get_num(opP->con1,80); + outro=get_num(opP->con2,80); + /* Figure out the 'addressing mode' */ + /* Also turn on the BASE_DISABLE bit, if needed */ + if(opP->reg==PC || opP->reg==ZPC) { + tmpreg=0x3b; /* 7.3 */ + if(opP->reg==ZPC) + nextword|=0x80; } else if(opP->reg==FAIL) { nextword|=0x80; tmpreg=0x30; /* 6.garbage */ - } else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ - - siz1= (opP->con1) ? opP->con1->e_siz : 0; - siz2= (opP->con2) ? opP->con2->e_siz : 0; - - /* Index register stuff */ - if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) { - nextword|=(opP->ireg-DATA)<<12; - - if(opP->isiz==0 || opP->isiz==3) - nextword|=0x800; - switch(opP->imul) { + } else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */ + + siz1= (opP->con1) ? opP->con1->e_siz : 0; + siz2= (opP->con2) ? opP->con2->e_siz : 0; + + /* Index register stuff */ + if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) { + nextword|=(opP->ireg-DATA)<<12; + + if(opP->isiz==0 || opP->isiz==3) + nextword|=0x800; + switch(opP->imul) { case 1: break; case 2: nextword|=0x200; break; case 4: nextword|=0x400; break; case 8: nextword|=0x600; break; default: as_fatal("failed sanity check."); } - /* IF its simple, - GET US OUT OF HERE! */ - - /* Must be INDEX, with an index - register. Address register - cannot be ZERO-PC, and either - :b was forced, or we know - it will fit */ - if( opP->mode==AINDX - && opP->reg!=FAIL - && opP->reg!=ZPC - && ( siz1==1 - || ( issbyte(baseo) - && !isvar(opP->con1)))) { - nextword +=baseo&0xff; - addword(nextword); - if(isvar(opP->con1)) - add_fix('B',opP->con1,0); - break; + /* IF its simple, + GET US OUT OF HERE! */ + + /* Must be INDEX, with an index + register. Address register + cannot be ZERO-PC, and either + :b was forced, or we know + it will fit */ + if( opP->mode==AINDX + && opP->reg!=FAIL + && opP->reg!=ZPC + && ( siz1==1 + || ( issbyte(baseo) + && !isvar(opP->con1)))) { + nextword +=baseo&0xff; + addword(nextword); + if(isvar(opP->con1)) + add_fix('B',opP->con1,0); + break; } } else - nextword|=0x40; /* No index reg */ - - /* It aint simple */ - nextword|=0x100; - /* If the guy specified a width, we assume that - it is wide enough. Maybe it isn't. If so, we lose - */ - switch(siz1) { + nextword|=0x40; /* No index reg */ + + /* It aint simple */ + nextword|=0x100; + /* If the guy specified a width, we assume that + it is wide enough. Maybe it isn't. If so, we lose + */ + switch(siz1) { case 0: - if(isvar(opP->con1) || !issword(baseo)) { - siz1=3; - nextword|=0x30; + if(isvar(opP->con1) || !issword(baseo)) { + siz1=3; + nextword|=0x30; } else if(baseo==0) - nextword|=0x10; + nextword|=0x10; else { nextword|=0x20; siz1=2; - } - break; + } + break; case 1: - as_warn("Byte dispacement won't work. Defaulting to :w"); + as_warn("Byte dispacement won't work. Defaulting to :w"); case 2: - nextword|=0x20; - break; + nextword|=0x20; + break; case 3: - nextword|=0x30; - break; + nextword|=0x30; + break; } - - /* Figure out innner displacement stuff */ - if(opP->mode!=AINDX) { - switch(siz2) { + + /* Figure out innner displacement stuff */ + if(opP->mode!=AINDX) { + switch(siz2) { case 0: - if(isvar(opP->con2) || !issword(outro)) { - siz2=3; - nextword|=0x3; + if(isvar(opP->con2) || !issword(outro)) { + siz2=3; + nextword|=0x3; } else if(outro==0) - nextword|=0x1; + nextword|=0x1; else { - nextword|=0x2; - siz2=2; - } - break; - case 1: - as_warn("Byte dispacement won't work. Defaulting to :w"); - case 2: - nextword|=0x2; - break; - case 3: - nextword|=0x3; - break; - } - if(opP->mode==APODX) nextword|=0x04; - else if(opP->mode==AMIND) nextword|=0x40; - } - addword(nextword); - - if(isvar(opP->con1)) { - if(opP->reg==PC || opP->reg==ZPC) { - add_fix(siz1==3 ? 'l' : 'w',opP->con1,1); - opP->con1->e_exp.X_add_number+=6; - } else - add_fix(siz1==3 ? 'l' : 'w',opP->con1,0); - } - if(siz1==3) - addword(baseo>>16); - if(siz1) - addword(baseo); - - if(isvar(opP->con2)) { - if(opP->reg==PC || opP->reg==ZPC) { - add_fix(siz2==3 ? 'l' : 'w',opP->con2,1); - opP->con1->e_exp.X_add_number+=6; - } else - add_fix(siz2==3 ? 'l' : 'w',opP->con2,0); - } - if(siz2==3) - addword(outro>>16); - if(siz2) - addword(outro); - - break; - - case ABSL: - nextword=get_num(opP->con1,80); - switch(opP->con1->e_siz) { - default: - as_warn("Unknown size for absolute reference"); - case 0: - if(!isvar(opP->con1) && issword(offs(opP->con1))) { - tmpreg=0x38; /* 7.0 */ - addword(nextword); - break; - } - /* Don't generate pc relative code - on 68010 and 68000 */ - if(isvar(opP->con1) - && !subs(opP->con1) - && seg(opP->con1) == SEG_TEXT - && now_seg == SEG_TEXT - && cpu_of_arch(current_architecture) < m68020 - && !flagseen['S'] - && !strchr("~%&$?", s[0])) { - tmpreg=0x3A; /* 7.2 */ - add_frag(adds(opP->con1), - offs(opP->con1), - TAB(PCREL,SZ_UNDEF)); - break; - } - case 3: /* Fall through into long */ - if(isvar(opP->con1)) - add_fix('l',opP->con1,0); - - tmpreg=0x39; /* 7.1 mode */ - addword(nextword>>16); - addword(nextword); - break; - - case 2: /* Word */ - if(isvar(opP->con1)) - add_fix('w',opP->con1,0); - - tmpreg=0x38; /* 7.0 mode */ - addword(nextword); - break; - } - break; - case MSCR: - default: - as_bad("unknown/incorrect operand"); - /* abort(); */ + nextword|=0x2; + siz2=2; } - install_gen_operand(s[1],tmpreg); break; - - case '#': - case '^': - switch(s[1]) { /* JF: I hate floating point! */ - case 'j': - tmpreg=70; - break; - case '8': - tmpreg=20; - break; - case 'C': - tmpreg=50; - break; - case '3': - default: - tmpreg=80; - break; - } - tmpreg=get_num(opP->con1,tmpreg); - if(isvar(opP->con1)) - add_fix(s[1],opP->con1,0); - switch(s[1]) { - case 'b': /* Danger: These do no check for - certain types of overflow. - user beware! */ - if(!isbyte(tmpreg)) - opP->error="out of range"; - insop(tmpreg); - if(isvar(opP->con1)) - the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; - break; - case 'w': - if(!isword(tmpreg)) - opP->error="out of range"; - insop(tmpreg); - if(isvar(opP->con1)) - the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; - break; - case 'l': - insop(tmpreg); /* Because of the way insop works, we put these two out backwards */ - insop(tmpreg>>16); - if(isvar(opP->con1)) - the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; - break; - case '3': - tmpreg&=0xFF; - case '8': - case 'C': - install_operand(s[1],tmpreg); - break; - default: - as_fatal("Internal error: Unknown mode #%c in line %s of file \"%s\"", s[1], __LINE__, __FILE__); - } - break; - - case '+': - case '-': - case 'A': - case 'a': - install_operand(s[1],opP->reg-ADDR); - break; - - case 'B': - tmpreg=get_num(opP->con1,80); - switch(s[1]) { - case 'B': - /* Needs no offsetting */ - add_fix('B',opP->con1,1); - break; - case 'W': - /* Offset the displacement to be relative to byte disp location */ - opP->con1->e_exp.X_add_number+=2; - add_fix('w',opP->con1,1); - addword(0); - break; - case 'L': - long_branch: - if (cpu_of_arch(current_architecture) < m68020) /* 68000 or 010 */ - as_warn("Can't use long branches on 68000/68010"); - the_ins.opcode[the_ins.numo-1]|=0xff; - /* Offset the displacement to be relative to byte disp location */ - opP->con1->e_exp.X_add_number+=4; - add_fix('l',opP->con1,1); - addword(0); - addword(0); - break; - case 'g': - if(subs(opP->con1)) /* We can't relax it */ - goto long_branch; - - /* This could either be a symbol, or an - absolute address. No matter, the - frag hacking will finger it out. - Not quite: it can't switch from - BRANCH to BCC68000 for the case - where opnd is absolute (it needs - to use the 68000 hack since no - conditional abs jumps). */ - if (((cpu_of_arch(current_architecture) < m68020) || (0==adds(opP->con1))) - && (the_ins.opcode[0] >= 0x6200) - && (the_ins.opcode[0] <= 0x6f00)) { - add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF)); - } else { - add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF)); - } - break; - case 'w': - if(isvar(opP->con1)) { - /* check for DBcc instruction */ - if ((the_ins.opcode[0] & 0xf0f8) ==0x50c8) { - /* size varies if patch */ - /* needed for long form */ - add_frag(adds(opP->con1),offs(opP->con1),TAB(DBCC,SZ_UNDEF)); - break; - } - - /* Don't ask! */ - opP->con1->e_exp.X_add_number+=2; - add_fix('w',opP->con1,1); - } - addword(0); - break; - case 'C': /* Fixed size LONG coproc branches */ - the_ins.opcode[the_ins.numo-1]|=0x40; - /* Offset the displacement to be relative to byte disp location */ - /* Coproc branches don't have a byte disp option, but they are - compatible with the ordinary branches, which do... */ - opP->con1->e_exp.X_add_number+=4; - add_fix('l',opP->con1,1); - addword(0); - addword(0); - break; - case 'c': /* Var size Coprocesssor branches */ - if(subs(opP->con1)) { - add_fix('l',opP->con1,1); - add_frag((symbolS *)0,(long)0,TAB(FBRANCH,LONG)); - } else if(adds(opP->con1)) { - add_frag(adds(opP->con1),offs(opP->con1),TAB(FBRANCH,SZ_UNDEF)); - } else { - /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */ - the_ins.opcode[the_ins.numo-1]|=0x40; - add_fix('l',opP->con1,1); - addword(0); - addword(4); - } - break; - default: - as_fatal("Internal error: operand type B%c unknown in line %s of file \"%s\"", - s[1], __LINE__, __FILE__); - } - break; - - case 'C': /* Ignore it */ - break; - - case 'd': /* JF this is a kludge */ - if(opP->mode==AOFF) { - install_operand('s',opP->reg-ADDR); - } else { - char *tmpP; - - tmpP=opP->con1->e_end-2; - opP->con1->e_beg++; - opP->con1->e_end-=4; /* point to the , */ - baseo=m68k_reg_parse(&tmpP); - if(baseo<ADDR+0 || baseo>ADDR+7) { - as_bad("Unknown address reg, using A0"); - baseo=0; - } else baseo-=ADDR; - install_operand('s',baseo); - } - tmpreg=get_num(opP->con1,80); - if(!issword(tmpreg)) { - as_warn("Expression out of range, using 0"); - tmpreg=0; - } - addword(tmpreg); + case 1: + as_warn("Byte dispacement won't work. Defaulting to :w"); + case 2: + nextword|=0x2; break; - - case 'D': - install_operand(s[1],opP->reg-DATA); - break; - - case 'F': - install_operand(s[1],opP->reg-FPREG); + case 3: + nextword|=0x3; break; - - case 'I': - tmpreg=1+opP->reg-COPNUM; - if(tmpreg==8) - tmpreg=0; - install_operand(s[1],tmpreg); - break; - - case 'J': /* JF foo */ - switch(opP->reg) { - case SFC: tmpreg=0x000; break; - case DFC: tmpreg=0x001; break; - case CACR: tmpreg=0x002; break; - case TC: tmpreg=0x003; break; - case ITT0: tmpreg=0x004; break; - case ITT1: tmpreg=0x005; break; - case DTT0: tmpreg=0x006; break; - case DTT1: tmpreg=0x007; break; - - case USP: tmpreg=0x800; break; - case VBR: tmpreg=0x801; break; - case CAAR: tmpreg=0x802; break; - case MSP: tmpreg=0x803; break; - case ISP: tmpreg=0x804; break; - case MMUSR: tmpreg=0x805; break; - case URP: tmpreg=0x806; break; - case SRP: tmpreg=0x807; break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - - case 'k': - tmpreg=get_num(opP->con1,55); - install_operand(s[1],tmpreg&0x7f); - break; - - case 'l': - tmpreg=opP->reg; - if(s[1]=='w') { - if(tmpreg&0x7FF0000) - as_bad("Floating point register in register list"); - insop(reverse_16_bits(tmpreg)); - } else { - if(tmpreg&0x700FFFF) - as_bad("Wrong register in floating-point reglist"); - install_operand(s[1],reverse_8_bits(tmpreg>>16)); - } - break; - - case 'L': - tmpreg=opP->reg; - if(s[1]=='w') { - if(tmpreg&0x7FF0000) - as_bad("Floating point register in register list"); - insop(tmpreg); - } else if(s[1]=='8') { - if(tmpreg&0x0FFFFFF) - as_bad("incorrect register in reglist"); - install_operand(s[1],tmpreg>>24); - } else { - if(tmpreg&0x700FFFF) - as_bad("wrong register in floating-point reglist"); - else - install_operand(s[1],tmpreg>>16); - } - break; - - case 'M': - install_operand(s[1],get_num(opP->con1,60)); - break; - - case 'O': - tmpreg= (opP->mode==DREG) - ? 0x20+opP->reg-DATA - : (get_num(opP->con1,40)&0x1F); - install_operand(s[1],tmpreg); - break; - - case 'Q': - tmpreg=get_num(opP->con1,10); - if(tmpreg==8) - tmpreg=0; - install_operand(s[1],tmpreg); - break; - - case 'R': - /* This depends on the fact that ADDR registers are - eight more than their corresponding DATA regs, so - the result will have the ADDR_REG bit set */ - install_operand(s[1],opP->reg-DATA); - break; - - case 's': - if(opP->reg==FPI) tmpreg=0x1; - else if(opP->reg==FPS) tmpreg=0x2; - else if(opP->reg==FPC) tmpreg=0x4; - else as_fatal("failed sanity check."); - install_operand(s[1],tmpreg); - break; - - case 'S': /* Ignore it */ - break; - - case 'T': - install_operand(s[1],get_num(opP->con1,30)); + } + if(opP->mode==APODX) nextword|=0x04; + else if(opP->mode==AMIND) nextword|=0x40; + } + addword(nextword); + + if(isvar(opP->con1)) { + if(opP->reg==PC || opP->reg==ZPC) { + add_fix(siz1==3 ? 'l' : 'w',opP->con1,1); + opP->con1->e_exp.X_add_number+=6; + } else + add_fix(siz1==3 ? 'l' : 'w',opP->con1,0); + } + if(siz1==3) + addword(baseo>>16); + if(siz1) + addword(baseo); + + if(isvar(opP->con2)) { + if(opP->reg==PC || opP->reg==ZPC) { + add_fix(siz2==3 ? 'l' : 'w',opP->con2,1); + opP->con1->e_exp.X_add_number+=6; + } else + add_fix(siz2==3 ? 'l' : 'w',opP->con2,0); + } + if(siz2==3) + addword(outro>>16); + if(siz2) + addword(outro); + + break; + + case ABSL: + nextword=get_num(opP->con1,80); + switch(opP->con1->e_siz) { + default: + as_warn("Unknown size for absolute reference"); + case 0: + if(!isvar(opP->con1) && issword(offs(opP->con1))) { + tmpreg=0x38; /* 7.0 */ + addword(nextword); break; - - case 'U': /* Ignore it */ + } + /* Don't generate pc relative code + on 68010 and 68000 */ + if(isvar(opP->con1) + && !subs(opP->con1) + && seg(opP->con1) == SEG_TEXT + && now_seg == SEG_TEXT + && cpu_of_arch(current_architecture) < m68020 + && !flagseen['S'] + && !strchr("~%&$?", s[0])) { + tmpreg=0x3A; /* 7.2 */ + add_frag(adds(opP->con1), + offs(opP->con1), + TAB(PCREL,SZ_UNDEF)); break; - - case 'c': - switch (opP->reg) { - case NC: tmpreg = 0; break; - case DC: tmpreg = 1; break; - case IC: tmpreg = 2; break; - case BC: tmpreg = 3; break; - default: - as_fatal("failed sanity check"); - } /* switch on cache token */ - install_operand(s[1], tmpreg); + } + case 3: /* Fall through into long */ + if(isvar(opP->con1)) + add_fix('l',opP->con1,0); + + tmpreg=0x39; /* 7.1 mode */ + addword(nextword>>16); + addword(nextword); + break; + + case 2: /* Word */ + if(isvar(opP->con1)) + add_fix('w',opP->con1,0); + + tmpreg=0x38; /* 7.0 mode */ + addword(nextword); + break; + } + break; + case MSCR: + default: + as_bad("unknown/incorrect operand"); + /* abort(); */ + } + install_gen_operand(s[1],tmpreg); + break; + + case '#': + case '^': + switch(s[1]) { /* JF: I hate floating point! */ + case 'j': + tmpreg=70; + break; + case '8': + tmpreg=20; + break; + case 'C': + tmpreg=50; + break; + case '3': + default: + tmpreg=80; + break; + } + tmpreg=get_num(opP->con1,tmpreg); + if(isvar(opP->con1)) + add_fix(s[1],opP->con1,0); + switch(s[1]) { + case 'b': /* Danger: These do no check for + certain types of overflow. + user beware! */ + if(!isbyte(tmpreg)) + opP->error="out of range"; + insop(tmpreg); + if(isvar(opP->con1)) + the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; + break; + case 'w': + if(!isword(tmpreg)) + opP->error="out of range"; + insop(tmpreg); + if(isvar(opP->con1)) + the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; + break; + case 'l': + insop(tmpreg); /* Because of the way insop works, we put these two out backwards */ + insop(tmpreg>>16); + if(isvar(opP->con1)) + the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2; + break; + case '3': + tmpreg&=0xFF; + case '8': + case 'C': + install_operand(s[1],tmpreg); + break; + default: + as_fatal("Internal error: Unknown mode #%c in line %s of file \"%s\"", s[1], __LINE__, __FILE__); + } + break; + + case '+': + case '-': + case 'A': + case 'a': + install_operand(s[1],opP->reg-ADDR); + break; + + case 'B': + tmpreg=get_num(opP->con1,80); + switch(s[1]) { + case 'B': + /* Needs no offsetting */ + add_fix('B',opP->con1,1); + break; + case 'W': + /* Offset the displacement to be relative to byte disp location */ + opP->con1->e_exp.X_add_number+=2; + add_fix('w',opP->con1,1); + addword(0); + break; + case 'L': + long_branch: + if (cpu_of_arch(current_architecture) < m68020) /* 68000 or 010 */ + as_warn("Can't use long branches on 68000/68010"); + the_ins.opcode[the_ins.numo-1]|=0xff; + /* Offset the displacement to be relative to byte disp location */ + opP->con1->e_exp.X_add_number+=4; + add_fix('l',opP->con1,1); + addword(0); + addword(0); + break; + case 'g': + if(subs(opP->con1)) /* We can't relax it */ + goto long_branch; + + /* This could either be a symbol, or an + absolute address. No matter, the + frag hacking will finger it out. + Not quite: it can't switch from + BRANCH to BCC68000 for the case + where opnd is absolute (it needs + to use the 68000 hack since no + conditional abs jumps). */ + if (((cpu_of_arch(current_architecture) < m68020) || (0==adds(opP->con1))) + && (the_ins.opcode[0] >= 0x6200) + && (the_ins.opcode[0] <= 0x6f00)) { + add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF)); + } else { + add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF)); + } + break; + case 'w': + if(isvar(opP->con1)) { + /* check for DBcc instruction */ + if ((the_ins.opcode[0] & 0xf0f8) ==0x50c8) { + /* size varies if patch */ + /* needed for long form */ + add_frag(adds(opP->con1),offs(opP->con1),TAB(DBCC,SZ_UNDEF)); break; + } + + /* Don't ask! */ + opP->con1->e_exp.X_add_number+=2; + add_fix('w',opP->con1,1); + } + addword(0); + break; + case 'C': /* Fixed size LONG coproc branches */ + the_ins.opcode[the_ins.numo-1]|=0x40; + /* Offset the displacement to be relative to byte disp location */ + /* Coproc branches don't have a byte disp option, but they are + compatible with the ordinary branches, which do... */ + opP->con1->e_exp.X_add_number+=4; + add_fix('l',opP->con1,1); + addword(0); + addword(0); + break; + case 'c': /* Var size Coprocesssor branches */ + if(subs(opP->con1)) { + add_fix('l',opP->con1,1); + add_frag((symbolS *)0,(long)0,TAB(FBRANCH,LONG)); + } else if(adds(opP->con1)) { + add_frag(adds(opP->con1),offs(opP->con1),TAB(FBRANCH,SZ_UNDEF)); + } else { + /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */ + the_ins.opcode[the_ins.numo-1]|=0x40; + add_fix('l',opP->con1,1); + addword(0); + addword(4); + } + break; + default: + as_fatal("Internal error: operand type B%c unknown in line %s of file \"%s\"", + s[1], __LINE__, __FILE__); + } + break; + + case 'C': /* Ignore it */ + break; + + case 'd': /* JF this is a kludge */ + if(opP->mode==AOFF) { + install_operand('s',opP->reg-ADDR); + } else { + char *tmpP; + + tmpP=opP->con1->e_end-2; + opP->con1->e_beg++; + opP->con1->e_end-=4; /* point to the , */ + baseo=m68k_reg_parse(&tmpP); + if(baseo<ADDR+0 || baseo>ADDR+7) { + as_bad("Unknown address reg, using A0"); + baseo=0; + } else baseo-=ADDR; + install_operand('s',baseo); + } + tmpreg=get_num(opP->con1,80); + if(!issword(tmpreg)) { + as_warn("Expression out of range, using 0"); + tmpreg=0; + } + addword(tmpreg); + break; + + case 'D': + install_operand(s[1],opP->reg-DATA); + break; + + case 'F': + install_operand(s[1],opP->reg-FPREG); + break; + + case 'I': + tmpreg=1+opP->reg-COPNUM; + if(tmpreg==8) + tmpreg=0; + install_operand(s[1],tmpreg); + break; + + case 'J': /* JF foo */ + switch(opP->reg) { + case SFC: tmpreg=0x000; break; + case DFC: tmpreg=0x001; break; + case CACR: tmpreg=0x002; break; + case TC: tmpreg=0x003; break; + case ITT0: tmpreg=0x004; break; + case ITT1: tmpreg=0x005; break; + case DTT0: tmpreg=0x006; break; + case DTT1: tmpreg=0x007; break; + + case USP: tmpreg=0x800; break; + case VBR: tmpreg=0x801; break; + case CAAR: tmpreg=0x802; break; + case MSP: tmpreg=0x803; break; + case ISP: tmpreg=0x804; break; + case MMUSR: tmpreg=0x805; break; + case URP: tmpreg=0x806; break; + case SRP: tmpreg=0x807; break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'k': + tmpreg=get_num(opP->con1,55); + install_operand(s[1],tmpreg&0x7f); + break; + + case 'l': + tmpreg=opP->reg; + if(s[1]=='w') { + if(tmpreg&0x7FF0000) + as_bad("Floating point register in register list"); + insop(reverse_16_bits(tmpreg)); + } else { + if(tmpreg&0x700FFFF) + as_bad("Wrong register in floating-point reglist"); + install_operand(s[1],reverse_8_bits(tmpreg>>16)); + } + break; + + case 'L': + tmpreg=opP->reg; + if(s[1]=='w') { + if(tmpreg&0x7FF0000) + as_bad("Floating point register in register list"); + insop(tmpreg); + } else if(s[1]=='8') { + if(tmpreg&0x0FFFFFF) + as_bad("incorrect register in reglist"); + install_operand(s[1],tmpreg>>24); + } else { + if(tmpreg&0x700FFFF) + as_bad("wrong register in floating-point reglist"); + else + install_operand(s[1],tmpreg>>16); + } + break; + + case 'M': + install_operand(s[1],get_num(opP->con1,60)); + break; + + case 'O': + tmpreg= (opP->mode==DREG) + ? 0x20+opP->reg-DATA + : (get_num(opP->con1,40)&0x1F); + install_operand(s[1],tmpreg); + break; + + case 'Q': + tmpreg=get_num(opP->con1,10); + if(tmpreg==8) + tmpreg=0; + install_operand(s[1],tmpreg); + break; + + case 'R': + /* This depends on the fact that ADDR registers are + eight more than their corresponding DATA regs, so + the result will have the ADDR_REG bit set */ + install_operand(s[1],opP->reg-DATA); + break; + + case 's': + if(opP->reg==FPI) tmpreg=0x1; + else if(opP->reg==FPS) tmpreg=0x2; + else if(opP->reg==FPC) tmpreg=0x4; + else as_fatal("failed sanity check."); + install_operand(s[1],tmpreg); + break; + + case 'S': /* Ignore it */ + break; + + case 'T': + install_operand(s[1],get_num(opP->con1,30)); + break; + + case 'U': /* Ignore it */ + break; + + case 'c': + switch (opP->reg) { + case NC: tmpreg = 0; break; + case DC: tmpreg = 1; break; + case IC: tmpreg = 2; break; + case BC: tmpreg = 3; break; + default: + as_fatal("failed sanity check"); + } /* switch on cache token */ + install_operand(s[1], tmpreg); + break; #ifndef NO_68851 - /* JF: These are out of order, I fear. */ - case 'f': - switch (opP->reg) { - case SFC: - tmpreg=0; - break; - case DFC: - tmpreg=1; - break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - - case 'P': - switch(opP->reg) { - case TC: - tmpreg=0; - break; - case CAL: - tmpreg=4; - break; - case VAL: - tmpreg=5; - break; - case SCC: - tmpreg=6; - break; - case AC: - tmpreg=7; - break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - - case 'V': - if (opP->reg == VAL) - break; - as_fatal("failed sanity check."); - - case 'W': - switch(opP->reg) { - - case DRP: - tmpreg=1; - break; - case SRP: - tmpreg=2; - break; - case CRP: - tmpreg=3; - break; - default: - as_fatal("failed sanity check."); - } - install_operand(s[1],tmpreg); - break; - - case 'X': - switch (opP->reg) { - case BAD: case BAD+1: case BAD+2: case BAD+3: - case BAD+4: case BAD+5: case BAD+6: case BAD+7: - tmpreg = (4 << 10) | ((opP->reg - BAD) << 2); - break; - - case BAC: case BAC+1: case BAC+2: case BAC+3: - case BAC+4: case BAC+5: case BAC+6: case BAC+7: - tmpreg = (5 << 10) | ((opP->reg - BAC) << 2); - break; - - default: - as_fatal("failed sanity check."); - } - install_operand(s[1], tmpreg); - break; - case 'Y': - know(opP->reg == PSR); - break; - case 'Z': - know(opP->reg == PCSR); - break; + /* JF: These are out of order, I fear. */ + case 'f': + switch (opP->reg) { + case SFC: + tmpreg=0; + break; + case DFC: + tmpreg=1; + break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'P': + switch(opP->reg) { + case TC: + tmpreg=0; + break; + case CAL: + tmpreg=4; + break; + case VAL: + tmpreg=5; + break; + case SCC: + tmpreg=6; + break; + case AC: + tmpreg=7; + break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'V': + if (opP->reg == VAL) + break; + as_fatal("failed sanity check."); + + case 'W': + switch(opP->reg) { + + case DRP: + tmpreg=1; + break; + case SRP: + tmpreg=2; + break; + case CRP: + tmpreg=3; + break; + default: + as_fatal("failed sanity check."); + } + install_operand(s[1],tmpreg); + break; + + case 'X': + switch (opP->reg) { + case BAD: case BAD+1: case BAD+2: case BAD+3: + case BAD+4: case BAD+5: case BAD+6: case BAD+7: + tmpreg = (4 << 10) | ((opP->reg - BAD) << 2); + break; + + case BAC: case BAC+1: case BAC+2: case BAC+3: + case BAC+4: case BAC+5: case BAC+6: case BAC+7: + tmpreg = (5 << 10) | ((opP->reg - BAC) << 2); + break; + + default: + as_fatal("failed sanity check."); + } + install_operand(s[1], tmpreg); + break; + case 'Y': + know(opP->reg == PSR); + break; + case 'Z': + know(opP->reg == PCSR); + break; #endif /* m68851 */ - case '_': - tmpreg=get_num(opP->con1,80); - install_operand(s[1], tmpreg); - break; - default: - as_fatal("Internal error: Operand type %c unknown in line %s of file \"%s\"", s[0], __LINE__, __FILE__); - } + case '_': + tmpreg=get_num(opP->con1,80); + install_operand(s[1], tmpreg); + break; + default: + as_fatal("Internal error: Operand type %c unknown in line %s of file \"%s\"", s[0], __LINE__, __FILE__); } - /* By the time whe get here (FINALLY) the_ins contains the complete - instruction, ready to be emitted. . . */ + } + /* By the time whe get here (FINALLY) the_ins contains the complete + instruction, ready to be emitted. . . */ } /* m68k_ip() */ /* @@ -2746,211 +2746,211 @@ char *instring; * | <empty> * ; * - + * The idea here must be to scan in a set of registers but I don't * understand it. Looks awfully sloppy to me but I don't have any doc on * this format so... - + * * */ static int get_regs(i,str,opP) -int i; -struct m68k_op *opP; -char *str; + int i; + struct m68k_op *opP; + char *str; { - /* 26, 25, 24, 23-16, 15-8, 0-7 */ - /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */ - unsigned long cur_regs = 0; - int reg1, - reg2; - + /* 26, 25, 24, 23-16, 15-8, 0-7 */ + /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */ + unsigned long cur_regs = 0; + int reg1, + reg2; + #define ADD_REG(x) { if(x==FPI) cur_regs|=(1<<24);\ - else if(x==FPS) cur_regs|=(1<<25);\ - else if(x==FPC) cur_regs|=(1<<26);\ - else cur_regs|=(1<<(x-1)); } - - reg1=i; - for(;;) { - if(*str=='/') { - ADD_REG(reg1); - str++; - } else if(*str=='-') { - str++; - reg2=m68k_reg_parse(&str); - if(reg2<DATA || reg2>=FPREG+8 || reg1==FPI || reg1==FPS || reg1==FPC) { - opP->error="unknown register in register list"; - return FAIL; - } - while(reg1<=reg2) { - ADD_REG(reg1); - reg1++; - } - if(*str=='\0') - break; - } else if(*str=='\0') { - ADD_REG(reg1); - break; - } else { - opP->error="unknow character in register list"; - return FAIL; - } -/* DJA -- Bug Fix. Did't handle d1-d2/a1 until the following instruction was added */ - if (*str=='/') - str ++; - reg1=m68k_reg_parse(&str); - if((reg1<DATA || reg1>=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) { - opP->error="unknown register in register list"; - return FAIL; - } +else if(x==FPS) cur_regs|=(1<<25);\ +else if(x==FPC) cur_regs|=(1<<26);\ +else cur_regs|=(1<<(x-1)); } + + reg1=i; + for(;;) { + if(*str=='/') { + ADD_REG(reg1); + str++; + } else if(*str=='-') { + str++; + reg2=m68k_reg_parse(&str); + if(reg2<DATA || reg2>=FPREG+8 || reg1==FPI || reg1==FPS || reg1==FPC) { + opP->error="unknown register in register list"; + return FAIL; + } + while(reg1<=reg2) { + ADD_REG(reg1); + reg1++; + } + if(*str=='\0') + break; + } else if(*str=='\0') { + ADD_REG(reg1); + break; + } else { + opP->error="unknow character in register list"; + return FAIL; } - opP->reg=cur_regs; - return OK; + /* DJA -- Bug Fix. Did't handle d1-d2/a1 until the following instruction was added */ + if (*str=='/') + str ++; + reg1=m68k_reg_parse(&str); + if((reg1<DATA || reg1>=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) { + opP->error="unknown register in register list"; + return FAIL; + } + } + opP->reg=cur_regs; + return OK; } /* get_regs() */ static int reverse_16_bits(in) -int in; + int in; { - int out=0; - int n; - - static int mask[16] = { -0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, -0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000 + int out=0; + int n; + + static int mask[16] = { + 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, + 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000 }; - for(n=0;n<16;n++) { - if(in&mask[n]) - out|=mask[15-n]; - } - return out; + for(n=0;n<16;n++) { + if(in&mask[n]) + out|=mask[15-n]; + } + return out; } /* reverse_16_bits() */ static int reverse_8_bits(in) -int in; + int in; { - int out=0; - int n; - - static int mask[8] = { -0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, - }; - - for(n=0;n<8;n++) { - if(in&mask[n]) - out|=mask[7-n]; - } - return out; + int out=0; + int n; + + static int mask[8] = { + 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, + }; + + for(n=0;n<8;n++) { + if(in&mask[n]) + out|=mask[7-n]; + } + return out; } /* reverse_8_bits() */ static void install_operand(mode,val) -int mode; -int val; + int mode; + int val; { - switch(mode) { - case 's': - the_ins.opcode[0]|=val & 0xFF; /* JF FF is for M kludge */ - break; - case 'd': - the_ins.opcode[0]|=val<<9; - break; - case '1': - the_ins.opcode[1]|=val<<12; - break; - case '2': - the_ins.opcode[1]|=val<<6; - break; - case '3': - the_ins.opcode[1]|=val; - break; - case '4': - the_ins.opcode[2]|=val<<12; - break; - case '5': - the_ins.opcode[2]|=val<<6; - break; - case '6': - /* DANGER! This is a hack to force cas2l and cas2w cmds - to be three words long! */ - the_ins.numo++; - the_ins.opcode[2]|=val; - break; - case '7': - the_ins.opcode[1]|=val<<7; - break; - case '8': - the_ins.opcode[1]|=val<<10; - break; + switch(mode) { + case 's': + the_ins.opcode[0]|=val & 0xFF; /* JF FF is for M kludge */ + break; + case 'd': + the_ins.opcode[0]|=val<<9; + break; + case '1': + the_ins.opcode[1]|=val<<12; + break; + case '2': + the_ins.opcode[1]|=val<<6; + break; + case '3': + the_ins.opcode[1]|=val; + break; + case '4': + the_ins.opcode[2]|=val<<12; + break; + case '5': + the_ins.opcode[2]|=val<<6; + break; + case '6': + /* DANGER! This is a hack to force cas2l and cas2w cmds + to be three words long! */ + the_ins.numo++; + the_ins.opcode[2]|=val; + break; + case '7': + the_ins.opcode[1]|=val<<7; + break; + case '8': + the_ins.opcode[1]|=val<<10; + break; #ifndef NO_68851 - case '9': - the_ins.opcode[1]|=val<<5; - break; + case '9': + the_ins.opcode[1]|=val<<5; + break; #endif - - case 't': - the_ins.opcode[1]|=(val<<10)|(val<<7); - break; - case 'D': - the_ins.opcode[1]|=(val<<12)|val; - break; - case 'g': - the_ins.opcode[0]|=val=0xff; - break; - case 'i': - the_ins.opcode[0]|=val<<9; - break; - case 'C': - the_ins.opcode[1]|=val; - break; - case 'j': - the_ins.opcode[1]|=val; - the_ins.numo++; /* What a hack */ - break; - case 'k': - the_ins.opcode[1]|=val<<4; - break; - case 'b': - case 'w': - case 'l': - break; - case 'e': - the_ins.opcode[0] |= (val << 6); - break; - case 'L': - the_ins.opcode[1] = (val >> 16); - the_ins.opcode[2] = val & 0xffff; - break; - case 'c': - default: - as_fatal("failed sanity check."); - } + + case 't': + the_ins.opcode[1]|=(val<<10)|(val<<7); + break; + case 'D': + the_ins.opcode[1]|=(val<<12)|val; + break; + case 'g': + the_ins.opcode[0]|=val=0xff; + break; + case 'i': + the_ins.opcode[0]|=val<<9; + break; + case 'C': + the_ins.opcode[1]|=val; + break; + case 'j': + the_ins.opcode[1]|=val; + the_ins.numo++; /* What a hack */ + break; + case 'k': + the_ins.opcode[1]|=val<<4; + break; + case 'b': + case 'w': + case 'l': + break; + case 'e': + the_ins.opcode[0] |= (val << 6); + break; + case 'L': + the_ins.opcode[1] = (val >> 16); + the_ins.opcode[2] = val & 0xffff; + break; + case 'c': + default: + as_fatal("failed sanity check."); + } } /* install_operand() */ static void install_gen_operand(mode,val) -int mode; -int val; + int mode; + int val; { - switch(mode) { - case 's': - the_ins.opcode[0]|=val; - break; - case 'd': - /* This is a kludge!!! */ - the_ins.opcode[0]|=(val&0x07)<<9|(val&0x38)<<3; - break; - case 'b': - case 'w': - case 'l': - case 'f': - case 'F': - case 'x': - case 'p': - the_ins.opcode[0]|=val; - break; - /* more stuff goes here */ - default: - as_fatal("failed sanity check."); - } + switch(mode) { + case 's': + the_ins.opcode[0]|=val; + break; + case 'd': + /* This is a kludge!!! */ + the_ins.opcode[0]|=(val&0x07)<<9|(val&0x38)<<3; + break; + case 'b': + case 'w': + case 'l': + case 'f': + case 'F': + case 'x': + case 'p': + the_ins.opcode[0]|=val; + break; + /* more stuff goes here */ + default: + as_fatal("failed sanity check."); + } } /* install_gen_operand() */ /* @@ -2959,360 +2959,360 @@ int val; */ static char *crack_operand(str,opP) -register char *str; -register struct m68k_op *opP; + register char *str; + register struct m68k_op *opP; { - register int parens; - register int c; - register char *beg_str; - - if(!str) { - return str; - } - beg_str=str; - for(parens=0;*str && (parens>0 || notend(str));str++) { - if(*str=='(') parens++; - else if(*str==')') { - if(!parens) { /* ERROR */ - opP->error="Extra )"; - return str; - } - --parens; - } - } - if(!*str && parens) { /* ERROR */ - opP->error="Missing )"; - return str; - } - c= *str; - *str='\0'; - if(m68k_ip_op(beg_str,opP)==FAIL) { - *str=c; + register int parens; + register int c; + register char *beg_str; + + if(!str) { + return str; + } + beg_str=str; + for(parens=0;*str && (parens>0 || notend(str));str++) { + if(*str=='(') parens++; + else if(*str==')') { + if(!parens) { /* ERROR */ + opP->error="Extra )"; return str; + } + --parens; } + } + if(!*str && parens) { /* ERROR */ + opP->error="Missing )"; + return str; + } + c= *str; + *str='\0'; + if(m68k_ip_op(beg_str,opP)==FAIL) { *str=c; - - if(c=='}') - c= *++str; /* JF bitfield hack */ - - if(c) { - c= *++str; - if(!c) - as_bad("Missing operand"); - } return str; + } + *str=c; + + if(c=='}') + c= *++str; /* JF bitfield hack */ + + if(c) { + c= *++str; + if(!c) + as_bad("Missing operand"); + } + return str; } /* See the comment up above where the #define notend(... is */ #if 0 notend(s) -char *s; + char *s; { - if(*s==',') return 0; - if(*s=='{' || *s=='}') - return 0; - if(*s!=':') return 1; - /* This kludge here is for the division cmd, which is a kludge */ - if(index("aAdD#",s[1])) return 0; - return 1; + if(*s==',') return 0; + if(*s=='{' || *s=='}') + return 0; + if(*s!=':') return 1; + /* This kludge here is for the division cmd, which is a kludge */ + if(index("aAdD#",s[1])) return 0; + return 1; } #endif int done_pseudo(str) -char *str; + char *str; { - extern struct hash_control * po_hash; - char *ptr = str; - char *null_ptr; - pseudo_typeS * pop; - - char c; - - is_end_of_line[0] = 1; - /* Skip over name of pseudo, change to lower case */ - while (isalpha(*ptr) || *ptr == '.') - { - if (isupper(*ptr)) { - *ptr = tolower(*ptr); - } - ptr++; - } - null_ptr = ptr; - c = *null_ptr; - *null_ptr = 0; - - - pop = (pseudo_typeS *)hash_find(po_hash, str); - - *null_ptr = c; - if (pop != (pseudo_typeS *)NULL) - { - input_line_pointer = null_ptr+1; - SKIP_WHITESPACE(); - /* Now we point to first non-blank char after pseudo op */ - (*pop->poc_handler)(pop->poc_val); - input_line_pointer--; + extern struct hash_control * po_hash; + char *ptr = str; + char *null_ptr; + pseudo_typeS * pop; + + char c; + + is_end_of_line[0] = 1; + /* Skip over name of pseudo, change to lower case */ + while (isalpha(*ptr) || *ptr == '.') + { + if (isupper(*ptr)) { + *ptr = tolower(*ptr); + } + ptr++; + } + null_ptr = ptr; + c = *null_ptr; + *null_ptr = 0; + + + pop = (pseudo_typeS *)hash_find(po_hash, str); + + *null_ptr = c; + if (pop != (pseudo_typeS *)NULL) + { + input_line_pointer = null_ptr+1; + SKIP_WHITESPACE(); + /* Now we point to first non-blank char after pseudo op */ + (*pop->poc_handler)(pop->poc_val); + input_line_pointer--; + + return 1; + + } + /* Just put back the char where the null was put and return as if nothing had happened */ + + *null_ptr = c; + return 0; - return 1; - - } - /* Just put back the char where the null was put and return as if nothing had happened */ - - *null_ptr = c; - return 0; - } /* This is the guts of the machine-dependent assembler. STR points to a machine dependent instruction. This function is supposed to emit the frags/bytes it assembles to. - */ + */ void -md_assemble(str) + md_assemble(str) char *str; { - char *er; - short *fromP; - char *toP = NULL; - int m,n = 0; - char *to_beg_P; - int shorts_this_frag; - -/* if (done_pseudo(str)) return ;*/ - - - - if (current_architecture == 0) { - current_architecture = (m68020 + char *er; + short *fromP; + char *toP = NULL; + int m,n = 0; + char *to_beg_P; + int shorts_this_frag; + + /* if (done_pseudo(str)) return ;*/ + + + + if (current_architecture == 0) { + current_architecture = (m68020 #ifndef NO_68881 - | m68881 + | m68881 #endif #ifndef NO_68851 - | m68851 + | m68851 #endif - ); + ); } /* default current_architecture */ - - bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */ - - m68k_ip(str); - er=the_ins.error; - if(!er) { - for(n=the_ins.numargs;n;--n) - if(the_ins.operands[n].error) { - er=the_ins.operands[n].error; - break; - } + + bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */ + + m68k_ip(str); + er=the_ins.error; + if(!er) { + for(n=the_ins.numargs;n;--n) + if(the_ins.operands[n].error) { + er=the_ins.operands[n].error; + break; + } } - if(er) { - as_bad("\"%s\" -- Statement '%s' ignored",er,str); - return; + if(er) { + as_bad("\"%s\" -- Statement '%s' ignored",er,str); + return; } - - if(the_ins.nfrag==0) { /* No frag hacking involved; just put it out */ - toP=frag_more(2*the_ins.numo); - fromP= &the_ins.opcode[0]; - for(m=the_ins.numo;m;--m) { - md_number_to_chars(toP,(long)(*fromP),2); - toP+=2; - fromP++; + + if(the_ins.nfrag==0) { /* No frag hacking involved; just put it out */ + toP=frag_more(2*the_ins.numo); + fromP= &the_ins.opcode[0]; + for(m=the_ins.numo;m;--m) { + md_number_to_chars(toP,(long)(*fromP),2); + toP+=2; + fromP++; } - /* put out symbol-dependent info */ - for(m=0;m<the_ins.nrel;m++) { - switch(the_ins.reloc[m].wid) { + /* put out symbol-dependent info */ + for(m=0;m<the_ins.nrel;m++) { + switch(the_ins.reloc[m].wid) { case 'B': - n=1; - break; + n=1; + break; case 'b': - n=1; - break; + n=1; + break; case '3': - n=2; - break; + n=2; + break; case 'w': - n=2; - break; + n=2; + break; case 'l': - n=4; - break; + n=4; + break; default: - as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins.reloc[m].wid); + as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins.reloc[m].wid); } - - fix_new(frag_now, - (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, - n, - the_ins.reloc[m].add, - the_ins.reloc[m].sub, - the_ins.reloc[m].off, - the_ins.reloc[m].pcrel, - NO_RELOC); + + fix_new(frag_now, + (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, + n, + the_ins.reloc[m].add, + the_ins.reloc[m].sub, + the_ins.reloc[m].off, + the_ins.reloc[m].pcrel, + NO_RELOC); } - return; + return; } - - /* There's some frag hacking */ - for(n=0,fromP= &the_ins.opcode[0];n<the_ins.nfrag;n++) { - int wid; - - if(n==0) wid=2*the_ins.fragb[n].fragoff; - else wid=2*(the_ins.numo-the_ins.fragb[n-1].fragoff); - toP=frag_more(wid); - to_beg_P=toP; - shorts_this_frag=0; - for(m=wid/2;m;--m) { - md_number_to_chars(toP,(long)(*fromP),2); - toP+=2; - fromP++; - shorts_this_frag++; + + /* There's some frag hacking */ + for(n=0,fromP= &the_ins.opcode[0];n<the_ins.nfrag;n++) { + int wid; + + if(n==0) wid=2*the_ins.fragb[n].fragoff; + else wid=2*(the_ins.numo-the_ins.fragb[n-1].fragoff); + toP=frag_more(wid); + to_beg_P=toP; + shorts_this_frag=0; + for(m=wid/2;m;--m) { + md_number_to_chars(toP,(long)(*fromP),2); + toP+=2; + fromP++; + shorts_this_frag++; } - for(m=0;m<the_ins.nrel;m++) { - if((the_ins.reloc[m].n)>= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */) { - the_ins.reloc[m].n-= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */; - break; + for(m=0;m<the_ins.nrel;m++) { + if((the_ins.reloc[m].n)>= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */) { + the_ins.reloc[m].n-= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */; + break; } - wid=the_ins.reloc[m].wid; - if(wid==0) - continue; - the_ins.reloc[m].wid=0; - wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; - - fix_new(frag_now, - (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, - wid, - the_ins.reloc[m].add, - the_ins.reloc[m].sub, - the_ins.reloc[m].off, - the_ins.reloc[m].pcrel, - NO_RELOC); + wid=the_ins.reloc[m].wid; + if(wid==0) + continue; + the_ins.reloc[m].wid=0; + wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; + + fix_new(frag_now, + (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n, + wid, + the_ins.reloc[m].add, + the_ins.reloc[m].sub, + the_ins.reloc[m].off, + the_ins.reloc[m].pcrel, + NO_RELOC); } - /* know(the_ins.fragb[n].fadd); */ - (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty), - the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P); + /* know(the_ins.fragb[n].fadd); */ + (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty), + the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P); } - n=(the_ins.numo-the_ins.fragb[n-1].fragoff); - shorts_this_frag=0; - if(n) { - toP=frag_more(n*sizeof(short)); - while(n--) { - md_number_to_chars(toP,(long)(*fromP),2); - toP+=2; - fromP++; - shorts_this_frag++; + n=(the_ins.numo-the_ins.fragb[n-1].fragoff); + shorts_this_frag=0; + if(n) { + toP=frag_more(n*sizeof(short)); + while(n--) { + md_number_to_chars(toP,(long)(*fromP),2); + toP+=2; + fromP++; + shorts_this_frag++; } } - for(m=0;m<the_ins.nrel;m++) { - int wid; - - wid=the_ins.reloc[m].wid; - if(wid==0) - continue; - the_ins.reloc[m].wid=0; - wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; - - fix_new(frag_now, - (the_ins.reloc[m].n + toP-frag_now->fr_literal)- /* the_ins.numo */ shorts_this_frag*2, - wid, - the_ins.reloc[m].add, - the_ins.reloc[m].sub, - the_ins.reloc[m].off, - the_ins.reloc[m].pcrel, - NO_RELOC); + for(m=0;m<the_ins.nrel;m++) { + int wid; + + wid=the_ins.reloc[m].wid; + if(wid==0) + continue; + the_ins.reloc[m].wid=0; + wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000; + + fix_new(frag_now, + (the_ins.reloc[m].n + toP-frag_now->fr_literal)- /* the_ins.numo */ shorts_this_frag*2, + wid, + the_ins.reloc[m].add, + the_ins.reloc[m].sub, + the_ins.reloc[m].off, + the_ins.reloc[m].pcrel, + NO_RELOC); } } /* This function is called once, at assembler startup time. This should set up all the tables, etc that the MD part of the assembler needs - */ + */ void -md_begin() + md_begin() { -/* - * md_begin -- set up hash tables with 68000 instructions. - * similar to what the vax assembler does. ---phr - */ - /* RMS claims the thing to do is take the m68k-opcode.h table, and make - a copy of it at runtime, adding in the information we want but isn't - there. I think it'd be better to have an awk script hack the table - at compile time. Or even just xstr the table and use it as-is. But - my lord ghod hath spoken, so we do it this way. Excuse the ugly var - names. */ - - register const struct m68k_opcode *ins; - register struct m68k_incant *hack, - *slak; - register char *retval = 0; /* empty string, or error msg text */ - register unsigned int i; - register char c; - - if ((op_hash = hash_new()) == NULL) - as_fatal("Virtual memory exhausted"); - - obstack_begin(&robyn,4000); - for (ins = m68k_opcodes; ins < endop; ins++) { - hack=slak=(struct m68k_incant *)obstack_alloc(&robyn,sizeof(struct m68k_incant)); - do { - /* we *could* ignore insns that don't match our - arch here but just leaving them out of the - hash. */ - slak->m_operands=ins->args; - slak->m_opnum=strlen(slak->m_operands)/2; - slak->m_arch = ins->arch; - slak->m_opcode=ins->opcode; - /* This is kludgey */ - slak->m_codenum=((ins->match)&0xffffL) ? 2 : 1; - if((ins+1)!=endop && !strcmp(ins->name,(ins+1)->name)) { - slak->m_next=(struct m68k_incant *) obstack_alloc(&robyn,sizeof(struct m68k_incant)); - ins++; - } else - slak->m_next=0; - slak=slak->m_next; - } while(slak); - - retval = hash_insert (op_hash, ins->name,(char *)hack); - /* Didn't his mommy tell him about null pointers? */ - if(retval && *retval) - as_fatal("Internal Error: Can't hash %s: %s",ins->name,retval); - } - - for (i = 0; i < sizeof(mklower_table) ; i++) - mklower_table[i] = (isupper(c = (char) i)) ? tolower(c) : c; - - for (i = 0 ; i < sizeof(notend_table) ; i++) { - notend_table[i] = 0; - alt_notend_table[i] = 0; - } - notend_table[','] = 1; - notend_table['{'] = 1; - notend_table['}'] = 1; - alt_notend_table['a'] = 1; - alt_notend_table['A'] = 1; - alt_notend_table['d'] = 1; - alt_notend_table['D'] = 1; - alt_notend_table['#'] = 1; - alt_notend_table['f'] = 1; - alt_notend_table['F'] = 1; + /* + * md_begin -- set up hash tables with 68000 instructions. + * similar to what the vax assembler does. ---phr + */ + /* RMS claims the thing to do is take the m68k-opcode.h table, and make + a copy of it at runtime, adding in the information we want but isn't + there. I think it'd be better to have an awk script hack the table + at compile time. Or even just xstr the table and use it as-is. But + my lord ghod hath spoken, so we do it this way. Excuse the ugly var + names. */ + + register const struct m68k_opcode *ins; + register struct m68k_incant *hack, + *slak; + register char *retval = 0; /* empty string, or error msg text */ + register unsigned int i; + register char c; + + if ((op_hash = hash_new()) == NULL) + as_fatal("Virtual memory exhausted"); + + obstack_begin(&robyn,4000); + for (ins = m68k_opcodes; ins < endop; ins++) { + hack=slak=(struct m68k_incant *)obstack_alloc(&robyn,sizeof(struct m68k_incant)); + do { + /* we *could* ignore insns that don't match our + arch here but just leaving them out of the + hash. */ + slak->m_operands=ins->args; + slak->m_opnum=strlen(slak->m_operands)/2; + slak->m_arch = ins->arch; + slak->m_opcode=ins->opcode; + /* This is kludgey */ + slak->m_codenum=((ins->match)&0xffffL) ? 2 : 1; + if((ins+1)!=endop && !strcmp(ins->name,(ins+1)->name)) { + slak->m_next=(struct m68k_incant *) obstack_alloc(&robyn,sizeof(struct m68k_incant)); + ins++; + } else + slak->m_next=0; + slak=slak->m_next; + } while(slak); + retval = hash_insert (op_hash, ins->name,(char *)hack); + /* Didn't his mommy tell him about null pointers? */ + if(retval && *retval) + as_fatal("Internal Error: Can't hash %s: %s",ins->name,retval); + } + + for (i = 0; i < sizeof(mklower_table) ; i++) + mklower_table[i] = (isupper(c = (char) i)) ? tolower(c) : c; + + for (i = 0 ; i < sizeof(notend_table) ; i++) { + notend_table[i] = 0; + alt_notend_table[i] = 0; + } + notend_table[','] = 1; + notend_table['{'] = 1; + notend_table['}'] = 1; + alt_notend_table['a'] = 1; + alt_notend_table['A'] = 1; + alt_notend_table['d'] = 1; + alt_notend_table['D'] = 1; + alt_notend_table['#'] = 1; + alt_notend_table['f'] = 1; + alt_notend_table['F'] = 1; + #ifdef REGISTER_PREFIX - alt_notend_table[REGISTER_PREFIX] = 1; + alt_notend_table[REGISTER_PREFIX] = 1; #endif - - + + } #if 0 #define notend(s) ((*s == ',' || *s == '}' || *s == '{' \ - || (*s == ':' && strchr("aAdD#", s[1]))) \ - ? 0 : 1) + || (*s == ':' && strchr("aAdD#", s[1]))) \ + ? 0 : 1) #endif /* This funciton is called once, before the assembler exits. It is supposed to do any final cleanup for this part of the assembler. - */ + */ void -md_end() + md_end() { } @@ -3322,58 +3322,58 @@ md_end() /* Turn a string in str into a floating point constant of type type, and store the appropriate bytes in *litP. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ + */ char * -md_atof(type,litP,sizeP) + md_atof(type,litP,sizeP) char type; char *litP; int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee(); - - switch(type) { - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words;prec--;) { - md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee(); + + switch(type) { + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words;prec--;) { + md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } /* Turn an integer of n bytes (in val) into a stream of bytes appropriate @@ -3382,149 +3382,149 @@ int *sizeP; THE RIGHT THING, whatever it is. Possible values for n are 1 (byte) 2 (short) and 4 (long) Floating numbers are put out as a series of LITTLENUMS (shorts, here at least) - */ + */ void -md_number_to_chars(buf,val,n) + md_number_to_chars(buf,val,n) char *buf; long val; int n; { - switch(n) { - case 1: - *buf++=val; - break; - case 2: - *buf++=(val>>8); - *buf++=val; - break; - case 4: - *buf++=(val>>24); - *buf++=(val>>16); - *buf++=(val>>8); - *buf++=val; - break; - default: - as_fatal("failed sanity check."); - } + switch(n) { + case 1: + *buf++=val; + break; + case 2: + *buf++=(val>>8); + *buf++=val; + break; + case 4: + *buf++=(val>>24); + *buf++=(val>>16); + *buf++=(val>>8); + *buf++=val; + break; + default: + as_fatal("failed sanity check."); + } } void -md_apply_fix(fixP, val) - fixS *fixP; - long val; + md_apply_fix(fixP, val) +fixS *fixP; +long val; { - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - - switch(fixP->fx_size) { - case 1: - *buf++=val; - break; - case 2: - *buf++=(val>>8); - *buf++=val; - break; - case 4: - *buf++=(val>>24); - *buf++=(val>>16); - *buf++=(val>>8); - *buf++=val; - break; - default: - BAD_CASE (fixP->fx_size); - } + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + switch(fixP->fx_size) { + case 1: + *buf++=val; + break; + case 2: + *buf++=(val>>8); + *buf++=val; + break; + case 4: + *buf++=(val>>24); + *buf++=(val>>16); + *buf++=(val>>8); + *buf++=val; + break; + default: + BAD_CASE (fixP->fx_size); + } } /* *fragP has been relaxed to its final size, and now needs to have the bytes inside it modified to conform to the new size There is UGLY MAGIC here. .. - */ + */ void -md_convert_frag(headers, fragP) + md_convert_frag(headers, fragP) object_headers *headers; register fragS *fragP; { - long disp; - long ext = 0; - - /* Address in object code of the displacement. */ - register int object_address = fragP -> fr_fix + fragP -> fr_address; - + long disp; + long ext = 0; + + /* Address in object code of the displacement. */ + register int object_address = fragP -> fr_fix + fragP -> fr_address; + #ifdef IBM_COMPILER_SUX - /* This is wrong but it convinces the native rs6000 compiler to - generate the code we want. */ - register char *buffer_address = fragP -> fr_literal; - buffer_address += fragP -> fr_fix; + /* This is wrong but it convinces the native rs6000 compiler to + generate the code we want. */ + register char *buffer_address = fragP -> fr_literal; + buffer_address += fragP -> fr_fix; #else /* IBM_COMPILER_SUX */ - /* Address in gas core of the place to store the displacement. */ - register char *buffer_address = fragP->fr_fix + fragP->fr_literal; + /* Address in gas core of the place to store the displacement. */ + register char *buffer_address = fragP->fr_fix + fragP->fr_literal; #endif /* IBM_COMPILER_SUX */ - - /* No longer true: know(fragP->fr_symbol); */ - - /* The displacement of the address, from current location. */ - disp = fragP->fr_symbol ? S_GET_VALUE(fragP->fr_symbol) : 0; - disp = (disp + fragP->fr_offset) - object_address; - - switch(fragP->fr_subtype) { - case TAB(BCC68000,BYTE): - case TAB(BRANCH,BYTE): - know(issbyte(disp)); - if(disp==0) - as_bad("short branch with zero offset: use :w"); - fragP->fr_opcode[1]=disp; - ext=0; - break; - case TAB(DBCC,SHORT): - know(issword(disp)); - ext=2; - break; - case TAB(BCC68000,SHORT): - case TAB(BRANCH,SHORT): - know(issword(disp)); - fragP->fr_opcode[1]=0x00; - ext=2; - break; - case TAB(BRANCH,LONG): - if (cpu_of_arch(current_architecture) < m68020) { - if (fragP->fr_opcode[0]==0x61) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - - fix_new(fragP, - fragP->fr_fix, - 4, - fragP->fr_symbol, - 0, - fragP->fr_offset, - 0, - NO_RELOC); - - fragP->fr_fix+=4; + + /* No longer true: know(fragP->fr_symbol); */ + + /* The displacement of the address, from current location. */ + disp = fragP->fr_symbol ? S_GET_VALUE(fragP->fr_symbol) : 0; + disp = (disp + fragP->fr_offset) - object_address; + + switch(fragP->fr_subtype) { + case TAB(BCC68000,BYTE): + case TAB(BRANCH,BYTE): + know(issbyte(disp)); + if(disp==0) + as_bad("short branch with zero offset: use :w"); + fragP->fr_opcode[1]=disp; ext=0; - } else if (fragP->fr_opcode[0]==0x60) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,0, - NO_RELOC); - fragP->fr_fix+=4; - ext=0; - } else { - as_bad("Long branch offset not supported."); - } - } else { - fragP->fr_opcode[1]=0xff; - ext=4; - } - break; - case TAB(BCC68000,LONG): + break; + case TAB(DBCC,SHORT): + know(issword(disp)); + ext=2; + break; + case TAB(BCC68000,SHORT): + case TAB(BRANCH,SHORT): + know(issword(disp)); + fragP->fr_opcode[1]=0x00; + ext=2; + break; + case TAB(BRANCH,LONG): + if (cpu_of_arch(current_architecture) < m68020) { + if (fragP->fr_opcode[0]==0x61) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + + fix_new(fragP, + fragP->fr_fix, + 4, + fragP->fr_symbol, + 0, + fragP->fr_offset, + 0, + NO_RELOC); + + fragP->fr_fix+=4; + ext=0; + } else if (fragP->fr_opcode[0]==0x60) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,0, + NO_RELOC); + fragP->fr_fix+=4; + ext=0; + } else { + as_bad("Long branch offset not supported."); + } + } else { + fragP->fr_opcode[1]=0xff; + ext=4; + } + break; + case TAB(BCC68000,LONG): /* only Bcc 68000 instructions can come here */ /* change bcc into b!cc/jmp absl long */ fragP->fr_opcode[0] ^= 0x01; /* invert bcc */ fragP->fr_opcode[1] = 0x6; /* branch offset = 6 */ - + /* JF: these used to be fr_opcode[2,3], but they may be in a different frag, in which case refering to them is a no-no. Only fr_opcode[0,1] are guaranteed to work. */ @@ -3533,12 +3533,12 @@ register fragS *fragP; fragP->fr_fix += 2; /* account for jmp instruction */ subseg_change(SEG_TEXT,0); fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset,0, - NO_RELOC); + fragP->fr_offset,0, + NO_RELOC); fragP->fr_fix += 4; ext=0; break; - case TAB(DBCC,LONG): + case TAB(DBCC,LONG): /* only DBcc 68000 instructions can come here */ /* change dbcc into dbcc/jmp absl long */ /* JF: these used to be fr_opcode[2-7], but that's wrong */ @@ -3548,254 +3548,254 @@ register fragS *fragP; *buffer_address++ = 0x06; *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */ *buffer_address++ = 0xf9; - + fragP->fr_fix += 6; /* account for bra/jmp instructions */ subseg_change(SEG_TEXT,0); fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset,0, - NO_RELOC); + fragP->fr_offset,0, + NO_RELOC); fragP->fr_fix += 4; ext=0; - break; - case TAB(FBRANCH,SHORT): - know((fragP->fr_opcode[1]&0x40)==0); - ext=2; - break; - case TAB(FBRANCH,LONG): - fragP->fr_opcode[1]|=0x40; /* Turn on LONG bit */ - ext=4; - break; - case TAB(PCREL,SHORT): - ext=2; - break; - case TAB(PCREL,LONG): - /* The thing to do here is force it to ABSOLUTE LONG, since - PCREL is really trying to shorten an ABSOLUTE address anyway */ - /* JF FOO This code has not been tested */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); - if((fragP->fr_opcode[1] & 0x3F) != 0x3A) - as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx", - fragP->fr_opcode[0],fragP->fr_address); - fragP->fr_opcode[1]&= ~0x3F; - fragP->fr_opcode[1]|=0x39; /* Mode 7.1 */ - fragP->fr_fix+=4; - /* md_number_to_chars(buffer_address, - (long)(fragP->fr_symbol->sy_value + fragP->fr_offset), - 4); */ - ext=0; - break; - case TAB(PCLEA,SHORT): - subseg_change(SEG_TEXT,0); - fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset,1, - NO_RELOC); - fragP->fr_opcode[1] &= ~0x3F; - fragP->fr_opcode[1] |= 0x3A; - ext=2; - break; - case TAB(PCLEA,LONG): - subseg_change(SEG_TEXT,0); - fix_new(fragP,(int)(fragP->fr_fix)+2,4,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset+2,1, - NO_RELOC); - *buffer_address++ = 0x01; - *buffer_address++ = 0x70; - fragP->fr_fix+=2; - /* buffer_address+=2; */ - ext=4; - break; - - } /* switch on subtype */ - - if (ext) { - md_number_to_chars(buffer_address, (long) disp, (int) ext); - fragP->fr_fix += ext; -/* H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */ - } /* if extending */ - - return; + break; + case TAB(FBRANCH,SHORT): + know((fragP->fr_opcode[1]&0x40)==0); + ext=2; + break; + case TAB(FBRANCH,LONG): + fragP->fr_opcode[1]|=0x40; /* Turn on LONG bit */ + ext=4; + break; + case TAB(PCREL,SHORT): + ext=2; + break; + case TAB(PCREL,LONG): + /* The thing to do here is force it to ABSOLUTE LONG, since + PCREL is really trying to shorten an ABSOLUTE address anyway */ + /* JF FOO This code has not been tested */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); + if((fragP->fr_opcode[1] & 0x3F) != 0x3A) + as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx", + fragP->fr_opcode[0],fragP->fr_address); + fragP->fr_opcode[1]&= ~0x3F; + fragP->fr_opcode[1]|=0x39; /* Mode 7.1 */ + fragP->fr_fix+=4; + /* md_number_to_chars(buffer_address, + (long)(fragP->fr_symbol->sy_value + fragP->fr_offset), + 4); */ + ext=0; + break; + case TAB(PCLEA,SHORT): + subseg_change(SEG_TEXT,0); + fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset,1, + NO_RELOC); + fragP->fr_opcode[1] &= ~0x3F; + fragP->fr_opcode[1] |= 0x3A; + ext=2; + break; + case TAB(PCLEA,LONG): + subseg_change(SEG_TEXT,0); + fix_new(fragP,(int)(fragP->fr_fix)+2,4,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset+2,1, + NO_RELOC); + *buffer_address++ = 0x01; + *buffer_address++ = 0x70; + fragP->fr_fix+=2; + /* buffer_address+=2; */ + ext=4; + break; + + } /* switch on subtype */ + + if (ext) { + md_number_to_chars(buffer_address, (long) disp, (int) ext); + fragP->fr_fix += ext; + /* H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */ + } /* if extending */ + + return; } /* md_convert_frag() */ /* Force truly undefined symbols to their maximum size, and generally set up the frag list to be relaxed - */ + */ int md_estimate_size_before_relax(fragP, segment) -register fragS *fragP; -segT segment; + register fragS *fragP; + segT segment; { - int old_fix; - register char *buffer_address = fragP->fr_fix + fragP->fr_literal; - - old_fix = fragP->fr_fix; - - /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ - switch(fragP->fr_subtype) { - - case TAB(BRANCH,SZ_UNDEF): { - if((fragP->fr_symbol != NULL) /* Not absolute */ - && S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); - break; - } else if((fragP->fr_symbol == 0) || (cpu_of_arch(current_architecture) < m68020)) { - /* On 68000, or for absolute value, switch to abs long */ - /* FIXME, we should check abs val, pick short or long */ - if(fragP->fr_opcode[0]==0x61) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - fix_new(fragP, fragP->fr_fix, 4, - fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix+=4; - frag_wane(fragP); - } else if(fragP->fr_opcode[0]==0x60) { - fragP->fr_opcode[0]= 0x4E; - fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ - subseg_change(SEG_TEXT, 0); - fix_new(fragP, fragP->fr_fix, 4, - fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix+=4; - frag_wane(fragP); - } else { - as_warn("Long branch offset to extern symbol not supported."); - } - } else { /* Symbol is still undefined. Make it simple */ - fix_new(fragP, (int)(fragP->fr_fix), 4, fragP->fr_symbol, - (symbolS *)0, fragP->fr_offset+4, 1, NO_RELOC); - fragP->fr_fix+=4; - fragP->fr_opcode[1]=0xff; - frag_wane(fragP); - break; - } - - break; - } /* case TAB(BRANCH,SZ_UNDEF) */ - - case TAB(FBRANCH,SZ_UNDEF): { - if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { - fragP->fr_subtype = TAB(FBRANCH,SHORT); - fragP->fr_var += 2; - } else { - fragP->fr_subtype = TAB(FBRANCH,LONG); - fragP->fr_var += 4; - } - break; - } /* TAB(FBRANCH,SZ_UNDEF) */ - - case TAB(PCREL,SZ_UNDEF): { - if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { - fragP->fr_subtype = TAB(PCREL,SHORT); - fragP->fr_var += 2; - } else { - fragP->fr_subtype = TAB(PCREL,LONG); - fragP->fr_var += 4; - } - break; - } /* TAB(PCREL,SZ_UNDEF) */ - - case TAB(BCC68000,SZ_UNDEF): { - if((fragP->fr_symbol != NULL) - && S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype=TAB(BCC68000,BYTE); - break; - } - /* only Bcc 68000 instructions can come here */ - /* change bcc into b!cc/jmp absl long */ - fragP->fr_opcode[0] ^= 0x01; /* invert bcc */ - if(flagseen['l']) { - fragP->fr_opcode[1] = 0x04; /* branch offset = 6 */ - /* JF: these were fr_opcode[2,3] */ - buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */ - buffer_address[1] = 0xf8; - fragP->fr_fix += 2; /* account for jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 2; - } else { - fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */ - /* JF: these were fr_opcode[2,3] */ - buffer_address[2] = 0x4e; /* put in jmp long (0x4ef9) */ - buffer_address[3] = 0xf9; - fragP->fr_fix += 2; /* account for jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 4; - } + int old_fix; + register char *buffer_address = fragP->fr_fix + fragP->fr_literal; + + old_fix = fragP->fr_fix; + + /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ + switch(fragP->fr_subtype) { + + case TAB(BRANCH,SZ_UNDEF): { + if((fragP->fr_symbol != NULL) /* Not absolute */ + && S_GET_SEGMENT(fragP->fr_symbol) == segment) { + fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); + break; + } else if((fragP->fr_symbol == 0) || (cpu_of_arch(current_architecture) < m68020)) { + /* On 68000, or for absolute value, switch to abs long */ + /* FIXME, we should check abs val, pick short or long */ + if(fragP->fr_opcode[0]==0x61) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + fix_new(fragP, fragP->fr_fix, 4, + fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix+=4; frag_wane(fragP); - break; - } /* case TAB(BCC68000,SZ_UNDEF) */ - - case TAB(DBCC,SZ_UNDEF): { - if (fragP->fr_symbol != NULL && S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype=TAB(DBCC,SHORT); - fragP->fr_var+=2; - break; - } - /* only DBcc 68000 instructions can come here */ - /* change dbcc into dbcc/jmp absl long */ - /* JF: these used to be fr_opcode[2-4], which is wrong. */ - buffer_address[0] = 0x00; /* branch offset = 4 */ - buffer_address[1] = 0x04; - buffer_address[2] = 0x60; /* put in bra pc + ... */ - - if(flagseen['l']) { - /* JF: these were fr_opcode[5-7] */ - buffer_address[3] = 0x04; /* plus 4 */ - buffer_address[4] = 0x4e;/* Put in Jump Word */ - buffer_address[5] = 0xf8; - fragP->fr_fix += 6; /* account for bra/jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 2; - } else { - /* JF: these were fr_opcode[5-7] */ - buffer_address[3] = 0x06; /* Plus 6 */ - buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */ - buffer_address[5] = 0xf9; - fragP->fr_fix += 6; /* account for bra/jmp instruction */ - subseg_change(SEG_TEXT,0); - fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 0, NO_RELOC); - fragP->fr_fix += 4; - } - + } else if(fragP->fr_opcode[0]==0x60) { + fragP->fr_opcode[0]= 0x4E; + fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */ + subseg_change(SEG_TEXT, 0); + fix_new(fragP, fragP->fr_fix, 4, + fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix+=4; frag_wane(fragP); - break; - } /* case TAB(DBCC,SZ_UNDEF) */ - - case TAB(PCLEA,SZ_UNDEF): { - if ((S_GET_SEGMENT(fragP->fr_symbol))==segment || flagseen['l']) { - fragP->fr_subtype=TAB(PCLEA,SHORT); - fragP->fr_var+=2; - } else { - fragP->fr_subtype=TAB(PCLEA,LONG); - fragP->fr_var+=6; - } - break; - } /* TAB(PCLEA,SZ_UNDEF) */ - - default: - break; - - } /* switch on subtype looking for SZ_UNDEF's. */ - - /* now that SZ_UNDEF are taken care of, check others */ - switch(fragP->fr_subtype) { - case TAB(BCC68000,BYTE): - case TAB(BRANCH,BYTE): - /* We can't do a short jump to the next instruction, - so we force word mode. */ - if (fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 && - fragP->fr_symbol->sy_frag==fragP->fr_next) { - fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); - fragP->fr_var+=2; - } - break; - default: - break; + } else { + as_warn("Long branch offset to extern symbol not supported."); + } + } else { /* Symbol is still undefined. Make it simple */ + fix_new(fragP, (int)(fragP->fr_fix), 4, fragP->fr_symbol, + (symbolS *)0, fragP->fr_offset+4, 1, NO_RELOC); + fragP->fr_fix+=4; + fragP->fr_opcode[1]=0xff; + frag_wane(fragP); + break; + } + + break; + } /* case TAB(BRANCH,SZ_UNDEF) */ + + case TAB(FBRANCH,SZ_UNDEF): { + if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { + fragP->fr_subtype = TAB(FBRANCH,SHORT); + fragP->fr_var += 2; + } else { + fragP->fr_subtype = TAB(FBRANCH,LONG); + fragP->fr_var += 4; + } + break; + } /* TAB(FBRANCH,SZ_UNDEF) */ + + case TAB(PCREL,SZ_UNDEF): { + if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { + fragP->fr_subtype = TAB(PCREL,SHORT); + fragP->fr_var += 2; + } else { + fragP->fr_subtype = TAB(PCREL,LONG); + fragP->fr_var += 4; + } + break; + } /* TAB(PCREL,SZ_UNDEF) */ + + case TAB(BCC68000,SZ_UNDEF): { + if((fragP->fr_symbol != NULL) + && S_GET_SEGMENT(fragP->fr_symbol) == segment) { + fragP->fr_subtype=TAB(BCC68000,BYTE); + break; + } + /* only Bcc 68000 instructions can come here */ + /* change bcc into b!cc/jmp absl long */ + fragP->fr_opcode[0] ^= 0x01; /* invert bcc */ + if(flagseen['l']) { + fragP->fr_opcode[1] = 0x04; /* branch offset = 6 */ + /* JF: these were fr_opcode[2,3] */ + buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */ + buffer_address[1] = 0xf8; + fragP->fr_fix += 2; /* account for jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 2; + } else { + fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */ + /* JF: these were fr_opcode[2,3] */ + buffer_address[2] = 0x4e; /* put in jmp long (0x4ef9) */ + buffer_address[3] = 0xf9; + fragP->fr_fix += 2; /* account for jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 4; + } + frag_wane(fragP); + break; + } /* case TAB(BCC68000,SZ_UNDEF) */ + + case TAB(DBCC,SZ_UNDEF): { + if (fragP->fr_symbol != NULL && S_GET_SEGMENT(fragP->fr_symbol) == segment) { + fragP->fr_subtype=TAB(DBCC,SHORT); + fragP->fr_var+=2; + break; + } + /* only DBcc 68000 instructions can come here */ + /* change dbcc into dbcc/jmp absl long */ + /* JF: these used to be fr_opcode[2-4], which is wrong. */ + buffer_address[0] = 0x00; /* branch offset = 4 */ + buffer_address[1] = 0x04; + buffer_address[2] = 0x60; /* put in bra pc + ... */ + + if(flagseen['l']) { + /* JF: these were fr_opcode[5-7] */ + buffer_address[3] = 0x04; /* plus 4 */ + buffer_address[4] = 0x4e;/* Put in Jump Word */ + buffer_address[5] = 0xf8; + fragP->fr_fix += 6; /* account for bra/jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 2; + } else { + /* JF: these were fr_opcode[5-7] */ + buffer_address[3] = 0x06; /* Plus 6 */ + buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */ + buffer_address[5] = 0xf9; + fragP->fr_fix += 6; /* account for bra/jmp instruction */ + subseg_change(SEG_TEXT,0); + fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 0, NO_RELOC); + fragP->fr_fix += 4; + } + + frag_wane(fragP); + break; + } /* case TAB(DBCC,SZ_UNDEF) */ + + case TAB(PCLEA,SZ_UNDEF): { + if ((S_GET_SEGMENT(fragP->fr_symbol))==segment || flagseen['l']) { + fragP->fr_subtype=TAB(PCLEA,SHORT); + fragP->fr_var+=2; + } else { + fragP->fr_subtype=TAB(PCLEA,LONG); + fragP->fr_var+=6; } - return fragP->fr_var + fragP->fr_fix - old_fix; + break; + } /* TAB(PCLEA,SZ_UNDEF) */ + + default: + break; + + } /* switch on subtype looking for SZ_UNDEF's. */ + + /* now that SZ_UNDEF are taken care of, check others */ + switch(fragP->fr_subtype) { + case TAB(BCC68000,BYTE): + case TAB(BRANCH,BYTE): + /* We can't do a short jump to the next instruction, + so we force word mode. */ + if (fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 && + fragP->fr_symbol->sy_frag==fragP->fr_next) { + fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); + fragP->fr_var+=2; + } + break; + default: + break; + } + return fragP->fr_var + fragP->fr_fix - old_fix; } #if defined(OBJ_AOUT) | defined(OBJ_BOUT) @@ -3804,64 +3804,64 @@ segT segment; I added this mach. dependent ri twiddler. Ugly, but it gets you there. -KWK */ /* on m68k: first 4 bytes are normal unsigned long, next three bytes -are symbolnum, most sig. byte first. Last byte is broken up with -bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower -nibble as nuthin. (on Sun 3 at least) */ + are symbolnum, most sig. byte first. Last byte is broken up with + bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower + nibble as nuthin. (on Sun 3 at least) */ /* Translate the internal relocation information into target-specific format. */ #ifdef comment void -md_ri_to_chars(the_bytes, ri) - char *the_bytes; - struct reloc_info_generic *ri; + md_ri_to_chars(the_bytes, ri) +char *the_bytes; +struct reloc_info_generic *ri; { - /* this is easy */ - md_number_to_chars(the_bytes, ri->r_address, 4); - /* now the fun stuff */ - the_bytes[4] = (ri->r_symbolnum >> 16) & 0x0ff; - the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff; - the_bytes[6] = ri->r_symbolnum & 0x0ff; - the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) | - ((ri->r_extern << 4) & 0x10)); + /* this is easy */ + md_number_to_chars(the_bytes, ri->r_address, 4); + /* now the fun stuff */ + the_bytes[4] = (ri->r_symbolnum >> 16) & 0x0ff; + the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff; + the_bytes[6] = ri->r_symbolnum & 0x0ff; + the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) | + ((ri->r_extern << 4) & 0x10)); } #endif /* comment */ void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) -char *where; -fixS *fixP; -relax_addressT segment_address_in_file; + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; { - /* - * In: length of relocation (or of address) in chars: 1, 2 or 4. - * Out: GNU LD relocation length code: 0, 1, or 2. - */ - - static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 }; - - long r_extern; - long r_symbolnum; - - /* this is easy */ - md_number_to_chars(where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); - - /* now the fun stuff */ - if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) { - r_extern = 1; - r_symbolnum = fixP->fx_addsy->sy_number; - } else { - r_extern = 0; - r_symbolnum = S_GET_TYPE(fixP->fx_addsy); - } - - where[4] = (r_symbolnum >> 16) & 0x0ff; - where[5] = (r_symbolnum >> 8) & 0x0ff; - where[6] = r_symbolnum & 0x0ff; - where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) | - ((r_extern << 4) & 0x10)); - - return; + /* + * In: length of relocation (or of address) in chars: 1, 2 or 4. + * Out: GNU LD relocation length code: 0, 1, or 2. + */ + + static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 }; + + long r_extern; + long r_symbolnum; + + /* this is easy */ + md_number_to_chars(where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + /* now the fun stuff */ + if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) { + r_extern = 1; + r_symbolnum = fixP->fx_addsy->sy_number; + } else { + r_extern = 0; + r_symbolnum = S_GET_TYPE(fixP->fx_addsy); + } + + where[4] = (r_symbolnum >> 16) & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[6] = r_symbolnum & 0x0ff; + where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) | + ((r_extern << 4) & 0x10)); + + return; } /* tc_aout_fix_to_chars() */ #endif /* OBJ_AOUT or OBJ_BOUT */ @@ -3871,233 +3871,233 @@ const int md_short_jump_size = 4; const int md_long_jump_size = 6; void -md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol) + md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol) char *ptr; long from_addr, - to_addr; + to_addr; fragS *frag; symbolS *to_symbol; { - long offset; - - offset = to_addr - (from_addr+2); - - md_number_to_chars(ptr ,(long)0x6000,2); - md_number_to_chars(ptr+2,(long)offset,2); + long offset; + + offset = to_addr - (from_addr+2); + + md_number_to_chars(ptr ,(long)0x6000,2); + md_number_to_chars(ptr+2,(long)offset,2); } void -md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) + md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) char *ptr; long from_addr, - to_addr; + to_addr; fragS *frag; symbolS *to_symbol; { - long offset; - - if (cpu_of_arch(current_architecture) < m68020) { - offset=to_addr-S_GET_VALUE(to_symbol); - md_number_to_chars(ptr ,(long)0x4EF9,2); - md_number_to_chars(ptr+2,(long)offset,4); - fix_new(frag,(ptr+2)-frag->fr_literal,4,to_symbol,(symbolS *)0,(long)0,0, - NO_RELOC); - } else { - offset=to_addr - (from_addr+2); - md_number_to_chars(ptr ,(long)0x60ff,2); - md_number_to_chars(ptr+2,(long)offset,4); - } + long offset; + + if (cpu_of_arch(current_architecture) < m68020) { + offset=to_addr-S_GET_VALUE(to_symbol); + md_number_to_chars(ptr ,(long)0x4EF9,2); + md_number_to_chars(ptr+2,(long)offset,4); + fix_new(frag,(ptr+2)-frag->fr_literal,4,to_symbol,(symbolS *)0,(long)0,0, + NO_RELOC); + } else { + offset=to_addr - (from_addr+2); + md_number_to_chars(ptr ,(long)0x60ff,2); + md_number_to_chars(ptr+2,(long)offset,4); + } } #endif /* Different values of OK tell what its OK to return. Things that aren't OK are an error (what a shock, no?) - - 0: Everything is OK - 10: Absolute 1:8 only - 20: Absolute 0:7 only - 30: absolute 0:15 only - 40: Absolute 0:31 only - 50: absolute 0:127 only - 55: absolute -64:63 only - 60: absolute -128:127 only - 70: absolute 0:4095 only - 80: No bignums - -*/ + + 0: Everything is OK + 10: Absolute 1:8 only + 20: Absolute 0:7 only + 30: absolute 0:15 only + 40: Absolute 0:31 only + 50: absolute 0:127 only + 55: absolute -64:63 only + 60: absolute -128:127 only + 70: absolute 0:4095 only + 80: No bignums + + */ static int get_num(exp,ok) -struct m68k_exp *exp; -int ok; + struct m68k_exp *exp; + int ok; { #ifdef TEST2 - long l = 0; - - if(!exp->e_beg) - return 0; - if(*exp->e_beg=='0') { - if(exp->e_beg[1]=='x') - sscanf(exp->e_beg+2,"%x",&l); - else - sscanf(exp->e_beg+1,"%O",&l); - return l; - } - return atol(exp->e_beg); + long l = 0; + + if(!exp->e_beg) + return 0; + if(*exp->e_beg=='0') { + if(exp->e_beg[1]=='x') + sscanf(exp->e_beg+2,"%x",&l); + else + sscanf(exp->e_beg+1,"%O",&l); + return l; + } + return atol(exp->e_beg); #else - char *save_in; - char c_save; - - if(!exp) { - /* Can't do anything */ - return 0; - } - if(!exp->e_beg || !exp->e_end) { - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Null expression defaults to %ld",offs(exp)); - return 0; + char *save_in; + char c_save; + + if(!exp) { + /* Can't do anything */ + return 0; + } + if(!exp->e_beg || !exp->e_end) { + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Null expression defaults to %ld",offs(exp)); + return 0; + } + + exp->e_siz=0; + if(/* ok!=80 && */exp->e_end[-1]==SIZER && (exp->e_end-exp->e_beg)>=2) { + switch(exp->e_end[0]) { + case 's': + case 'S': + case 'b': + case 'B': + exp->e_siz=1; + break; + case 'w': + case 'W': + exp->e_siz=2; + break; + case 'l': + case 'L': + exp->e_siz=3; + break; + default: + as_bad("Unknown size for expression \"%c\"",exp->e_end[0]); } - - exp->e_siz=0; - if(/* ok!=80 && */exp->e_end[-1]==SIZER && (exp->e_end-exp->e_beg)>=2) { - switch(exp->e_end[0]) { - case 's': - case 'S': - case 'b': - case 'B': - exp->e_siz=1; - break; - case 'w': - case 'W': - exp->e_siz=2; - break; - case 'l': - case 'L': - exp->e_siz=3; - break; - default: - as_bad("Unknown size for expression \"%c\"",exp->e_end[0]); - } - exp->e_end-=2; + exp->e_end-=2; + } + c_save=exp->e_end[1]; + exp->e_end[1]='\0'; + save_in=input_line_pointer; + input_line_pointer=exp->e_beg; + switch(expression(&(exp->e_exp))) { + case SEG_PASS1: + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp)); + break; + + case SEG_ABSENT: + /* Do the same thing the VAX asm does */ + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)=0; + if(ok==10) { + as_warn("expression out of range: defaulting to 1"); + offs(exp)=1; } - c_save=exp->e_end[1]; - exp->e_end[1]='\0'; - save_in=input_line_pointer; - input_line_pointer=exp->e_beg; - switch(expression(&(exp->e_exp))) { - case SEG_PASS1: - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp)); - break; - - case SEG_ABSENT: - /* Do the same thing the VAX asm does */ - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; + break; + case SEG_ABSOLUTE: + switch(ok) { + case 10: + if(offs(exp)<1 || offs(exp)>8) { + as_warn("expression out of range: defaulting to 1"); + offs(exp)=1; + } + break; + case 20: + if(offs(exp)<0 || offs(exp)>7) + goto outrange; + break; + case 30: + if(offs(exp)<0 || offs(exp)>15) + goto outrange; + break; + case 40: + if(offs(exp)<0 || offs(exp)>32) + goto outrange; + break; + case 50: + if(offs(exp)<0 || offs(exp)>127) + goto outrange; + break; + case 55: + if(offs(exp)<-64 || offs(exp)>63) + goto outrange; + break; + case 60: + if(offs(exp)<-128 || offs(exp)>127) + goto outrange; + break; + case 70: + if(offs(exp)<0 || offs(exp)>4095) { + outrange: + as_warn("expression out of range: defaulting to 0"); offs(exp)=0; - if(ok==10) { - as_warn("expression out of range: defaulting to 1"); - offs(exp)=1; - } - break; - case SEG_ABSOLUTE: - switch(ok) { - case 10: - if(offs(exp)<1 || offs(exp)>8) { - as_warn("expression out of range: defaulting to 1"); - offs(exp)=1; - } - break; - case 20: - if(offs(exp)<0 || offs(exp)>7) - goto outrange; - break; - case 30: - if(offs(exp)<0 || offs(exp)>15) - goto outrange; - break; - case 40: - if(offs(exp)<0 || offs(exp)>32) - goto outrange; - break; - case 50: - if(offs(exp)<0 || offs(exp)>127) - goto outrange; - break; - case 55: - if(offs(exp)<-64 || offs(exp)>63) - goto outrange; - break; - case 60: - if(offs(exp)<-128 || offs(exp)>127) - goto outrange; - break; - case 70: - if(offs(exp)<0 || offs(exp)>4095) { - outrange: - as_warn("expression out of range: defaulting to 0"); - offs(exp)=0; - } - break; - default: - break; - } - break; - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - if(ok>=10 && ok<=70) { - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); - } - break; - case SEG_BIG: - if(ok==80 && offs(exp)<0) { /* HACK! Turn it into a long */ - LITTLENUM_TYPE words[6]; - - gen_to_words(words,2,8L);/* These numbers are magic! */ - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)=words[1]|(words[0]<<16); - } else if(ok!=0) { - seg(exp)=SEG_ABSOLUTE; - adds(exp)=0; - subs(exp)=0; - offs(exp)= (ok==10) ? 1 : 0; - as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); - } - break; + } + break; default: - as_fatal("failed sanity check."); + break; } - if(input_line_pointer!=exp->e_end+1) - as_bad("Ignoring junk after expression"); - exp->e_end[1]=c_save; - input_line_pointer=save_in; - if(exp->e_siz) { - switch(exp->e_siz) { - case 1: - if(!isbyte(offs(exp))) - as_warn("expression doesn't fit in BYTE"); - break; - case 2: - if(!isword(offs(exp))) - as_warn("expression doesn't fit in WORD"); - break; - } + break; + case SEG_TEXT: + case SEG_DATA: + case SEG_BSS: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + if(ok>=10 && ok<=70) { + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); + } + break; + case SEG_BIG: + if(ok==80 && offs(exp)<0) { /* HACK! Turn it into a long */ + LITTLENUM_TYPE words[6]; + + gen_to_words(words,2,8L);/* These numbers are magic! */ + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)=words[1]|(words[0]<<16); + } else if(ok!=0) { + seg(exp)=SEG_ABSOLUTE; + adds(exp)=0; + subs(exp)=0; + offs(exp)= (ok==10) ? 1 : 0; + as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp)); } - return offs(exp); + break; + default: + as_fatal("failed sanity check."); + } + if(input_line_pointer!=exp->e_end+1) + as_bad("Ignoring junk after expression"); + exp->e_end[1]=c_save; + input_line_pointer=save_in; + if(exp->e_siz) { + switch(exp->e_siz) { + case 1: + if(!isbyte(offs(exp))) + as_warn("expression doesn't fit in BYTE"); + break; + case 2: + if(!isword(offs(exp))) + as_warn("expression doesn't fit in WORD"); + break; + } + } + return offs(exp); #endif } /* get_num() */ @@ -4105,35 +4105,35 @@ int ok; void demand_empty_rest_of_line(); /* Hate those extra verbose names */ static void s_data1() { - subseg_new(SEG_DATA,1); - demand_empty_rest_of_line(); + subseg_new(SEG_DATA,1); + demand_empty_rest_of_line(); } /* s_data1() */ static void s_data2() { - subseg_new(SEG_DATA,2); - demand_empty_rest_of_line(); + subseg_new(SEG_DATA,2); + demand_empty_rest_of_line(); } /* s_data2() */ static void s_bss() { - /* We don't support putting frags in the BSS segment, but we - can put them into initialized data for now... */ - subseg_new(SEG_DATA,255); /* FIXME-SOON */ - demand_empty_rest_of_line(); + /* We don't support putting frags in the BSS segment, but we + can put them into initialized data for now... */ + subseg_new(SEG_DATA,255); /* FIXME-SOON */ + demand_empty_rest_of_line(); } /* s_bss() */ static void s_even() { - register int temp; - register long temp_fill; - - temp = 1; /* JF should be 2? */ - temp_fill = get_absolute_expression (); - if ( ! need_pass_2 ) /* Never make frag if expect extra pass. */ - frag_align (temp, (int)temp_fill); - demand_empty_rest_of_line(); + register int temp; + register long temp_fill; + + temp = 1; /* JF should be 2? */ + temp_fill = get_absolute_expression (); + if ( ! need_pass_2 ) /* Never make frag if expect extra pass. */ + frag_align (temp, (int)temp_fill); + demand_empty_rest_of_line(); } /* s_even() */ static void s_proc() { - demand_empty_rest_of_line(); + demand_empty_rest_of_line(); } /* s_proc() */ /* s_space is defined in read.c .skip is simply an alias to it. */ @@ -4163,79 +4163,79 @@ static void s_proc() { #endif int md_parse_option(argP,cntP,vecP) -char **argP; -int *cntP; -char ***vecP; + char **argP; + int *cntP; + char ***vecP; { - switch(**argP) { - case 'l': /* -l means keep external to 2 bit offset - rather than 16 bit one */ - break; - - case 'S': /* -S means that jbsr's always turn into jsr's. */ - break; - - case 'A': - (*argP)++; - /* intentional fall-through */ - case 'm': - (*argP)++; - - if (**argP=='c') { - (*argP)++; - } /* allow an optional "c" */ - - if (!strcmp(*argP, "68000") - || !strcmp(*argP, "68008")) { - current_architecture |= m68000; - } else if (!strcmp(*argP, "68010")) { + switch(**argP) { + case 'l': /* -l means keep external to 2 bit offset + rather than 16 bit one */ + break; + + case 'S': /* -S means that jbsr's always turn into jsr's. */ + break; + + case 'A': + (*argP)++; + /* intentional fall-through */ + case 'm': + (*argP)++; + + if (**argP=='c') { + (*argP)++; + } /* allow an optional "c" */ + + if (!strcmp(*argP, "68000") + || !strcmp(*argP, "68008")) { + current_architecture |= m68000; + } else if (!strcmp(*argP, "68010")) { #ifdef TE_SUN - omagic= 1<<16|OMAGIC; + omagic= 1<<16|OMAGIC; #endif - current_architecture |= m68010; - - } else if (!strcmp(*argP, "68020")) { - current_architecture |= m68020 | MAYBE_FLOAT_TOO; - - } else if (!strcmp(*argP, "68030")) { - current_architecture |= m68030 | MAYBE_FLOAT_TOO; - - } else if (!strcmp(*argP, "68040")) { - current_architecture |= m68040 | MAYBE_FLOAT_TOO; - + current_architecture |= m68010; + + } else if (!strcmp(*argP, "68020")) { + current_architecture |= m68020 | MAYBE_FLOAT_TOO; + + } else if (!strcmp(*argP, "68030")) { + current_architecture |= m68030 | MAYBE_FLOAT_TOO; + + } else if (!strcmp(*argP, "68040")) { + current_architecture |= m68040 | MAYBE_FLOAT_TOO; + #ifndef NO_68881 - } else if (!strcmp(*argP, "68881")) { - current_architecture |= m68881; - - } else if (!strcmp(*argP, "68882")) { - current_architecture |= m68882; - + } else if (!strcmp(*argP, "68881")) { + current_architecture |= m68881; + + } else if (!strcmp(*argP, "68882")) { + current_architecture |= m68882; + #endif /* NO_68881 */ #ifndef NO_68851 - } else if (!strcmp(*argP,"68851")) { - current_architecture |= m68851; - + } else if (!strcmp(*argP,"68851")) { + current_architecture |= m68851; + #endif /* NO_68851 */ - } else { - as_warn("Unknown architecture, \"%s\". option ignored", *argP); - } /* switch on architecture */ - - while(**argP) (*argP)++; - - break; - - case 'p': - if (!strcmp(*argP,"pic")) { - (*argP) += 3; - break; /* -pic, Position Independent Code */ - } else { - return(0); - } /* pic or not */ - - default: - return 0; - } - return 1; + } else { + as_warn("Unknown architecture, \"%s\". option ignored", *argP); + } /* switch on architecture */ + + while(**argP) (*argP)++; + + break; + + case 'p': + if (!strcmp(*argP,"pic")) { + (*argP) += 3; + break; /* -pic, Position Independent Code */ + } else { + return(0); + } /* pic or not */ + + default: + return 0; + } + return 1; } @@ -4246,134 +4246,134 @@ char ***vecP; main() { - struct m68k_it the_ins; - char buf[120]; - char *cp; - int n; - - m68k_ip_begin(); - for(;;) { - if(!gets(buf) || !*buf) - break; - if(buf[0]=='|' || buf[1]=='.') - continue; - for(cp=buf;*cp;cp++) - if(*cp=='\t') - *cp=' '; - if(is_label(buf)) - continue; - bzero(&the_ins,sizeof(the_ins)); - m68k_ip(&the_ins,buf); - if(the_ins.error) { - printf("Error %s in %s\n",the_ins.error,buf); - } else { - printf("Opcode(%d.%s): ",the_ins.numo,the_ins.args); - for(n=0;n<the_ins.numo;n++) - printf(" 0x%x",the_ins.opcode[n]&0xffff); - printf(" "); - print_the_insn(&the_ins.opcode[0],stdout); - (void)putchar('\n'); - } - for(n=0;n<strlen(the_ins.args)/2;n++) { - if(the_ins.operands[n].error) { - printf("op%d Error %s in %s\n",n,the_ins.operands[n].error,buf); - continue; - } - printf("mode %d, reg %d, ",the_ins.operands[n].mode,the_ins.operands[n].reg); - if(the_ins.operands[n].b_const) - printf("Constant: '%.*s', ",1+the_ins.operands[n].e_const-the_ins.operands[n].b_const,the_ins.operands[n].b_const); - printf("ireg %d, isiz %d, imul %d, ",the_ins.operands[n].ireg,the_ins.operands[n].isiz,the_ins.operands[n].imul); - if(the_ins.operands[n].b_iadd) - printf("Iadd: '%.*s',",1+the_ins.operands[n].e_iadd-the_ins.operands[n].b_iadd,the_ins.operands[n].b_iadd); - (void)putchar('\n'); - } + struct m68k_it the_ins; + char buf[120]; + char *cp; + int n; + + m68k_ip_begin(); + for(;;) { + if(!gets(buf) || !*buf) + break; + if(buf[0]=='|' || buf[1]=='.') + continue; + for(cp=buf;*cp;cp++) + if(*cp=='\t') + *cp=' '; + if(is_label(buf)) + continue; + bzero(&the_ins,sizeof(the_ins)); + m68k_ip(&the_ins,buf); + if(the_ins.error) { + printf("Error %s in %s\n",the_ins.error,buf); + } else { + printf("Opcode(%d.%s): ",the_ins.numo,the_ins.args); + for(n=0;n<the_ins.numo;n++) + printf(" 0x%x",the_ins.opcode[n]&0xffff); + printf(" "); + print_the_insn(&the_ins.opcode[0],stdout); + (void)putchar('\n'); } - m68k_ip_end(); - return 0; + for(n=0;n<strlen(the_ins.args)/2;n++) { + if(the_ins.operands[n].error) { + printf("op%d Error %s in %s\n",n,the_ins.operands[n].error,buf); + continue; + } + printf("mode %d, reg %d, ",the_ins.operands[n].mode,the_ins.operands[n].reg); + if(the_ins.operands[n].b_const) + printf("Constant: '%.*s', ",1+the_ins.operands[n].e_const-the_ins.operands[n].b_const,the_ins.operands[n].b_const); + printf("ireg %d, isiz %d, imul %d, ",the_ins.operands[n].ireg,the_ins.operands[n].isiz,the_ins.operands[n].imul); + if(the_ins.operands[n].b_iadd) + printf("Iadd: '%.*s',",1+the_ins.operands[n].e_iadd-the_ins.operands[n].b_iadd,the_ins.operands[n].b_iadd); + (void)putchar('\n'); + } + } + m68k_ip_end(); + return 0; } is_label(str) -char *str; + char *str; { - while(ISSPACE(*str)) - str++; - while(*str && !ISSPACE(*str)) - str++; - if(str[-1]==':' || str[1]=='=') - return 1; - return 0; + while(ISSPACE(*str)) + str++; + while(*str && !ISSPACE(*str)) + str++; + if(str[-1]==':' || str[1]=='=') + return 1; + return 0; } #endif /* Possible states for relaxation: - -0 0 branch offset byte (bra, etc) -0 1 word -0 2 long - -1 0 indexed offsets byte a0@(32,d4:w:1) etc -1 1 word -1 2 long - -2 0 two-offset index word-word a0@(32,d4)@(45) etc -2 1 word-long -2 2 long-word -2 3 long-long - -*/ + + 0 0 branch offset byte (bra, etc) + 0 1 word + 0 2 long + + 1 0 indexed offsets byte a0@(32,d4:w:1) etc + 1 1 word + 1 2 long + + 2 0 two-offset index word-word a0@(32,d4)@(45) etc + 2 1 word-long + 2 2 long-word + 2 3 long-long + + */ #ifdef DONTDEF abort() { - printf("ABORT!\n"); - exit(12); + printf("ABORT!\n"); + exit(12); } char *index(s,c) -char *s; + char *s; { - while(*s!=c) { - if(!*s) return 0; - s++; - } - return s; + while(*s!=c) { + if(!*s) return 0; + s++; + } + return s; } bzero(s,n) -char *s; + char *s; { - while(n--) - *s++=0; + while(n--) + *s++=0; } print_frags() { - fragS *fragP; - extern fragS *text_frag_root; - - for(fragP=text_frag_root;fragP;fragP=fragP->fr_next) { - printf("addr %lu next 0x%x fix %ld var %ld symbol 0x%x offset %ld\n", - fragP->fr_address,fragP->fr_next,fragP->fr_fix,fragP->fr_var,fragP->fr_symbol,fragP->fr_offset); - printf("opcode 0x%x type %d subtype %d\n\n",fragP->fr_opcode,fragP->fr_type,fragP->fr_subtype); - } - fflush(stdout); - return 0; + fragS *fragP; + extern fragS *text_frag_root; + + for(fragP=text_frag_root;fragP;fragP=fragP->fr_next) { + printf("addr %lu next 0x%x fix %ld var %ld symbol 0x%x offset %ld\n", + fragP->fr_address,fragP->fr_next,fragP->fr_fix,fragP->fr_var,fragP->fr_symbol,fragP->fr_offset); + printf("opcode 0x%x type %d subtype %d\n\n",fragP->fr_opcode,fragP->fr_type,fragP->fr_subtype); + } + fflush(stdout); + return 0; } #endif #ifdef DONTDEF /*VARARGS1*/ panic(format,args) -char *format; + char *format; { - fputs("Internal error:",stderr); - _doprnt(format,&args,stderr); - (void)putc('\n',stderr); - as_where(); - abort(); + fputs("Internal error:",stderr); + _doprnt(format,&args,stderr); + (void)putc('\n',stderr); + as_where(); + abort(); } #endif @@ -4381,10 +4381,10 @@ char *format; /* ARGSUSED */ symbolS * -md_undefined_symbol (name) - char *name; + md_undefined_symbol (name) +char *name; { - return 0; + return 0; } /* Parse an operand that is machine-specific. @@ -4393,113 +4393,114 @@ md_undefined_symbol (name) /* ARGSUSED */ void -md_operand (expressionP) - expressionS *expressionP; + md_operand (expressionP) +expressionS *expressionP; { } /* Round up a section size to the appropriate boundary. */ long -md_section_align (segment, size) - segT segment; - long size; + md_section_align (segment, size) +segT segment; +long size; { - return size; /* Byte alignment is fine */ + return size; /* Byte alignment is fine */ } /* Exactly what point is a PC-relative offset relative TO? On the 68k, they're relative to the address of the offset, plus its size. (??? Is this right? FIXME-SOON!) */ long -md_pcrel_from (fixP) - fixS *fixP; + md_pcrel_from (fixP) +fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } #ifdef MRI void s_ds(size) { - unsigned int fill = get_absolute_expression() * size; - char *p = frag_var (rs_fill, fill, fill, (relax_substateT)0, (symbolS *)0, - 1, (char *)0); - * p = 0; - demand_empty_rest_of_line(); + unsigned int fill = get_absolute_expression() * size; + char *p = frag_var (rs_fill, fill, fill, (relax_substateT)0, (symbolS *)0, + 1, (char *)0); + * p = 0; + demand_empty_rest_of_line(); } void s_dc(size) { - - cons(size); - - + + cons(size); + + } void s_dcb(size) { - int repeat = get_absolute_expression(); - int fill; - - if (*input_line_pointer == ',') - { - char *p; - input_line_pointer++; - - fill = get_absolute_expression(); - p = frag_var(rs_fill, - size, - size, - (relax_substateT)0, - (symbolS *)0, - repeat, - 0); - md_number_to_chars(p, fill, size); - } - demand_empty_rest_of_line(); + int repeat = get_absolute_expression(); + int fill; + + if (*input_line_pointer == ',') + { + char *p; + input_line_pointer++; + + fill = get_absolute_expression(); + p = frag_var(rs_fill, + size, + size, + (relax_substateT)0, + (symbolS *)0, + repeat, + 0); + md_number_to_chars(p, fill, size); + } + demand_empty_rest_of_line(); + - } void s_chip() { - unsigned int target = get_absolute_expression(); + unsigned int target = get_absolute_expression(); #define MACHINE_MASK (m68000 | m68008 | m68010 | m68020 | m68040) - switch (target) - { - case 68000: - case 68008: - current_architecture = (current_architecture & ~ MACHINE_MASK) | m68000; - break; - case 68010: - current_architecture = (current_architecture & ~ MACHINE_MASK) | m68010; - break; - case 68020: - current_architecture = (current_architecture & ~ MACHINE_MASK) | m68020; - break; - case 68030: - current_architecture = (current_architecture & ~ MACHINE_MASK) | m68030; - break; - case 68040: - current_architecture = (current_architecture & ~ MACHINE_MASK) | m68040; - break; - case 68881: - current_architecture |= m68881; - break; - case 68882: - current_architecture |= m68882; - break; - case 68851: - current_architecture |= m68851; - break; - - default: - as_bad("Unrecognised CHIP %d\n", target); - - } - demand_empty_rest_of_line(); + switch (target) + { + case 68000: + case 68008: + current_architecture = (current_architecture & ~ MACHINE_MASK) | m68000; + break; + case 68010: + current_architecture = (current_architecture & ~ MACHINE_MASK) | m68010; + break; + case 68020: + current_architecture = (current_architecture & ~ MACHINE_MASK) | m68020; + break; + case 68030: + current_architecture = (current_architecture & ~ MACHINE_MASK) | m68030; + break; + case 68040: + current_architecture = (current_architecture & ~ MACHINE_MASK) | m68040; + break; + case 68881: + current_architecture |= m68881; + break; + case 68882: + current_architecture |= m68882; + break; + case 68851: + current_architecture |= m68851; + break; + + default: + as_bad("Unrecognised CHIP %d\n", target); + + } + demand_empty_rest_of_line(); } #endif + /* * Local Variables: * comment-column: 0 diff --git a/gas/config/tc-m68kmote.h b/gas/config/tc-m68kmote.h index f5f4780..533c298 100644 --- a/gas/config/tc-m68kmote.h +++ b/gas/config/tc-m68kmote.h @@ -12,11 +12,11 @@ #define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (2<<16|OMAGIC); /* Magic byte for file header */ #endif /* TE_SUN3 */ - + #define AOUT_MACHTYPE 0x2 #define REVERSE_SORT_RELOCS /* FIXME-NOW: this line can be removed. */ #define LOCAL_LABELS_FB - + #define tc_crawl_symbol_chain(a) {;} /* not used */ #define tc_headers_hook(a) {;} /* not used */ #define tc_aout_pre_write_hook(x) {;} /* not used */ @@ -29,9 +29,9 @@ /* Copied from write.c */ #define M68K_AIM_KLUDGE(aim, this_state,this_type) \ - if (aim==0 && this_state== 4) { /* hard encoded from tc-m68k.c */ \ + if (aim==0 && this_state== 4) { /* hard encoded from tc-m68k.c */ \ aim=this_type->rlx_forward+1; /* Force relaxation into word mode */ \ - } + } /* * Local Variables: diff --git a/gas/config/tc-ns32k.c b/gas/config/tc-ns32k.c index f4fd883..5f3e19a 100644 --- a/gas/config/tc-ns32k.c +++ b/gas/config/tc-ns32k.c @@ -1,21 +1,21 @@ /* ns32k.c -- Assemble on the National Semiconductor 32k series Copyright (C) 1987 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. */ + + 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 SHOW_NUM 1*/ /* uncomment for debugging */ @@ -26,7 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #else #include <strings.h> #endif -#include "ns32k-opcode.h" +#include "opcode/ns32k.h" #include "as.h" @@ -39,17 +39,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define DEFAULT -1 /* addr_mode returns this value when plain constant or label is encountered */ #define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \ - iif.iifP[ptr].type= a1; \ - iif.iifP[ptr].size= c1; \ - iif.iifP[ptr].object= e1; \ - iif.iifP[ptr].object_adjust= g1; \ - iif.iifP[ptr].pcrel= i1; \ - iif.iifP[ptr].pcrel_adjust= k1; \ - iif.iifP[ptr].im_disp= m1; \ - iif.iifP[ptr].relax_substate= o1; \ - iif.iifP[ptr].bit_fixP= q1; \ - iif.iifP[ptr].addr_mode= s1; \ - iif.iifP[ptr].bsr= u1; + iif.iifP[ptr].type= a1; \ + iif.iifP[ptr].size= c1; \ + iif.iifP[ptr].object= e1; \ + iif.iifP[ptr].object_adjust= g1; \ + iif.iifP[ptr].pcrel= i1; \ + iif.iifP[ptr].pcrel_adjust= k1; \ + iif.iifP[ptr].im_disp= m1; \ + iif.iifP[ptr].relax_substate= o1; \ + iif.iifP[ptr].bit_fixP= q1; \ + iif.iifP[ptr].addr_mode= s1; \ + iif.iifP[ptr].bsr= u1; #ifdef SEQUENT_COMPATABILITY #define LINE_COMMENT_CHARS "|" @@ -68,17 +68,17 @@ char line_comment_chars[] = LINE_COMMENT_CHARS; #endif struct addr_mode { - char mode; /* addressing mode of operand (0-31) */ - char scaled_mode; /* mode combined with scaled mode */ - char scaled_reg; /* register used in scaled+1 (1-8) */ - char float_flag; /* set if R0..R7 was F0..F7 ie a floating-point-register */ - char am_size; /* estimated max size of general addr-mode parts*/ - char im_disp; /* if im_disp==1 we have a displacement */ - char pcrel; /* 1 if pcrel, this is really redundant info */ - char disp_suffix[2]; /* length of displacement(s), 0=undefined */ - char *disp[2]; /* pointer(s) at displacement(s) - or immediates(s) (ascii) */ - char index_byte; /* index byte */ + char mode; /* addressing mode of operand (0-31) */ + char scaled_mode; /* mode combined with scaled mode */ + char scaled_reg; /* register used in scaled+1 (1-8) */ + char float_flag; /* set if R0..R7 was F0..F7 ie a floating-point-register */ + char am_size; /* estimated max size of general addr-mode parts*/ + char im_disp; /* if im_disp==1 we have a displacement */ + char pcrel; /* 1 if pcrel, this is really redundant info */ + char disp_suffix[2]; /* length of displacement(s), 0=undefined */ + char *disp[2]; /* pointer(s) at displacement(s) + or immediates(s) (ascii) */ + char index_byte; /* index byte */ }; typedef struct addr_mode addr_modeS; @@ -100,27 +100,27 @@ char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */ /* internal structs */ struct option { - char *pattern; - unsigned long or; - unsigned long and; + char *pattern; + unsigned long or; + unsigned long and; }; typedef struct { - int type; /* how to interpret object */ - int size; /* Estimated max size of object */ - unsigned long object; /* binary data */ - int object_adjust; /* number added to object */ - int pcrel; /* True if object is pcrel */ - int pcrel_adjust; /* It's value reflects the length in bytes from the instruction start to the displacement */ - int im_disp; /* True if the object is a displacement */ - relax_substateT relax_substate; /* Initial relaxsubstate */ - bit_fixS *bit_fixP; /* Pointer at bit_fix struct */ - int addr_mode; /* What addrmode do we associate with this iif-entry */ - char bsr; /* Sequent hack */ + int type; /* how to interpret object */ + int size; /* Estimated max size of object */ + unsigned long object; /* binary data */ + int object_adjust; /* number added to object */ + int pcrel; /* True if object is pcrel */ + int pcrel_adjust; /* It's value reflects the length in bytes from the instruction start to the displacement */ + int im_disp; /* True if the object is a displacement */ + relax_substateT relax_substate; /* Initial relaxsubstate */ + bit_fixS *bit_fixP; /* Pointer at bit_fix struct */ + int addr_mode; /* What addrmode do we associate with this iif-entry */ + char bsr; /* Sequent hack */ }iif_entryT; /* Internal Instruction Format */ struct int_ins_form { - int instr_size; /* Max size of instruction in bytes. */ - iif_entryT iifP[IIF_ENTRIES+1]; + int instr_size; /* Max size of instruction in bytes. */ + iif_entryT iifP[IIF_ENTRIES+1]; }; struct int_ins_form iif; expressionS exprP; @@ -175,124 +175,124 @@ char *input_line_pointer; struct option opt1[]= /* restore, exit */ { - { "r0", 0x80, 0xff }, - { "r1", 0x40, 0xff }, - { "r2", 0x20, 0xff }, - { "r3", 0x10, 0xff }, - { "r4", 0x08, 0xff }, - { "r5", 0x04, 0xff }, - { "r6", 0x02, 0xff }, - { "r7", 0x01, 0xff }, - { 0 , 0x00, 0xff } +{ "r0", 0x80, 0xff }, +{ "r1", 0x40, 0xff }, +{ "r2", 0x20, 0xff }, +{ "r3", 0x10, 0xff }, +{ "r4", 0x08, 0xff }, +{ "r5", 0x04, 0xff }, +{ "r6", 0x02, 0xff }, +{ "r7", 0x01, 0xff }, +{ 0 , 0x00, 0xff } }; struct option opt2[]= /* save, enter */ { - { "r0", 0x01, 0xff }, - { "r1", 0x02, 0xff }, - { "r2", 0x04, 0xff }, - { "r3", 0x08, 0xff }, - { "r4", 0x10, 0xff }, - { "r5", 0x20, 0xff }, - { "r6", 0x40, 0xff }, - { "r7", 0x80, 0xff }, - { 0 , 0x00, 0xff } +{ "r0", 0x01, 0xff }, +{ "r1", 0x02, 0xff }, +{ "r2", 0x04, 0xff }, +{ "r3", 0x08, 0xff }, +{ "r4", 0x10, 0xff }, +{ "r5", 0x20, 0xff }, +{ "r6", 0x40, 0xff }, +{ "r7", 0x80, 0xff }, +{ 0 , 0x00, 0xff } }; struct option opt3[]= /* setcfg */ { - { "c", 0x8, 0xff }, - { "m", 0x4, 0xff }, - { "f", 0x2, 0xff }, - { "i", 0x1, 0xff }, - { 0 , 0x0, 0xff } +{ "c", 0x8, 0xff }, +{ "m", 0x4, 0xff }, +{ "f", 0x2, 0xff }, +{ "i", 0x1, 0xff }, +{ 0 , 0x0, 0xff } }; struct option opt4[]= /* cinv */ { - { "a", 0x4, 0xff }, - { "i", 0x2, 0xff }, - { "d", 0x1, 0xff }, - { 0 , 0x0, 0xff } +{ "a", 0x4, 0xff }, +{ "i", 0x2, 0xff }, +{ "d", 0x1, 0xff }, +{ 0 , 0x0, 0xff } }; struct option opt5[]= /* string inst */ { - { "b", 0x2, 0xff }, - { "u", 0xc, 0xff }, - { "w", 0x4, 0xff }, - { 0 , 0x0, 0xff } +{ "b", 0x2, 0xff }, +{ "u", 0xc, 0xff }, +{ "w", 0x4, 0xff }, +{ 0 , 0x0, 0xff } }; struct option opt6[]= /* plain reg ext,cvtp etc */ { - { "r0", 0x00, 0xff }, - { "r1", 0x01, 0xff }, - { "r2", 0x02, 0xff }, - { "r3", 0x03, 0xff }, - { "r4", 0x04, 0xff }, - { "r5", 0x05, 0xff }, - { "r6", 0x06, 0xff }, - { "r7", 0x07, 0xff }, - { 0 , 0x00, 0xff } +{ "r0", 0x00, 0xff }, +{ "r1", 0x01, 0xff }, +{ "r2", 0x02, 0xff }, +{ "r3", 0x03, 0xff }, +{ "r4", 0x04, 0xff }, +{ "r5", 0x05, 0xff }, +{ "r6", 0x06, 0xff }, +{ "r7", 0x07, 0xff }, +{ 0 , 0x00, 0xff } }; #if !defined(NS32032) && !defined(NS32532) #define NS32032 #endif - -struct option cpureg_532[]= /* lpr spr */ + + struct option cpureg_532[]= /* lpr spr */ { - { "us", 0x0, 0xff }, - { "dcr", 0x1, 0xff }, - { "bpc", 0x2, 0xff }, - { "dsr", 0x3, 0xff }, - { "car", 0x4, 0xff }, - { "fp", 0x8, 0xff }, - { "sp", 0x9, 0xff }, - { "sb", 0xa, 0xff }, - { "usp", 0xb, 0xff }, - { "cfg", 0xc, 0xff }, - { "psr", 0xd, 0xff }, - { "intbase", 0xe, 0xff }, - { "mod", 0xf, 0xff }, - { 0 , 0x00, 0xff } +{ "us", 0x0, 0xff }, +{ "dcr", 0x1, 0xff }, +{ "bpc", 0x2, 0xff }, +{ "dsr", 0x3, 0xff }, +{ "car", 0x4, 0xff }, +{ "fp", 0x8, 0xff }, +{ "sp", 0x9, 0xff }, +{ "sb", 0xa, 0xff }, +{ "usp", 0xb, 0xff }, +{ "cfg", 0xc, 0xff }, +{ "psr", 0xd, 0xff }, +{ "intbase", 0xe, 0xff }, +{ "mod", 0xf, 0xff }, +{ 0 , 0x00, 0xff } }; struct option mmureg_532[]= /* lmr smr */ { - { "mcr", 0x9, 0xff }, - { "msr", 0xa, 0xff }, - { "tear", 0xb, 0xff }, - { "ptb0", 0xc, 0xff }, - { "ptb1", 0xd, 0xff }, - { "ivar0", 0xe, 0xff }, - { "ivar1", 0xf, 0xff }, - { 0 , 0x0, 0xff } +{ "mcr", 0x9, 0xff }, +{ "msr", 0xa, 0xff }, +{ "tear", 0xb, 0xff }, +{ "ptb0", 0xc, 0xff }, +{ "ptb1", 0xd, 0xff }, +{ "ivar0", 0xe, 0xff }, +{ "ivar1", 0xf, 0xff }, +{ 0 , 0x0, 0xff } }; struct option cpureg_032[]= /* lpr spr */ { - { "upsr", 0x0, 0xff }, - { "fp", 0x8, 0xff }, - { "sp", 0x9, 0xff }, - { "sb", 0xa, 0xff }, - { "psr", 0xd, 0xff }, - { "intbase", 0xe, 0xff }, - { "mod", 0xf, 0xff }, - { 0 , 0x0, 0xff } +{ "upsr", 0x0, 0xff }, +{ "fp", 0x8, 0xff }, +{ "sp", 0x9, 0xff }, +{ "sb", 0xa, 0xff }, +{ "psr", 0xd, 0xff }, +{ "intbase", 0xe, 0xff }, +{ "mod", 0xf, 0xff }, +{ 0 , 0x0, 0xff } }; struct option mmureg_032[]= /* lmr smr */ { - { "bpr0", 0x0, 0xff }, - { "bpr1", 0x1, 0xff }, - { "pf0", 0x4, 0xff }, - { "pf1", 0x5, 0xff }, - { "sc", 0x8, 0xff }, - { "msr", 0xa, 0xff }, - { "bcnt", 0xb, 0xff }, - { "ptb0", 0xc, 0xff }, - { "ptb1", 0xd, 0xff }, - { "eia", 0xf, 0xff }, - { 0 , 0x0, 0xff } +{ "bpr0", 0x0, 0xff }, +{ "bpr1", 0x1, 0xff }, +{ "pf0", 0x4, 0xff }, +{ "pf1", 0x5, 0xff }, +{ "sc", 0x8, 0xff }, +{ "msr", 0xa, 0xff }, +{ "bcnt", 0xb, 0xff }, +{ "ptb0", 0xc, 0xff }, +{ "ptb1", 0xd, 0xff }, +{ "eia", 0xf, 0xff }, +{ 0 , 0x0, 0xff } }; #if defined(NS32532) -struct option *cpureg = cpureg_532; + struct option *cpureg = cpureg_532; struct option *mmureg = mmureg_532; #else struct option *cpureg = cpureg_032; @@ -301,53 +301,53 @@ struct option *mmureg = mmureg_032; const pseudo_typeS md_pseudo_table[]={ /* so far empty */ - { 0, 0, 0 } +{ 0, 0, 0 } }; #define IND(x,y) (((x)<<2)+(y)) - -/* those are index's to relax groups in md_relax_table - ie it must be multiplied by 4 to point at a group start. Viz IND(x,y) - Se function relax_segment in write.c for more info */ - + + /* those are index's to relax groups in md_relax_table + ie it must be multiplied by 4 to point at a group start. Viz IND(x,y) + Se function relax_segment in write.c for more info */ + #define BRANCH 1 #define PCREL 2 - -/* those are index's to entries in a relax group */ - + + /* those are index's to entries in a relax group */ + #define BYTE 0 #define WORD 1 #define DOUBLE 2 #define UNDEF 3 -/* Those limits are calculated from the displacement start in memory. - The ns32k uses the begining of the instruction as displacement base. - This type of displacements could be handled here by moving the limit window - up or down. I choose to use an internal displacement base-adjust as there - are other routines that must consider this. Also, as we have two various - offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits - would have had to be used. - Now we dont have to think about that. */ - - -const relax_typeS md_relax_table[]={ - { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, - - { (63), (-64), 1, IND(BRANCH,WORD) }, - { (8192), (-8192), 2, IND(BRANCH,DOUBLE) }, - { 0, 0, 4, 0 }, - { 1, 1, 0, 0 } + /* Those limits are calculated from the displacement start in memory. + The ns32k uses the begining of the instruction as displacement base. + This type of displacements could be handled here by moving the limit window + up or down. I choose to use an internal displacement base-adjust as there + are other routines that must consider this. Also, as we have two various + offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits + would have had to be used. + Now we dont have to think about that. */ + + + const relax_typeS md_relax_table[]={ +{ 1, 1, 0, 0 }, +{ 1, 1, 0, 0 }, +{ 1, 1, 0, 0 }, +{ 1, 1, 0, 0 }, + +{ (63), (-64), 1, IND(BRANCH,WORD) }, +{ (8192), (-8192), 2, IND(BRANCH,DOUBLE) }, +{ 0, 0, 4, 0 }, +{ 1, 1, 0, 0 } }; /* Array used to test if mode contains displacements. Value is true if mode contains displacement. */ char disp_test[]={ 0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1, - 1,1,1,0,0,1,1,0, - 1,1,1,1,1,1,1,1 }; + 1,1,1,1,1,1,1,1, + 1,1,1,0,0,1,1,0, + 1,1,1,1,1,1,1,1 }; /* Array used to calculate max size of displacements */ @@ -369,209 +369,209 @@ static void md_number_to_imm(); #endif /* __STDC__ */ /* Parses a general operand into an addressingmode struct - + in: pointer at operand in ascii form - pointer at addr_mode struct for result - the level of recursion. (always 0 or 1) - + pointer at addr_mode struct for result + the level of recursion. (always 0 or 1) + out: data in addr_mode struct - */ + */ int addr_mode(operand,addr_modeP,recursive_level) - char *operand; - register addr_modeS *addr_modeP; -int recursive_level; + char *operand; + register addr_modeS *addr_modeP; + int recursive_level; { - register char *str; - register int i; - register int strl; - register int mode; - int j; - mode = DEFAULT; /* default */ - addr_modeP->scaled_mode=0; /* why not */ - addr_modeP->scaled_reg=0; /* if 0, not scaled index */ - addr_modeP->float_flag=0; - addr_modeP->am_size=0; - addr_modeP->im_disp=0; - addr_modeP->pcrel=0; /* not set in this function */ - addr_modeP->disp_suffix[0]=0; - addr_modeP->disp_suffix[1]=0; - addr_modeP->disp[0]=NULL; - addr_modeP->disp[1]=NULL; - str=operand; - if (str[0]==0) {return (0);} /* we don't want this */ - strl=strlen(str); - switch (str[0]) { - /* the following three case statements controls the mode-chars - this is the place to ed if you want to change them */ + register char *str; + register int i; + register int strl; + register int mode; + int j; + mode = DEFAULT; /* default */ + addr_modeP->scaled_mode=0; /* why not */ + addr_modeP->scaled_reg=0; /* if 0, not scaled index */ + addr_modeP->float_flag=0; + addr_modeP->am_size=0; + addr_modeP->im_disp=0; + addr_modeP->pcrel=0; /* not set in this function */ + addr_modeP->disp_suffix[0]=0; + addr_modeP->disp_suffix[1]=0; + addr_modeP->disp[0]=NULL; + addr_modeP->disp[1]=NULL; + str=operand; + if (str[0]==0) {return (0);} /* we don't want this */ + strl=strlen(str); + switch (str[0]) { + /* the following three case statements controls the mode-chars + this is the place to ed if you want to change them */ #ifdef ABSOLUTE_PREFIX - case ABSOLUTE_PREFIX: - if (str[strl-1]==']') break; - addr_modeP->mode=21; /* absolute */ - addr_modeP->disp[0]=str+1; - return (-1); + case ABSOLUTE_PREFIX: + if (str[strl-1]==']') break; + addr_modeP->mode=21; /* absolute */ + addr_modeP->disp[0]=str+1; + return (-1); #endif #ifdef IMMEDIATE_PREFIX - case IMMEDIATE_PREFIX: - if (str[strl-1]==']') break; - addr_modeP->mode=20; /* immediate */ - addr_modeP->disp[0]=str+1; - return (-1); + case IMMEDIATE_PREFIX: + if (str[strl-1]==']') break; + addr_modeP->mode=20; /* immediate */ + addr_modeP->disp[0]=str+1; + return (-1); #endif - case '.': - if (str[strl-1]!=']') { - switch (str[1]) { - case'-':case'+': - if (str[2]!='\000') { - addr_modeP->mode=27; /* pc-relativ */ - addr_modeP->disp[0]=str+2; - return (-1); + case '.': + if (str[strl-1]!=']') { + switch (str[1]) { + case'-':case'+': + if (str[2]!='\000') { + addr_modeP->mode=27; /* pc-relativ */ + addr_modeP->disp[0]=str+2; + return (-1); + } + default: + as_warn("Invalid syntax in PC-relative addressing mode"); + return(0); + } } - default: - as_warn("Invalid syntax in PC-relative addressing mode"); - return(0); - } - } - break; - case'e': - if (str[strl-1]!=']') { - if((!strncmp(str,"ext(",4)) && strl>7) { /* external */ - addr_modeP->disp[0]=str+4; - i=0; - j=2; - do { /* disp[0]'s termination point */ - j+=1; - if (str[j]=='(') i++; - if (str[j]==')') i--; - } while (j<strl && i!=0); - if (i!=0 || !(str[j+1]=='-' || str[j+1]=='+') ) { - as_warn("Invalid syntax in External addressing mode"); - return(0); + break; + case'e': + if (str[strl-1]!=']') { + if((!strncmp(str,"ext(",4)) && strl>7) { /* external */ + addr_modeP->disp[0]=str+4; + i=0; + j=2; + do { /* disp[0]'s termination point */ + j+=1; + if (str[j]=='(') i++; + if (str[j]==')') i--; + } while (j<strl && i!=0); + if (i!=0 || !(str[j+1]=='-' || str[j+1]=='+') ) { + as_warn("Invalid syntax in External addressing mode"); + return(0); + } + str[j]='\000'; /* null terminate disp[0] */ + addr_modeP->disp[1]=str+j+2; + addr_modeP->mode=22; + return (-1); + } } - str[j]='\000'; /* null terminate disp[0] */ - addr_modeP->disp[1]=str+j+2; - addr_modeP->mode=22; - return (-1); - } - } - break; - default:; - } - strl=strlen(str); - switch(strl) { - case 2: - switch (str[0]) { - case'f':addr_modeP->float_flag=1; - case'r': - if (str[1]>='0' && str[1]<'8') { - addr_modeP->mode=str[1]-'0'; - return (-1); - } - } - case 3: - if (!strncmp(str,"tos",3)) { - addr_modeP->mode=23; /* TopOfStack */ - return (-1); + break; + default:; } - default:; - } - if (strl>4) { - if (str[strl-1]==')') { - if (str[strl-2]==')') { - if (!strncmp(&str[strl-5],"(fp",3)) { - mode=16; /* Memory Relative */ - } - if (!strncmp(&str[strl-5],"(sp",3)) { - mode=17; - } - if (!strncmp(&str[strl-5],"(sb",3)) { - mode=18; - } - if (mode!=DEFAULT) { /* memory relative */ - addr_modeP->mode=mode; - j=strl-5; /* temp for end of disp[0] */ - i=0; - do { - strl-=1; - if (str[strl]==')') i++; - if (str[strl]=='(') i--; - } while (strl>-1 && i!=0); - if (i!=0) { - as_warn("Invalid syntax in Memory Relative addressing mode"); - return(0); - } - addr_modeP->disp[1]=str; - addr_modeP->disp[0]=str+strl+1; - str[j]='\000'; /* null terminate disp[0] */ - str[strl]='\000'; /* null terminate disp[1] */ - return (-1); - } - } - switch (str[strl-3]) { - case'r':case'R': - if (str[strl-2]>='0' && str[strl-2]<'8' && str[strl-4]=='(') { - addr_modeP->mode=str[strl-2]-'0'+8; - addr_modeP->disp[0]=str; - str[strl-4]=0; - return (-1); /* reg rel */ - } - default: - if (!strncmp(&str[strl-4],"(fp",3)) { - mode=24; - } - if (!strncmp(&str[strl-4],"(sp",3)) { - mode=25; - } - if (!strncmp(&str[strl-4],"(sb",3)) { - mode=26; - } - if (!strncmp(&str[strl-4],"(pc",3)) { - mode=27; + strl=strlen(str); + switch(strl) { + case 2: + switch (str[0]) { + case'f':addr_modeP->float_flag=1; + case'r': + if (str[1]>='0' && str[1]<'8') { + addr_modeP->mode=str[1]-'0'; + return (-1); + } } - if (mode!=DEFAULT) { - addr_modeP->mode=mode; - addr_modeP->disp[0]=str; - str[strl-4]='\0'; - return (-1); /* memory space */ + case 3: + if (!strncmp(str,"tos",3)) { + addr_modeP->mode=23; /* TopOfStack */ + return (-1); } - } + default:; } - /* no trailing ')' do we have a ']' ? */ - if (str[strl-1]==']') { - switch (str[strl-2]) { - case'b':mode=28;break; - case'w':mode=29;break; - case'd':mode=30;break; - case'q':mode=31;break; - default:; - as_warn("Invalid scaled-indexed mode, use (b,w,d,q)"); - if (str[strl-3]!=':' || str[strl-6]!='[' || - str[strl-5]=='r' || str[strl-4]<'0' || str[strl-4]>'7') { - as_warn("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"); + if (strl>4) { + if (str[strl-1]==')') { + if (str[strl-2]==')') { + if (!strncmp(&str[strl-5],"(fp",3)) { + mode=16; /* Memory Relative */ + } + if (!strncmp(&str[strl-5],"(sp",3)) { + mode=17; + } + if (!strncmp(&str[strl-5],"(sb",3)) { + mode=18; + } + if (mode!=DEFAULT) { /* memory relative */ + addr_modeP->mode=mode; + j=strl-5; /* temp for end of disp[0] */ + i=0; + do { + strl-=1; + if (str[strl]==')') i++; + if (str[strl]=='(') i--; + } while (strl>-1 && i!=0); + if (i!=0) { + as_warn("Invalid syntax in Memory Relative addressing mode"); + return(0); + } + addr_modeP->disp[1]=str; + addr_modeP->disp[0]=str+strl+1; + str[j]='\000'; /* null terminate disp[0] */ + str[strl]='\000'; /* null terminate disp[1] */ + return (-1); + } + } + switch (str[strl-3]) { + case'r':case'R': + if (str[strl-2]>='0' && str[strl-2]<'8' && str[strl-4]=='(') { + addr_modeP->mode=str[strl-2]-'0'+8; + addr_modeP->disp[0]=str; + str[strl-4]=0; + return (-1); /* reg rel */ + } + default: + if (!strncmp(&str[strl-4],"(fp",3)) { + mode=24; + } + if (!strncmp(&str[strl-4],"(sp",3)) { + mode=25; + } + if (!strncmp(&str[strl-4],"(sb",3)) { + mode=26; + } + if (!strncmp(&str[strl-4],"(pc",3)) { + mode=27; + } + if (mode!=DEFAULT) { + addr_modeP->mode=mode; + addr_modeP->disp[0]=str; + str[strl-4]='\0'; + return (-1); /* memory space */ + } + } } - } /* scaled index */ - { - if (recursive_level>0) { - as_warn("Scaled-indexed addressing mode combined with scaled-index"); - return(0); + /* no trailing ')' do we have a ']' ? */ + if (str[strl-1]==']') { + switch (str[strl-2]) { + case'b':mode=28;break; + case'w':mode=29;break; + case'd':mode=30;break; + case'q':mode=31;break; + default:; + as_warn("Invalid scaled-indexed mode, use (b,w,d,q)"); + if (str[strl-3]!=':' || str[strl-6]!='[' || + str[strl-5]=='r' || str[strl-4]<'0' || str[strl-4]>'7') { + as_warn("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"); + } + } /* scaled index */ + { + if (recursive_level>0) { + as_warn("Scaled-indexed addressing mode combined with scaled-index"); + return(0); + } + addr_modeP->am_size+=1; /* scaled index byte */ + j=str[strl-4]-'0'; /* store temporary */ + str[strl-6]='\000'; /* nullterminate for recursive call */ + i=addr_mode(str,addr_modeP,1); + if (!i || addr_modeP->mode==20) { + as_warn("Invalid or illegal addressing mode combined with scaled-index"); + return(0); + } + addr_modeP->scaled_mode=addr_modeP->mode; /* store the inferior mode */ + addr_modeP->mode=mode; + addr_modeP->scaled_reg=j+1; + return (-1); } - addr_modeP->am_size+=1; /* scaled index byte */ - j=str[strl-4]-'0'; /* store temporary */ - str[strl-6]='\000'; /* nullterminate for recursive call */ - i=addr_mode(str,addr_modeP,1); - if (!i || addr_modeP->mode==20) { - as_warn("Invalid or illegal addressing mode combined with scaled-index"); - return(0); } - addr_modeP->scaled_mode=addr_modeP->mode; /* store the inferior mode */ - addr_modeP->mode=mode; - addr_modeP->scaled_reg=j+1; - return (-1); - } } - } - addr_modeP->mode = DEFAULT; /* default to whatever */ - addr_modeP->disp[0]=str; - return (-1); + addr_modeP->mode = DEFAULT; /* default to whatever */ + addr_modeP->disp[0]=str; + return (-1); } /* ptr points at string @@ -580,129 +580,129 @@ int recursive_level; the operand. When this is ready it parses the displacements for size specifying suffixes and determines size of immediate mode via ns32k-opcode. Also builds index bytes if needed. - */ + */ int get_addr_mode(ptr,addr_modeP) - char *ptr; - addr_modeS *addr_modeP; + char *ptr; + addr_modeS *addr_modeP; { - int tmp; - addr_mode(ptr,addr_modeP,0); - if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1) { - /* resolve ambigious operands, this shouldn't - be necessary if one uses standard NSC operand - syntax. But the sequent compiler doesn't!!! - This finds a proper addressinging mode if it - is implicitly stated. See ns32k-opcode.h */ - (void)evaluate_expr(&exprP,ptr); /* this call takes time Sigh! */ - if (addr_modeP->mode == DEFAULT) { - if (exprP.X_add_symbol || exprP.X_subtract_symbol) { - addr_modeP->mode=desc->default_model; /* we have a label */ - } else { - addr_modeP->mode=desc->default_modec; /* we have a constant */ - } - } else { - if (exprP.X_add_symbol || exprP.X_subtract_symbol) { - addr_modeP->scaled_mode=desc->default_model; - } else { - addr_modeP->scaled_mode=desc->default_modec; - } + int tmp; + addr_mode(ptr,addr_modeP,0); + if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1) { + /* resolve ambigious operands, this shouldn't + be necessary if one uses standard NSC operand + syntax. But the sequent compiler doesn't!!! + This finds a proper addressinging mode if it + is implicitly stated. See ns32k-opcode.h */ + (void)evaluate_expr(&exprP,ptr); /* this call takes time Sigh! */ + if (addr_modeP->mode == DEFAULT) { + if (exprP.X_add_symbol || exprP.X_subtract_symbol) { + addr_modeP->mode=desc->default_model; /* we have a label */ + } else { + addr_modeP->mode=desc->default_modec; /* we have a constant */ + } + } else { + if (exprP.X_add_symbol || exprP.X_subtract_symbol) { + addr_modeP->scaled_mode=desc->default_model; + } else { + addr_modeP->scaled_mode=desc->default_modec; + } + } + /* must put this mess down in addr_mode to handle the scaled case better */ + } + /* It appears as the sequent compiler wants an absolute when we have a + label without @. Constants becomes immediates besides the addr case. + Think it does so with local labels too, not optimum, pcrel is better. + When I have time I will make gas check this and select pcrel when possible + Actually that is trivial. + */ + if (tmp=addr_modeP->scaled_reg) { /* build indexbyte */ + tmp--; /* remember regnumber comes incremented for flagpurpose */ + tmp|=addr_modeP->scaled_mode<<3; + addr_modeP->index_byte=(char)tmp; + addr_modeP->am_size+=1; } - /* must put this mess down in addr_mode to handle the scaled case better */ - } - /* It appears as the sequent compiler wants an absolute when we have a - label without @. Constants becomes immediates besides the addr case. - Think it does so with local labels too, not optimum, pcrel is better. - When I have time I will make gas check this and select pcrel when possible - Actually that is trivial. - */ - if (tmp=addr_modeP->scaled_reg) { /* build indexbyte */ - tmp--; /* remember regnumber comes incremented for flagpurpose */ - tmp|=addr_modeP->scaled_mode<<3; - addr_modeP->index_byte=(char)tmp; - addr_modeP->am_size+=1; - } - if (disp_test[addr_modeP->mode]) { /* there was a displacement, probe for length specifying suffix*/ + if (disp_test[addr_modeP->mode]) { /* there was a displacement, probe for length specifying suffix*/ { - register char c; - register char suffix; - register char suffix_sub; - register int i; - register char *toP; - register char *fromP; - - addr_modeP->pcrel=0; - if (disp_test[addr_modeP->mode]) { /* there is a displacement */ - if (addr_modeP->mode==27 || addr_modeP->scaled_mode==27) { /* do we have pcrel. mode */ - addr_modeP->pcrel=1; - } - addr_modeP->im_disp=1; - for(i=0;i<2;i++) { - suffix_sub=suffix=0; - if (toP=addr_modeP->disp[i]) { /* suffix of expression, the largest size rules */ - fromP=toP; - while (c = *fromP++) { - *toP++=c; - if (c==':') { - switch (*fromP) { - case '\0': - as_warn("Premature end of suffix--Defaulting to d"); - suffix=4; - continue; - case 'b':suffix_sub=1;break; - case 'w':suffix_sub=2;break; - case 'd':suffix_sub=4;break; - default: - as_warn("Bad suffix after ':' use {b|w|d} Defaulting to d"); - suffix=4; + register char c; + register char suffix; + register char suffix_sub; + register int i; + register char *toP; + register char *fromP; + + addr_modeP->pcrel=0; + if (disp_test[addr_modeP->mode]) { /* there is a displacement */ + if (addr_modeP->mode==27 || addr_modeP->scaled_mode==27) { /* do we have pcrel. mode */ + addr_modeP->pcrel=1; + } + addr_modeP->im_disp=1; + for(i=0;i<2;i++) { + suffix_sub=suffix=0; + if (toP=addr_modeP->disp[i]) { /* suffix of expression, the largest size rules */ + fromP=toP; + while (c = *fromP++) { + *toP++=c; + if (c==':') { + switch (*fromP) { + case '\0': + as_warn("Premature end of suffix--Defaulting to d"); + suffix=4; + continue; + case 'b':suffix_sub=1;break; + case 'w':suffix_sub=2;break; + case 'd':suffix_sub=4;break; + default: + as_warn("Bad suffix after ':' use {b|w|d} Defaulting to d"); + suffix=4; + } + fromP++; + toP--; /* So we write over the ':' */ + if (suffix<suffix_sub) suffix=suffix_sub; + } + } + *toP='\0'; /* terminate properly */ + addr_modeP->disp_suffix[i]=suffix; + addr_modeP->am_size+=suffix ? suffix : 4; } - fromP++; - toP--; /* So we write over the ':' */ - if (suffix<suffix_sub) suffix=suffix_sub; - } } - *toP='\0'; /* terminate properly */ - addr_modeP->disp_suffix[i]=suffix; - addr_modeP->am_size+=suffix ? suffix : 4; - } } - } } - } else { +} else { if (addr_modeP->mode==20) { /* look in ns32k_opcode for size */ - addr_modeP->disp_suffix[0]=addr_modeP->am_size=desc->im_size; - addr_modeP->im_disp=0; + addr_modeP->disp_suffix[0]=addr_modeP->am_size=desc->im_size; + addr_modeP->im_disp=0; } - } - return addr_modeP->mode; +} + return addr_modeP->mode; } /* read an optionlist */ void optlist(str,optionP,default_map) - char *str; /* the string to extract options from */ - struct option *optionP; /* how to search the string */ - unsigned long *default_map; /* default pattern and output */ + char *str; /* the string to extract options from */ + struct option *optionP; /* how to search the string */ + unsigned long *default_map; /* default pattern and output */ { - register int i,j,k,strlen1,strlen2; - register char *patternP,*strP; - strlen1=strlen(str); - if (strlen1<1) { - as_fatal("Very short instr to option, ie you can't do it on a NULLstr"); - } - for (i=0;optionP[i].pattern!=0;i++) { - strlen2=strlen(optionP[i].pattern); - for (j=0;j<strlen1;j++) { - patternP=optionP[i].pattern; - strP = &str[j]; - for (k=0;k<strlen2;k++) { - if (*(strP++)!=*(patternP++)) break; - } - if (k==strlen2) { /* match */ - *default_map|=optionP[i].or; - *default_map&=optionP[i].and; - } + register int i,j,k,strlen1,strlen2; + register char *patternP,*strP; + strlen1=strlen(str); + if (strlen1<1) { + as_fatal("Very short instr to option, ie you can't do it on a NULLstr"); + } + for (i=0;optionP[i].pattern!=0;i++) { + strlen2=strlen(optionP[i].pattern); + for (j=0;j<strlen1;j++) { + patternP=optionP[i].pattern; + strP = &str[j]; + for (k=0;k<strlen2;k++) { + if (*(strP++)!=*(patternP++)) break; + } + if (k==strlen2) { /* match */ + *default_map|=optionP[i].or; + *default_map&=optionP[i].and; + } + } } - } } /* search struct for symbols This function is used to get the short integer form of reg names @@ -710,32 +710,32 @@ void optlist(str,optionP,default_map) return true if str is found in list */ int list_search(str,optionP,default_map) - char *str; /* the string to match */ - struct option *optionP; /* list to search */ - unsigned long *default_map; /* default pattern and output */ + char *str; /* the string to match */ + struct option *optionP; /* list to search */ + unsigned long *default_map; /* default pattern and output */ { - register int i; - for (i=0;optionP[i].pattern!=0;i++) { - if (!strncmp(optionP[i].pattern,str,20)) { /* use strncmp to be safe */ - *default_map|=optionP[i].or; - *default_map&=optionP[i].and; - return -1; + register int i; + for (i=0;optionP[i].pattern!=0;i++) { + if (!strncmp(optionP[i].pattern,str,20)) { /* use strncmp to be safe */ + *default_map|=optionP[i].or; + *default_map&=optionP[i].and; + return -1; + } } - } - as_warn("No such entry in list. (cpu/mmu register)"); - return 0; + as_warn("No such entry in list. (cpu/mmu register)"); + return 0; } static segT evaluate_expr(resultP,ptr) -expressionS *resultP; -char *ptr; + expressionS *resultP; + char *ptr; { - register char *tmp_line; - register segT segment; - tmp_line=input_line_pointer; - input_line_pointer=ptr; - segment=expression(&exprP); - input_line_pointer=tmp_line; - return (segment); + register char *tmp_line; + register segT segment; + tmp_line=input_line_pointer; + input_line_pointer=ptr; + segment=expression(&exprP); + input_line_pointer=tmp_line; + return (segment); } /* Convert operands to iif-format and adds bitfields to the opcode. @@ -746,520 +746,520 @@ char *ptr; */ void encode_operand(argc,argv,operandsP,suffixP,im_size,opcode_bit_ptr) - int argc; - char **argv; - char *operandsP; - char *suffixP; - char im_size; - char opcode_bit_ptr; + int argc; + char **argv; + char *operandsP; + char *suffixP; + char im_size; + char opcode_bit_ptr; { - register int i,j; - int pcrel,tmp,b,loop,pcrel_adjust; - for(loop=0;loop<argc;loop++) { - i=operandsP[loop<<1]-'1'; /* what operand are we supposed to work on */ - if (i>3) as_fatal("Internal consistency error. check ns32k-opcode.h"); - pcrel=0; - pcrel_adjust=0; - tmp=0; - switch (operandsP[(loop<<1)+1]) { - case 'f': /* operand of sfsr turns out to be a nasty specialcase */ - opcode_bit_ptr-=5; - case 'F': /* 32 bit float general form */ - case 'L': /* 64 bit float */ - case 'Q': /* quad-word */ - case 'B': /* byte */ - case 'W': /* word */ - case 'D': /* double-word */ - case 'A': /* double-word gen-address-form ie no regs allowed */ - get_addr_mode(argv[i],&addr_modeP); - iif.instr_size+=addr_modeP.am_size; - if (opcode_bit_ptr==desc->opcode_size) b=4; else b=6; - for (j=b;j<(b+2);j++) { - if (addr_modeP.disp[j-b]) { - IIF(j, - 2, - addr_modeP.disp_suffix[j-b], - (unsigned long)addr_modeP.disp[j-b], - 0, - addr_modeP.pcrel, - iif.instr_size-addr_modeP.am_size, /* this aint used (now) */ - addr_modeP.im_disp, - IND(BRANCH,BYTE), - NULL, - addr_modeP.scaled_reg ? addr_modeP.scaled_mode:addr_modeP.mode, - 0); + register int i,j; + int pcrel,tmp,b,loop,pcrel_adjust; + for(loop=0;loop<argc;loop++) { + i=operandsP[loop<<1]-'1'; /* what operand are we supposed to work on */ + if (i>3) as_fatal("Internal consistency error. check ns32k-opcode.h"); + pcrel=0; + pcrel_adjust=0; + tmp=0; + switch (operandsP[(loop<<1)+1]) { + case 'f': /* operand of sfsr turns out to be a nasty specialcase */ + opcode_bit_ptr-=5; + case 'F': /* 32 bit float general form */ + case 'L': /* 64 bit float */ + case 'Q': /* quad-word */ + case 'B': /* byte */ + case 'W': /* word */ + case 'D': /* double-word */ + case 'A': /* double-word gen-address-form ie no regs allowed */ + get_addr_mode(argv[i],&addr_modeP); + iif.instr_size+=addr_modeP.am_size; + if (opcode_bit_ptr==desc->opcode_size) b=4; else b=6; + for (j=b;j<(b+2);j++) { + if (addr_modeP.disp[j-b]) { + IIF(j, + 2, + addr_modeP.disp_suffix[j-b], + (unsigned long)addr_modeP.disp[j-b], + 0, + addr_modeP.pcrel, + iif.instr_size-addr_modeP.am_size, /* this aint used (now) */ + addr_modeP.im_disp, + IND(BRANCH,BYTE), + NULL, + addr_modeP.scaled_reg ? addr_modeP.scaled_mode:addr_modeP.mode, + 0); + } + } + opcode_bit_ptr-=5; + iif.iifP[1].object|=((long)addr_modeP.mode)<<opcode_bit_ptr; + if (addr_modeP.scaled_reg) { + j=b/2; + IIF(j,1,1, (unsigned long)addr_modeP.index_byte,0,0,0,0,0, NULL,-1,0); + } + break; + case 'b': /* multiple instruction disp */ + freeptr++; /* OVE:this is an useful hack */ + tmp=(int)sprintf(freeptr,"((%s-1)*%d)\000",argv[i],desc->im_size); + argv[i]=freeptr; + freeptr=(char*)tmp; + pcrel-=1; /* make pcrel 0 inspite of what case 'p': wants */ + /* fall thru */ + case 'p': /* displacement - pc relative addressing */ + pcrel+=1; + /* fall thru */ + case 'd': /* displacement */ + iif.instr_size+=suffixP[i] ? suffixP[i] : 4; + IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0, + pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,0); + break; + case 'H': /* sequent-hack: the linker wants a bit set when bsr */ + pcrel=1; + iif.instr_size+=suffixP[i] ? suffixP[i] : 4; + IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0, + pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,1);break; + case 'q': /* quick */ + opcode_bit_ptr-=4; + IIF(11,2,42,(unsigned long)argv[i],0,0,0,0,0, + bit_fix_new(4,opcode_bit_ptr,-8,7,0,1,0),-1,0); + break; + case 'r': /* register number (3 bits) */ + list_search(argv[i],opt6,&tmp); + opcode_bit_ptr-=3; + iif.iifP[1].object|=tmp<<opcode_bit_ptr; + break; + case 'O': /* setcfg instruction optionslist */ + optlist(argv[i],opt3,&tmp); + opcode_bit_ptr-=4; + iif.iifP[1].object|=tmp<<15; + break; + case 'C': /* cinv instruction optionslist */ + optlist(argv[i],opt4,&tmp); + opcode_bit_ptr-=4; + iif.iifP[1].object|=tmp<<15;/*insert the regtype in opcode */ + break; + case 'S': /* stringinstruction optionslist */ + optlist(argv[i],opt5,&tmp); + opcode_bit_ptr-=4; + iif.iifP[1].object|=tmp<<15; + break; + case 'u':case 'U': /* registerlist */ + IIF(10,1,1,0,0,0,0,0,0,NULL,-1,0); + switch (operandsP[(i<<1)+1]) { + case 'u': /* restore, exit */ + optlist(argv[i],opt1,&iif.iifP[10].object); + break; + case 'U': /* save,enter */ + optlist(argv[i],opt2,&iif.iifP[10].object); + break; + } + iif.instr_size+=1; + break; + case 'M': /* mmu register */ + list_search(argv[i],mmureg,&tmp); + opcode_bit_ptr-=4; + iif.iifP[1].object|=tmp<<opcode_bit_ptr; + break; + case 'P': /* cpu register */ + list_search(argv[i],cpureg,&tmp); + opcode_bit_ptr-=4; + iif.iifP[1].object|=tmp<<opcode_bit_ptr; + break; + case 'g': /* inss exts */ + iif.instr_size+=1; /* 1 byte is allocated after the opcode */ + IIF(10,2,1, + (unsigned long)argv[i], /* i always 2 here */ + 0,0,0,0,0, + bit_fix_new(3,5,0,7,0,0,0), /* a bit_fix is targeted to the byte */ + -1,0); + case 'G': + IIF(11,2,42, + (unsigned long)argv[i], /* i always 3 here */ + 0,0,0,0,0, + bit_fix_new(5,0,1,32,-1,0,-1),-1,0); + break; + case 'i': + iif.instr_size+=1; + b=2+i; /* put the extension byte after opcode */ + IIF(b,2,1,0,0,0,0,0,0,0,-1,0); + default: + as_fatal("Bad opcode-table-option, check in file ns32k-opcode.h"); } - } - opcode_bit_ptr-=5; - iif.iifP[1].object|=((long)addr_modeP.mode)<<opcode_bit_ptr; - if (addr_modeP.scaled_reg) { - j=b/2; - IIF(j,1,1, (unsigned long)addr_modeP.index_byte,0,0,0,0,0, NULL,-1,0); - } - break; - case 'b': /* multiple instruction disp */ - freeptr++; /* OVE:this is an useful hack */ - tmp=(int)sprintf(freeptr,"((%s-1)*%d)\000",argv[i],desc->im_size); - argv[i]=freeptr; - freeptr=(char*)tmp; - pcrel-=1; /* make pcrel 0 inspite of what case 'p': wants */ - /* fall thru */ - case 'p': /* displacement - pc relative addressing */ - pcrel+=1; - /* fall thru */ - case 'd': /* displacement */ - iif.instr_size+=suffixP[i] ? suffixP[i] : 4; - IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0, - pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,0); - break; - case 'H': /* sequent-hack: the linker wants a bit set when bsr */ - pcrel=1; - iif.instr_size+=suffixP[i] ? suffixP[i] : 4; - IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0, - pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,1);break; - case 'q': /* quick */ - opcode_bit_ptr-=4; - IIF(11,2,42,(unsigned long)argv[i],0,0,0,0,0, - bit_fix_new(4,opcode_bit_ptr,-8,7,0,1,0),-1,0); - break; - case 'r': /* register number (3 bits) */ - list_search(argv[i],opt6,&tmp); - opcode_bit_ptr-=3; - iif.iifP[1].object|=tmp<<opcode_bit_ptr; - break; - case 'O': /* setcfg instruction optionslist */ - optlist(argv[i],opt3,&tmp); - opcode_bit_ptr-=4; - iif.iifP[1].object|=tmp<<15; - break; - case 'C': /* cinv instruction optionslist */ - optlist(argv[i],opt4,&tmp); - opcode_bit_ptr-=4; - iif.iifP[1].object|=tmp<<15;/*insert the regtype in opcode */ - break; - case 'S': /* stringinstruction optionslist */ - optlist(argv[i],opt5,&tmp); - opcode_bit_ptr-=4; - iif.iifP[1].object|=tmp<<15; - break; - case 'u':case 'U': /* registerlist */ - IIF(10,1,1,0,0,0,0,0,0,NULL,-1,0); - switch (operandsP[(i<<1)+1]) { - case 'u': /* restore, exit */ - optlist(argv[i],opt1,&iif.iifP[10].object); - break; - case 'U': /* save,enter */ - optlist(argv[i],opt2,&iif.iifP[10].object); - break; - } - iif.instr_size+=1; - break; - case 'M': /* mmu register */ - list_search(argv[i],mmureg,&tmp); - opcode_bit_ptr-=4; - iif.iifP[1].object|=tmp<<opcode_bit_ptr; - break; - case 'P': /* cpu register */ - list_search(argv[i],cpureg,&tmp); - opcode_bit_ptr-=4; - iif.iifP[1].object|=tmp<<opcode_bit_ptr; - break; - case 'g': /* inss exts */ - iif.instr_size+=1; /* 1 byte is allocated after the opcode */ - IIF(10,2,1, - (unsigned long)argv[i], /* i always 2 here */ - 0,0,0,0,0, - bit_fix_new(3,5,0,7,0,0,0), /* a bit_fix is targeted to the byte */ - -1,0); - case 'G': - IIF(11,2,42, - (unsigned long)argv[i], /* i always 3 here */ - 0,0,0,0,0, - bit_fix_new(5,0,1,32,-1,0,-1),-1,0); - break; - case 'i': - iif.instr_size+=1; - b=2+i; /* put the extension byte after opcode */ - IIF(b,2,1,0,0,0,0,0,0,0,-1,0); - default: - as_fatal("Bad opcode-table-option, check in file ns32k-opcode.h"); } - } } /* in: instruction line out: internal structure of instruction - that has been prepared for direct conversion to fragment(s) and - fixes in a systematical fashion - Return-value = recursive_level -*/ + that has been prepared for direct conversion to fragment(s) and + fixes in a systematical fashion + Return-value = recursive_level + */ /* build iif of one assembly text line */ int parse(line,recursive_level) - char *line; - int recursive_level; + char *line; + int recursive_level; { - register char *lineptr,c,suffix_separator; - register int i; - int argc,arg_type; - char sqr,sep; - char suffix[MAX_ARGS],*argv[MAX_ARGS];/* no more than 4 operands */ - if (recursive_level<=0) { /* called from md_assemble */ - for (lineptr=line;(*lineptr)!='\0' && (*lineptr)!=' ';lineptr++); - c = *lineptr; - *lineptr='\0'; - if (!(desc=(struct ns32k_opcode*)hash_find(inst_hash_handle,line))) { - as_fatal("No such opcode"); + register char *lineptr,c,suffix_separator; + register int i; + int argc,arg_type; + char sqr,sep; + char suffix[MAX_ARGS],*argv[MAX_ARGS];/* no more than 4 operands */ + if (recursive_level<=0) { /* called from md_assemble */ + for (lineptr=line;(*lineptr)!='\0' && (*lineptr)!=' ';lineptr++); + c = *lineptr; + *lineptr='\0'; + if (!(desc=(struct ns32k_opcode*)hash_find(inst_hash_handle,line))) { + as_fatal("No such opcode"); + } + *lineptr=c; + } else { + lineptr=line; } - *lineptr=c; - } else { - lineptr=line; - } - argc=0; - if (*desc->operands) { - if (*lineptr++!='\0') { - sqr='['; - sep=','; - while (*lineptr!='\0') { - if (desc->operands[argc<<1]) { - suffix[argc]=0; - arg_type=desc->operands[(argc<<1)+1]; - switch (arg_type) { - case 'd': case 'b': case 'p': case 'H': /* the operand is supposed to be a displacement */ - /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */ - suffix_separator=':'; - break; - default: - suffix_separator='\255'; /* if this char occurs we loose */ - } - suffix[argc]=0; /* 0 when no ':' is encountered */ - argv[argc]=freeptr; - *freeptr='\0'; - while ((c = *lineptr)!='\0' && c!=sep) { - if (c==sqr) { - if (sqr=='[') { - sqr=']';sep='\0'; - } else { - sqr='[';sep=','; - } - } - if (c==suffix_separator) { /* ':' - label/suffix separator */ - switch (lineptr[1]) { - case 'b':suffix[argc]=1;break; - case 'w':suffix[argc]=2;break; - case 'd':suffix[argc]=4;break; - default: as_warn("Bad suffix, defaulting to d"); - suffix[argc]=4; - if (lineptr[1]=='\0' || lineptr[1]==sep) { - lineptr+=1; - continue; + argc=0; + if (*desc->operands) { + if (*lineptr++!='\0') { + sqr='['; + sep=','; + while (*lineptr!='\0') { + if (desc->operands[argc<<1]) { + suffix[argc]=0; + arg_type=desc->operands[(argc<<1)+1]; + switch (arg_type) { + case 'd': case 'b': case 'p': case 'H': /* the operand is supposed to be a displacement */ + /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */ + suffix_separator=':'; + break; + default: + suffix_separator='\255'; /* if this char occurs we loose */ + } + suffix[argc]=0; /* 0 when no ':' is encountered */ + argv[argc]=freeptr; + *freeptr='\0'; + while ((c = *lineptr)!='\0' && c!=sep) { + if (c==sqr) { + if (sqr=='[') { + sqr=']';sep='\0'; + } else { + sqr='[';sep=','; + } + } + if (c==suffix_separator) { /* ':' - label/suffix separator */ + switch (lineptr[1]) { + case 'b':suffix[argc]=1;break; + case 'w':suffix[argc]=2;break; + case 'd':suffix[argc]=4;break; + default: as_warn("Bad suffix, defaulting to d"); + suffix[argc]=4; + if (lineptr[1]=='\0' || lineptr[1]==sep) { + lineptr+=1; + continue; + } + } + lineptr+=2; + continue; + } + *freeptr++=c; + lineptr++; + } + *freeptr++='\0'; + argc+=1; + if (*lineptr=='\0') continue; + lineptr+=1; + } else { + as_fatal("Too many operands passed to instruction"); } - } - lineptr+=2; - continue; } - *freeptr++=c; - lineptr++; - } - *freeptr++='\0'; - argc+=1; - if (*lineptr=='\0') continue; - lineptr+=1; + } + } + if (argc!=strlen(desc->operands)/2) { + if (strlen(desc->default_args)) { /* we can apply default, dont goof */ + if (parse(desc->default_args,1)!=1) { /* check error in default */ + as_fatal("Wrong numbers of operands in default, check ns32k-opcodes.h"); + } } else { - as_fatal("Too many operands passed to instruction"); + as_fatal("Wrong number of operands"); } - } + } - } - if (argc!=strlen(desc->operands)/2) { - if (strlen(desc->default_args)) { /* we can apply default, dont goof */ - if (parse(desc->default_args,1)!=1) { /* check error in default */ - as_fatal("Wrong numbers of operands in default, check ns32k-opcodes.h"); - } - } else { - as_fatal("Wrong number of operands"); + for (i=0;i<IIF_ENTRIES;i++) { + iif.iifP[i].type=0; /* mark all entries as void*/ } - - } - for (i=0;i<IIF_ENTRIES;i++) { - iif.iifP[i].type=0; /* mark all entries as void*/ - } - + /* build opcode iif-entry */ - iif.instr_size=desc->opcode_size/8; - IIF(1,1,iif.instr_size,desc->opcode_seed,0,0,0,0,0,0,-1,0); - + iif.instr_size=desc->opcode_size/8; + IIF(1,1,iif.instr_size,desc->opcode_seed,0,0,0,0,0,0,-1,0); + /* this call encodes operands to iif format */ - if (argc) { - encode_operand(argc, - argv, - &desc->operands[0], - &suffix[0], - desc->im_size, - desc->opcode_size); - } - return recursive_level; + if (argc) { + encode_operand(argc, + argv, + &desc->operands[0], + &suffix[0], + desc->im_size, + desc->opcode_size); + } + return recursive_level; } - /* Convert iif to fragments. - From this point we start to dribble with functions in other files than - this one.(Except hash.c) So, if it's possible to make an iif for an other - CPU, you don't need to know what frags, relax, obstacks, etc is in order - to port this assembler. You only need to know if it's possible to reduce - your cpu-instruction to iif-format (takes some work) and adopt the other - md_? parts according to given instructions - Note that iif was invented for the clean ns32k`s architecure. - */ +/* Convert iif to fragments. + From this point we start to dribble with functions in other files than + this one.(Except hash.c) So, if it's possible to make an iif for an other + CPU, you don't need to know what frags, relax, obstacks, etc is in order + to port this assembler. You only need to know if it's possible to reduce + your cpu-instruction to iif-format (takes some work) and adopt the other + md_? parts according to given instructions + Note that iif was invented for the clean ns32k`s architecure. + */ void convert_iif() { - register int i,j; - fragS *inst_frag; - char *inst_offset,*inst_opcode; - char *memP; - segT segment; - int l,k; - register int rem_size; /* count the remaining bytes of instruction */ - register char type; - register char size = 0; - int size_so_far=0; /* used to calculate pcrel_adjust */ - + register int i,j; + fragS *inst_frag; + char *inst_offset,*inst_opcode; + char *memP; + segT segment; + int l,k; + register int rem_size; /* count the remaining bytes of instruction */ + register char type; + register char size = 0; + int size_so_far=0; /* used to calculate pcrel_adjust */ + rem_size=iif.instr_size; memP=frag_more(iif.instr_size); /* make sure we have enough bytes for instruction */ inst_opcode=memP; inst_offset=(char*)(memP-frag_now->fr_literal); inst_frag=frag_now; for (i=0;i<IIF_ENTRIES;i++) { - if (type=iif.iifP[i].type) { /* the object exist, so handle it */ - switch (size=iif.iifP[i].size) { - case 42: size=0; /* it's a bitfix that operates on an existing object*/ - if (iif.iifP[i].bit_fixP->fx_bit_base) { /* expand fx_bit_base to point at opcode */ - iif.iifP[i].bit_fixP->fx_bit_base=(long)inst_opcode; - } - case 8: /* bignum or doublefloat */ - bzero (memP,8); - case 1:case 2:case 3:case 4:/* the final size in objectmemory is known */ - j=(unsigned long)iif.iifP[i].bit_fixP; - switch (type) { - case 1: /* the object is pure binary */ - if (j || iif.iifP[i].pcrel) { - fix_new_ns32k(frag_now, - (long)(memP-frag_now->fr_literal), - size, - 0, - 0, - iif.iifP[i].object, - iif.iifP[i].pcrel, - (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ - iif.iifP[i].im_disp, - j, - iif.iifP[i].bsr); /* sequent hack */ - } else { /* good, just put them bytes out */ - switch (iif.iifP[i].im_disp) { - case 0: - md_number_to_chars(memP,iif.iifP[i].object,size);break; - case 1: - md_number_to_disp(memP,iif.iifP[i].object,size);break; - default: as_fatal("iif convert internal pcrel/binary"); - } - } - memP+=size; - rem_size-=size; - break; - case 2: /* the object is a pointer at an expression, so unpack - it, note that bignums may result from the expression - */ - if ((segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object))==SEG_BIG || size==8) { - if ((k=exprP.X_add_number)>0) { /* we have a bignum ie a quad */ - /* this can only happens in a long suffixed instruction */ - bzero(memP,size); /* size normally is 8 */ - if (k*2>size) as_warn("Bignum too big for long"); - if (k==3) memP+=2; - for (l=0;k>0;k--,l+=2) { - md_number_to_chars(memP+l,generic_bignum[l>>1],sizeof(LITTLENUM_TYPE)); + if (type=iif.iifP[i].type) { /* the object exist, so handle it */ + switch (size=iif.iifP[i].size) { + case 42: size=0; /* it's a bitfix that operates on an existing object*/ + if (iif.iifP[i].bit_fixP->fx_bit_base) { /* expand fx_bit_base to point at opcode */ + iif.iifP[i].bit_fixP->fx_bit_base=(long)inst_opcode; } - } else { /* flonum */ - LITTLENUM_TYPE words[4]; - - switch(size) { - case 4: - gen_to_words(words,2,8); - md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE)); - md_number_to_imm(memP+sizeof(LITTLENUM_TYPE),(long)words[1],sizeof(LITTLENUM_TYPE)); - break; - case 8: - gen_to_words(words,4,11); - md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE)); - md_number_to_imm(memP+sizeof(LITTLENUM_TYPE) ,(long)words[1],sizeof(LITTLENUM_TYPE)); - md_number_to_imm(memP+2*sizeof(LITTLENUM_TYPE),(long)words[2],sizeof(LITTLENUM_TYPE)); - md_number_to_imm(memP+3*sizeof(LITTLENUM_TYPE),(long)words[3],sizeof(LITTLENUM_TYPE)); - break; + case 8: /* bignum or doublefloat */ + bzero (memP,8); + case 1:case 2:case 3:case 4:/* the final size in objectmemory is known */ + j=(unsigned long)iif.iifP[i].bit_fixP; + switch (type) { + case 1: /* the object is pure binary */ + if (j || iif.iifP[i].pcrel) { + fix_new_ns32k(frag_now, + (long)(memP-frag_now->fr_literal), + size, + 0, + 0, + iif.iifP[i].object, + iif.iifP[i].pcrel, + (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ + iif.iifP[i].im_disp, + j, + iif.iifP[i].bsr); /* sequent hack */ + } else { /* good, just put them bytes out */ + switch (iif.iifP[i].im_disp) { + case 0: + md_number_to_chars(memP,iif.iifP[i].object,size);break; + case 1: + md_number_to_disp(memP,iif.iifP[i].object,size);break; + default: as_fatal("iif convert internal pcrel/binary"); + } + } + memP+=size; + rem_size-=size; + break; + case 2: /* the object is a pointer at an expression, so unpack + it, note that bignums may result from the expression + */ + if ((segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object))==SEG_BIG || size==8) { + if ((k=exprP.X_add_number)>0) { /* we have a bignum ie a quad */ + /* this can only happens in a long suffixed instruction */ + bzero(memP,size); /* size normally is 8 */ + if (k*2>size) as_warn("Bignum too big for long"); + if (k==3) memP+=2; + for (l=0;k>0;k--,l+=2) { + md_number_to_chars(memP+l,generic_bignum[l>>1],sizeof(LITTLENUM_TYPE)); + } + } else { /* flonum */ + LITTLENUM_TYPE words[4]; + + switch(size) { + case 4: + gen_to_words(words,2,8); + md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE)); + md_number_to_imm(memP+sizeof(LITTLENUM_TYPE),(long)words[1],sizeof(LITTLENUM_TYPE)); + break; + case 8: + gen_to_words(words,4,11); + md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE)); + md_number_to_imm(memP+sizeof(LITTLENUM_TYPE) ,(long)words[1],sizeof(LITTLENUM_TYPE)); + md_number_to_imm(memP+2*sizeof(LITTLENUM_TYPE),(long)words[2],sizeof(LITTLENUM_TYPE)); + md_number_to_imm(memP+3*sizeof(LITTLENUM_TYPE),(long)words[3],sizeof(LITTLENUM_TYPE)); + break; + } + } + memP+=size; + rem_size-=size; + break; + } + if (j || + exprP.X_add_symbol || + exprP.X_subtract_symbol || + iif.iifP[i].pcrel) { /* fixit */ + /* the expression was undefined due to an undefined label */ + /* create a fix so we can fix the object later */ + exprP.X_add_number+=iif.iifP[i].object_adjust; + fix_new_ns32k(frag_now, + (long)(memP-frag_now->fr_literal), + size, + exprP.X_add_symbol, + exprP.X_subtract_symbol, + exprP.X_add_number, + iif.iifP[i].pcrel, + (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ + iif.iifP[i].im_disp, + j, + iif.iifP[i].bsr); /* sequent hack */ + + } else { /* good, just put them bytes out */ + switch (iif.iifP[i].im_disp) { + case 0: + md_number_to_imm(memP,exprP.X_add_number,size);break; + case 1: + md_number_to_disp(memP,exprP.X_add_number,size);break; + default: as_fatal("iif convert internal pcrel/pointer"); + } + } + memP+=size; + rem_size-=size; + break; + default: as_fatal("Internal logic error in iif.iifP[n].type"); } - } - memP+=size; - rem_size-=size; - break; - } - if (j || - exprP.X_add_symbol || - exprP.X_subtract_symbol || - iif.iifP[i].pcrel) { /* fixit */ - /* the expression was undefined due to an undefined label */ - /* create a fix so we can fix the object later */ - exprP.X_add_number+=iif.iifP[i].object_adjust; - fix_new_ns32k(frag_now, - (long)(memP-frag_now->fr_literal), - size, - exprP.X_add_symbol, - exprP.X_subtract_symbol, - exprP.X_add_number, - iif.iifP[i].pcrel, - (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ - iif.iifP[i].im_disp, - j, - iif.iifP[i].bsr); /* sequent hack */ - - } else { /* good, just put them bytes out */ - switch (iif.iifP[i].im_disp) { - case 0: - md_number_to_imm(memP,exprP.X_add_number,size);break; - case 1: - md_number_to_disp(memP,exprP.X_add_number,size);break; - default: as_fatal("iif convert internal pcrel/pointer"); - } - } - memP+=size; - rem_size-=size; - break; - default: as_fatal("Internal logic error in iif.iifP[n].type"); - } - break; - case 0: /* To bad, the object may be undefined as far as its final + break; + case 0: /* To bad, the object may be undefined as far as its final nsize in object memory is concerned. The size of the object in objectmemory is not explicitly given. If the object is defined its length can be determined and a fix can replace the frag. */ - { - int temp; - segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object); - if ((exprP.X_add_symbol || exprP.X_subtract_symbol) && - !iif.iifP[i].pcrel) { /* OVE: hack, clamp to 4 bytes */ - size=4; /* we dont wan't to frag this, use 4 so it reaches */ - fix_new_ns32k(frag_now, - (long)(memP-frag_now->fr_literal), - size, - exprP.X_add_symbol, - exprP.X_subtract_symbol, - exprP.X_add_number, - 0, /* never iif.iifP[i].pcrel, */ - (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ - 1, /* always iif.iifP[i].im_disp, */ - 0,0); - memP+=size; - rem_size-=4; - break; /* exit this absolute hack */ - } - - if (exprP.X_add_symbol || exprP.X_subtract_symbol) { /* frag it */ - if (exprP.X_subtract_symbol) { /* We cant relax this case */ - as_fatal("Can't relax difference"); - } - else { - /* at this stage we must undo some of the effect caused - by frag_more, ie we must make sure that frag_var causes - frag_new to creat a valid fix-size in the frag it`s closing - */ - temp = -(rem_size-4); - obstack_blank_fast(&frags,temp); - /* we rewind none, some or all of the requested size we - requested by the first frag_more for this iif chunk. - Note: that we allocate 4 bytes to an object we NOT YET - know the size of, thus rem_size-4. - */ - (void)frag_variant(rs_machine_dependent, - 4, - 0, - IND(BRANCH,UNDEF), /* expecting the worst */ - exprP.X_add_symbol, - exprP.X_add_number, - (char*)inst_opcode, - (char)size_so_far, /*iif.iifP[i].pcrel_adjust);*/ - iif.iifP[i].bsr); /* sequent linker hack */ - rem_size-=4; - if (rem_size>0) { - memP=frag_more(rem_size); + { + int temp; + segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object); + if ((exprP.X_add_symbol || exprP.X_subtract_symbol) && + !iif.iifP[i].pcrel) { /* OVE: hack, clamp to 4 bytes */ + size=4; /* we dont wan't to frag this, use 4 so it reaches */ + fix_new_ns32k(frag_now, + (long)(memP-frag_now->fr_literal), + size, + exprP.X_add_symbol, + exprP.X_subtract_symbol, + exprP.X_add_number, + 0, /* never iif.iifP[i].pcrel, */ + (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ + 1, /* always iif.iifP[i].im_disp, */ + 0,0); + memP+=size; + rem_size-=4; + break; /* exit this absolute hack */ } - } - } - else {/* Double work, this is done in md_number_to_disp */ -/* exprP.X_add_number; what was this supposed to be? - xoxorich. */ - if (-64<=exprP.X_add_number && exprP.X_add_number<=63) { - size=1; - } else { - if (-8192<=exprP.X_add_number && exprP.X_add_number<=8191) { - size=2; - } else { - if (-0x1f000000<=exprP.X_add_number && - exprP.X_add_number<=0x1fffffff) - /* if (-0x40000000<=exprP.X_add_number && - exprP.X_add_number<=0x3fffffff) */ - { - size=4; - } else { - as_warn("Displacement to large for :d"); - size=4; - } + + if (exprP.X_add_symbol || exprP.X_subtract_symbol) { /* frag it */ + if (exprP.X_subtract_symbol) { /* We cant relax this case */ + as_fatal("Can't relax difference"); + } + else { + /* at this stage we must undo some of the effect caused + by frag_more, ie we must make sure that frag_var causes + frag_new to creat a valid fix-size in the frag it`s closing + */ + temp = -(rem_size-4); + obstack_blank_fast(&frags,temp); + /* we rewind none, some or all of the requested size we + requested by the first frag_more for this iif chunk. + Note: that we allocate 4 bytes to an object we NOT YET + know the size of, thus rem_size-4. + */ + (void)frag_variant(rs_machine_dependent, + 4, + 0, + IND(BRANCH,UNDEF), /* expecting the worst */ + exprP.X_add_symbol, + exprP.X_add_number, + (char*)inst_opcode, + (char)size_so_far, /*iif.iifP[i].pcrel_adjust);*/ + iif.iifP[i].bsr); /* sequent linker hack */ + rem_size-=4; + if (rem_size>0) { + memP=frag_more(rem_size); + } + } + } + else {/* Double work, this is done in md_number_to_disp */ + /* exprP.X_add_number; what was this supposed to be? + xoxorich. */ + if (-64<=exprP.X_add_number && exprP.X_add_number<=63) { + size=1; + } else { + if (-8192<=exprP.X_add_number && exprP.X_add_number<=8191) { + size=2; + } else { + if (-0x1f000000<=exprP.X_add_number && + exprP.X_add_number<=0x1fffffff) + /* if (-0x40000000<=exprP.X_add_number && + exprP.X_add_number<=0x3fffffff) */ + { + size=4; + } else { + as_warn("Displacement to large for :d"); + size=4; + } + } + } + /* rewind the bytes not used */ + temp = -(4-size); + md_number_to_disp(memP,exprP.X_add_number,size); + obstack_blank_fast(&frags,temp); + memP+=size; + rem_size-=4; /* we allocated this amount */ } - } - /* rewind the bytes not used */ - temp = -(4-size); - md_number_to_disp(memP,exprP.X_add_number,size); - obstack_blank_fast(&frags,temp); - memP+=size; - rem_size-=4; /* we allocated this amount */ } - } - break; - default: - as_fatal("Internal logic error in iif.iifP[].type"); + break; + default: + as_fatal("Internal logic error in iif.iifP[].type"); + } + size_so_far+=size; + size=0; } - size_so_far+=size; - size=0; - } } } void md_assemble(line) -char *line; + char *line; { - freeptr=freeptr_static; - parse(line,0); /* explode line to more fix form in iif */ - convert_iif(); /* convert iif to frags, fix's etc */ + freeptr=freeptr_static; + parse(line,0); /* explode line to more fix form in iif */ + convert_iif(); /* convert iif to frags, fix's etc */ #ifdef SHOW_NUM - printf(" \t\t\t%s\n",line); + printf(" \t\t\t%s\n",line); #endif } void md_begin() { - /* build a hashtable of the instructions */ - register const struct ns32k_opcode *ptr; - register char *stat; - inst_hash_handle=hash_new(); - for (ptr=ns32k_opcodes;ptr<endop;ptr++) { - if (*(stat=hash_insert(inst_hash_handle,ptr->name,(char*)ptr))) { - as_fatal("Can't hash %s: %s", ptr->name,stat); /*fatal*/ - exit(0); + /* build a hashtable of the instructions */ + register const struct ns32k_opcode *ptr; + register char *stat; + inst_hash_handle=hash_new(); + for (ptr=ns32k_opcodes;ptr<endop;ptr++) { + if (*(stat=hash_insert(inst_hash_handle,ptr->name,(char*)ptr))) { + as_fatal("Can't hash %s: %s", ptr->name,stat); /*fatal*/ + exit(0); + } } - } - freeptr_static=(char*)malloc(PRIVATE_SIZE); /* some private space please! */ + freeptr_static=(char*)malloc(PRIVATE_SIZE); /* some private space please! */ } void -md_end() { - free(freeptr_static); -} + md_end() { + free(freeptr_static); + } /* Must be equal to MAX_PRECISON in atof-ieee.c */ #define MAX_LITTLENUMS 6 @@ -1267,57 +1267,57 @@ md_end() { /* Turn the string pointed to by litP into a floating point constant of type type, and emit the appropriate bytes. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK. - */ + */ char * -md_atof(type,litP,sizeP) + md_atof(type,litP,sizeP) char type; char *litP; int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - - switch(type) { - case 'f': - prec = 2; - break; - - case 'd': - prec = 4; - break; - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words+prec;prec--;) { - md_number_to_chars(litP,(long)(*--wordP),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + + switch(type) { + case 'f': + prec = 2; + break; + + case 'd': + prec = 4; + break; + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words+prec;prec--;) { + md_number_to_chars(litP,(long)(*--wordP),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } /* Convert number to chars in correct order */ void -md_number_to_chars (buf, value, nbytes) - char *buf; - long value; - int nbytes; + md_number_to_chars (buf, value, nbytes) +char *buf; +long value; +int nbytes; { - while (nbytes--) + while (nbytes--) { #ifdef SHOW_NUM - printf("%x ",value & 0xff); + printf("%x ",value & 0xff); #endif - *buf++ = value; /* Lint wants & MASK_CHAR. */ - value >>= BITS_PER_CHAR; + *buf++ = value; /* Lint wants & MASK_CHAR. */ + value >>= BITS_PER_CHAR; } } /* Convert number to chars in correct order */ @@ -1328,163 +1328,163 @@ md_number_to_chars (buf, value, nbytes) is the fact that ns32k uses Huffman coded displacements. This implies that the bit order is reversed in displacements and that they are prefixed with a size-tag. - + binary: msb -> lsb 0xxxxxxx byte - 10xxxxxx xxxxxxxx word - 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word - + 10xxxxxx xxxxxxxx word + 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word + This must be taken care of and we do it here! - */ + */ static void md_number_to_disp(buf,val,n) - char *buf; - long val; - char n; + char *buf; + long val; + char n; { - switch(n) { - case 1: - if (val < -64 || val > 63) - as_warn("Byte displacement out of range. line number not valid"); - val&=0x7f; + switch(n) { + case 1: + if (val < -64 || val > 63) + as_warn("Byte displacement out of range. line number not valid"); + val&=0x7f; #ifdef SHOW_NUM - printf("%x ",val & 0xff); + printf("%x ",val & 0xff); #endif - *buf++=val; - break; - case 2: - if (val < -8192 || val > 8191) - as_warn("Word displacement out of range. line number not valid"); - val&=0x3fff; - val|=0x8000; + *buf++=val; + break; + case 2: + if (val < -8192 || val > 8191) + as_warn("Word displacement out of range. line number not valid"); + val&=0x3fff; + val|=0x8000; #ifdef SHOW_NUM - printf("%x ",val>>8 & 0xff); + printf("%x ",val>>8 & 0xff); #endif - *buf++=(val>>8); + *buf++=(val>>8); #ifdef SHOW_NUM - printf("%x ",val & 0xff); + printf("%x ",val & 0xff); #endif - *buf++=val; - break; - case 4: - if (val < -0x1f000000 || val >= 0x20000000) - /* if (val < -0x20000000 || val >= 0x20000000) */ - as_warn("Double word displacement out of range"); - val|=0xc0000000; + *buf++=val; + break; + case 4: + if (val < -0x1f000000 || val >= 0x20000000) + /* if (val < -0x20000000 || val >= 0x20000000) */ + as_warn("Double word displacement out of range"); + val|=0xc0000000; #ifdef SHOW_NUM - printf("%x ",val>>24 & 0xff); + printf("%x ",val>>24 & 0xff); #endif - *buf++=(val>>24); + *buf++=(val>>24); #ifdef SHOW_NUM - printf("%x ",val>>16 & 0xff); + printf("%x ",val>>16 & 0xff); #endif - *buf++=(val>>16); + *buf++=(val>>16); #ifdef SHOW_NUM - printf("%x ",val>>8 & 0xff); + printf("%x ",val>>8 & 0xff); #endif - *buf++=(val>>8); + *buf++=(val>>8); #ifdef SHOW_NUM - printf("%x ",val & 0xff); + printf("%x ",val & 0xff); #endif - *buf++=val; - break; - default: - as_fatal("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__); - } + *buf++=val; + break; + default: + as_fatal("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__); + } } static void md_number_to_imm(buf,val,n) - char *buf; - long val; - char n; + char *buf; + long val; + char n; { - switch(n) { - case 1: + switch(n) { + case 1: #ifdef SHOW_NUM - printf("%x ",val & 0xff); + printf("%x ",val & 0xff); #endif - *buf++=val; - break; - case 2: + *buf++=val; + break; + case 2: #ifdef SHOW_NUM - printf("%x ",val>>8 & 0xff); + printf("%x ",val>>8 & 0xff); #endif - *buf++=(val>>8); + *buf++=(val>>8); #ifdef SHOW_NUM - printf("%x ",val & 0xff); + printf("%x ",val & 0xff); #endif - *buf++=val; - break; - case 4: + *buf++=val; + break; + case 4: #ifdef SHOW_NUM - printf("%x ",val>>24 & 0xff); + printf("%x ",val>>24 & 0xff); #endif - *buf++=(val>>24); + *buf++=(val>>24); #ifdef SHOW_NUM - printf("%x ",val>>16 & 0xff); + printf("%x ",val>>16 & 0xff); #endif - *buf++=(val>>16); + *buf++=(val>>16); #ifdef SHOW_NUM - printf("%x ",val>>8 & 0xff); + printf("%x ",val>>8 & 0xff); #endif - *buf++=(val>>8); + *buf++=(val>>8); #ifdef SHOW_NUM - printf("%x ",val & 0xff); + printf("%x ",val & 0xff); #endif - *buf++=val; - break; - default: - as_fatal("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__); - } + *buf++=val; + break; + default: + as_fatal("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__); + } } /* Translate internal representation of relocation info into target format. - + OVE: on a ns32k the twiddling continues at an even deeper level here we have to distinguish between displacements and immediates. - + The sequent has a bit for this. It also has a bit for relocobjects that points at the target for a bsr (BranchSubRoutine) !?!?!?! - + This md_ri.... is tailored for sequent. */ void -md_ri_to_chars(the_bytes, ri) - char *the_bytes; - struct reloc_info_generic *ri; + md_ri_to_chars(the_bytes, ri) +char *the_bytes; +struct reloc_info_generic *ri; { - if (ri->r_bsr) {ri->r_pcrel=0;} /* sequent seems to want this */ - md_number_to_chars(the_bytes, ri->r_address, sizeof(ri->r_address)); - md_number_to_chars(the_bytes+4, - (long)(ri->r_symbolnum ) | - (long)(ri->r_pcrel << 24 ) | - (long)(ri->r_length << 25 ) | - (long)(ri->r_extern << 27 ) | - (long)(ri->r_bsr << 28 ) | - (long)(ri->r_disp << 29 ), - 4); - /* the first and second md_number_to_chars never overlaps (32bit cpu case) */ + if (ri->r_bsr) {ri->r_pcrel=0;} /* sequent seems to want this */ + md_number_to_chars(the_bytes, ri->r_address, sizeof(ri->r_address)); + md_number_to_chars(the_bytes+4, + (long)(ri->r_symbolnum ) | + (long)(ri->r_pcrel << 24 ) | + (long)(ri->r_length << 25 ) | + (long)(ri->r_extern << 27 ) | + (long)(ri->r_bsr << 28 ) | + (long)(ri->r_disp << 29 ), + 4); + /* the first and second md_number_to_chars never overlaps (32bit cpu case) */ } /* fast bitfiddling support */ /* mask used to zero bitfield before oring in the true field */ static unsigned long l_mask[]={ 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, - 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, - 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, - 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, - 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, - 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, - 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, - 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, + 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, + 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, + 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, + 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, + 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, + 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, + 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, }; static unsigned long r_mask[]={ 0x00000000, 0x00000001, 0x00000003, 0x00000007, - 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, - 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, - 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, - 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, - 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, - 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, - 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, }; #define MASK_BITS 31 /* Insert bitfield described by field_ptr and val at buf @@ -1492,100 +1492,100 @@ static unsigned long r_mask[]={ 0x00000000, 0x00000001, 0x00000003, 0x00000007, to by buf, to yield speed. The ifdef stuff is for selection between a ns32k-dependent routine and a general version. (My advice: use the general version!) - */ + */ static void -md_number_to_field(buf,val,field_ptr) - register char *buf; - register long val; - register bit_fixS *field_ptr; + md_number_to_field(buf,val,field_ptr) +register char *buf; +register long val; +register bit_fixS *field_ptr; { - register unsigned long object; - register unsigned long mask; -/* define ENDIAN on a ns32k machine */ + register unsigned long object; + register unsigned long mask; + /* define ENDIAN on a ns32k machine */ #ifdef ENDIAN - register unsigned long *mem_ptr; + register unsigned long *mem_ptr; #else - register char *mem_ptr; + register char *mem_ptr; #endif - if (field_ptr->fx_bit_min<=val && val<=field_ptr->fx_bit_max) { + if (field_ptr->fx_bit_min<=val && val<=field_ptr->fx_bit_max) { #ifdef ENDIAN - if (field_ptr->fx_bit_base) { /* override buf */ - mem_ptr=(unsigned long*)field_ptr->fx_bit_base; - } else { - mem_ptr=(unsigned long*)buf; - } + if (field_ptr->fx_bit_base) { /* override buf */ + mem_ptr=(unsigned long*)field_ptr->fx_bit_base; + } else { + mem_ptr=(unsigned long*)buf; + } #else - if (field_ptr->fx_bit_base) { /* override buf */ - mem_ptr=(char*)field_ptr->fx_bit_base; - } else { - mem_ptr=buf; - } + if (field_ptr->fx_bit_base) { /* override buf */ + mem_ptr=(char*)field_ptr->fx_bit_base; + } else { + mem_ptr=buf; + } #endif - mem_ptr+=field_ptr->fx_bit_base_adj; + mem_ptr+=field_ptr->fx_bit_base_adj; #ifdef ENDIAN /* we have a nice ns32k machine with lowbyte at low-physical mem */ - object = *mem_ptr; /* get some bytes */ + object = *mem_ptr; /* get some bytes */ #else /* OVE Goof! the machine is a m68k or dito */ - /* That takes more byte fiddling */ - object=0; - object|=mem_ptr[3] & 0xff; - object<<=8; - object|=mem_ptr[2] & 0xff; - object<<=8; - object|=mem_ptr[1] & 0xff; - object<<=8; - object|=mem_ptr[0] & 0xff; + /* That takes more byte fiddling */ + object=0; + object|=mem_ptr[3] & 0xff; + object<<=8; + object|=mem_ptr[2] & 0xff; + object<<=8; + object|=mem_ptr[1] & 0xff; + object<<=8; + object|=mem_ptr[0] & 0xff; #endif - mask=0; - mask|=(r_mask[field_ptr->fx_bit_offset]); - mask|=(l_mask[field_ptr->fx_bit_offset+field_ptr->fx_bit_size]); - object&=mask; - val+=field_ptr->fx_bit_add; - object|=((val<<field_ptr->fx_bit_offset) & (mask ^ 0xffffffff)); + mask=0; + mask|=(r_mask[field_ptr->fx_bit_offset]); + mask|=(l_mask[field_ptr->fx_bit_offset+field_ptr->fx_bit_size]); + object&=mask; + val+=field_ptr->fx_bit_add; + object|=((val<<field_ptr->fx_bit_offset) & (mask ^ 0xffffffff)); #ifdef ENDIAN - *mem_ptr=object; + *mem_ptr=object; #else - mem_ptr[0]=(char)object; - object>>=8; - mem_ptr[1]=(char)object; - object>>=8; - mem_ptr[2]=(char)object; - object>>=8; - mem_ptr[3]=(char)object; + mem_ptr[0]=(char)object; + object>>=8; + mem_ptr[1]=(char)object; + object>>=8; + mem_ptr[2]=(char)object; + object>>=8; + mem_ptr[3]=(char)object; #endif - } else { - as_warn("Bit field out of range"); - } + } else { + as_warn("Bit field out of range"); + } } /* Apply a fixS (fixup of an instruction or data that we didn't have enough info to complete immediately) to the data in a frag. - + On the ns32k, everything is in a different format, so we have broken out separate functions for each kind of thing we could be fixing. They all get called from here. */ void -md_apply_fix(fixP, val) - fixS *fixP; - long val; + md_apply_fix(fixP, val) +fixS *fixP; +long val; { char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - + if (fixP->fx_bit_fixP) { /* Bitfields to fix, sigh */ md_number_to_field (buf, val, fixP->fx_bit_fixP); } else switch (fixP->fx_im_disp) { - + case 0: /* Immediate field */ md_number_to_imm (buf, val, fixP->fx_size); break; - + case 1: /* Displacement field */ md_number_to_disp (buf, - fixP->fx_pcrel? val + fixP->fx_pcrel_adjust: val, - fixP->fx_size); + fixP->fx_pcrel? val + fixP->fx_pcrel_adjust: val, + fixP->fx_size); break; - + case 2: /* Pointer in a data object */ md_number_to_chars (buf, val, fixP->fx_size); break; @@ -1595,38 +1595,39 @@ md_apply_fix(fixP, val) /* Convert a relaxed displacement to ditto in final output */ void -md_convert_frag(fragP) + md_convert_frag(headers, fragP) +object_headers *headers; register fragS *fragP; { - long disp; - long ext; - - /* Address in gas core of the place to store the displacement. */ - register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal; - /* Address in object code of the displacement. */ - register int object_address = fragP -> fr_fix + fragP -> fr_address; - - know(fragP->fr_symbol); - - /* The displacement of the address, from current location. */ - disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address; - disp+= fragP->fr_pcrel_adjust; - - switch(fragP->fr_subtype) { - case IND(BRANCH,BYTE): - ext=1; - break; - case IND(BRANCH,WORD): - ext=2; - break; - case IND(BRANCH,DOUBLE): - ext=4; - break; - } - if(ext) { - md_number_to_disp(buffer_address,(long)disp,(int)ext); - fragP->fr_fix+=ext; - } + long disp; + long ext; + + /* Address in gas core of the place to store the displacement. */ + register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal; + /* Address in object code of the displacement. */ + register int object_address = fragP -> fr_fix + fragP -> fr_address; + + know(fragP->fr_symbol); + + /* The displacement of the address, from current location. */ + disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address; + disp+= fragP->fr_pcrel_adjust; + + switch(fragP->fr_subtype) { + case IND(BRANCH,BYTE): + ext=1; + break; + case IND(BRANCH,WORD): + ext=2; + break; + case IND(BRANCH,DOUBLE): + ext=4; + break; + } + if(ext) { + md_number_to_disp(buffer_address,(long)disp,(int)ext); + fragP->fr_fix+=ext; + } } @@ -1634,44 +1635,44 @@ register fragS *fragP; /* This function returns the estimated size a variable object will occupy, one can say that we tries to guess the size of the objects before we actually know it */ - + int md_estimate_size_before_relax(fragP, segment) - register fragS *fragP; - segT segment; + register fragS *fragP; + segT segment; { - int old_fix; - old_fix=fragP->fr_fix; - switch(fragP->fr_subtype) { - case IND(BRANCH,UNDEF): - if(S_GET_SEGMENT(fragP->fr_symbol) == segment) { - /* the symbol has been assigned a value */ - fragP->fr_subtype=IND(BRANCH,BYTE); - } else { - /* we don't relax symbols defined in an other segment - the thing to do is to assume the object will occupy 4 bytes */ - fix_new_ns32k(fragP, - (int)(fragP->fr_fix), - 4, - fragP->fr_symbol, - (symbolS *)0, - fragP->fr_offset, - 1, - fragP->fr_pcrel_adjust, - 1, - 0, - fragP->fr_bsr); /*sequent hack */ - fragP->fr_fix+=4; - /* fragP->fr_opcode[1]=0xff; */ - frag_wane(fragP); - break; + int old_fix; + old_fix=fragP->fr_fix; + switch(fragP->fr_subtype) { + case IND(BRANCH,UNDEF): + if(S_GET_SEGMENT(fragP->fr_symbol) == segment) { + /* the symbol has been assigned a value */ + fragP->fr_subtype=IND(BRANCH,BYTE); + } else { + /* we don't relax symbols defined in an other segment + the thing to do is to assume the object will occupy 4 bytes */ + fix_new_ns32k(fragP, + (int)(fragP->fr_fix), + 4, + fragP->fr_symbol, + (symbolS *)0, + fragP->fr_offset, + 1, + fragP->fr_pcrel_adjust, + 1, + 0, + fragP->fr_bsr); /*sequent hack */ + fragP->fr_fix+=4; + /* fragP->fr_opcode[1]=0xff; */ + frag_wane(fragP); + break; + } + case IND(BRANCH,BYTE): + fragP->fr_var+=1; + break; + default: + break; } - case IND(BRANCH,BYTE): - fragP->fr_var+=1; - break; - default: - break; - } - return fragP->fr_var + fragP->fr_fix - old_fix; + return fragP->fr_var + fragP->fr_fix - old_fix; } int md_short_jump_size = 3; @@ -1679,63 +1680,63 @@ int md_long_jump_size = 5; int md_reloc_size = 8; /* Size of relocation record */ void -md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol) + md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol) char *ptr; long from_addr, - to_addr; + to_addr; fragS *frag; symbolS *to_symbol; { - long offset; - - offset = to_addr - from_addr; - md_number_to_chars(ptr, (long)0xEA ,1); - md_number_to_disp(ptr+1,(long)offset,2); + long offset; + + offset = to_addr - from_addr; + md_number_to_chars(ptr, (long)0xEA ,1); + md_number_to_disp(ptr+1,(long)offset,2); } void -md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) + md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) char *ptr; long from_addr, - to_addr; + to_addr; fragS *frag; symbolS *to_symbol; { - long offset; - - offset= to_addr - from_addr; - md_number_to_chars(ptr, (long)0xEA, 2); - md_number_to_disp(ptr+2,(long)offset,4); + long offset; + + offset= to_addr - from_addr; + md_number_to_chars(ptr, (long)0xEA, 2); + md_number_to_disp(ptr+2,(long)offset,4); } /* JF this is a new function to parse machine-dep options */ int -md_parse_option(argP,cntP,vecP) + md_parse_option(argP,cntP,vecP) char **argP; int *cntP; char ***vecP; { - switch(**argP) { - case 'm': - (*argP)++; - - if(!strcmp(*argP,"32032")) { + switch(**argP) { + case 'm': + (*argP)++; + + if(!strcmp(*argP,"32032")) { cpureg = cpureg_032; mmureg = mmureg_032; - } else if(!strcmp(*argP, "32532")) { + } else if(!strcmp(*argP, "32532")) { cpureg = cpureg_532; mmureg = mmureg_532; - } else + } else as_warn("Unknown -m option ignored"); - - while(**argP) + + while(**argP) (*argP)++; - break; - - default: - return 0; - } - return 1; + break; + + default: + return 0; + } + return 1; } /* @@ -1746,71 +1747,71 @@ char ***vecP; * valid pointer (not NULL) the bit_fix data will be used to format the fix. */ bit_fixS *bit_fix_new (size,offset,min,max,add,base_type,base_adj) - char size; /* Length of bitfield */ - char offset; /* Bit offset to bitfield */ - long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr */ - long base_adj; - long min; /* Signextended min for bitfield */ - long max; /* Signextended max for bitfield */ - long add; /* Add mask, used for huffman prefix */ + char size; /* Length of bitfield */ + char offset; /* Bit offset to bitfield */ + long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr */ + long base_adj; + long min; /* Signextended min for bitfield */ + long max; /* Signextended max for bitfield */ + long add; /* Add mask, used for huffman prefix */ { - register bit_fixS * bit_fixP; - - bit_fixP = (bit_fixS *)obstack_alloc(¬es,sizeof(bit_fixS)); - - bit_fixP -> fx_bit_size = size; - bit_fixP -> fx_bit_offset = offset; - bit_fixP -> fx_bit_base = base_type; - bit_fixP -> fx_bit_base_adj = base_adj; - bit_fixP -> fx_bit_max = max; - bit_fixP -> fx_bit_min = min; - bit_fixP -> fx_bit_add = add; - - return bit_fixP; + register bit_fixS * bit_fixP; + + bit_fixP = (bit_fixS *)obstack_alloc(¬es,sizeof(bit_fixS)); + + bit_fixP -> fx_bit_size = size; + bit_fixP -> fx_bit_offset = offset; + bit_fixP -> fx_bit_base = base_type; + bit_fixP -> fx_bit_base_adj = base_adj; + bit_fixP -> fx_bit_max = max; + bit_fixP -> fx_bit_min = min; + bit_fixP -> fx_bit_add = add; + + return bit_fixP; } void -fix_new_ns32k (frag, where, size, add_symbol, sub_symbol, offset, pcrel, - pcrel_adjust, im_disp, bit_fixP, bsr) - fragS * frag; /* Which frag? */ - int where; /* Where in that frag? */ - short int size; /* 1, 2 or 4 usually. */ - symbolS * add_symbol; /* X_add_symbol. */ - symbolS * sub_symbol; /* X_subtract_symbol. */ - long offset; /* X_add_number. */ - int pcrel; /* TRUE if PC-relative relocation. */ - char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */ - char im_disp; /* true if the value to write is a displacement */ - bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */ - char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */ - + fix_new_ns32k (frag, where, size, add_symbol, sub_symbol, offset, pcrel, + pcrel_adjust, im_disp, bit_fixP, bsr) +fragS * frag; /* Which frag? */ +int where; /* Where in that frag? */ +short int size; /* 1, 2 or 4 usually. */ +symbolS * add_symbol; /* X_add_symbol. */ +symbolS * sub_symbol; /* X_subtract_symbol. */ +long offset; /* X_add_number. */ +int pcrel; /* TRUE if PC-relative relocation. */ +char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */ +char im_disp; /* true if the value to write is a displacement */ +bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */ +char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */ + { - register fixS * fixP; - - fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS)); - fixP -> fx_frag = frag; - fixP -> fx_where = where; - fixP -> fx_size = size; - fixP -> fx_addsy = add_symbol; - fixP -> fx_subsy = sub_symbol; - fixP -> fx_offset = offset; - fixP -> fx_pcrel = pcrel; - fixP -> fx_pcrel_adjust = pcrel_adjust; - fixP -> fx_im_disp = im_disp; - fixP -> fx_bit_fixP = bit_fixP; - fixP -> fx_bsr = bsr; - fixP -> fx_next = * seg_fix_rootP; - - * seg_fix_rootP = fixP; + register fixS * fixP; + + fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS)); + fixP -> fx_frag = frag; + fixP -> fx_where = where; + fixP -> fx_size = size; + fixP -> fx_addsy = add_symbol; + fixP -> fx_subsy = sub_symbol; + fixP -> fx_offset = offset; + fixP -> fx_pcrel = pcrel; + fixP -> fx_pcrel_adjust = pcrel_adjust; + fixP -> fx_im_disp = im_disp; + fixP -> fx_bit_fixP = bit_fixP; + fixP -> fx_bsr = bsr; + fixP -> fx_next = * seg_fix_rootP; + + * seg_fix_rootP = fixP; } /* We have no need to default values of symbols. */ symbolS * -md_undefined_symbol (name) - char *name; + md_undefined_symbol (name) +char *name; { - return 0; + return 0; } /* Parse an operand that is machine-specific. @@ -1819,18 +1820,18 @@ md_undefined_symbol (name) /* ARGSUSED */ void -md_operand (expressionP) - expressionS *expressionP; + md_operand (expressionP) +expressionS *expressionP; { } /* Round up a section size to the appropriate boundary. */ long -md_section_align (segment, size) - segT segment; - long size; + md_section_align (segment, size) +segT segment; +long size; { - return size; /* Byte alignment is fine */ + return size; /* Byte alignment is fine */ } /* Exactly what point is a PC-relative offset relative TO? @@ -1838,21 +1839,39 @@ md_section_align (segment, size) with some funny adjustments in some circumstances during blue moons. (??? Is this right? FIXME-SOON) */ long -md_pcrel_from (fixP) - fixS *fixP; + md_pcrel_from (fixP) +fixS *fixP; { - long res; - res = fixP->fx_where + fixP->fx_frag->fr_address; + long res; + res = fixP->fx_where + fixP->fx_frag->fr_address; #ifdef SEQUENT_COMPATABILITY - if (fixP->fx_frag->fr_bsr) - res += 0x12 /* FOO Kludge alert! */ + if (fixP->fx_frag->fr_bsr) + res += 0x12 /* FOO Kludge alert! */ #endif - return res; + return res; } /* * $Log$ - * Revision 1.1 1991/04/04 18:17:05 rich + * Revision 1.5 1992/02/13 08:33:29 rich + * 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. + * + * Revision 1.4 1991/12/01 07:11:38 sac + * More filename renaming. + * + * Revision 1.3 1991/07/27 02:32:47 rich + * Polishing m68k support. + * + * Revision 1.2 1991/06/14 14:02:27 rich + * Version 2 GPL. + * + * Revision 1.1.1.1 1991/04/04 18:17:07 rich + * new gas main line + * + * Revision 1.1 1991/04/04 18:17:05 rich * Initial revision * * diff --git a/gas/config/tc-ns32k.h b/gas/config/tc-ns32k.h index b96b650..64adb6b 100644 --- a/gas/config/tc-ns32k.h +++ b/gas/config/tc-ns32k.h @@ -1,21 +1,21 @@ /* ns32k-opcode.h -- Opcode table for National Semi 32k processor Copyright (C) 1987 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. */ + + 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. */ #ifdef SEQUENT_COMPATABILITY diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index df18f15..c5ffc39 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -1,3 +1,4 @@ +#define cypress 1234 /* tc-sparc.c -- Assemble for the SPARC Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. @@ -43,7 +44,7 @@ static int architecture_requested = 0; static int warn_on_bump = 0; const relax_typeS md_relax_table[] = { - 0 }; + 0 }; /* handle of the OPCODE hash table */ static struct hash_control *op_hash = NULL; @@ -53,17 +54,17 @@ extern void s_globl(), s_long(), s_short(), s_space(), cons(); extern void s_align_bytes(), s_ignore(); const pseudo_typeS md_pseudo_table[] = { - { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */ - { "common", s_common, 0 }, - { "global", s_globl, 0 }, - { "half", cons, 2 }, - { "optim", s_ignore, 0 }, - { "proc", s_proc, 0 }, - { "reserve", s_reserve, 0 }, - { "seg", s_seg, 0 }, - { "skip", s_space, 0 }, - { "word", cons, 4 }, - { NULL, 0, 0 }, +{ "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */ +{ "common", s_common, 0 }, +{ "global", s_globl, 0 }, +{ "half", cons, 2 }, +{ "optim", s_ignore, 0 }, +{ "proc", s_proc, 0 }, +{ "reserve", s_reserve, 0 }, +{ "seg", s_seg, 0 }, +{ "skip", s_space, 0 }, +{ "word", cons, 4 }, +{ NULL, 0, 0 }, }; const int md_short_jump_size = 4; @@ -99,15 +100,15 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; static unsigned char octal[256]; #define isoctal(c) octal[c] -static unsigned char toHex[256]; + static unsigned char toHex[256]; struct sparc_it { - char *error; - unsigned long opcode; - struct nlist *nlistp; - expressionS exp; - int pcrel; - enum reloc_type reloc; + char *error; +unsigned long opcode; +struct nlist *nlistp; +expressionS exp; +int pcrel; +enum reloc_type reloc; } the_insn, set_insn; #ifdef __STDC__ @@ -139,249 +140,249 @@ static int max_alignment = 15; static void s_reserve() { char *name; - char *p; - char c; - int align; - int size; - int temp; - symbolS *symbolP; + char *p; + char c; + int align; + int size; + int temp; + symbolS *symbolP; + + name = input_line_pointer; + c = get_symbol_end(); + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE(); + + if (*input_line_pointer != ',') { + as_bad("Expected comma after name"); + ignore_rest_of_line(); + return; + } + + ++input_line_pointer; + + if ((size = get_absolute_expression()) < 0) { + as_bad("BSS length (%d.) <0! Ignored.", size); + ignore_rest_of_line(); + return; + } /* bad length */ + + *p = 0; + symbolP = symbol_find_or_make(name); + *p = c; + + if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) { + as_bad("bad .reserve segment: `%s'", input_line_pointer); + return; + } /* if not bss */ + + input_line_pointer += 6; + SKIP_WHITESPACE(); + + if (*input_line_pointer == ',') { + ++input_line_pointer; - name = input_line_pointer; - c = get_symbol_end(); - p = input_line_pointer; - *p = c; SKIP_WHITESPACE(); - - if (*input_line_pointer != ',') { - as_bad("Expected comma after name"); - ignore_rest_of_line(); - return; + if (*input_line_pointer == '\n') { + as_bad("Missing alignment"); + return; + } + + align = get_absolute_expression(); + if (align > max_alignment){ + align = max_alignment; + as_warn("Alignment too large: %d. assumed.", align); + } else if (align < 0) { + align = 0; + as_warn("Alignment negative. 0 assumed."); } - - ++input_line_pointer; - - if ((size = get_absolute_expression()) < 0) { - as_bad("BSS length (%d.) <0! Ignored.", size); - ignore_rest_of_line(); - return; - } /* bad length */ - - *p = 0; - symbolP = symbol_find_or_make(name); - *p = c; - - if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) { - as_bad("bad .reserve segment: `%s'", input_line_pointer); - return; - } /* if not bss */ - - input_line_pointer += 6; - SKIP_WHITESPACE(); - - if (*input_line_pointer == ',') { - ++input_line_pointer; - - SKIP_WHITESPACE(); - if (*input_line_pointer == '\n') { - as_bad("Missing alignment"); - return; - } - - align = get_absolute_expression(); - if (align > max_alignment){ - align = max_alignment; - as_warn("Alignment too large: %d. assumed.", align); - } else if (align < 0) { - align = 0; - as_warn("Alignment negative. 0 assumed."); - } #ifdef MANY_SEGMENTS #define SEG_BSS SEG_E2 - record_alignment(SEG_E2, align); + record_alignment(SEG_E2, align); #else - record_alignment(SEG_BSS, align); + record_alignment(SEG_BSS, align); #endif - - /* convert to a power of 2 alignment */ - for (temp = 0; (align & 1) == 0; align >>= 1, ++temp) ;; - - if (align != 1) { - as_bad("Alignment not a power of 2"); - ignore_rest_of_line(); - return; - } /* not a power of two */ - - align = temp; + + /* convert to a power of 2 alignment */ + for (temp = 0; (align & 1) == 0; align >>= 1, ++temp) ;; + + if (align != 1) { + as_bad("Alignment not a power of 2"); + ignore_rest_of_line(); + return; + } /* not a power of two */ + + align = temp; + + /* Align */ + align = ~((~0) << align); /* Convert to a mask */ + local_bss_counter = (local_bss_counter + align) & (~align); + } /* if has optional alignment */ - /* Align */ - align = ~((~0) << align); /* Convert to a mask */ - local_bss_counter = (local_bss_counter + align) & (~align); - } /* if has optional alignment */ - - if (S_GET_OTHER(symbolP) == 0 - && S_GET_DESC(symbolP) == 0 - && ((S_GET_SEGMENT(symbolP) == SEG_BSS - && S_GET_VALUE(symbolP) == local_bss_counter) - || !S_IS_DEFINED(symbolP))) { - S_SET_VALUE(symbolP, local_bss_counter); - S_SET_SEGMENT(symbolP, SEG_BSS); - symbolP->sy_frag = &bss_address_frag; - local_bss_counter += size; - } else { - as_warn("Ignoring attempt to re-define symbol from %d. to %d.", - S_GET_VALUE(symbolP), local_bss_counter); - } /* if not redefining */ - - demand_empty_rest_of_line(); - return; + if (S_GET_OTHER(symbolP) == 0 + && S_GET_DESC(symbolP) == 0 + && ((S_GET_SEGMENT(symbolP) == SEG_BSS + && S_GET_VALUE(symbolP) == local_bss_counter) + || !S_IS_DEFINED(symbolP))) { + S_SET_VALUE(symbolP, local_bss_counter); + S_SET_SEGMENT(symbolP, SEG_BSS); + symbolP->sy_frag = &bss_address_frag; + local_bss_counter += size; + } else { + as_warn("Ignoring attempt to re-define symbol from %d. to %d.", + S_GET_VALUE(symbolP), local_bss_counter); + } /* if not redefining */ + + demand_empty_rest_of_line(); + return; } /* s_reserve() */ static void s_common() { 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' */ - p = input_line_pointer; - *p = c; - SKIP_WHITESPACE(); - if (* input_line_pointer != ',') { - as_bad("Expected comma after symbol-name"); - ignore_rest_of_line(); - return; - } - input_line_pointer ++; /* skip ',' */ - if ((temp = get_absolute_expression ()) < 0) { - as_bad(".COMMon length (%d.) <0! Ignored.", temp); - ignore_rest_of_line(); - return; - } - *p = 0; - symbolP = symbol_find_or_make(name); - *p = c; - if (S_IS_DEFINED(symbolP)) { - as_bad("Ignoring attempt to re-define symbol"); - ignore_rest_of_line(); - return; - } - if (S_GET_VALUE(symbolP) != 0) { - if (S_GET_VALUE(symbolP) != temp) { - as_warn("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); - } - know(symbolP->sy_frag == &zero_address_frag); - if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0 - && strncmp(input_line_pointer, ",\"data\"", 7) != 0) { - p=input_line_pointer; - while(*p && *p!='\n') - p++; - c= *p; - *p='\0'; - as_bad("bad .common segment: `%s'", input_line_pointer); - *p=c; - return; + 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' */ + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE(); + if (* input_line_pointer != ',') { + as_bad("Expected comma after symbol-name"); + ignore_rest_of_line(); + return; + } + input_line_pointer ++; /* skip ',' */ + if ((temp = get_absolute_expression ()) < 0) { + as_bad(".COMMon length (%d.) <0! Ignored.", temp); + ignore_rest_of_line(); + return; + } + *p = 0; + symbolP = symbol_find_or_make(name); + *p = c; + if (S_IS_DEFINED(symbolP)) { + as_bad("Ignoring attempt to re-define symbol"); + ignore_rest_of_line(); + return; + } + if (S_GET_VALUE(symbolP) != 0) { + if (S_GET_VALUE(symbolP) != temp) { + as_warn("Length of .comm \"%s\" is already %d. Not changed to %d.", + S_GET_NAME(symbolP), S_GET_VALUE(symbolP), temp); } - input_line_pointer += 6 + (input_line_pointer[2] == 'd'); /* Skip either */ - demand_empty_rest_of_line(); + } else { + S_SET_VALUE(symbolP, temp); + S_SET_EXTERNAL(symbolP); + } + know(symbolP->sy_frag == &zero_address_frag); + if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0 + && strncmp(input_line_pointer, ",\"data\"", 7) != 0) { + p=input_line_pointer; + while(*p && *p!='\n') + p++; + c= *p; + *p='\0'; + as_bad("bad .common segment: `%s'", input_line_pointer); + *p=c; return; + } + input_line_pointer += 6 + (input_line_pointer[2] == 'd'); /* Skip either */ + demand_empty_rest_of_line(); + return; } /* s_common() */ static void s_seg() { if (strncmp(input_line_pointer, "\"text\"", 6) == 0) { - input_line_pointer += 6; - s_text(); - return; - } - if (strncmp(input_line_pointer, "\"data\"", 6) == 0) { - input_line_pointer += 6; - s_data(); - return; - } - if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) { - input_line_pointer += 7; - s_data1(); - return; - } - if (strncmp(input_line_pointer, "\"bss\"", 5) == 0) { - input_line_pointer += 5; - /* We only support 2 segments -- text and data -- for now, so - things in the "bss segment" will have to go into data for now. - You can still allocate SEG_BSS stuff with .lcomm or .reserve. */ - subseg_new(SEG_DATA, 255); /* FIXME-SOMEDAY */ - return; + input_line_pointer += 6; + s_text(); + return; } - as_bad("Unknown segment type"); - demand_empty_rest_of_line(); + if (strncmp(input_line_pointer, "\"data\"", 6) == 0) { + input_line_pointer += 6; + s_data(); + return; + } + if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) { + input_line_pointer += 7; + s_data1(); return; + } + if (strncmp(input_line_pointer, "\"bss\"", 5) == 0) { + input_line_pointer += 5; + /* We only support 2 segments -- text and data -- for now, so + things in the "bss segment" will have to go into data for now. + You can still allocate SEG_BSS stuff with .lcomm or .reserve. */ + subseg_new(SEG_DATA, 255); /* FIXME-SOMEDAY */ + return; + } + as_bad("Unknown segment type"); + demand_empty_rest_of_line(); + return; } /* s_seg() */ static void s_data1() { subseg_new(SEG_DATA, 1); - demand_empty_rest_of_line(); - return; + demand_empty_rest_of_line(); + return; } /* s_data1() */ static void s_proc() { extern char is_end_of_line[]; - - while (!is_end_of_line[*input_line_pointer]) { - ++input_line_pointer; - } + + while (!is_end_of_line[*input_line_pointer]) { ++input_line_pointer; - return; + } + ++input_line_pointer; + return; } /* s_proc() */ /* This function is called once, at assembler startup time. It should set up all the tables, etc. that the MD part of the assembler will need. */ void md_begin() { register char *retval = NULL; - int lose = 0; - register unsigned int i = 0; - - op_hash = hash_new(); - if (op_hash == NULL) - as_fatal("Virtual memory exhausted"); - - while (i < NUMOPCODES) { - const char *name = sparc_opcodes[i].name; - retval = hash_insert(op_hash, name, &sparc_opcodes[i]); - if(retval != NULL && *retval != '\0') { - fprintf (stderr, "internal error: can't hash `%s': %s\n", - sparc_opcodes[i].name, retval); - lose = 1; - } - do - { - if (sparc_opcodes[i].match & sparc_opcodes[i].lose) { - fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n", - sparc_opcodes[i].name, sparc_opcodes[i].args); - lose = 1; - } - ++i; - } while (i < NUMOPCODES - && !strcmp(sparc_opcodes[i].name, name)); + int lose = 0; + register unsigned int i = 0; + + op_hash = hash_new(); + if (op_hash == NULL) + as_fatal("Virtual memory exhausted"); + + while (i < NUMOPCODES) { + const char *name = sparc_opcodes[i].name; + retval = hash_insert(op_hash, name, &sparc_opcodes[i]); + if(retval != NULL && *retval != '\0') { + fprintf (stderr, "internal error: can't hash `%s': %s\n", + sparc_opcodes[i].name, retval); + lose = 1; } - - if (lose) - as_fatal("Broken assembler. No assembly attempted."); - - for (i = '0'; i < '8'; ++i) - octal[i] = 1; - for (i = '0'; i <= '9'; ++i) - toHex[i] = i - '0'; - for (i = 'a'; i <= 'f'; ++i) - toHex[i] = i + 10 - 'a'; - for (i = 'A'; i <= 'F'; ++i) - toHex[i] = i + 10 - 'A'; + do + { + if (sparc_opcodes[i].match & sparc_opcodes[i].lose) { + fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n", + sparc_opcodes[i].name, sparc_opcodes[i].args); + lose = 1; + } + ++i; + } while (i < NUMOPCODES + && !strcmp(sparc_opcodes[i].name, name)); + } + + if (lose) + as_fatal("Broken assembler. No assembly attempted."); + + for (i = '0'; i < '8'; ++i) + octal[i] = 1; + for (i = '0'; i <= '9'; ++i) + toHex[i] = i - '0'; + for (i = 'a'; i <= 'f'; ++i) + toHex[i] = i + 10 - 'a'; + for (i = 'A'; i <= 'F'; ++i) + toHex[i] = i + 10 - 'A'; } /* md_begin() */ void md_end() { @@ -389,828 +390,827 @@ void md_end() { } /* md_end() */ void md_assemble(str) -char *str; + char *str; { - char *toP; - int rsd; - - know(str); - sparc_ip(str); - - /* See if "set" operand is absolute and small; skip sethi if so. */ - if (special_case == SPECIAL_CASE_SET && the_insn.exp.X_seg == SEG_ABSOLUTE) { - if (the_insn.exp.X_add_number >= -(1<<12) - && the_insn.exp.X_add_number < (1<<12)) { - the_insn.opcode = 0x80102000 /* or %g0,imm,... */ - | (the_insn.opcode & 0x3E000000) /* dest reg */ - | (the_insn.exp.X_add_number & 0x1FFF); /* imm */ - special_case = 0; /* No longer special */ - the_insn.reloc = NO_RELOC; /* No longer relocated */ - } + char *toP; + int rsd; + + know(str); + sparc_ip(str); + + /* See if "set" operand is absolute and small; skip sethi if so. */ + if (special_case == SPECIAL_CASE_SET && the_insn.exp.X_seg == SEG_ABSOLUTE) { + if (the_insn.exp.X_add_number >= -(1<<12) + && the_insn.exp.X_add_number < (1<<12)) { + the_insn.opcode = 0x80102000 /* or %g0,imm,... */ + | (the_insn.opcode & 0x3E000000) /* dest reg */ + | (the_insn.exp.X_add_number & 0x1FFF); /* imm */ + special_case = 0; /* No longer special */ + the_insn.reloc = NO_RELOC; /* No longer relocated */ } + } + + toP = frag_more(4); + /* put out the opcode */ + md_number_to_chars(toP, the_insn.opcode, 4); + + /* put out the symbol-dependent stuff */ + if (the_insn.reloc != NO_RELOC) { + fix_new(frag_now, /* which frag */ + (toP - frag_now->fr_literal), /* where */ + 4, /* size */ + the_insn.exp.X_add_symbol, + the_insn.exp.X_subtract_symbol, + the_insn.exp.X_add_number, + the_insn.pcrel, + the_insn.reloc); + } + switch (special_case) { + case SPECIAL_CASE_SET: + special_case = 0; + assert(the_insn.reloc == RELOC_HI22); + /* See if "set" operand has no low-order bits; skip OR if so. */ + if (the_insn.exp.X_seg == SEG_ABSOLUTE + && ((the_insn.exp.X_add_number & 0x3FF) == 0)) + return; toP = frag_more(4); - /* put out the opcode */ + rsd = (the_insn.opcode >> 25) & 0x1f; + the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14); md_number_to_chars(toP, the_insn.opcode, 4); + fix_new(frag_now, /* which frag */ + (toP - frag_now->fr_literal), /* where */ + 4, /* size */ + the_insn.exp.X_add_symbol, + the_insn.exp.X_subtract_symbol, + the_insn.exp.X_add_number, + the_insn.pcrel, + RELOC_LO10); + return; - /* put out the symbol-dependent stuff */ - if (the_insn.reloc != NO_RELOC) { - fix_new(frag_now, /* which frag */ - (toP - frag_now->fr_literal), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - the_insn.reloc); - } - switch (special_case) { - - case SPECIAL_CASE_SET: - special_case = 0; - assert(the_insn.reloc == RELOC_HI22); - /* See if "set" operand has no low-order bits; skip OR if so. */ - if (the_insn.exp.X_seg == SEG_ABSOLUTE - && ((the_insn.exp.X_add_number & 0x3FF) == 0)) - return; - toP = frag_more(4); - rsd = (the_insn.opcode >> 25) & 0x1f; - the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14); - md_number_to_chars(toP, the_insn.opcode, 4); - fix_new(frag_now, /* which frag */ - (toP - frag_now->fr_literal), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - RELOC_LO10); - return; - - case SPECIAL_CASE_FDIV: - /* According to information leaked from Sun, the "fdiv" instructions - on early SPARC machines would produce incorrect results sometimes. - The workaround is to add an fmovs of the destination register to - itself just after the instruction. This was true on machines - with Weitek 1165 float chips, such as the Sun-4/260 and /280. */ - special_case = 0; - assert(the_insn.reloc == NO_RELOC); - toP = frag_more(4); - rsd = (the_insn.opcode >> 25) & 0x1f; - the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */ - md_number_to_chars(toP, the_insn.opcode, 4); - return; - - case 0: - return; - - default: - as_fatal("failed sanity check."); - } + case SPECIAL_CASE_FDIV: + /* According to information leaked from Sun, the "fdiv" instructions + on early SPARC machines would produce incorrect results sometimes. + The workaround is to add an fmovs of the destination register to + itself just after the instruction. This was true on machines + with Weitek 1165 float chips, such as the Sun-4/260 and /280. */ + special_case = 0; + assert(the_insn.reloc == NO_RELOC); + toP = frag_more(4); + rsd = (the_insn.opcode >> 25) & 0x1f; + the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */ + md_number_to_chars(toP, the_insn.opcode, 4); + return; + + case 0: + return; + + default: + as_fatal("failed sanity check."); + } } /* md_assemble() */ static void sparc_ip(str) -char *str; + char *str; { - char *error_message = ""; - char *s; - const char *args; - char c; - struct sparc_opcode *insn; - char *argsStart; - unsigned long opcode; - unsigned int mask = 0; - int match = 0; - int comma = 0; + char *error_message = ""; + char *s; + const char *args; + char c; + struct sparc_opcode *insn; + char *argsStart; + unsigned long opcode; + unsigned int mask = 0; + int match = 0; + int comma = 0; + + for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s) + ; + switch (*s) { + + case '\0': + break; + + case ',': + comma = 1; + + /*FALLTHROUGH */ + + case ' ': + *s++ = '\0'; + break; + + default: + as_bad("Unknown opcode: `%s'", str); + exit(1); + } + if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) { + as_bad("Unknown opcode: `%s'", str); + return; + } + if (comma) { + *--s = ','; + } + argsStart = s; + for (;;) { + opcode = insn->match; + bzero(&the_insn, sizeof(the_insn)); + the_insn.reloc = NO_RELOC; - for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s) - ; - switch (*s) { + /* + * Build the opcode, checking as we go to make + * sure that the operands match + */ + for (args = insn->args; ; ++args) { + switch (*args) { - case '\0': + case 'M': + case 'm': + if (strncmp(s, "%asr", 4) == 0) { + s += 4; + + if (isdigit(*s)) { + long num = 0; + + while (isdigit(*s)) { + num = num*10 + *s-'0'; + ++s; + } + + if (num < 16 || 31 < num) { + error_message = ": asr number must be between 15 and 31"; + goto error; + } /* out of range */ + + opcode |= (*args == 'M' ? RS1(num) : RD(num)); + continue; + } else { + error_message = ": expecting %asrN"; + goto error; + } /* if %asr followed by a number. */ + + } /* if %asr */ break; - case ',': - comma = 1; + /* start-sanitize-v9 */ +#ifndef NO_V9 + case 'I': + the_insn.reloc = RELOC_11; + goto immediate; - /*FALLTHROUGH */ + case 'k': + the_insn.reloc = RELOC_WDISP2_14; + the_insn.pcrel = 1; + goto immediate; - case ' ': - *s++ = '\0'; + case 'G': + the_insn.reloc = RELOC_WDISP19; + the_insn.pcrel = 1; + goto immediate; + + case 'N': + if (*s == 'p' && s[1] == 'n') { + s += 2; + continue; + } break; - default: - as_bad("Unknown opcode: `%s'", str); - exit(1); - } - if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) { - as_bad("Unknown opcode: `%s'", str); - return; - } - if (comma) { - *--s = ','; - } - argsStart = s; - for (;;) { - opcode = insn->match; - bzero(&the_insn, sizeof(the_insn)); - the_insn.reloc = NO_RELOC; + case 'T': + if (*s == 'p' && s[1] == 't') { + s += 2; + continue; + } + break; - /* - * Build the opcode, checking as we go to make - * sure that the operands match - */ - for (args = insn->args; ; ++args) { - switch (*args) { - - case 'M': - case 'm': - if (strncmp(s, "%asr", 4) == 0) { - s += 4; - - if (isdigit(*s)) { - long num = 0; - - while (isdigit(*s)) { - num = num*10 + *s-'0'; - ++s; - } - - if (num < 16 || 31 < num) { - error_message = ": asr number must be between 15 and 31"; - goto error; - } /* out of range */ - - opcode |= (*args == 'M' ? RS1(num) : RD(num)); - continue; - } else { - error_message = ": expecting %asrN"; - goto error; - } /* if %asr followed by a number. */ - - } /* if %asr */ - break; - - /* start-sanitize-v9 */ -#ifndef NO_V9 - case 'I': - the_insn.reloc = RELOC_11; - goto immediate; - - case 'k': - the_insn.reloc = RELOC_WDISP2_14; - the_insn.pcrel = 1; - goto immediate; - - case 'G': - the_insn.reloc = RELOC_WDISP19; - the_insn.pcrel = 1; - goto immediate; - - case 'N': - if (*s == 'p' && s[1] == 'n') { - s += 2; - continue; - } - break; - - case 'T': - if (*s == 'p' && s[1] == 't') { - s += 2; - continue; - } - break; - - case 'Y': - if (strncmp(s, "%amr", 4) == 0) { - s += 4; - continue; - } - break; - - case 'z': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "icc", 3) == 0) { - s += 3; - continue; - } - break; - - case 'Z': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "xcc", 3) == 0) { - s += 3; - continue; - } - break; - - case '6': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc0", 4) == 0) { - s += 4; - continue; - } - break; - - case '7': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc1", 4) == 0) { - s += 4; - continue; - } - break; - - case '8': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc2", 4) == 0) { - s += 4; - continue; - } - break; - - case '9': - if (*s == ' ') { - ++s; - } - if (strncmp(s, "fcc3", 4) == 0) { - s += 4; - continue; - } - break; - - case 'P': - if (strncmp(s, "%pc", 3) == 0) { - s += 3; - continue; - } - break; - - case 'E': - if (strncmp(s, "%modes", 6) == 0) { - s += 6; - continue; - } - break; - - case 'W': - if (strncmp(s, "%tick", 5) == 0) { - s += 5; - continue; - } - break; + case 'Y': + if (strncmp(s, "%amr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'z': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "icc", 3) == 0) { + s += 3; + continue; + } + break; + + case 'Z': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "xcc", 3) == 0) { + s += 3; + continue; + } + break; + + case '6': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc0", 4) == 0) { + s += 4; + continue; + } + break; + + case '7': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc1", 4) == 0) { + s += 4; + continue; + } + break; + + case '8': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc2", 4) == 0) { + s += 4; + continue; + } + break; + + case '9': + if (*s == ' ') { + ++s; + } + if (strncmp(s, "fcc3", 4) == 0) { + s += 4; + continue; + } + break; + + case 'P': + if (strncmp(s, "%pc", 3) == 0) { + s += 3; + continue; + } + break; + + case 'E': + if (strncmp(s, "%modes", 6) == 0) { + s += 6; + continue; + } + break; + + case 'W': + if (strncmp(s, "%tick", 5) == 0) { + s += 5; + continue; + } + break; #endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case '\0': /* end of args */ - if (*s == '\0') { - match = 1; - } - break; - - case '+': - if (*s == '+') { - ++s; - continue; - } - if (*s == '-') { - continue; - } - break; - - case '[': /* these must match exactly */ - case ']': - case ',': - case ' ': - if (*s++ == *args) - continue; - break; - - case '#': /* must be at least one digit */ - if (isdigit(*s++)) { - while (isdigit(*s)) { - ++s; - } - continue; - } - break; - - case 'C': /* coprocessor state register */ - if (strncmp(s, "%csr", 4) == 0) { - s += 4; - continue; - } - break; - - case 'b': /* next operand is a coprocessor register */ - case 'c': - case 'D': - if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) { - mask = *s++; - if (isdigit(*s)) { - mask = 10 * (mask - '0') + (*s++ - '0'); - if (mask >= 32) { - break; - } - } else { - mask -= '0'; - } - switch (*args) { - - case 'b': - opcode |= mask << 14; - continue; - - case 'c': - opcode |= mask; - continue; - - case 'D': - opcode |= mask << 25; - continue; - } - } - break; - - case 'r': /* next operand must be a register */ - case '1': - case '2': - case 'd': - if (*s++ == '%') { - switch (c = *s++) { - - case 'f': /* frame pointer */ - if (*s++ == 'p') { - mask = 0x1e; - break; - } - goto error; - - case 'g': /* global register */ - if (isoctal(c = *s++)) { - mask = c - '0'; - break; - } - goto error; - - case 'i': /* in register */ - if (isoctal(c = *s++)) { - mask = c - '0' + 24; - break; - } - goto error; - - case 'l': /* local register */ - if (isoctal(c = *s++)) { - mask= (c - '0' + 16) ; - break; - } - goto error; - - case 'o': /* out register */ - if (isoctal(c = *s++)) { - mask= (c - '0' + 8) ; - break; - } - goto error; - - case 's': /* stack pointer */ - if (*s++ == 'p') { - mask= 0xe; - break; - } - goto error; - - case 'r': /* any register */ - if (!isdigit(c = *s++)) { - goto error; - } - /* FALLTHROUGH */ - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (isdigit(*s)) { - if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) { - goto error; - } - } else { - c -= '0'; - } - mask= c; - break; - - default: - goto error; - } - /* - * Got the register, now figure out where - * it goes in the opcode. - */ - switch (*args) { - - case '1': - opcode |= mask << 14; - continue; - - case '2': - opcode |= mask; - continue; - - case 'd': - opcode |= mask << 25; - continue; - - case 'r': - opcode |= (mask << 25) | (mask << 14); - continue; - } - } - break; - - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + + case '\0': /* end of args */ + if (*s == '\0') { + match = 1; + } + break; + + case '+': + if (*s == '+') { + ++s; + continue; + } + if (*s == '-') { + continue; + } + break; + + case '[': /* these must match exactly */ + case ']': + case ',': + case ' ': + if (*s++ == *args) + continue; + break; + + case '#': /* must be at least one digit */ + if (isdigit(*s++)) { + while (isdigit(*s)) { + ++s; + } + continue; + } + break; + + case 'C': /* coprocessor state register */ + if (strncmp(s, "%csr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'b': /* next operand is a coprocessor register */ + case 'c': + case 'D': + if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) { + mask = *s++; + if (isdigit(*s)) { + mask = 10 * (mask - '0') + (*s++ - '0'); + if (mask >= 32) { + break; + } + } else { + mask -= '0'; + } + switch (*args) { + + case 'b': + opcode |= mask << 14; + continue; + + case 'c': + opcode |= mask; + continue; + + case 'D': + opcode |= mask << 25; + continue; + } + } + break; + + case 'r': /* next operand must be a register */ + case '1': + case '2': + case 'd': + if (*s++ == '%') { + switch (c = *s++) { + + case 'f': /* frame pointer */ + if (*s++ == 'p') { + mask = 0x1e; + break; + } + goto error; + + case 'g': /* global register */ + if (isoctal(c = *s++)) { + mask = c - '0'; + break; + } + goto error; + + case 'i': /* in register */ + if (isoctal(c = *s++)) { + mask = c - '0' + 24; + break; + } + goto error; + + case 'l': /* local register */ + if (isoctal(c = *s++)) { + mask= (c - '0' + 16) ; + break; + } + goto error; + + case 'o': /* out register */ + if (isoctal(c = *s++)) { + mask= (c - '0' + 8) ; + break; + } + goto error; + + case 's': /* stack pointer */ + if (*s++ == 'p') { + mask= 0xe; + break; + } + goto error; + + case 'r': /* any register */ + if (!isdigit(c = *s++)) { + goto error; + } + /* FALLTHROUGH */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (isdigit(*s)) { + if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) { + goto error; + } + } else { + c -= '0'; + } + mask= c; + break; + + default: + goto error; + } + /* + * Got the register, now figure out where + * it goes in the opcode. + */ + switch (*args) { + + case '1': + opcode |= mask << 14; + continue; + + case '2': + opcode |= mask; + continue; + + case 'd': + opcode |= mask << 25; + continue; + + case 'r': + opcode |= (mask << 25) | (mask << 14); + continue; + } + } + break; + + /* start-sanitize-v9 */ #ifndef NO_V9 - case 'j': - case 'u': - case 'U': + case 'j': + case 'u': + case 'U': #endif /* NO_V9 */ - /* end-sanitize-v9 */ - case 'e': /* next operand is a floating point register */ - case 'v': - case 'V': - - case 'f': - case 'B': - case 'R': - - case 'g': - case 'H': - case 'J': { - char format; - - if (*s++ == '%' - - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + case 'e': /* next operand is a floating point register */ + case 'v': + case 'V': + + case 'f': + case 'B': + case 'R': + + case 'g': + case 'H': + case 'J': { + char format; + + if (*s++ == '%' + + /* start-sanitize-v9 */ #ifndef NO_V9 - && ((format = *s) == 'f' - || *s == 'd' - || *s == 'q') + && ((format = *s) == 'f' + || *s == 'd' + || *s == 'q') #else - /* end-sanitize-v9 */ - && ((format = *s) == 'f') - - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + && ((format = *s) == 'f') + + /* start-sanitize-v9 */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - && isdigit(*++s)) { - - - - for (mask = 0; isdigit(*s); ++s) { - mask = 10 * mask + (*s - '0'); - } /* read the number */ - - if ((*args == 'u' - || *args == 'v' - || *args == 'B' - || *args == 'H') - && (mask & 1)) { - break; - } /* register must be even numbered */ - - if ((*args == 'U' - || *args == 'V' - || *args == 'R' - || *args == 'J') - && (mask & 3)) { - break; - } /* register must be multiple of 4 */ - - if (format == 'f') { - if (mask >= 32) { - error_message = ": There are only 32 f registers; [0-31]"; - goto error; - } /* on error */ - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + && isdigit(*++s)) { + + + + for (mask = 0; isdigit(*s); ++s) { + mask = 10 * mask + (*s - '0'); + } /* read the number */ + + if ((*args == 'u' + || *args == 'v' + || *args == 'B' + || *args == 'H') + && (mask & 1)) { + break; + } /* register must be even numbered */ + + if ((*args == 'U' + || *args == 'V' + || *args == 'R' + || *args == 'J') + && (mask & 3)) { + break; + } /* register must be multiple of 4 */ + + if (format == 'f') { + if (mask >= 32) { + error_message = ": There are only 32 f registers; [0-31]"; + goto error; + } /* on error */ + /* start-sanitize-v9 */ #ifndef NO_V9 - } else { - if (format == 'd') { - if (mask >= 64) { - error_message = ": There are only 32 d registers [0, 2, ... 62]."; - goto error; - } else if (mask & 1) { - error_message = ": Only even numbered d registers exist."; - goto error; - } /* on error */ - - } else if (format == 'q') { - if (mask >= 64) { - error_message = - ": There are only 16 q registers [0, 4, ... 60]."; - goto error; - } else if (mask & 3) { - error_message = - ": Only q registers evenly divisible by four exist."; - goto error; - } /* on error */ - } else { - know(0); - } /* depending on format */ - - if (mask >= 32) { - mask -= 31; - } /* wrap high bit */ + } else { + if (format == 'd') { + if (mask >= 64) { + error_message = ": There are only 32 d registers [0, 2, ... 62]."; + goto error; + } else if (mask & 1) { + error_message = ": Only even numbered d registers exist."; + goto error; + } /* on error */ + + } else if (format == 'q') { + if (mask >= 64) { + error_message = + ": There are only 16 q registers [0, 4, ... 60]."; + goto error; + } else if (mask & 3) { + error_message = + ": Only q registers evenly divisible by four exist."; + goto error; + } /* on error */ + } else { + know(0); + } /* depending on format */ + + if (mask >= 32) { + mask -= 31; + } /* wrap high bit */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - } /* if not an 'f' register. */ - } /* on error */ - - switch (*args) { - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + } /* if not an 'f' register. */ + } /* on error */ + + switch (*args) { + /* start-sanitize-v9 */ #ifndef NO_V9 - case 'j': - case 'u': - case 'U': - opcode |= (mask & 0x1f) << 9; - continue; + case 'j': + case 'u': + case 'U': + opcode |= (mask & 0x1f) << 9; + continue; #endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case 'v': - case 'V': - case 'e': - opcode |= RS1(mask); - continue; - - - case 'f': - case 'B': - case 'R': - opcode |= RS2(mask); - continue; - - case 'g': - case 'H': - case 'J': - opcode |= RD(mask); - continue; - } /* pack it in. */ - - know(0); - break; - } /* float arg */ - - case 'F': - if (strncmp(s, "%fsr", 4) == 0) { - s += 4; - continue; - } - break; - - case 'h': /* high 22 bits */ - the_insn.reloc = RELOC_HI22; - goto immediate; - - case 'l': /* 22 bit PC relative immediate */ - the_insn.reloc = RELOC_WDISP22; - the_insn.pcrel = 1; - goto immediate; - - case 'L': /* 30 bit immediate */ - the_insn.reloc = RELOC_WDISP30; - the_insn.pcrel = 1; - goto immediate; - - case 'n': /* 22 bit immediate */ - the_insn.reloc = RELOC_22; - goto immediate; - - case 'i': /* 13 bit immediate */ - the_insn.reloc = RELOC_BASE13; - - /*FALLTHROUGH */ - - immediate: - if(*s==' ') - s++; - if (*s == '%') { - if ((c = s[1]) == 'h' && s[2] == 'i') { - the_insn.reloc = RELOC_HI22; - s+=3; - } else if (c == 'l' && s[2] == 'o') { - the_insn.reloc = RELOC_LO10; - s+=3; - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + + case 'v': + case 'V': + case 'e': + opcode |= RS1(mask); + continue; + + + case 'f': + case 'B': + case 'R': + opcode |= RS2(mask); + continue; + + case 'g': + case 'H': + case 'J': + opcode |= RD(mask); + continue; + } /* pack it in. */ + + know(0); + break; + } /* float arg */ + + case 'F': + if (strncmp(s, "%fsr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'h': /* high 22 bits */ + the_insn.reloc = RELOC_HI22; + goto immediate; + + case 'l': /* 22 bit PC relative immediate */ + the_insn.reloc = RELOC_WDISP22; + the_insn.pcrel = 1; + goto immediate; + + case 'L': /* 30 bit immediate */ + the_insn.reloc = RELOC_WDISP30; + the_insn.pcrel = 1; + goto immediate; + + case 'n': /* 22 bit immediate */ + the_insn.reloc = RELOC_22; + goto immediate; + + case 'i': /* 13 bit immediate */ + the_insn.reloc = RELOC_BASE13; + + /*FALLTHROUGH */ + + immediate: + if(*s==' ') + s++; + if (*s == '%') { + if ((c = s[1]) == 'h' && s[2] == 'i') { + the_insn.reloc = RELOC_HI22; + s+=3; + } else if (c == 'l' && s[2] == 'o') { + the_insn.reloc = RELOC_LO10; + s+=3; + /* start-sanitize-v9 */ #ifndef NO_V9 - } else if (c == 'h' - && s[2] == 'h' - && s[3] == 'i') { - the_insn.reloc = RELOC_HHI22; - s += 4; - - } else if (c == 'h' - && s[2] == 'l' - && s[3] == 'o') { - the_insn.reloc = RELOC_HLO10; - s += 4; + } else if (c == 'h' + && s[2] == 'h' + && s[3] == 'i') { + the_insn.reloc = RELOC_HHI22; + s += 4; + + } else if (c == 'h' + && s[2] == 'l' + && s[3] == 'o') { + the_insn.reloc = RELOC_HLO10; + s += 4; #endif /* NO_V9 */ - /* end-sanitize-v9 */ - } else - break; - } - /* Note that if the getExpression() fails, we - will still have created U entries in the - symbol table for the 'symbols' in the input - string. Try not to create U symbols for - registers, etc. */ - { - /* This stuff checks to see if the - expression ends in +%reg If it does, - it removes the register from the - expression, and re-sets 's' to point - to the right place */ - - char *s1; - - for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;; - - if (s1 != s && isdigit(s1[-1])) { - if(s1[-2] == '%' && s1[-3] == '+') { - s1 -= 3; - *s1 = '\0'; - (void) getExpression(s); - *s1 = '+'; - s = s1; - continue; - } else if (strchr("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') { - s1 -= 4; - *s1 = '\0'; - (void) getExpression(s); - *s1 = '+'; - s = s1; - continue; - } - } - } - (void)getExpression(s); - s = expr_end; - continue; - - case 'a': - if (*s++ == 'a') { - opcode |= ANNUL; - continue; - } - break; - - case 'A': { - char *push = input_line_pointer; - expressionS e; - - input_line_pointer = s; - - if (expression(&e) == SEG_ABSOLUTE) { - opcode |= e.X_add_number << 5; - s = input_line_pointer; - input_line_pointer = push; - continue; - } /* if absolute */ - - break; - } /* alternate space */ - - case 'p': - if (strncmp(s, "%psr", 4) == 0) { - s += 4; - continue; - } - break; - - case 'q': /* floating point queue */ - if (strncmp(s, "%fq", 3) == 0) { - s += 3; - continue; - } - break; - - case 'Q': /* coprocessor queue */ - if (strncmp(s, "%cq", 3) == 0) { - s += 3; - continue; - } - break; - - case 'S': - if (strcmp(str, "set") == 0) { - special_case = SPECIAL_CASE_SET; - continue; - } else if (strncmp(str, "fdiv", 4) == 0) { - special_case = SPECIAL_CASE_FDIV; - continue; - } - break; - - case 't': - if (strncmp(s, "%tbr", 4) != 0) - break; - s += 4; - continue; - - case 'w': - if (strncmp(s, "%wim", 4) != 0) - break; - s += 4; - continue; - - case 'y': - if (strncmp(s, "%y", 2) != 0) - break; - s += 2; - continue; - - default: - as_fatal("failed sanity check."); - } /* switch on arg code */ + /* end-sanitize-v9 */ + } else break; - } /* for each arg that we expect */ - error: - if (match == 0) { - /* Args don't match. */ - if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES - && !strcmp(insn->name, insn[1].name)) { - ++insn; - s = argsStart; - continue; - } else { - as_bad("Illegal operands%s", error_message); - return; - } - } else { - if (insn->architecture > current_architecture) { - if (current_architecture != cypress - && (!architecture_requested || warn_on_bump)) { - - if (warn_on_bump) { - as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"", - architecture_pname[current_architecture], - architecture_pname[insn->architecture], - str); - } /* if warning */ - - current_architecture = insn->architecture; - } else { - as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"", - str, - architecture_pname[insn->architecture], - architecture_pname[current_architecture]); - return; - } /* if bump ok else error */ - } /* if architecture higher */ - } /* if no match */ - + } + /* Note that if the getExpression() fails, we + will still have created U entries in the + symbol table for the 'symbols' in the input + string. Try not to create U symbols for + registers, etc. */ + { + /* This stuff checks to see if the + expression ends in +%reg If it does, + it removes the register from the + expression, and re-sets 's' to point + to the right place */ + + char *s1; + + for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;; + + if (s1 != s && isdigit(s1[-1])) { + if(s1[-2] == '%' && s1[-3] == '+') { + s1 -= 3; + *s1 = '\0'; + (void) getExpression(s); + *s1 = '+'; + s = s1; + continue; + } else if (strchr("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') { + s1 -= 4; + *s1 = '\0'; + (void) getExpression(s); + *s1 = '+'; + s = s1; + continue; + } + } + } + (void)getExpression(s); + s = expr_end; + continue; + + case 'a': + if (*s++ == 'a') { + opcode |= ANNUL; + continue; + } break; - } /* forever looking for a match */ - - the_insn.opcode = opcode; - return; + + case 'A': { + char *push = input_line_pointer; + expressionS e; + + input_line_pointer = s; + + if (expression(&e) == SEG_ABSOLUTE) { + opcode |= e.X_add_number << 5; + s = input_line_pointer; + input_line_pointer = push; + continue; + } /* if absolute */ + + break; + } /* alternate space */ + + case 'p': + if (strncmp(s, "%psr", 4) == 0) { + s += 4; + continue; + } + break; + + case 'q': /* floating point queue */ + if (strncmp(s, "%fq", 3) == 0) { + s += 3; + continue; + } + break; + + case 'Q': /* coprocessor queue */ + if (strncmp(s, "%cq", 3) == 0) { + s += 3; + continue; + } + break; + + case 'S': + if (strcmp(str, "set") == 0) { + special_case = SPECIAL_CASE_SET; + continue; + } else if (strncmp(str, "fdiv", 4) == 0) { + special_case = SPECIAL_CASE_FDIV; + continue; + } + break; + + case 't': + if (strncmp(s, "%tbr", 4) != 0) + break; + s += 4; + continue; + + case 'w': + if (strncmp(s, "%wim", 4) != 0) + break; + s += 4; + continue; + + case 'y': + if (strncmp(s, "%y", 2) != 0) + break; + s += 2; + continue; + + default: + as_fatal("failed sanity check."); + } /* switch on arg code */ + break; + } /* for each arg that we expect */ + error: + if (match == 0) { + /* Args don't match. */ + if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES + && !strcmp(insn->name, insn[1].name)) { + ++insn; + s = argsStart; + continue; + } else { + as_bad("Illegal operands%s", error_message); + return; + } + } else { + if (insn->architecture > current_architecture) { + if (!architecture_requested || warn_on_bump) { + + if (warn_on_bump) { + as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"", + architecture_pname[current_architecture], + architecture_pname[insn->architecture], + str); + } /* if warning */ + + current_architecture = insn->architecture; + } else { + as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"", + str, + architecture_pname[insn->architecture], + architecture_pname[current_architecture]); + return; + } /* if bump ok else error */ + } /* if architecture higher */ + } /* if no match */ + + break; + } /* forever looking for a match */ + + the_insn.opcode = opcode; + return; } /* sparc_ip() */ static int getExpression(str) -char *str; + char *str; { - char *save_in; - segT seg; + char *save_in; + segT seg; + + save_in = input_line_pointer; + input_line_pointer = str; + switch (seg = expression(&the_insn.exp)) { - save_in = input_line_pointer; - input_line_pointer = str; - switch (seg = expression(&the_insn.exp)) { - - case SEG_ABSOLUTE: - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_ABSENT: - break; - - default: - the_insn.error = "bad segment"; - expr_end = input_line_pointer; - input_line_pointer=save_in; - return 1; - } + case SEG_ABSOLUTE: + case SEG_TEXT: + case SEG_DATA: + case SEG_BSS: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + case SEG_BIG: + case SEG_ABSENT: + break; + + default: + the_insn.error = "bad segment"; expr_end = input_line_pointer; - input_line_pointer = save_in; - return 0; + input_line_pointer=save_in; + return 1; + } + expr_end = input_line_pointer; + input_line_pointer = save_in; + return 0; } /* getExpression() */ @@ -1227,259 +1227,259 @@ char *str; #define MAX_LITTLENUMS 6 char *md_atof(type,litP,sizeP) -char type; -char *litP; -int *sizeP; + char type; + char *litP; + int *sizeP; { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee(); + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee(); + + switch(type) { - switch(type) { - - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP=0; - return "Bad call to MD_ATOF()"; - } - t=atof_ieee(input_line_pointer,type,words); - if(t) - input_line_pointer=t; - *sizeP=prec * sizeof(LITTLENUM_TYPE); - for(wordP=words;prec--;) { - md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); - litP+=sizeof(LITTLENUM_TYPE); - } - return ""; /* Someone should teach Dean about null pointers */ + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words;prec--;) { + md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ } /* md_atof() */ /* * Write out big-endian. */ void md_number_to_chars(buf,val,n) -char *buf; -long val; -int n; + char *buf; + long val; + int n; { + + switch(n) { - switch(n) { - - case 4: - *buf++ = val >> 24; - *buf++ = val >> 16; - case 2: - *buf++ = val >> 8; - case 1: - *buf = val; - break; - - default: - as_fatal("failed sanity check."); - } - return; + case 4: + *buf++ = val >> 24; + *buf++ = val >> 16; + case 2: + *buf++ = val >> 8; + case 1: + *buf = val; + break; + + default: + as_fatal("failed sanity check."); + } + return; } /* md_number_to_chars() */ /* Apply a fixS to the frags, now that we know the value it ought to hold. */ void md_apply_fix(fixP, val) -fixS *fixP; -long val; + fixS *fixP; + long val; { - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - - assert(fixP->fx_size == 4); - assert(fixP->fx_r_type < NO_RELOC); - - fixP->fx_addnumber = val; /* Remember value for emit_reloc */ + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + assert(fixP->fx_size == 4); + assert(fixP->fx_r_type < NO_RELOC); + + fixP->fx_addnumber = val; /* Remember value for emit_reloc */ + + /* + * This is a hack. There should be a better way to + * handle this. + */ + if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) { + val += fixP->fx_where + fixP->fx_frag->fr_address; + } + + switch (fixP->fx_r_type) { - /* - * This is a hack. There should be a better way to - * handle this. - */ - if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) { - val += fixP->fx_where + fixP->fx_frag->fr_address; - } + case RELOC_32: + buf[0] = 0; /* val >> 24; */ + buf[1] = 0; /* val >> 16; */ + buf[2] = 0; /* val >> 8; */ + buf[3] = 0; /* val; */ + break; - switch (fixP->fx_r_type) { - - case RELOC_32: - buf[0] = 0; /* val >> 24; */ - buf[1] = 0; /* val >> 16; */ - buf[2] = 0; /* val >> 8; */ - buf[3] = 0; /* val; */ - break; - #if 0 - case RELOC_8: /* These don't seem to ever be needed. */ - case RELOC_16: - case RELOC_DISP8: - case RELOC_DISP16: - case RELOC_DISP32: + case RELOC_8: /* These don't seem to ever be needed. */ + case RELOC_16: + case RELOC_DISP8: + case RELOC_DISP16: + case RELOC_DISP32: #endif - case RELOC_WDISP30: - val = (val >>= 2) + 1; - buf[0] |= (val >> 24) & 0x3f; - buf[1]= (val >> 16); - buf[2] = val >> 8; - buf[3] = val; - break; - - /* start-sanitize-v9 */ + case RELOC_WDISP30: + val = (val >>= 2) + 1; + buf[0] |= (val >> 24) & 0x3f; + buf[1]= (val >> 16); + buf[2] = val >> 8; + buf[3] = val; + break; + + /* start-sanitize-v9 */ #ifndef NO_V9 - case RELOC_11: - if (((val > 0) && (val & ~0x7ff)) - || ((val < 0) && (~(val - 1) & ~0x7ff))) { - as_bad("relocation overflow."); - } /* on overflow */ - - buf[2] = (val >> 8) & 0x7; - buf[3] = val & 0xff; - break; - - case RELOC_WDISP2_14: - if (((val > 0) && (val & ~0x3fffc)) - || ((val < 0) && (~(val - 1) & ~0x3fffc))) { - as_bad("relocation overflow."); - } /* on overflow */ - - val = (val >>= 2) + 1; - buf[1] |= ((val >> 14) & 0x3) << 3; - buf[2] |= (val >> 8) & 0x3f ; - buf[3] = val & 0xff; - break; - - case RELOC_WDISP19: - if (((val > 0) && (val & ~0x1ffffc)) - || ((val < 0) && (~(val - 1) & ~0x1ffffc))) { - as_bad("relocation overflow."); - } /* on overflow */ - - val = (val >>= 2) + 1; - buf[1] |= (val >> 16) & 0x7; - buf[2] = (val >> 8) & 0xff; - buf[3] = val & 0xff; - break; - - case RELOC_HHI22: - val >>= 32; - /* intentional fallthrough */ + case RELOC_11: + if (((val > 0) && (val & ~0x7ff)) + || ((val < 0) && (~(val - 1) & ~0x7ff))) { + as_bad("relocation overflow."); + } /* on overflow */ + + buf[2] = (val >> 8) & 0x7; + buf[3] = val & 0xff; + break; + + case RELOC_WDISP2_14: + if (((val > 0) && (val & ~0x3fffc)) + || ((val < 0) && (~(val - 1) & ~0x3fffc))) { + as_bad("relocation overflow."); + } /* on overflow */ + + val = (val >>= 2) + 1; + buf[1] |= ((val >> 14) & 0x3) << 3; + buf[2] |= (val >> 8) & 0x3f ; + buf[3] = val & 0xff; + break; + + case RELOC_WDISP19: + if (((val > 0) && (val & ~0x1ffffc)) + || ((val < 0) && (~(val - 1) & ~0x1ffffc))) { + as_bad("relocation overflow."); + } /* on overflow */ + + val = (val >>= 2) + 1; + buf[1] |= (val >> 16) & 0x7; + buf[2] = (val >> 8) & 0xff; + buf[3] = val & 0xff; + break; + + case RELOC_HHI22: + val >>= 32; + /* intentional fallthrough */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case RELOC_HI22: - if(!fixP->fx_addsy) { - buf[1] |= (val >> 26) & 0x3f; - buf[2] = val >> 18; - buf[3] = val >> 10; - } else { - buf[2]=0; - buf[3]=0; - } - break; - - case RELOC_22: - if (val & ~0x003fffff) { - as_bad("relocation overflow"); - } /* on overflow */ - buf[1] |= (val >> 16) & 0x3f; - buf[2] = val >> 8; - buf[3] = val & 0xff; - break; - - case RELOC_13: - if (val & ~0x00001fff) { - as_bad("relocation overflow"); - } /* on overflow */ - buf[2] = (val >> 8) & 0x1f; - buf[3] = val & 0xff; - break; - - /* start-sanitize-v9 */ + /* end-sanitize-v9 */ + + case RELOC_HI22: + if(!fixP->fx_addsy) { + buf[1] |= (val >> 26) & 0x3f; + buf[2] = val >> 18; + buf[3] = val >> 10; + } else { + buf[2]=0; + buf[3]=0; + } + break; + + case RELOC_22: + if (val & ~0x003fffff) { + as_bad("relocation overflow"); + } /* on overflow */ + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val & 0xff; + break; + + case RELOC_13: + if (val & ~0x00001fff) { + as_bad("relocation overflow"); + } /* on overflow */ + buf[2] = (val >> 8) & 0x1f; + buf[3] = val & 0xff; + break; + + /* start-sanitize-v9 */ #ifndef NO_V9 - case RELOC_HLO10: - val >>= 32; - /* intentional fallthrough */ + case RELOC_HLO10: + val >>= 32; + /* intentional fallthrough */ #endif /* NO_V9 */ - /* end-sanitize-v9 */ - - case RELOC_LO10: - if(!fixP->fx_addsy) { - buf[2] |= (val >> 8) & 0x03; - buf[3] = val; - } else - buf[3]=0; - break; + /* end-sanitize-v9 */ + + case RELOC_LO10: + if(!fixP->fx_addsy) { + buf[2] |= (val >> 8) & 0x03; + buf[3] = val; + } else + buf[3]=0; + break; #if 0 - case RELOC_SFA_BASE: - case RELOC_SFA_OFF13: - case RELOC_BASE10: + case RELOC_SFA_BASE: + case RELOC_SFA_OFF13: + case RELOC_BASE10: #endif - case RELOC_BASE13: - buf[2] |= (val >> 8) & 0x1f; - buf[3] = val; - break; - - case RELOC_WDISP22: - val = (val >>= 2) + 1; - /* FALLTHROUGH */ - case RELOC_BASE22: - buf[1] |= (val >> 16) & 0x3f; - buf[2] = val >> 8; - buf[3] = val; - break; - + case RELOC_BASE13: + buf[2] |= (val >> 8) & 0x1f; + buf[3] = val; + break; + + case RELOC_WDISP22: + val = (val >>= 2) + 1; + /* FALLTHROUGH */ + case RELOC_BASE22: + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val; + break; + #if 0 - case RELOC_PC10: - case RELOC_PC22: - case RELOC_JMP_TBL: - case RELOC_SEGOFF16: - case RELOC_GLOB_DAT: - case RELOC_JMP_SLOT: - case RELOC_RELATIVE: + case RELOC_PC10: + case RELOC_PC22: + case RELOC_JMP_TBL: + case RELOC_SEGOFF16: + case RELOC_GLOB_DAT: + case RELOC_JMP_SLOT: + case RELOC_RELATIVE: #endif - - case NO_RELOC: - default: - as_bad("bad relocation type: 0x%02x", fixP->fx_r_type); - break; - } + + case NO_RELOC: + default: + as_bad("bad relocation type: 0x%02x", fixP->fx_r_type); + break; + } } /* md_apply_fix() */ /* should never be called for sparc */ void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) -char *ptr; -long from_addr; -long to_addr; -fragS *frag; -symbolS *to_symbol; + char *ptr; + long from_addr; + long to_addr; + fragS *frag; + symbolS *to_symbol; { - as_fatal("sparc_create_short_jmp\n"); + as_fatal("sparc_create_short_jmp\n"); } /* md_create_short_jump() */ /* Translate internal representation of relocation info to target format. @@ -1490,142 +1490,142 @@ symbolS *to_symbol; five bits as relocation type. Next 4 bytes are long addend. */ /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */ void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) -char *where; -fixS *fixP; -relax_addressT segment_address_in_file; + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; { - long r_index; - long r_extern; - long r_addend; - long r_address; - - know(fixP->fx_addsy); - - if ((S_GET_TYPE(fixP->fx_addsy)) == N_UNDF) { - r_extern = 1; - r_index = fixP->fx_addsy->sy_number; - } else { - r_extern = 0; - r_index = S_GET_TYPE(fixP->fx_addsy); - } - - /* this is easy */ - md_number_to_chars(where, - r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); - - /* now the fun stuff */ - where[4] = (r_index >> 16) & 0x0ff; - where[5] = (r_index >> 8) & 0x0ff; - where[6] = r_index & 0x0ff; - where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); - - /* Also easy */ - if (fixP->fx_addsy->sy_frag) { - r_addend = fixP->fx_addsy->sy_frag->fr_address; - } - - if (fixP->fx_pcrel) { - r_addend -= r_address; - } else { - r_addend = fixP->fx_addnumber; - } - - md_number_to_chars(&where[8], r_addend, 4); - - return; + long r_index; + long r_extern; + long r_addend; + long r_address; + + know(fixP->fx_addsy); + + if ((S_GET_TYPE(fixP->fx_addsy)) == N_UNDF) { + r_extern = 1; + r_index = fixP->fx_addsy->sy_number; + } else { + r_extern = 0; + r_index = S_GET_TYPE(fixP->fx_addsy); + } + + /* this is easy */ + md_number_to_chars(where, + r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + /* now the fun stuff */ + where[4] = (r_index >> 16) & 0x0ff; + where[5] = (r_index >> 8) & 0x0ff; + where[6] = r_index & 0x0ff; + where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); + + /* Also easy */ + if (fixP->fx_addsy->sy_frag) { + r_addend = fixP->fx_addsy->sy_frag->fr_address; + } + + if (fixP->fx_pcrel) { + r_addend -= r_address; + } else { + r_addend = fixP->fx_addnumber; + } + + md_number_to_chars(&where[8], r_addend, 4); + + return; } /* tc_aout_fix_to_chars() */ /* should never be called for sparc */ void md_convert_frag(headers, fragP) -object_headers *headers; -register fragS *fragP; + object_headers *headers; + register fragS *fragP; { - as_fatal("sparc_convert_frag\n"); + as_fatal("sparc_convert_frag\n"); } /* md_convert_frag() */ /* should never be called for sparc */ void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol) -char *ptr; -long from_addr, to_addr; -fragS *frag; -symbolS *to_symbol; + char *ptr; + long from_addr, to_addr; + fragS *frag; + symbolS *to_symbol; { - as_fatal("sparc_create_long_jump\n"); + as_fatal("sparc_create_long_jump\n"); } /* md_create_long_jump() */ /* should never be called for sparc */ int md_estimate_size_before_relax(fragP, segtype) -fragS *fragP; -segT segtype; + fragS *fragP; + segT segtype; { - as_fatal("sparc_estimate_size_before_relax\n"); - return(1); + as_fatal("sparc_estimate_size_before_relax\n"); + return(1); } /* md_estimate_size_before_relax() */ #if 0 /* for debugging only */ static void print_insn(insn) -struct sparc_it *insn; + struct sparc_it *insn; { - char *Reloc[] = { - "RELOC_8", - "RELOC_16", - "RELOC_32", - "RELOC_DISP8", - "RELOC_DISP16", - "RELOC_DISP32", - "RELOC_WDISP30", - "RELOC_WDISP22", - "RELOC_HI22", - "RELOC_22", - "RELOC_13", - "RELOC_LO10", - "RELOC_SFA_BASE", - "RELOC_SFA_OFF13", - "RELOC_BASE10", - "RELOC_BASE13", - "RELOC_BASE22", - "RELOC_PC10", - "RELOC_PC22", - "RELOC_JMP_TBL", - "RELOC_SEGOFF16", - "RELOC_GLOB_DAT", - "RELOC_JMP_SLOT", - "RELOC_RELATIVE", - "NO_RELOC" - }; - - if (insn->error) { - fprintf(stderr, "ERROR: %s\n"); - } - fprintf(stderr, "opcode=0x%08x\n", insn->opcode); - fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]); - fprintf(stderr, "exp = { + char *Reloc[] = { + "RELOC_8", + "RELOC_16", + "RELOC_32", + "RELOC_DISP8", + "RELOC_DISP16", + "RELOC_DISP32", + "RELOC_WDISP30", + "RELOC_WDISP22", + "RELOC_HI22", + "RELOC_22", + "RELOC_13", + "RELOC_LO10", + "RELOC_SFA_BASE", + "RELOC_SFA_OFF13", + "RELOC_BASE10", + "RELOC_BASE13", + "RELOC_BASE22", + "RELOC_PC10", + "RELOC_PC22", + "RELOC_JMP_TBL", + "RELOC_SEGOFF16", + "RELOC_GLOB_DAT", + "RELOC_JMP_SLOT", + "RELOC_RELATIVE", + "NO_RELOC" + }; + + if (insn->error) { + fprintf(stderr, "ERROR: %s\n"); + } + fprintf(stderr, "opcode=0x%08x\n", insn->opcode); + fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]); + fprintf(stderr, "exp = { \n"); - fprintf(stderr, "\t\tX_add_symbol = %s\n", - ((insn->exp.X_add_symbol != NULL) - ? ((S_GET_NAME(insn->exp.X_add_symbol) != NULL) - ? S_GET_NAME(insn->exp.X_add_symbol) - : "???") - : "0")); - fprintf(stderr, "\t\tX_sub_symbol = %s\n", - ((insn->exp.X_subtract_symbol != NULL) - ? (S_GET_NAME(insn->exp.X_subtract_symbol) - ? S_GET_NAME(insn->exp.X_subtract_symbol) - : "???") - : "0")); - fprintf(stderr, "\t\tX_add_number = %d\n", - insn->exp.X_add_number); - fprintf(stderr, "}\n"); - return; + fprintf(stderr, "\t\tX_add_symbol = %s\n", + ((insn->exp.X_add_symbol != NULL) + ? ((S_GET_NAME(insn->exp.X_add_symbol) != NULL) + ? S_GET_NAME(insn->exp.X_add_symbol) + : "???") + : "0")); + fprintf(stderr, "\t\tX_sub_symbol = %s\n", + ((insn->exp.X_subtract_symbol != NULL) + ? (S_GET_NAME(insn->exp.X_subtract_symbol) + ? S_GET_NAME(insn->exp.X_subtract_symbol) + : "???") + : "0")); + fprintf(stderr, "\t\tX_add_number = %d\n", + insn->exp.X_add_number); + fprintf(stderr, "}\n"); + return; } /* print_insn() */ #endif /* Set the hook... */ /* void emit_sparc_reloc(); -void (*md_emit_relocations)() = emit_sparc_reloc; */ + void (*md_emit_relocations)() = emit_sparc_reloc; */ #ifdef comment @@ -1635,47 +1635,47 @@ void (*md_emit_relocations)() = emit_sparc_reloc; */ */ #if defined(OBJ_AOUT) || defined(OBJ_BOUT) void emit_sparc_reloc(fixP, segment_address_in_file) -register fixS *fixP; -relax_addressT segment_address_in_file; + register fixS *fixP; + relax_addressT segment_address_in_file; { - struct reloc_info_generic ri; - register symbolS *symbolP; - extern char *next_object_file_charP; - /* long add_number; */ + struct reloc_info_generic ri; + register symbolS *symbolP; + extern char *next_object_file_charP; + /* long add_number; */ + + bzero((char *) &ri, sizeof(ri)); + for (; fixP; fixP = fixP->fx_next) { - bzero((char *) &ri, sizeof(ri)); - for (; fixP; fixP = fixP->fx_next) { - - if (fixP->fx_r_type >= NO_RELOC) { - as_fatal("fixP->fx_r_type = %d\n", fixP->fx_r_type); - } - - if ((symbolP = fixP->fx_addsy) != NULL) { - ri.r_address = fixP->fx_frag->fr_address + - fixP->fx_where - segment_address_in_file; - if ((S_GET_TYPE(symbolP)) == N_UNDF) { - ri.r_extern = 1; - ri.r_index = symbolP->sy_number; - } else { - ri.r_extern = 0; - ri.r_index = S_GET_TYPE(symbolP); - } - if (symbolP && symbolP->sy_frag) { - ri.r_addend = symbolP->sy_frag->fr_address; - } - ri.r_type = fixP->fx_r_type; - if (fixP->fx_pcrel) { - /* ri.r_addend -= fixP->fx_where; */ - ri.r_addend -= ri.r_address; - } else { - ri.r_addend = fixP->fx_addnumber; - } - - md_ri_to_chars(next_object_file_charP, &ri); - next_object_file_charP += md_reloc_size; - } + if (fixP->fx_r_type >= NO_RELOC) { + as_fatal("fixP->fx_r_type = %d\n", fixP->fx_r_type); } - return; + + if ((symbolP = fixP->fx_addsy) != NULL) { + ri.r_address = fixP->fx_frag->fr_address + + fixP->fx_where - segment_address_in_file; + if ((S_GET_TYPE(symbolP)) == N_UNDF) { + ri.r_extern = 1; + ri.r_index = symbolP->sy_number; + } else { + ri.r_extern = 0; + ri.r_index = S_GET_TYPE(symbolP); + } + if (symbolP && symbolP->sy_frag) { + ri.r_addend = symbolP->sy_frag->fr_address; + } + ri.r_type = fixP->fx_r_type; + if (fixP->fx_pcrel) { + /* ri.r_addend -= fixP->fx_where; */ + ri.r_addend -= ri.r_address; + } else { + ri.r_addend = fixP->fx_addnumber; + } + + md_ri_to_chars(next_object_file_charP, &ri); + next_object_file_charP += md_reloc_size; + } + } + return; } /* emit_sparc_reloc() */ #endif /* aout or bout */ #endif /* comment */ @@ -1688,7 +1688,7 @@ relax_addressT segment_address_in_file; * -bump * Warn on architecture bumps. See also -A. * - * -Av6, -Av7, -Acypress, -Av8 + * -Av6, -Av7, -Av8 * Select the architecture. Instructions or features not * supported by the selected architecture cause fatal errors. * @@ -1706,57 +1706,52 @@ relax_addressT segment_address_in_file; * architecture starts at the specified level, but bumps are * warnings. * - * Note that where cypress specific instructions conflict with - * other instructions, the other instruction is assumed. Nothing - * is upward compatible with cypress. Thus, to get the cypress - * instruction set you MUST -Acypress. - * */ - /* start-sanitize-v9 */ - /* There is also a -Av9 architecture option. xoxorich. */ - /* end-sanitize-v9 */ +/* start-sanitize-v9 */ +/* There is also a -Av9 architecture option. xoxorich. */ +/* end-sanitize-v9 */ int md_parse_option(argP, cntP, vecP) -char **argP; -int *cntP; -char ***vecP; + char **argP; + int *cntP; + char ***vecP; { - char *p; - const char **arch; + char *p; + const char **arch; + + if (!strcmp(*argP,"bump")){ + warn_on_bump = 1; - if (!strcmp(*argP,"bump")){ - warn_on_bump = 1; - - } else if (**argP == 'A'){ - p = (*argP) + 1; - - for (arch = architecture_pname; *arch != NULL; ++arch){ - if (strcmp(p, *arch) == 0){ - break; - } /* found a match */ - } /* walk the pname table */ - - if (*arch == NULL){ - as_bad("unknown architecture: %s", p); - } else { - current_architecture = (enum sparc_architecture) (arch - architecture_pname); - architecture_requested = 1; - } + } else if (**argP == 'A'){ + p = (*argP) + 1; + + for (arch = architecture_pname; *arch != NULL; ++arch){ + if (strcmp(p, *arch) == 0){ + break; + } /* found a match */ + } /* walk the pname table */ + + if (*arch == NULL){ + as_bad("unknown architecture: %s", p); } else { - /* Unknown option */ - (*argP)++; - return 0; + current_architecture = (enum sparc_architecture) (arch - architecture_pname); + architecture_requested = 1; } - **argP = '\0'; /* Done parsing this switch */ - return 1; + } else { + /* Unknown option */ + (*argP)++; + return 0; + } + **argP = '\0'; /* Done parsing this switch */ + return 1; } /* md_parse_option() */ /* We have no need to default values of symbols. */ /* ARGSUSED */ symbolS *md_undefined_symbol(name) -char *name; + char *name; { - return 0; + return 0; } /* md_undefined_symbol() */ /* Parse an operand that is machine-specific. @@ -1765,16 +1760,16 @@ char *name; /* ARGSUSED */ void md_operand(expressionP) -expressionS *expressionP; + expressionS *expressionP; { } /* md_operand() */ /* Round up a section size to the appropriate boundary. */ long md_section_align (segment, size) -segT segment; -long size; + segT segment; + long size; { - return (size + 7) & ~7; /* Round all sects to multiple of 8 */ + return (size + 7) & ~7; /* Round all sects to multiple of 8 */ } /* md_section_align() */ /* Exactly what point is a PC-relative offset relative TO? @@ -1782,16 +1777,16 @@ long size; its size. This gets us to the following instruction. (??? Is this right? FIXME-SOON) */ long md_pcrel_from(fixP) -fixS *fixP; + fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } /* md_pcrel_from() */ void tc_aout_pre_write_hook(headers) -object_headers *headers; + object_headers *headers; { - H_SET_VERSION(headers, 1); - return; + H_SET_VERSION(headers, 1); + return; } /* tc_aout_pre_write_hook() */ /* diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h index dd19fdb..9afc7b8 100644 --- a/gas/config/tc-sparc.h +++ b/gas/config/tc-sparc.h @@ -1,26 +1,28 @@ /* tc-sparc.h - Macros and type defines for the sparc. Copyright (C) 1989, 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. */ + + 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. */ /* $Id$ */ #define TC_SPARC 1 +#define LOCAL_LABELS_FB + #ifdef OBJ_BOUT #define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE ((0x103 << 16) | BMAGIC) /* Magic number for header */ #else @@ -29,14 +31,17 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif /* OBJ_AOUT */ #endif /* OBJ_BOUT */ +#define AOUT_MACHTYPE 3 + #define tc_headers_hook(a) ; /* don't need it. */ #define tc_crawl_symbol_chain(a) ; /* don't need it. */ - -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ - -/* end of tp-sparc.h */ + +#define LISTING_HEADER "SPARC GAS " + /* + * Local Variables: + * comment-column: 0 + * fill-column: 131 + * End: + */ + + /* end of tp-sparc.h */ diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index 11095c6..ceb6d9c 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -1,21 +1,21 @@ /* vax.c - vax-specific - Copyright (C) 1987, 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. */ + + 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. */ /* $Id$ */ @@ -52,19 +52,19 @@ const char FLT_CHARS[] = "dDfFgGhH"; /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be changed in read.c . Ideally it shouldn't have to know about it at all, but nothing is ideal around here. - */ + */ static expressionS /* Hold details of an operand expression */ - exp_of_operand[VIT_MAX_OPERANDS]; + exp_of_operand[VIT_MAX_OPERANDS]; static struct vit - v; /* A vax instruction after decoding. */ + v; /* A vax instruction after decoding. */ LITTLENUM_TYPE big_operand_bits[VIT_MAX_OPERANDS][SIZE_OF_LARGE_NUMBER]; - /* Hold details of big operands. */ +/* Hold details of big operands. */ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; - /* Above is made to point into */ - /* big_operand_bits by md_begin(). */ +/* Above is made to point into */ +/* big_operand_bits by md_begin(). */ /* * For VAX, relative addresses of "just the right length" are easy. @@ -83,185 +83,185 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; * The "how long" refers merely to the displacement length. * The address usually has some constant bytes in it as well. * - -groups for VAX address relaxing. - -1. "foo" pc-relative. - length of byte, word, long - -2a. J<cond> where <cond> is a simple flag test. - length of byte, word, long. - VAX opcodes are: (Hex) - bneq/bnequ 12 - beql/beqlu 13 - bgtr 14 - bleq 15 - bgeq 18 - blss 19 - bgtru 1a - blequ 1b - bvc 1c - bvs 1d - bgequ/bcc 1e - blssu/bcs 1f - Always, you complement 0th bit to reverse condition. - Always, 1-byte opcode, then 1-byte displacement. - -2b. J<cond> where cond tests a memory bit. - length of byte, word, long. - Vax opcodes are: (Hex) - bbs e0 - bbc e1 - bbss e2 - bbcs e3 - bbsc e4 - bbcc e5 - bbssi e6 - bbcci e7 - Always, you complement 0th bit to reverse condition. - Always, 1-byte opcde, longword-address, byte-address, 1-byte-displacement - -2c. J<cond> where cond tests low-order memory bit - length of byte,word,long. - Vax opcodes are: (Hex) - blbs e8 - blbc e9 - Always, you complement 0th bit to reverse condition. - Always, 1-byte opcode, longword-address, 1-byte displacement. - -3. Jbs/Jbr. - length of byte,word,long. - Vax opcodes are: (Hex) - bsbb 10 - brb 11 - These are like (2) but there is no condition to reverse. - Always, 1 byte opcode, then displacement/absolute. - -4a. JacbX - length of word, long. - Vax opcodes are: (Hex) - acbw 3d - acbf 4f - acbd 6f - abcb 9d - acbl f1 - acbg 4ffd - acbh 6ffd - Always, we cannot reverse the sense of the branch; we have a word - displacement. - The double-byte op-codes don't hurt: we never want to modify the - opcode, so we don't care how many bytes are between the opcode and - the operand. - -4b. JXobXXX - length of long, long, byte. - Vax opcodes are: (Hex) - aoblss f2 - aobleq f3 - sobgeq f4 - sobgtr f5 - Always, we cannot reverse the sense of the branch; we have a byte - displacement. - -The only time we need to modify the opcode is for class 2 instructions. -After relax() we may complement the lowest order bit of such instruction -to reverse sense of branch. - -For class 2 instructions, we store context of "where is the opcode literal". -We can change an opcode's lowest order bit without breaking anything else. - -We sometimes store context in the operand literal. This way we can figure out -after relax() what the original addressing mode was. -*/ + + groups for VAX address relaxing. + + 1. "foo" pc-relative. + length of byte, word, long + + 2a. J<cond> where <cond> is a simple flag test. + length of byte, word, long. + VAX opcodes are: (Hex) + bneq/bnequ 12 + beql/beqlu 13 + bgtr 14 + bleq 15 + bgeq 18 + blss 19 + bgtru 1a + blequ 1b + bvc 1c + bvs 1d + bgequ/bcc 1e + blssu/bcs 1f + Always, you complement 0th bit to reverse condition. + Always, 1-byte opcode, then 1-byte displacement. + + 2b. J<cond> where cond tests a memory bit. + length of byte, word, long. + Vax opcodes are: (Hex) + bbs e0 + bbc e1 + bbss e2 + bbcs e3 + bbsc e4 + bbcc e5 + bbssi e6 + bbcci e7 + Always, you complement 0th bit to reverse condition. + Always, 1-byte opcde, longword-address, byte-address, 1-byte-displacement + + 2c. J<cond> where cond tests low-order memory bit + length of byte,word,long. + Vax opcodes are: (Hex) + blbs e8 + blbc e9 + Always, you complement 0th bit to reverse condition. + Always, 1-byte opcode, longword-address, 1-byte displacement. + + 3. Jbs/Jbr. + length of byte,word,long. + Vax opcodes are: (Hex) + bsbb 10 + brb 11 + These are like (2) but there is no condition to reverse. + Always, 1 byte opcode, then displacement/absolute. + + 4a. JacbX + length of word, long. + Vax opcodes are: (Hex) + acbw 3d + acbf 4f + acbd 6f + abcb 9d + acbl f1 + acbg 4ffd + acbh 6ffd + Always, we cannot reverse the sense of the branch; we have a word + displacement. + The double-byte op-codes don't hurt: we never want to modify the + opcode, so we don't care how many bytes are between the opcode and + the operand. + + 4b. JXobXXX + length of long, long, byte. + Vax opcodes are: (Hex) + aoblss f2 + aobleq f3 + sobgeq f4 + sobgtr f5 + Always, we cannot reverse the sense of the branch; we have a byte + displacement. + + The only time we need to modify the opcode is for class 2 instructions. + After relax() we may complement the lowest order bit of such instruction + to reverse sense of branch. + + For class 2 instructions, we store context of "where is the opcode literal". + We can change an opcode's lowest order bit without breaking anything else. + + We sometimes store context in the operand literal. This way we can figure out + after relax() what the original addressing mode was. + */ - /* These displacements are relative to */ - /* the start address of the displacement. */ - /* The first letter is Byte, Word. */ - /* 2nd letter is Forward, Backward. */ +/* These displacements are relative to */ +/* the start address of the displacement. */ +/* The first letter is Byte, Word. */ +/* 2nd letter is Forward, Backward. */ #define BF (1+ 127) #define BB (1+-128) #define WF (2+ 32767) #define WB (2+-32768) - /* Dont need LF, LB because they always */ - /* reach. [They are coded as 0.] */ +/* Dont need LF, LB because they always */ +/* reach. [They are coded as 0.] */ #define C(a,b) ENCODE_RELAX(a,b) - /* This macro has no side-effects. */ +/* This macro has no side-effects. */ #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) const relax_typeS -md_relax_table[] = + md_relax_table[] = +{ { - { 1, 1, 0, 0 - }, /* error sentinel 0,0 */ - { + }, /* error sentinel 0,0 */ +{ 1, 1, 0, 0 - }, /* unused 0,1 */ - { + }, /* unused 0,1 */ +{ 1, 1, 0, 0 - }, /* unused 0,2 */ - { + }, /* unused 0,2 */ +{ 1, 1, 0, 0 - }, /* unused 0,3 */ - { + }, /* unused 0,3 */ +{ BF + 1, BB + 1, 2, C (1, 1) - }, /* B^"foo" 1,0 */ - { + }, /* B^"foo" 1,0 */ +{ WF + 1, WB + 1, 3, C (1, 2) - }, /* W^"foo" 1,1 */ - { + }, /* W^"foo" 1,1 */ +{ 0, 0, 5, 0 - }, /* L^"foo" 1,2 */ - { + }, /* L^"foo" 1,2 */ +{ 1, 1, 0, 0 - }, /* unused 1,3 */ - { + }, /* unused 1,3 */ +{ BF, BB, 1, C (2, 1) - }, /* b<cond> B^"foo" 2,0 */ - { + }, /* b<cond> B^"foo" 2,0 */ +{ WF + 2, WB + 2, 4, C (2, 2) - }, /* br.+? brw X 2,1 */ - { + }, /* br.+? brw X 2,1 */ +{ 0, 0, 7, 0 - }, /* br.+? jmp X 2,2 */ - { + }, /* br.+? jmp X 2,2 */ +{ 1, 1, 0, 0 - }, /* unused 2,3 */ - { + }, /* unused 2,3 */ +{ BF, BB, 1, C (3, 1) - }, /* brb B^foo 3,0 */ - { + }, /* brb B^foo 3,0 */ +{ WF, WB, 2, C (3, 2) - }, /* brw W^foo 3,1 */ - { + }, /* brw W^foo 3,1 */ +{ 0, 0, 5, 0 - }, /* Jmp L^foo 3,2 */ - { + }, /* Jmp L^foo 3,2 */ +{ 1, 1, 0, 0 - }, /* unused 3,3 */ - { + }, /* unused 3,3 */ +{ 1, 1, 0, 0 - }, /* unused 4,0 */ - { + }, /* unused 4,0 */ +{ WF, WB, 2, C (4, 2) - }, /* acb_ ^Wfoo 4,1 */ - { + }, /* acb_ ^Wfoo 4,1 */ +{ 0, 0, 10, 0 - }, /* acb_,br,jmp L^foo4,2 */ - { + }, /* acb_,br,jmp L^foo4,2 */ +{ 1, 1, 0, 0 - }, /* unused 4,3 */ - { + }, /* unused 4,3 */ +{ BF, BB, 1, C (5, 1) - }, /* Xob___,,foo 5,0 */ - { + }, /* Xob___,,foo 5,0 */ +{ WF + 4, WB + 4, 6, C (5, 2) - }, /* Xob.+2,brb.+3,brw5,1 */ - { + }, /* Xob.+2,brb.+3,brw5,1 */ +{ 0, 0, 9, 0 - }, /* Xob.+2,brb.+6,jmp5,2 */ + }, /* Xob.+2,brb.+6,jmp5,2 */ }; #undef C @@ -274,11 +274,11 @@ void float_cons (); const pseudo_typeS md_pseudo_table[] = { - {"dfloat", float_cons, 'd'}, - {"ffloat", float_cons, 'f'}, - {"gfloat", float_cons, 'g'}, - {"hfloat", float_cons, 'h'}, - {0} +{"dfloat", float_cons, 'd'}, +{"ffloat", float_cons, 'f'}, +{"gfloat", float_cons, 'g'}, +{"hfloat", float_cons, 'h'}, +{0} }; #define STATE_PC_RELATIVE (1) @@ -286,897 +286,897 @@ const pseudo_typeS md_pseudo_table[] = #define STATE_ALWAYS_BRANCH (3) /* includes BSB... */ #define STATE_COMPLEX_BRANCH (4) #define STATE_COMPLEX_HOP (5) - + #define STATE_BYTE (0) #define STATE_WORD (1) #define STATE_LONG (2) #define STATE_UNDF (3) /* Symbol undefined in pass1 */ - - + + #define min(a, b) ((a) < (b) ? (a) : (b)) - - -void -md_begin () + + + void + md_begin () { - char *vip_begin (); - char *errtxt; - FLONUM_TYPE *fP; - int i; - - if (*(errtxt = vip_begin (TRUE, "$", "*", "`"))) + char *vip_begin (); + char *errtxt; + FLONUM_TYPE *fP; + int i; + + if (*(errtxt = vip_begin (TRUE, "$", "*", "`"))) { - as_fatal("VIP_BEGIN error:%s", errtxt); + as_fatal("VIP_BEGIN error:%s", errtxt); } - - for (i = 0, fP = float_operand; - fP < float_operand + VIT_MAX_OPERANDS; - i++, fP++) + + for (i = 0, fP = float_operand; + fP < float_operand + VIT_MAX_OPERANDS; + i++, fP++) { - fP->low = &big_operand_bits[i][0]; - fP->high = &big_operand_bits[i][SIZE_OF_LARGE_NUMBER - 1]; + fP->low = &big_operand_bits[i][0]; + fP->high = &big_operand_bits[i][SIZE_OF_LARGE_NUMBER - 1]; } } void -md_end () + md_end () { - vip_end (); + vip_end (); } void /* Knows about order of bytes in address. */ -md_number_to_chars (con, value, nbytes) - char con[]; /* Return 'nbytes' of chars here. */ - long value; /* The value of the bits. */ - int nbytes; /* Number of bytes in the output. */ + md_number_to_chars (con, value, nbytes) +char con[]; /* Return 'nbytes' of chars here. */ +long value; /* The value of the bits. */ +int nbytes; /* Number of bytes in the output. */ { - int n; - long v; - - n = nbytes; - v = value; - while (nbytes--) + int n; + long v; + + n = nbytes; + v = value; + while (nbytes--) { - *con++ = value; /* Lint wants & MASK_CHAR. */ - value >>= BITS_PER_CHAR; + *con++ = value; /* Lint wants & MASK_CHAR. */ + value >>= BITS_PER_CHAR; } - /* XXX line number probably botched for this warning message. */ - if (value != 0 && value != -1) - as_bad("Displacement (%ld) long for instruction field length (%d).", v, n); + /* XXX line number probably botched for this warning message. */ + if (value != 0 && value != -1) + as_bad("Displacement (%ld) long for instruction field length (%d).", v, n); } /* Fix up some data or instructions after we find out the value of a symbol that they reference. */ void /* Knows about order of bytes in address. */ -md_apply_fix(fixP, value) - fixS *fixP; /* Fixup struct pointer */ - long value; /* The value of the bits. */ + md_apply_fix(fixP, value) +fixS *fixP; /* Fixup struct pointer */ +long value; /* The value of the bits. */ { - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - int nbytes; /* Number of bytes in the output. */ - - nbytes = fixP->fx_size; - while (nbytes--) + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + int nbytes; /* Number of bytes in the output. */ + + nbytes = fixP->fx_size; + while (nbytes--) { - *buf++ = value; /* Lint wants & MASK_CHAR. */ - value >>= BITS_PER_CHAR; + *buf++ = value; /* Lint wants & MASK_CHAR. */ + value >>= BITS_PER_CHAR; } } long /* Knows about the byte order in a word. */ -md_chars_to_number (con, nbytes) - unsigned char con[]; /* Low order byte 1st. */ - int nbytes; /* Number of bytes in the input. */ + md_chars_to_number (con, nbytes) +unsigned char con[]; /* Low order byte 1st. */ +int nbytes; /* Number of bytes in the input. */ { - long retval; - for (retval = 0, con += nbytes - 1; nbytes--; con--) + long retval; + for (retval = 0, con += nbytes - 1; nbytes--; con--) { - retval <<= BITS_PER_CHAR; - retval |= *con; + retval <<= BITS_PER_CHAR; + retval |= *con; } - return retval; + return retval; } /* vax:md_assemble() emit frags for 1 instruction */ void -md_assemble (instruction_string) - char *instruction_string; /* A string: assemble 1 instruction. */ -{ - char *p; - register struct vop *operandP;/* An operand. Scans all operands. */ - char *save_input_line_pointer; - char c_save; /* What used to live after an expression. */ - struct frag *fragP; /* Fragment of code we just made. */ - register int goofed; /* TRUE: instruction_string bad for all passes. */ - register struct vop *end_operandP; /* -> slot just after last operand */ - /* Limit of the for (each operand). */ - register expressionS *expP; /* -> expression values for this operand */ - - /* These refer to an instruction operand expression. */ - segT to_seg; /* Target segment of the address. */ - register valueT this_add_number; - register struct symbol *this_add_symbol; /* +ve (minuend) symbol. */ - register struct symbol *this_subtract_symbol; /* -ve(subtrahend) symbol. */ - - long opcode_as_number; /* As a number. */ - char *opcode_as_chars; /* Least significant byte 1st. */ - /* As an array of characters. */ - char *opcode_low_byteP; /* Least significant byte 1st */ - struct details *detP; /* The details of an ADxxx frag. */ - int length; /* length (bytes) meant by vop_short. */ - int at; /* 0, or 1 if '@' is in addressing mode. */ - int nbytes; /* From vop_nbytes: vax_operand_width (in bytes) */ - FLONUM_TYPE *floatP; - char *vip (); - LITTLENUM_TYPE literal_float[8]; - /* Big enough for any floating point literal. */ - - if (*(p = vip (&v, instruction_string))) + md_assemble (instruction_string) +char *instruction_string; /* A string: assemble 1 instruction. */ +{ + char *p; + register struct vop *operandP;/* An operand. Scans all operands. */ + char *save_input_line_pointer; + char c_save; /* What used to live after an expression. */ + struct frag *fragP; /* Fragment of code we just made. */ + register int goofed; /* TRUE: instruction_string bad for all passes. */ + register struct vop *end_operandP; /* -> slot just after last operand */ + /* Limit of the for (each operand). */ + register expressionS *expP; /* -> expression values for this operand */ + + /* These refer to an instruction operand expression. */ + segT to_seg; /* Target segment of the address. */ + register valueT this_add_number; + register struct symbol *this_add_symbol; /* +ve (minuend) symbol. */ + register struct symbol *this_subtract_symbol; /* -ve(subtrahend) symbol. */ + + long opcode_as_number; /* As a number. */ + char *opcode_as_chars; /* Least significant byte 1st. */ + /* As an array of characters. */ + char *opcode_low_byteP; /* Least significant byte 1st */ + struct details *detP; /* The details of an ADxxx frag. */ + int length; /* length (bytes) meant by vop_short. */ + int at; /* 0, or 1 if '@' is in addressing mode. */ + int nbytes; /* From vop_nbytes: vax_operand_width (in bytes) */ + FLONUM_TYPE *floatP; + char *vip (); + LITTLENUM_TYPE literal_float[8]; + /* Big enough for any floating point literal. */ + + if (*(p = vip (&v, instruction_string))) { - as_fatal("vax_assemble\"%s\" in=\"%s\"", p, instruction_string); + as_fatal("vax_assemble\"%s\" in=\"%s\"", p, instruction_string); } - /* - * Now we try to find as many as_warn()s as we can. If we do any as_warn()s - * then goofed=TRUE. Notice that we don't make any frags yet. - * Should goofed be TRUE, then this instruction will wedge in any pass, - * and we can safely flush it, without causing interpass symbol phase - * errors. That is, without changing label values in different passes. - */ - if (goofed = (*v.vit_error)) + /* + * Now we try to find as many as_warn()s as we can. If we do any as_warn()s + * then goofed=TRUE. Notice that we don't make any frags yet. + * Should goofed be TRUE, then this instruction will wedge in any pass, + * and we can safely flush it, without causing interpass symbol phase + * errors. That is, without changing label values in different passes. + */ + if (goofed = (*v.vit_error)) { - as_warn ("Ignoring statement due to \"%s\"", v.vit_error); + as_warn ("Ignoring statement due to \"%s\"", v.vit_error); } - /* - * We need to use expression() and friends, which require us to diddle - * input_line_pointer. So we save it and restore it later. - */ - save_input_line_pointer = input_line_pointer; - for (operandP = v.vit_operand, - expP = exp_of_operand, - floatP = float_operand, - end_operandP = v.vit_operand + v.vit_operands; - - operandP < end_operandP; - - operandP++, - expP++, - floatP++ - ) /* for each operand */ + /* + * We need to use expression() and friends, which require us to diddle + * input_line_pointer. So we save it and restore it later. + */ + save_input_line_pointer = input_line_pointer; + for (operandP = v.vit_operand, + expP = exp_of_operand, + floatP = float_operand, + end_operandP = v.vit_operand + v.vit_operands; + + operandP < end_operandP; + + operandP++, + expP++, + floatP++ + ) /* for each operand */ { - if (*(operandP->vop_error)) + if (*(operandP->vop_error)) { - as_warn ("Ignoring statement because \"%s\"", (operandP->vop_error)); - goofed = TRUE; + as_warn ("Ignoring statement because \"%s\"", (operandP->vop_error)); + goofed = TRUE; } - else + else { /* statement has no syntax goofs: lets sniff the expression */ - int can_be_short; /* TRUE if a bignum can be reduced to a short literal. */ - - input_line_pointer = operandP->vop_expr_begin; - c_save = operandP->vop_expr_end[1]; - operandP->vop_expr_end[1] = '\0'; - /* If to_seg == SEG_PASS1, expression() will have set need_pass_2 = TRUE. */ - switch (to_seg = expression (expP)) + int can_be_short; /* TRUE if a bignum can be reduced to a short literal. */ + + input_line_pointer = operandP->vop_expr_begin; + c_save = operandP->vop_expr_end[1]; + operandP->vop_expr_end[1] = '\0'; + /* If to_seg == SEG_PASS1, expression() will have set need_pass_2 = TRUE. */ + switch (to_seg = expression (expP)) { case SEG_ABSENT: - /* for BSD4.2 compatibility, missing expression is absolute 0 */ - to_seg = expP->X_seg = SEG_ABSOLUTE; - expP->X_add_number = 0; - /* for SEG_ABSOLUTE, we shouldnt need to set X_subtract_symbol, X_add_symbol to any particular value. */ - /* But, we will program defensively. Since this situation occurs */ - /* rarely so it costs us little to do, and stops Dean */ - /* worrying about the origin of random bits in expressionS's. */ - expP->X_add_symbol = NULL; - expP->X_subtract_symbol = NULL; + /* for BSD4.2 compatibility, missing expression is absolute 0 */ + to_seg = expP->X_seg = SEG_ABSOLUTE; + expP->X_add_number = 0; + /* for SEG_ABSOLUTE, we shouldnt need to set X_subtract_symbol, X_add_symbol to any particular value. */ + /* But, we will program defensively. Since this situation occurs */ + /* rarely so it costs us little to do, and stops Dean */ + /* worrying about the origin of random bits in expressionS's. */ + expP->X_add_symbol = NULL; + expP->X_subtract_symbol = NULL; case SEG_TEXT: case SEG_DATA: case SEG_BSS: case SEG_ABSOLUTE: case SEG_UNKNOWN: - break; - + break; + case SEG_DIFFERENCE: case SEG_PASS1: - /* - * Major bug. We can't handle the case of a - * SEG_DIFFERENCE expression in a VIT_OPCODE_SYNTHETIC - * variable-length instruction. - * We don't have a frag type that is smart enough to - * relax a SEG_DIFFERENCE, and so we just force all - * SEG_DIFFERENCEs to behave like SEG_PASS1s. - * Clearly, if there is a demand we can invent a new or - * modified frag type and then coding up a frag for this - * case will be easy. SEG_DIFFERENCE was invented for the - * .words after a CASE opcode, and was never intended for - * instruction operands. - */ - need_pass_2 = TRUE; - as_warn("Can't relocate expression"); - break; - + /* + * Major bug. We can't handle the case of a + * SEG_DIFFERENCE expression in a VIT_OPCODE_SYNTHETIC + * variable-length instruction. + * We don't have a frag type that is smart enough to + * relax a SEG_DIFFERENCE, and so we just force all + * SEG_DIFFERENCEs to behave like SEG_PASS1s. + * Clearly, if there is a demand we can invent a new or + * modified frag type and then coding up a frag for this + * case will be easy. SEG_DIFFERENCE was invented for the + * .words after a CASE opcode, and was never intended for + * instruction operands. + */ + need_pass_2 = TRUE; + as_warn("Can't relocate expression"); + break; + case SEG_BIG: - /* Preserve the bits. */ - if (expP->X_add_number > 0) + /* Preserve the bits. */ + if (expP->X_add_number > 0) { - bignum_copy (generic_bignum, expP->X_add_number, - floatP->low, SIZE_OF_LARGE_NUMBER); + bignum_copy (generic_bignum, expP->X_add_number, + floatP->low, SIZE_OF_LARGE_NUMBER); } - else + else { - know (expP->X_add_number < 0); - flonum_copy (&generic_floating_point_number, - floatP); - if (strchr ("s i", operandP->vop_short)) + know (expP->X_add_number < 0); + flonum_copy (&generic_floating_point_number, + floatP); + if (strchr ("s i", operandP->vop_short)) { /* Could possibly become S^# */ - flonum_gen2vax (-expP->X_add_number, floatP, literal_float); - switch (-expP->X_add_number) + flonum_gen2vax (-expP->X_add_number, floatP, literal_float); + switch (-expP->X_add_number) { case 'f': - can_be_short = - (literal_float[0] & 0xFC0F) == 0x4000 - && literal_float[1] == 0; - break; - + can_be_short = + (literal_float[0] & 0xFC0F) == 0x4000 + && literal_float[1] == 0; + break; + case 'd': - can_be_short = - (literal_float[0] & 0xFC0F) == 0x4000 - && literal_float[1] == 0 - && literal_float[2] == 0 - && literal_float[3] == 0; - break; - + can_be_short = + (literal_float[0] & 0xFC0F) == 0x4000 + && literal_float[1] == 0 + && literal_float[2] == 0 + && literal_float[3] == 0; + break; + case 'g': - can_be_short = - (literal_float[0] & 0xFF81) == 0x4000 - && literal_float[1] == 0 - && literal_float[2] == 0 - && literal_float[3] == 0; - break; - + can_be_short = + (literal_float[0] & 0xFF81) == 0x4000 + && literal_float[1] == 0 + && literal_float[2] == 0 + && literal_float[3] == 0; + break; + case 'h': - can_be_short = - (literal_float[0] & 0xFFF8) == 0x4000 - && (literal_float[1] & 0xE000) == 0 - && literal_float[2] == 0 - && literal_float[3] == 0 - && literal_float[4] == 0 - && literal_float[5] == 0 - && literal_float[6] == 0 - && literal_float[7] == 0; - break; - + can_be_short = + (literal_float[0] & 0xFFF8) == 0x4000 + && (literal_float[1] & 0xE000) == 0 + && literal_float[2] == 0 + && literal_float[3] == 0 + && literal_float[4] == 0 + && literal_float[5] == 0 + && literal_float[6] == 0 + && literal_float[7] == 0; + break; + default: - BAD_CASE (-expP->X_add_number); - break; + BAD_CASE (-expP->X_add_number); + break; } /* switch (float type) */ } /* if (could want to become S^#...) */ } /* bignum or flonum ? */ - - if (operandP->vop_short == 's' - || operandP->vop_short == 'i' - || (operandP->vop_short == ' ' - && operandP->vop_reg == 0xF - && (operandP->vop_mode & 0xE) == 0x8)) + + if (operandP->vop_short == 's' + || operandP->vop_short == 'i' + || (operandP->vop_short == ' ' + && operandP->vop_reg == 0xF + && (operandP->vop_mode & 0xE) == 0x8)) { - /* Saw a '#'. */ - if (operandP->vop_short == ' ') + /* Saw a '#'. */ + if (operandP->vop_short == ' ') { /* We must chose S^ or I^. */ - if (expP->X_add_number > 0) + if (expP->X_add_number > 0) { /* Bignum: Short literal impossible. */ - operandP->vop_short = 'i'; - operandP->vop_mode = 8; - operandP->vop_reg = 0xF; /* VAX PC. */ + operandP->vop_short = 'i'; + operandP->vop_mode = 8; + operandP->vop_reg = 0xF; /* VAX PC. */ } - else + else { /* Flonum: Try to do it. */ - if (can_be_short) + if (can_be_short) { - operandP->vop_short = 's'; - operandP->vop_mode = 0; - operandP->vop_ndx = -1; - operandP->vop_reg = -1; - /* JF hope this is the right thing */ - expP->X_seg = SEG_ABSOLUTE; + operandP->vop_short = 's'; + operandP->vop_mode = 0; + operandP->vop_ndx = -1; + operandP->vop_reg = -1; + /* JF hope this is the right thing */ + expP->X_seg = SEG_ABSOLUTE; } - else + else { - operandP->vop_short = 'i'; - operandP->vop_mode = 8; - operandP->vop_reg = 0xF; /* VAX PC */ + operandP->vop_short = 'i'; + operandP->vop_mode = 8; + operandP->vop_reg = 0xF; /* VAX PC */ } } /* bignum or flonum ? */ } /* if #, but no S^ or I^ seen. */ - /* No more ' ' case: either 's' or 'i'. */ - if (operandP->vop_short == 's') + /* No more ' ' case: either 's' or 'i'. */ + if (operandP->vop_short == 's') { - /* Wants to be a short literal. */ - if (expP->X_add_number > 0) + /* Wants to be a short literal. */ + if (expP->X_add_number > 0) { - as_warn ("Bignum not permitted in short literal. Immediate mode assumed."); - operandP->vop_short = 'i'; - operandP->vop_mode = 8; - operandP->vop_reg = 0xF; /* VAX PC. */ + as_warn ("Bignum not permitted in short literal. Immediate mode assumed."); + operandP->vop_short = 'i'; + operandP->vop_mode = 8; + operandP->vop_reg = 0xF; /* VAX PC. */ } - else + else { - if (!can_be_short) + if (!can_be_short) { - as_warn ("Can't do flonum short literal: immediate mode used."); - operandP->vop_short = 'i'; - operandP->vop_mode = 8; - operandP->vop_reg = 0xF; /* VAX PC. */ + as_warn ("Can't do flonum short literal: immediate mode used."); + operandP->vop_short = 'i'; + operandP->vop_mode = 8; + operandP->vop_reg = 0xF; /* VAX PC. */ } - else + else { /* Encode short literal now. */ - register int temp; - - switch (-expP->X_add_number) + register int temp; + + switch (-expP->X_add_number) { case 'f': case 'd': - temp = literal_float[0] >> 4; - break; - + temp = literal_float[0] >> 4; + break; + case 'g': - temp = literal_float[0] >> 1; - break; - + temp = literal_float[0] >> 1; + break; + case 'h': - temp = ((literal_float[0] << 3) & 070) - | ((literal_float[1] >> 13) & 07); - break; - + temp = ((literal_float[0] << 3) & 070) + | ((literal_float[1] >> 13) & 07); + break; + default: - BAD_CASE (-expP->X_add_number); - break; + BAD_CASE (-expP->X_add_number); + break; } - - floatP->low[0] = temp & 077; - floatP->low[1] = 0; + + floatP->low[0] = temp & 077; + floatP->low[1] = 0; } /* if can be short literal float */ } /* flonum or bignum ? */ } - else + else { /* I^# seen: set it up if float. */ - if (expP->X_add_number < 0) + if (expP->X_add_number < 0) { - bcopy (literal_float, floatP->low, sizeof (literal_float)); + bcopy (literal_float, floatP->low, sizeof (literal_float)); } } /* if S^# seen. */ } - else + else { - as_warn ("A bignum/flonum may not be a displacement: 0x%x used", - expP->X_add_number = 0x80000000); - /* Chosen so luser gets the most offset bits to patch later. */ + as_warn ("A bignum/flonum may not be a displacement: 0x%x used", + expP->X_add_number = 0x80000000); + /* Chosen so luser gets the most offset bits to patch later. */ } - expP->X_add_number = floatP->low[0] - | ((LITTLENUM_MASK & (floatP->low[1])) << LITTLENUM_NUMBER_OF_BITS); -/* - * For the SEG_BIG case we have: - * If vop_short == 's' then a short floating literal is in the - * lowest 6 bits of floatP -> low [0], which is - * big_operand_bits [---] [0]. - * If vop_short == 'i' then the appropriate number of elements - * of big_operand_bits [---] [...] are set up with the correct - * bits. - * Also, just in case width is byte word or long, we copy the lowest - * 32 bits of the number to X_add_number. - */ - break; - + expP->X_add_number = floatP->low[0] + | ((LITTLENUM_MASK & (floatP->low[1])) << LITTLENUM_NUMBER_OF_BITS); + /* + * For the SEG_BIG case we have: + * If vop_short == 's' then a short floating literal is in the + * lowest 6 bits of floatP -> low [0], which is + * big_operand_bits [---] [0]. + * If vop_short == 'i' then the appropriate number of elements + * of big_operand_bits [---] [...] are set up with the correct + * bits. + * Also, just in case width is byte word or long, we copy the lowest + * 32 bits of the number to X_add_number. + */ + break; + default: - BAD_CASE (to_seg); - break; + BAD_CASE (to_seg); + break; } - if (input_line_pointer != operandP->vop_expr_end + 1) + if (input_line_pointer != operandP->vop_expr_end + 1) { - as_warn ("Junk at end of expression \"%s\"", input_line_pointer); - goofed = TRUE; + as_warn ("Junk at end of expression \"%s\"", input_line_pointer); + goofed = TRUE; } - operandP->vop_expr_end[1] = c_save; + operandP->vop_expr_end[1] = c_save; } } /* for(each operand) */ - input_line_pointer = save_input_line_pointer; - - if (!need_pass_2 && !goofed) + input_line_pointer = save_input_line_pointer; + + if (!need_pass_2 && !goofed) { - /* We saw no errors in any operands - try to make frag(s) */ - int is_undefined; /* True if operand expression's */ - /* segment not known yet. */ - int length_code; - - /* Emit op-code. */ - /* Remember where it is, in case we want to modify the op-code later. */ - opcode_low_byteP = frag_more (v.vit_opcode_nbytes); - bcopy (v.vit_opcode, opcode_low_byteP, v.vit_opcode_nbytes); - opcode_as_number = md_chars_to_number (opcode_as_chars = v.vit_opcode, 4); - for (operandP = v.vit_operand, - expP = exp_of_operand, - floatP = float_operand, - end_operandP = v.vit_operand + v.vit_operands; - - operandP < end_operandP; - - operandP++, - floatP++, - expP++ - ) /* for each operand */ + /* We saw no errors in any operands - try to make frag(s) */ + int is_undefined; /* True if operand expression's */ + /* segment not known yet. */ + int length_code; + + /* Emit op-code. */ + /* Remember where it is, in case we want to modify the op-code later. */ + opcode_low_byteP = frag_more (v.vit_opcode_nbytes); + bcopy (v.vit_opcode, opcode_low_byteP, v.vit_opcode_nbytes); + opcode_as_number = md_chars_to_number (opcode_as_chars = v.vit_opcode, 4); + for (operandP = v.vit_operand, + expP = exp_of_operand, + floatP = float_operand, + end_operandP = v.vit_operand + v.vit_operands; + + operandP < end_operandP; + + operandP++, + floatP++, + expP++ + ) /* for each operand */ { - if (operandP->vop_ndx >= 0) + if (operandP->vop_ndx >= 0) { - /* indexed addressing byte */ - /* Legality of indexed mode already checked: it is OK */ - FRAG_APPEND_1_CHAR (0x40 + operandP->vop_ndx); + /* indexed addressing byte */ + /* Legality of indexed mode already checked: it is OK */ + FRAG_APPEND_1_CHAR (0x40 + operandP->vop_ndx); } /* if(vop_ndx>=0) */ - - /* Here to make main operand frag(s). */ - this_add_number = expP->X_add_number; - this_add_symbol = expP->X_add_symbol; - this_subtract_symbol = expP->X_subtract_symbol; - to_seg = expP->X_seg; - is_undefined = (to_seg == SEG_UNKNOWN); - know (to_seg == SEG_UNKNOWN - ||to_seg == SEG_ABSOLUTE - ||to_seg == SEG_DATA - ||to_seg == SEG_TEXT - ||to_seg == SEG_BSS - ||to_seg == SEG_BIG - ); - at = operandP->vop_mode & 1; - length = operandP->vop_short == 'b' ? 1 : operandP->vop_short == 'w' ? 2 : operandP->vop_short == 'l' ? 4 : 0; - nbytes = operandP->vop_nbytes; - if (operandP->vop_access == 'b') + + /* Here to make main operand frag(s). */ + this_add_number = expP->X_add_number; + this_add_symbol = expP->X_add_symbol; + this_subtract_symbol = expP->X_subtract_symbol; + to_seg = expP->X_seg; + is_undefined = (to_seg == SEG_UNKNOWN); + know (to_seg == SEG_UNKNOWN + ||to_seg == SEG_ABSOLUTE + ||to_seg == SEG_DATA + ||to_seg == SEG_TEXT + ||to_seg == SEG_BSS + ||to_seg == SEG_BIG + ); + at = operandP->vop_mode & 1; + length = operandP->vop_short == 'b' ? 1 : operandP->vop_short == 'w' ? 2 : operandP->vop_short == 'l' ? 4 : 0; + nbytes = operandP->vop_nbytes; + if (operandP->vop_access == 'b') { - if (to_seg == now_seg || is_undefined) + if (to_seg == now_seg || is_undefined) { /* If is_undefined, then it might BECOME now_seg. */ - if (nbytes) + if (nbytes) { - p = frag_more (nbytes); - fix_new (frag_now, p - frag_now->fr_literal, nbytes, - this_add_symbol, 0, this_add_number, 1); + p = frag_more (nbytes); + fix_new (frag_now, p - frag_now->fr_literal, nbytes, + this_add_symbol, 0, this_add_number, 1); } - else + else { /* to_seg==now_seg || to_seg == SEG_UNKNOWN */ - /* nbytes==0 */ - length_code = is_undefined ? STATE_UNDF : STATE_BYTE; - if (opcode_as_number & VIT_OPCODE_SPECIAL) + /* nbytes==0 */ + length_code = is_undefined ? STATE_UNDF : STATE_BYTE; + if (opcode_as_number & VIT_OPCODE_SPECIAL) { - if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) + if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) { - /* br or jsb */ - frag_var (rs_machine_dependent, 5, 1, - ENCODE_RELAX (STATE_ALWAYS_BRANCH, length_code), - this_add_symbol, this_add_number, - opcode_low_byteP); + /* br or jsb */ + frag_var (rs_machine_dependent, 5, 1, + ENCODE_RELAX (STATE_ALWAYS_BRANCH, length_code), + this_add_symbol, this_add_number, + opcode_low_byteP); } - else + else { - if (operandP->vop_width == VAX_WIDTH_WORD_JUMP) + if (operandP->vop_width == VAX_WIDTH_WORD_JUMP) { - length_code = STATE_WORD; /* JF: There is no state_byte for this one! */ - frag_var (rs_machine_dependent, 10, 2, - ENCODE_RELAX (STATE_COMPLEX_BRANCH, length_code), - this_add_symbol, this_add_number, - opcode_low_byteP); + length_code = STATE_WORD; /* JF: There is no state_byte for this one! */ + frag_var (rs_machine_dependent, 10, 2, + ENCODE_RELAX (STATE_COMPLEX_BRANCH, length_code), + this_add_symbol, this_add_number, + opcode_low_byteP); } - else + else { - know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP); - frag_var (rs_machine_dependent, 9, 1, - ENCODE_RELAX (STATE_COMPLEX_HOP, length_code), - this_add_symbol, this_add_number, - opcode_low_byteP); + know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP); + frag_var (rs_machine_dependent, 9, 1, + ENCODE_RELAX (STATE_COMPLEX_HOP, length_code), + this_add_symbol, this_add_number, + opcode_low_byteP); } } } - else + else { - know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP); - frag_var (rs_machine_dependent, 7, 1, - ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, length_code), - this_add_symbol, this_add_number, - opcode_low_byteP); + know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP); + frag_var (rs_machine_dependent, 7, 1, + ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, length_code), + this_add_symbol, this_add_number, + opcode_low_byteP); } } } - else + else { /* to_seg != now_seg && to_seg != SEG_UNKNOWN */ -/* - * --- SEG FLOAT MAY APPEAR HERE ---- - */ - if (to_seg == SEG_ABSOLUTE) + /* + * --- SEG FLOAT MAY APPEAR HERE ---- + */ + if (to_seg == SEG_ABSOLUTE) { - if (nbytes) + if (nbytes) { - know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC)); - p = frag_more (nbytes); - /* Conventional relocation. */ - fix_new (frag_now, p - frag_now->fr_literal, - nbytes, &abs_symbol, 0, this_add_number, 1); + know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC)); + p = frag_more (nbytes); + /* Conventional relocation. */ + fix_new (frag_now, p - frag_now->fr_literal, + nbytes, &abs_symbol, 0, this_add_number, 1); } - else + else { - know (opcode_as_number & VIT_OPCODE_SYNTHETIC); - if (opcode_as_number & VIT_OPCODE_SPECIAL) + know (opcode_as_number & VIT_OPCODE_SYNTHETIC); + if (opcode_as_number & VIT_OPCODE_SPECIAL) { - if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) + if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) { - /* br or jsb */ - *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG; - know (opcode_as_chars[1] == 0); - p = frag_more (5); - p[0] = VAX_ABSOLUTE_MODE; /* @#... */ - md_number_to_chars (p + 1, this_add_number, 4); - /* Now (eg) JMP @#foo or JSB @#foo. */ + /* br or jsb */ + *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG; + know (opcode_as_chars[1] == 0); + p = frag_more (5); + p[0] = VAX_ABSOLUTE_MODE; /* @#... */ + md_number_to_chars (p + 1, this_add_number, 4); + /* Now (eg) JMP @#foo or JSB @#foo. */ } - else + else { - if (operandP->vop_width == VAX_WIDTH_WORD_JUMP) + if (operandP->vop_width == VAX_WIDTH_WORD_JUMP) { - p = frag_more (10); - p[0] = 2; - p[1] = 0; - p[2] = VAX_BRB; - p[3] = 6; - p[4] = VAX_JMP; - p[5] = VAX_ABSOLUTE_MODE; /* @#... */ - md_number_to_chars (p + 6, this_add_number, 4); - /* - * Now (eg) ACBx 1f - * BRB 2f - * 1: JMP @#foo - * 2: - */ + p = frag_more (10); + p[0] = 2; + p[1] = 0; + p[2] = VAX_BRB; + p[3] = 6; + p[4] = VAX_JMP; + p[5] = VAX_ABSOLUTE_MODE; /* @#... */ + md_number_to_chars (p + 6, this_add_number, 4); + /* + * Now (eg) ACBx 1f + * BRB 2f + * 1: JMP @#foo + * 2: + */ } - else + else { - know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP); - p = frag_more (9); - p[0] = 2; - p[1] = VAX_BRB; - p[2] = 6; - p[3] = VAX_JMP; - p[4] = VAX_PC_RELATIVE_MODE + 1; /* @#... */ - md_number_to_chars (p + 5, this_add_number, 4); - /* - * Now (eg) xOBxxx 1f - * BRB 2f - * 1: JMP @#foo - * 2: - */ + know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP); + p = frag_more (9); + p[0] = 2; + p[1] = VAX_BRB; + p[2] = 6; + p[3] = VAX_JMP; + p[4] = VAX_PC_RELATIVE_MODE + 1; /* @#... */ + md_number_to_chars (p + 5, this_add_number, 4); + /* + * Now (eg) xOBxxx 1f + * BRB 2f + * 1: JMP @#foo + * 2: + */ } } } - else + else { - /* b<cond> */ - *opcode_low_byteP ^= 1; /* To reverse the condition in a VAX branch, complement the lowest order bit. */ - p = frag_more (7); - p[0] = 6; - p[1] = VAX_JMP; - p[2] = VAX_ABSOLUTE_MODE; /* @#... */ - md_number_to_chars (p + 3, this_add_number, 4); - /* - * Now (eg) BLEQ 1f - * JMP @#foo - * 1: - */ + /* b<cond> */ + *opcode_low_byteP ^= 1; /* To reverse the condition in a VAX branch, complement the lowest order bit. */ + p = frag_more (7); + p[0] = 6; + p[1] = VAX_JMP; + p[2] = VAX_ABSOLUTE_MODE; /* @#... */ + md_number_to_chars (p + 3, this_add_number, 4); + /* + * Now (eg) BLEQ 1f + * JMP @#foo + * 1: + */ } } } - else + else { /* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */ - if (nbytes > 0) + if (nbytes > 0) { - /* Pc-relative. Conventional relocation. */ - know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC)); - p = frag_more (nbytes); - fix_new (frag_now, p - frag_now->fr_literal, - nbytes, &abs_symbol, 0, this_add_number, 1); + /* Pc-relative. Conventional relocation. */ + know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC)); + p = frag_more (nbytes); + fix_new (frag_now, p - frag_now->fr_literal, + nbytes, &abs_symbol, 0, this_add_number, 1); } - else + else { - know (opcode_as_number & VIT_OPCODE_SYNTHETIC); - if (opcode_as_number & VIT_OPCODE_SPECIAL) + know (opcode_as_number & VIT_OPCODE_SYNTHETIC); + if (opcode_as_number & VIT_OPCODE_SPECIAL) { - if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) + if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) { - /* br or jsb */ - know (opcode_as_chars[1] == 0); - *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG; - p = frag_more (5); - p[0] = VAX_PC_RELATIVE_MODE; - fix_new (frag_now, - p + 1 - frag_now->fr_literal, 4, - this_add_symbol, 0, - this_add_number, 1); - /* Now eg JMP foo or JSB foo. */ + /* br or jsb */ + know (opcode_as_chars[1] == 0); + *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG; + p = frag_more (5); + p[0] = VAX_PC_RELATIVE_MODE; + fix_new (frag_now, + p + 1 - frag_now->fr_literal, 4, + this_add_symbol, 0, + this_add_number, 1); + /* Now eg JMP foo or JSB foo. */ } - else + else { - if (operandP->vop_width == VAX_WIDTH_WORD_JUMP) + if (operandP->vop_width == VAX_WIDTH_WORD_JUMP) { - p = frag_more (10); - p[0] = 0; - p[1] = 2; - p[2] = VAX_BRB; - p[3] = 6; - p[4] = VAX_JMP; - p[5] = VAX_PC_RELATIVE_MODE; - fix_new (frag_now, - p + 6 - frag_now->fr_literal, 4, - this_add_symbol, 0, - this_add_number, 1); - /* - * Now (eg) ACBx 1f - * BRB 2f - * 1: JMP foo - * 2: - */ + p = frag_more (10); + p[0] = 0; + p[1] = 2; + p[2] = VAX_BRB; + p[3] = 6; + p[4] = VAX_JMP; + p[5] = VAX_PC_RELATIVE_MODE; + fix_new (frag_now, + p + 6 - frag_now->fr_literal, 4, + this_add_symbol, 0, + this_add_number, 1); + /* + * Now (eg) ACBx 1f + * BRB 2f + * 1: JMP foo + * 2: + */ } - else + else { - know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP); - p = frag_more (10); - p[0] = 2; - p[1] = VAX_BRB; - p[2] = 6; - p[3] = VAX_JMP; - p[4] = VAX_PC_RELATIVE_MODE; - fix_new (frag_now, - p + 5 - frag_now->fr_literal, - 4, this_add_symbol, 0, - this_add_number, 1); - /* - * Now (eg) xOBxxx 1f - * BRB 2f - * 1: JMP foo - * 2: - */ + know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP); + p = frag_more (10); + p[0] = 2; + p[1] = VAX_BRB; + p[2] = 6; + p[3] = VAX_JMP; + p[4] = VAX_PC_RELATIVE_MODE; + fix_new (frag_now, + p + 5 - frag_now->fr_literal, + 4, this_add_symbol, 0, + this_add_number, 1); + /* + * Now (eg) xOBxxx 1f + * BRB 2f + * 1: JMP foo + * 2: + */ } } } - else + else { - know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP); - *opcode_low_byteP ^= 1; /* Reverse branch condition. */ - p = frag_more (7); - p[0] = 6; - p[1] = VAX_JMP; - p[2] = VAX_PC_RELATIVE_MODE; - fix_new (frag_now, p + 3 - frag_now->fr_literal, - 4, this_add_symbol, 0, - this_add_number, 1); + know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP); + *opcode_low_byteP ^= 1; /* Reverse branch condition. */ + p = frag_more (7); + p[0] = 6; + p[1] = VAX_JMP; + p[2] = VAX_PC_RELATIVE_MODE; + fix_new (frag_now, p + 3 - frag_now->fr_literal, + 4, this_add_symbol, 0, + this_add_number, 1); } } } } } - else + else { - know (operandP->vop_access != 'b'); /* So it is ordinary operand. */ - know (operandP->vop_access != ' '); /* ' ' target-independent: elsewhere. */ - know (operandP->vop_access == 'a' || operandP->vop_access == 'm' || operandP->vop_access == 'r' || operandP->vop_access == 'v' || operandP->vop_access == 'w'); - if (operandP->vop_short == 's') + know (operandP->vop_access != 'b'); /* So it is ordinary operand. */ + know (operandP->vop_access != ' '); /* ' ' target-independent: elsewhere. */ + know (operandP->vop_access == 'a' || operandP->vop_access == 'm' || operandP->vop_access == 'r' || operandP->vop_access == 'v' || operandP->vop_access == 'w'); + if (operandP->vop_short == 's') { - if (to_seg == SEG_ABSOLUTE) + if (to_seg == SEG_ABSOLUTE) { - if (this_add_number < 0 || this_add_number >= 64) + if (this_add_number < 0 || this_add_number >= 64) { - as_warn ("Short literal overflow(%d.), immediate mode assumed.", this_add_number); - operandP->vop_short = 'i'; - operandP->vop_mode = 8; - operandP->vop_reg = 0xF; + as_warn ("Short literal overflow(%d.), immediate mode assumed.", this_add_number); + operandP->vop_short = 'i'; + operandP->vop_mode = 8; + operandP->vop_reg = 0xF; } } - else + else { - as_warn ("Forced short literal to immediate mode. now_seg=%s to_seg=%s", segment_name(now_seg), segment_name(to_seg)); - operandP->vop_short = 'i'; - operandP->vop_mode = 8; - operandP->vop_reg = 0xF; + as_warn ("Forced short literal to immediate mode. now_seg=%s to_seg=%s", segment_name(now_seg), segment_name(to_seg)); + operandP->vop_short = 'i'; + operandP->vop_mode = 8; + operandP->vop_reg = 0xF; } } - if (operandP->vop_reg >= 0 && (operandP->vop_mode < 8 || (operandP->vop_reg != 0xF && operandP->vop_mode < 10))) + if (operandP->vop_reg >= 0 && (operandP->vop_mode < 8 || (operandP->vop_reg != 0xF && operandP->vop_mode < 10))) { /* One byte operand. */ - know (operandP->vop_mode > 3); - FRAG_APPEND_1_CHAR (operandP->vop_mode << 4 | operandP->vop_reg); - /* All 1-bytes except S^# happen here. */ + know (operandP->vop_mode > 3); + FRAG_APPEND_1_CHAR (operandP->vop_mode << 4 | operandP->vop_reg); + /* All 1-bytes except S^# happen here. */ } - else + else { /* {@}{q^}foo{(Rn)} or S^#foo */ - if (operandP->vop_reg == -1 && operandP->vop_short != 's') + if (operandP->vop_reg == -1 && operandP->vop_short != 's') { /* "{@}{q^}foo" */ - if (to_seg == now_seg) + if (to_seg == now_seg) { - if (length == 0) + if (length == 0) { - know (operandP->vop_short == ' '); - p = frag_var (rs_machine_dependent, 10, 2, - ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE), - this_add_symbol, this_add_number, - opcode_low_byteP); - know (operandP->vop_mode == 10 + at); - *p = at << 4; - /* At is the only context we need to carry to */ - /* other side of relax() process. */ - /* Must be in the correct bit position of VAX */ - /* operand spec. byte. */ + know (operandP->vop_short == ' '); + p = frag_var (rs_machine_dependent, 10, 2, + ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE), + this_add_symbol, this_add_number, + opcode_low_byteP); + know (operandP->vop_mode == 10 + at); + *p = at << 4; + /* At is the only context we need to carry to */ + /* other side of relax() process. */ + /* Must be in the correct bit position of VAX */ + /* operand spec. byte. */ } - else + else { - know (length); - know (operandP->vop_short != ' '); - p = frag_more (length + 1); - /* JF is this array stuff really going to work? */ - p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4); - fix_new (frag_now, p + 1 - frag_now->fr_literal, - length, this_add_symbol, 0, - this_add_number, 1); + know (length); + know (operandP->vop_short != ' '); + p = frag_more (length + 1); + /* JF is this array stuff really going to work? */ + p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4); + fix_new (frag_now, p + 1 - frag_now->fr_literal, + length, this_add_symbol, 0, + this_add_number, 1); } } - else + else { /* to_seg != now_seg */ - if (this_add_symbol == NULL) + if (this_add_symbol == NULL) { - know (to_seg == SEG_ABSOLUTE); - /* Do @#foo: simpler relocation than foo-.(pc) anyway. */ - p = frag_more (5); - p[0] = VAX_ABSOLUTE_MODE; /* @#... */ - md_number_to_chars (p + 1, this_add_number, 4); - if (length && length != 4) + know (to_seg == SEG_ABSOLUTE); + /* Do @#foo: simpler relocation than foo-.(pc) anyway. */ + p = frag_more (5); + p[0] = VAX_ABSOLUTE_MODE; /* @#... */ + md_number_to_chars (p + 1, this_add_number, 4); + if (length && length != 4) { - as_warn ("Length specification ignored. Address mode 9F used"); + as_warn ("Length specification ignored. Address mode 9F used"); } } - else + else { - /* {@}{q^}other_seg */ - know ((length == 0 && operandP->vop_short == ' ') - ||(length > 0 && operandP->vop_short != ' ')); - if (is_undefined) + /* {@}{q^}other_seg */ + know ((length == 0 && operandP->vop_short == ' ') + ||(length > 0 && operandP->vop_short != ' ')); + if (is_undefined) { - /* - * We have a SEG_UNKNOWN symbol. It might - * turn out to be in the same segment as - * the instruction, permitting relaxation. - */ - p = frag_var (rs_machine_dependent, 5, 2, - ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF), - this_add_symbol, this_add_number, - 0); - p[0] = at << 4; + /* + * We have a SEG_UNKNOWN symbol. It might + * turn out to be in the same segment as + * the instruction, permitting relaxation. + */ + p = frag_var (rs_machine_dependent, 5, 2, + ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF), + this_add_symbol, this_add_number, + 0); + p[0] = at << 4; } - else + else { - if (length == 0) + if (length == 0) { - know (operandP->vop_short == ' '); - length = 4; /* Longest possible. */ + know (operandP->vop_short == ' '); + length = 4; /* Longest possible. */ } - p = frag_more (length + 1); - p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4); - md_number_to_chars (p + 1, this_add_number, length); - fix_new (frag_now, - p + 1 - frag_now->fr_literal, - length, this_add_symbol, 0, - this_add_number, 1); + p = frag_more (length + 1); + p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4); + md_number_to_chars (p + 1, this_add_number, length); + fix_new (frag_now, + p + 1 - frag_now->fr_literal, + length, this_add_symbol, 0, + this_add_number, 1); } } } } - else + else { /* {@}{q^}foo(Rn) or S^# or I^# or # */ - if (operandP->vop_mode < 0xA) + if (operandP->vop_mode < 0xA) { /* # or S^# or I^# */ - /* know( (length == 0 && operandP->vop_short == ' ') + /* know( (length == 0 && operandP->vop_short == ' ') || (length > 0 && operandP->vop_short != ' ')); */ - if (length == 0 - && to_seg == SEG_ABSOLUTE - && operandP->vop_mode == 8 /* No '@'. */ - && this_add_number < 64 - && this_add_number >= 0) + if (length == 0 + && to_seg == SEG_ABSOLUTE + && operandP->vop_mode == 8 /* No '@'. */ + && this_add_number < 64 + && this_add_number >= 0) { - operandP->vop_short = 's'; + operandP->vop_short = 's'; } - if (operandP->vop_short == 's') + if (operandP->vop_short == 's') { - FRAG_APPEND_1_CHAR (this_add_number); + FRAG_APPEND_1_CHAR (this_add_number); } - else + else { /* I^#... */ - know (nbytes); - p = frag_more (nbytes + 1); - know (operandP->vop_reg == 0xF); - p[0] = (operandP->vop_mode << 4) | 0xF; - if (to_seg == SEG_ABSOLUTE) + know (nbytes); + p = frag_more (nbytes + 1); + know (operandP->vop_reg == 0xF); + p[0] = (operandP->vop_mode << 4) | 0xF; + if (to_seg == SEG_ABSOLUTE) { -/* - * If nbytes > 4, then we are scrod. We don't know if the - * high order bytes are to be 0xFF or 0x00. - * BSD4.2 & RMS say use 0x00. OK --- but this - * assembler needs ANOTHER rewrite to - * cope properly with this bug. - */ - md_number_to_chars (p + 1, this_add_number, min (4, nbytes)); - if (nbytes > 4) + /* + * If nbytes > 4, then we are scrod. We don't know if the + * high order bytes are to be 0xFF or 0x00. + * BSD4.2 & RMS say use 0x00. OK --- but this + * assembler needs ANOTHER rewrite to + * cope properly with this bug. + */ + md_number_to_chars (p + 1, this_add_number, min (4, nbytes)); + if (nbytes > 4) { - bzero (p + 5, nbytes - 4); + bzero (p + 5, nbytes - 4); } } - else + else { - if (to_seg == SEG_BIG) + if (to_seg == SEG_BIG) { -/* - * Problem here is to get the bytes in the right order. - * We stored our constant as LITTLENUMs, not bytes. - */ - LITTLENUM_TYPE *lP; - - lP = floatP->low; - if (nbytes & 1) + /* + * Problem here is to get the bytes in the right order. + * We stored our constant as LITTLENUMs, not bytes. + */ + LITTLENUM_TYPE *lP; + + lP = floatP->low; + if (nbytes & 1) { - know (nbytes == 1); - p[1] = *lP; + know (nbytes == 1); + p[1] = *lP; } - else + else { - for (p++; nbytes; nbytes -= 2, p += 2, lP++) + for (p++; nbytes; nbytes -= 2, p += 2, lP++) { - md_number_to_chars (p, *lP, 2); + md_number_to_chars (p, *lP, 2); } } } - else + else { - fix_new (frag_now, p + 1 - frag_now->fr_literal, - nbytes, this_add_symbol, 0, - this_add_number, 0); + fix_new (frag_now, p + 1 - frag_now->fr_literal, + nbytes, this_add_symbol, 0, + this_add_number, 0); } } } } - else + else { /* {@}{q^}foo(Rn) */ - know ((length == 0 && operandP->vop_short == ' ') - ||(length > 0 && operandP->vop_short != ' ')); - if (length == 0) + know ((length == 0 && operandP->vop_short == ' ') + ||(length > 0 && operandP->vop_short != ' ')); + if (length == 0) { - if (to_seg == SEG_ABSOLUTE) + if (to_seg == SEG_ABSOLUTE) { - register long test; - - test = this_add_number; - - if (test < 0) - test = ~test; - - length = test & 0xffff8000 ? 4 - : test & 0xffffff80 ? 2 - : 1; + register long test; + + test = this_add_number; + + if (test < 0) + test = ~test; + + length = test & 0xffff8000 ? 4 + : test & 0xffffff80 ? 2 + : 1; } - else + else { - length = 4; + length = 4; } } - p = frag_more (1 + length); - know (operandP->vop_reg >= 0); - p[0] = operandP->vop_reg - | ((at | "?\12\14?\16"[length]) << 4); - if (to_seg == SEG_ABSOLUTE) + p = frag_more (1 + length); + know (operandP->vop_reg >= 0); + p[0] = operandP->vop_reg + | ((at | "?\12\14?\16"[length]) << 4); + if (to_seg == SEG_ABSOLUTE) { - md_number_to_chars (p + 1, this_add_number, length); + md_number_to_chars (p + 1, this_add_number, length); } - else + else { - fix_new (frag_now, p + 1 - frag_now->fr_literal, - length, this_add_symbol, 0, - this_add_number, 0); + fix_new (frag_now, p + 1 - frag_now->fr_literal, + length, this_add_symbol, 0, + this_add_number, 0); } } } @@ -1199,113 +1199,113 @@ md_assemble (instruction_string) * 0 value. */ int -md_estimate_size_before_relax (fragP, segment) - register fragS *fragP; - register segT segment; + md_estimate_size_before_relax (fragP, segment) +register fragS *fragP; +register segT segment; { - register char *p; - register int old_fr_fix; - - old_fr_fix = fragP->fr_fix; - switch (fragP->fr_subtype) + register char *p; + register int old_fr_fix; + + old_fr_fix = fragP->fr_fix; + switch (fragP->fr_subtype) { case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF): - if (S_GET_SEGMENT(fragP->fr_symbol) == segment) + if (S_GET_SEGMENT(fragP->fr_symbol) == segment) { /* A relaxable case. */ - fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE); + fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE); } - else + else { - p = fragP->fr_literal + old_fr_fix; - p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */ - fragP->fr_fix += 1 + 4; - fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 1); - frag_wane (fragP); + p = fragP->fr_literal + old_fr_fix; + p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */ + fragP->fr_fix += 1 + 4; + fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 1); + frag_wane (fragP); } - break; - + break; + case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF): - if (S_GET_SEGMENT(fragP->fr_symbol) == segment) + if (S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE); + fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE); } - else + else { - p = fragP->fr_literal + old_fr_fix; - *fragP->fr_opcode ^= 1; /* Reverse sense of branch. */ - p[0] = 6; - p[1] = VAX_JMP; - p[2] = VAX_PC_RELATIVE_MODE; /* ...(PC) */ - fragP->fr_fix += 1 + 1 + 1 + 4; - fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 1); - frag_wane (fragP); + p = fragP->fr_literal + old_fr_fix; + *fragP->fr_opcode ^= 1; /* Reverse sense of branch. */ + p[0] = 6; + p[1] = VAX_JMP; + p[2] = VAX_PC_RELATIVE_MODE; /* ...(PC) */ + fragP->fr_fix += 1 + 1 + 1 + 4; + fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 1); + frag_wane (fragP); } - break; - + break; + case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_UNDF): - if (S_GET_SEGMENT(fragP->fr_symbol) == segment) + if (S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD); + fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD); } - else + else { - p = fragP->fr_literal + old_fr_fix; - p[0] = 2; - p[1] = 0; - p[2] = VAX_BRB; - p[3] = 6; - p[4] = VAX_JMP; - p[5] = VAX_PC_RELATIVE_MODE; /* ...(pc) */ - fragP->fr_fix += 2 + 2 + 1 + 1 + 4; - fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 1); - frag_wane (fragP); + p = fragP->fr_literal + old_fr_fix; + p[0] = 2; + p[1] = 0; + p[2] = VAX_BRB; + p[3] = 6; + p[4] = VAX_JMP; + p[5] = VAX_PC_RELATIVE_MODE; /* ...(pc) */ + fragP->fr_fix += 2 + 2 + 1 + 1 + 4; + fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 1); + frag_wane (fragP); } - break; - + break; + case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_UNDF): - if (S_GET_SEGMENT(fragP->fr_symbol) == segment) + if (S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE); + fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE); } - else + else { - p = fragP->fr_literal + old_fr_fix; - p[0] = 2; - p[1] = VAX_BRB; - p[2] = 6; - p[3] = VAX_JMP; - p[4] = VAX_PC_RELATIVE_MODE; /* ...(pc) */ - fragP->fr_fix += 1 + 2 + 1 + 1 + 4; - fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 1); - frag_wane (fragP); + p = fragP->fr_literal + old_fr_fix; + p[0] = 2; + p[1] = VAX_BRB; + p[2] = 6; + p[3] = VAX_JMP; + p[4] = VAX_PC_RELATIVE_MODE; /* ...(pc) */ + fragP->fr_fix += 1 + 2 + 1 + 1 + 4; + fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 1); + frag_wane (fragP); } - break; - + break; + case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF): - if (S_GET_SEGMENT(fragP->fr_symbol) == segment) + if (S_GET_SEGMENT(fragP->fr_symbol) == segment) { - fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE); + fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE); } - else + else { - p = fragP->fr_literal + old_fr_fix; - *fragP->fr_opcode += VAX_WIDEN_LONG; - p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */ - fragP->fr_fix += 1 + 4; - fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0, - fragP->fr_offset, 1); - frag_wane (fragP); + p = fragP->fr_literal + old_fr_fix; + *fragP->fr_opcode += VAX_WIDEN_LONG; + p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */ + fragP->fr_fix += 1 + 4; + fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0, + fragP->fr_offset, 1); + frag_wane (fragP); } - break; - + break; + default: - break; + break; } - return (fragP->fr_var + fragP->fr_fix - old_fr_fix); + return (fragP->fr_var + fragP->fr_fix - old_fr_fix); } /* md_estimate_size_before_relax() */ /* @@ -1320,160 +1320,161 @@ md_estimate_size_before_relax (fragP, segment) * Caller will turn frag into a ".space 0". */ void -md_convert_frag (fragP) - register fragS *fragP; -{ - register char *addressP; /* -> _var to change. */ - register char *opcodeP; /* -> opcode char(s) to change. */ - register short int length_code; /* 2=long 1=word 0=byte */ - register short int extension; /* Size of relaxed address. */ - /* Added to fr_fix: incl. ALL var chars. */ - register symbolS *symbolP; - register long where; - register long address_of_var; - /* Where, in file space, is _var of *fragP? */ - register long target_address; - /* Where, in file space, does addr point? */ - - know (fragP->fr_type == rs_machine_dependent); - length_code = fragP->fr_subtype & 3; /* depends on ENCODE_RELAX() */ - know (length_code >= 0 && length_code < 3); - where = fragP->fr_fix; - addressP = fragP->fr_literal + where; - opcodeP = fragP->fr_opcode; - symbolP = fragP->fr_symbol; - know (symbolP); - target_address = symbolP->sy_value + fragP->fr_offset; - address_of_var = fragP->fr_address + where; - switch (fragP->fr_subtype) + md_convert_frag (headers, fragP) +object_headers *headers; +register fragS *fragP; +{ + register char *addressP; /* -> _var to change. */ + register char *opcodeP; /* -> opcode char(s) to change. */ + register short int length_code; /* 2=long 1=word 0=byte */ + register short int extension; /* Size of relaxed address. */ + /* Added to fr_fix: incl. ALL var chars. */ + register symbolS *symbolP; + register long where; + register long address_of_var; + /* Where, in file space, is _var of *fragP? */ + register long target_address; + /* Where, in file space, does addr point? */ + + know (fragP->fr_type == rs_machine_dependent); + length_code = fragP->fr_subtype & 3; /* depends on ENCODE_RELAX() */ + know (length_code >= 0 && length_code < 3); + where = fragP->fr_fix; + addressP = fragP->fr_literal + where; + opcodeP = fragP->fr_opcode; + symbolP = fragP->fr_symbol; + know (symbolP); + target_address = symbolP->sy_value + fragP->fr_offset; + address_of_var = fragP->fr_address + where; + switch (fragP->fr_subtype) { case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE): - know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ - addressP[0] |= 0xAF; /* Byte displacement. */ - addressP[1] = target_address - (address_of_var + 2); - extension = 2; - break; - + know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ + addressP[0] |= 0xAF; /* Byte displacement. */ + addressP[1] = target_address - (address_of_var + 2); + extension = 2; + break; + case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD): - know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ - addressP[0] |= 0xCF; /* Word displacement. */ - md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2); - extension = 3; - break; - + know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ + addressP[0] |= 0xCF; /* Word displacement. */ + md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2); + extension = 3; + break; + case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG): - know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ - addressP[0] |= 0xEF; /* Long word displacement. */ - md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4); - extension = 5; - break; - + know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ + addressP[0] |= 0xEF; /* Long word displacement. */ + md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4); + extension = 5; + break; + case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE): - addressP[0] = target_address - (address_of_var + 1); - extension = 1; - break; - + addressP[0] = target_address - (address_of_var + 1); + extension = 1; + break; + case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD): - opcodeP[0] ^= 1; /* Reverse sense of test. */ - addressP[0] = 3; - addressP[1] = VAX_BRB + VAX_WIDEN_WORD; - md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2); - extension = 4; - break; - + opcodeP[0] ^= 1; /* Reverse sense of test. */ + addressP[0] = 3; + addressP[1] = VAX_BRB + VAX_WIDEN_WORD; + md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2); + extension = 4; + break; + case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG): - opcodeP[0] ^= 1; /* Reverse sense of test. */ - addressP[0] = 6; - addressP[1] = VAX_JMP; - addressP[2] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 3, target_address, 4); - extension = 7; - break; - + opcodeP[0] ^= 1; /* Reverse sense of test. */ + addressP[0] = 6; + addressP[1] = VAX_JMP; + addressP[2] = VAX_PC_RELATIVE_MODE; + md_number_to_chars (addressP + 3, target_address, 4); + extension = 7; + break; + case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE): - addressP[0] = target_address - (address_of_var + 1); - extension = 1; - break; - + addressP[0] = target_address - (address_of_var + 1); + extension = 1; + break; + case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD): - opcodeP[0] += VAX_WIDEN_WORD; /* brb -> brw, bsbb -> bsbw */ - md_number_to_chars (addressP, target_address - (address_of_var + 2), 2); - extension = 2; - break; - + opcodeP[0] += VAX_WIDEN_WORD; /* brb -> brw, bsbb -> bsbw */ + md_number_to_chars (addressP, target_address - (address_of_var + 2), 2); + extension = 2; + break; + case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG): - opcodeP[0] += VAX_WIDEN_LONG; /* brb -> jmp, bsbb -> jsb */ - addressP[0] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4); - extension = 5; - break; - + opcodeP[0] += VAX_WIDEN_LONG; /* brb -> jmp, bsbb -> jsb */ + addressP[0] = VAX_PC_RELATIVE_MODE; + md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4); + extension = 5; + break; + case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD): - md_number_to_chars (addressP, target_address - (address_of_var + 2), 2); - extension = 2; - break; - + md_number_to_chars (addressP, target_address - (address_of_var + 2), 2); + extension = 2; + break; + case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_LONG): - addressP[0] = 2; - addressP[1] = 0; - addressP[2] = VAX_BRB; - addressP[3] = 6; - addressP[4] = VAX_JMP; - addressP[5] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 6, target_address, 4); - extension = 10; - break; - + addressP[0] = 2; + addressP[1] = 0; + addressP[2] = VAX_BRB; + addressP[3] = 6; + addressP[4] = VAX_JMP; + addressP[5] = VAX_PC_RELATIVE_MODE; + md_number_to_chars (addressP + 6, target_address, 4); + extension = 10; + break; + case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE): - addressP[0] = target_address - (address_of_var + 1); - extension = 1; - break; - + addressP[0] = target_address - (address_of_var + 1); + extension = 1; + break; + case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_WORD): - addressP[0] = 2; - addressP[1] = VAX_BRB; - addressP[2] = 3; - addressP[3] = VAX_BRW; - md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2); - extension = 6; - break; - + addressP[0] = 2; + addressP[1] = VAX_BRB; + addressP[2] = 3; + addressP[3] = VAX_BRW; + md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2); + extension = 6; + break; + case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_LONG): - addressP[0] = 2; - addressP[1] = VAX_BRB; - addressP[2] = 6; - addressP[3] = VAX_JMP; - addressP[4] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 5, target_address, 4); - extension = 9; - break; - + addressP[0] = 2; + addressP[1] = VAX_BRB; + addressP[2] = 6; + addressP[3] = VAX_JMP; + addressP[4] = VAX_PC_RELATIVE_MODE; + md_number_to_chars (addressP + 5, target_address, 4); + extension = 9; + break; + default: - BAD_CASE (fragP->fr_subtype); - break; + BAD_CASE (fragP->fr_subtype); + break; } - fragP->fr_fix += extension; + fragP->fr_fix += extension; } /* Translate internal format of relocation info into target format. - + On vax: first 4 bytes are normal unsigned long, next three bytes are symbolnum, least sig. byte first. Last byte is broken up with the upper nibble as nuthin, bit 3 as extern, bits 2 & 1 as length, and bit 0 as pcrel. */ void -md_ri_to_chars (the_bytes, ri) - char *the_bytes; - struct reloc_info_generic ri; -{ - /* this is easy */ - md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address)); - /* now the fun stuff */ - the_bytes[6] = (ri.r_symbolnum >> 16) & 0x0ff; - the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff; - the_bytes[4] = ri.r_symbolnum & 0x0ff; - the_bytes[7] = (((ri.r_extern << 3) & 0x08) | ((ri.r_length << 1) & 0x06) | - ((ri.r_pcrel << 0) & 0x01)) & 0x0F; + md_ri_to_chars (the_bytes, ri) +char *the_bytes; +struct reloc_info_generic ri; +{ + /* this is easy */ + md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address)); + /* now the fun stuff */ + the_bytes[6] = (ri.r_symbolnum >> 16) & 0x0ff; + the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff; + the_bytes[4] = ri.r_symbolnum & 0x0ff; + the_bytes[7] = (((ri.r_extern << 3) & 0x08) | ((ri.r_length << 1) & 0x06) | + ((ri.r_pcrel << 0) & 0x01)) & 0x0F; } /* @@ -1543,8 +1544,8 @@ md_ri_to_chars (the_bytes, ri) */ static char *op_hash = NULL; /* handle of the OPCODE hash table */ - /* NULL means any use before vip_begin() */ - /* will crash */ +/* NULL means any use before vip_begin() */ +/* will crash */ /* * In: 1 character, from "bdfghloqpw" being the data-type of an operand @@ -1556,24 +1557,24 @@ static char *op_hash = NULL; /* handle of the OPCODE hash table */ static const short int vax_operand_width_size[256] = { - + #define _ 0 - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16, /* ..b.d.fgh...l..o */ - _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _, /* .q.....w........ */ - _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16, /* ..b.d.fgh...l..o */ - _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _, /* .q.....w........ */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}; + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16, /* ..b.d.fgh...l..o */ + _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _, /* .q.....w........ */ + _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16, /* ..b.d.fgh...l..o */ + _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _, /* .q.....w........ */ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}; #undef _ /* @@ -1587,7 +1588,7 @@ static const short int vax_operand_width_size[256] = * So change 'vax.opcodes', then re-generate this table. */ -#include "vax-opcode.h" +#include "opcode/vax.h" /* * This is a table of optional op-codes. All of them represent @@ -1625,107 +1626,107 @@ static const short int vax_operand_width_size[256] = */ #if (VIT_OPCODE_SYNTHETIC != 0x80000000) You have just broken the encoding below, which assumes the sign bit - means 'I am an imaginary instruction'. + means 'I am an imaginary instruction'. #endif - + #if (VIT_OPCODE_SPECIAL != 0x40000000) - You have just broken the encoding below, which assumes the 0x40 M bit means - 'I am not to be "optimised" the way normal branches are'. +You have just broken the encoding below, which assumes the 0x40 M bit means + 'I am not to be "optimised" the way normal branches are'. #endif - -static const struct vot - synthetic_votstrs[] = -{ - {"jbsb", - {"b-", 0xC0000010}}, /* BSD 4.2 */ - /* jsb used already */ - {"jbr", - {"b-", 0xC0000011}}, /* BSD 4.2 */ - {"jr", - {"b-", 0xC0000011}}, /* consistent */ - {"jneq", - {"b?", 0x80000012}}, - {"jnequ", - {"b?", 0x80000012}}, - {"jeql", - {"b?", 0x80000013}}, - {"jeqlu", - {"b?", 0x80000013}}, - {"jgtr", - {"b?", 0x80000014}}, - {"jleq", - {"b?", 0x80000015}}, - /* un-used opcodes here */ - {"jgeq", - {"b?", 0x80000018}}, - {"jlss", - {"b?", 0x80000019}}, - {"jgtru", - {"b?", 0x8000001a}}, - {"jlequ", - {"b?", 0x8000001b}}, - {"jvc", - {"b?", 0x8000001c}}, - {"jvs", - {"b?", 0x8000001d}}, - {"jgequ", - {"b?", 0x8000001e}}, - {"jcc", - {"b?", 0x8000001e}}, - {"jlssu", - {"b?", 0x8000001f}}, - {"jcs", - {"b?", 0x8000001f}}, - - {"jacbw", - {"rwrwmwb!", 0xC000003d}}, - {"jacbf", - {"rfrfmfb!", 0xC000004f}}, - {"jacbd", - {"rdrdmdb!", 0xC000006f}}, - {"jacbb", - {"rbrbmbb!", 0xC000009d}}, - {"jacbl", - {"rlrlmlb!", 0xC00000f1}}, - {"jacbg", - {"rgrgmgb!", 0xC0004ffd}}, - {"jacbh", - {"rhrhmhb!", 0xC0006ffd}}, - - {"jbs", - {"rlvbb?", 0x800000e0}}, - {"jbc", - {"rlvbb?", 0x800000e1}}, - {"jbss", - {"rlvbb?", 0x800000e2}}, - {"jbcs", - {"rlvbb?", 0x800000e3}}, - {"jbsc", - {"rlvbb?", 0x800000e4}}, - {"jbcc", - {"rlvbb?", 0x800000e5}}, - {"jbssi", - {"rlvbb?", 0x800000e6}}, - {"jbcci", - {"rlvbb?", 0x800000e7}}, - {"jlbs", - {"rlb?", 0x800000e8}}, /* JF changed from rlvbb? */ - {"jlbc", - {"rlb?", 0x800000e9}}, /* JF changed from rlvbb? */ - - {"jaoblss", - {"rlmlb:", 0xC00000f2}}, - {"jaobleq", - {"rlmlb:", 0xC00000f3}}, - {"jsobgeq", - {"mlb:", 0xC00000f4}}, /* JF was rlmlb: */ - {"jsobgtr", - {"mlb:", 0xC00000f5}}, /* JF was rlmlb: */ - -/* CASEx has no branch addresses in our conception of it. */ -/* You should use ".word ..." statements after the "case ...". */ - - {"", ""} /* empty is end sentinel */ + + static const struct vot + synthetic_votstrs[] = +{ +{"jbsb", + {"b-", 0xC0000010}}, /* BSD 4.2 */ + /* jsb used already */ +{"jbr", + {"b-", 0xC0000011}}, /* BSD 4.2 */ +{"jr", + {"b-", 0xC0000011}}, /* consistent */ +{"jneq", + {"b?", 0x80000012}}, +{"jnequ", + {"b?", 0x80000012}}, +{"jeql", + {"b?", 0x80000013}}, +{"jeqlu", + {"b?", 0x80000013}}, +{"jgtr", + {"b?", 0x80000014}}, +{"jleq", + {"b?", 0x80000015}}, + /* un-used opcodes here */ +{"jgeq", + {"b?", 0x80000018}}, +{"jlss", + {"b?", 0x80000019}}, +{"jgtru", + {"b?", 0x8000001a}}, +{"jlequ", + {"b?", 0x8000001b}}, +{"jvc", + {"b?", 0x8000001c}}, +{"jvs", + {"b?", 0x8000001d}}, +{"jgequ", + {"b?", 0x8000001e}}, +{"jcc", + {"b?", 0x8000001e}}, +{"jlssu", + {"b?", 0x8000001f}}, +{"jcs", + {"b?", 0x8000001f}}, + +{"jacbw", + {"rwrwmwb!", 0xC000003d}}, +{"jacbf", + {"rfrfmfb!", 0xC000004f}}, +{"jacbd", + {"rdrdmdb!", 0xC000006f}}, +{"jacbb", + {"rbrbmbb!", 0xC000009d}}, +{"jacbl", + {"rlrlmlb!", 0xC00000f1}}, +{"jacbg", + {"rgrgmgb!", 0xC0004ffd}}, +{"jacbh", + {"rhrhmhb!", 0xC0006ffd}}, + +{"jbs", + {"rlvbb?", 0x800000e0}}, +{"jbc", + {"rlvbb?", 0x800000e1}}, +{"jbss", + {"rlvbb?", 0x800000e2}}, +{"jbcs", + {"rlvbb?", 0x800000e3}}, +{"jbsc", + {"rlvbb?", 0x800000e4}}, +{"jbcc", + {"rlvbb?", 0x800000e5}}, +{"jbssi", + {"rlvbb?", 0x800000e6}}, +{"jbcci", + {"rlvbb?", 0x800000e7}}, +{"jlbs", + {"rlb?", 0x800000e8}}, /* JF changed from rlvbb? */ +{"jlbc", + {"rlb?", 0x800000e9}}, /* JF changed from rlvbb? */ + +{"jaoblss", + {"rlmlb:", 0xC00000f2}}, +{"jaobleq", + {"rlmlb:", 0xC00000f3}}, +{"jsobgeq", + {"mlb:", 0xC00000f4}}, /* JF was rlmlb: */ +{"jsobgtr", + {"mlb:", 0xC00000f5}}, /* JF was rlmlb: */ + + /* CASEx has no branch addresses in our conception of it. */ + /* You should use ".word ..." statements after the "case ...". */ + +{"", ""} /* empty is end sentinel */ }; /* synthetic_votstrs */ @@ -1741,40 +1742,40 @@ static const struct vot */ char * -vip_begin (synthetic_too, immediate, indirect, displen) - int synthetic_too; /* TRUE means include jXXX op-codes. */ - char *immediate, *indirect, *displen; + vip_begin (synthetic_too, immediate, indirect, displen) +int synthetic_too; /* TRUE means include jXXX op-codes. */ +char *immediate, *indirect, *displen; { - register const struct vot *vP; /* scan votstrs */ - register char *retval; /* error text */ - - char *hash_insert (); /* */ - char *hash_new (); /* lies */ - - if ((op_hash = hash_new ())) + register const struct vot *vP; /* scan votstrs */ + register char *retval; /* error text */ + + char *hash_insert (); /* */ + char *hash_new (); /* lies */ + + if ((op_hash = hash_new ())) { - retval = ""; /* OK so far */ - for (vP = votstrs; *vP->vot_name && !*retval; vP++) + retval = ""; /* OK so far */ + for (vP = votstrs; *vP->vot_name && !*retval; vP++) { - retval = hash_insert (op_hash, vP->vot_name, &vP->vot_detail); + retval = hash_insert (op_hash, vP->vot_name, &vP->vot_detail); } - if (synthetic_too) + if (synthetic_too) { - for (vP = synthetic_votstrs; *vP->vot_name && !*retval; vP++) + for (vP = synthetic_votstrs; *vP->vot_name && !*retval; vP++) { - retval = hash_insert (op_hash, vP->vot_name, &vP->vot_detail); + retval = hash_insert (op_hash, vP->vot_name, &vP->vot_detail); } } } - else + else { - retval = "virtual memory exceeded"; + retval = "virtual memory exceeded"; } #ifndef CONST_TABLE - vip_op_defaults (immediate, indirect, displen); + vip_op_defaults (immediate, indirect, displen); #endif - - return (retval); + + return (retval); } @@ -1817,120 +1818,120 @@ vip_end () */ char * /* "" or bug string */ -vip (vitP, instring) - struct vit *vitP; /* We build an exploded instruction here. */ - char *instring; /* Text of a vax instruction: we modify. */ -{ - register struct vot_wot *vwP; /* How to bit-encode this opcode. */ - register char *p; /* 1/skip whitespace.2/scan vot_how */ - register char *q; /* */ - register char *bug; /* "" or program logic error */ - register unsigned char count; /* counts number of operands seen */ - register struct vop *operandp;/* scan operands in struct vit */ - register char *alloperr; /* error over all operands */ - register char c; /* Remember char, (we clobber it */ - /* with '\0' temporarily). */ - register vax_opcodeT oc; /* Op-code of this instruction. */ - - struct vot_wot *hash_find (); - char *vip_op (); - - bug = ""; - if (*instring == ' ') - ++instring; /* Skip leading whitespace. */ - for (p = instring; *p && *p != ' '; p++) - ; /* MUST end in end-of-string or exactly 1 space. */ - /* Scanned up to end of operation-code. */ - /* Operation-code is ended with whitespace. */ - if (p - instring == 0) + vip (vitP, instring) +struct vit *vitP; /* We build an exploded instruction here. */ +char *instring; /* Text of a vax instruction: we modify. */ +{ + register struct vot_wot *vwP; /* How to bit-encode this opcode. */ + register char *p; /* 1/skip whitespace.2/scan vot_how */ + register char *q; /* */ + register char *bug; /* "" or program logic error */ + register unsigned char count; /* counts number of operands seen */ + register struct vop *operandp;/* scan operands in struct vit */ + register char *alloperr; /* error over all operands */ + register char c; /* Remember char, (we clobber it */ + /* with '\0' temporarily). */ + register vax_opcodeT oc; /* Op-code of this instruction. */ + + struct vot_wot *hash_find (); + char *vip_op (); + + bug = ""; + if (*instring == ' ') + ++instring; /* Skip leading whitespace. */ + for (p = instring; *p && *p != ' '; p++) + ; /* MUST end in end-of-string or exactly 1 space. */ + /* Scanned up to end of operation-code. */ + /* Operation-code is ended with whitespace. */ + if (p - instring == 0) { - vitP->vit_error = "No operator"; - count = 0; - bzero (vitP->vit_opcode, sizeof (vitP->vit_opcode)); + vitP->vit_error = "No operator"; + count = 0; + bzero (vitP->vit_opcode, sizeof (vitP->vit_opcode)); } - else + else { - c = *p; - *p = '\0'; - /* - * Here with instring pointing to what better be an op-name, and p - * pointing to character just past that. - * We trust instring points to an op-name, with no whitespace. - */ - vwP = hash_find (op_hash, instring); - *p = c; /* Restore char after op-code. */ - if (vwP == 0) + c = *p; + *p = '\0'; + /* + * Here with instring pointing to what better be an op-name, and p + * pointing to character just past that. + * We trust instring points to an op-name, with no whitespace. + */ + vwP = hash_find (op_hash, instring); + *p = c; /* Restore char after op-code. */ + if (vwP == 0) { - vitP->vit_error = "Unknown operator"; - count = 0; - bzero (vitP->vit_opcode, sizeof (vitP->vit_opcode)); + vitP->vit_error = "Unknown operator"; + count = 0; + bzero (vitP->vit_opcode, sizeof (vitP->vit_opcode)); } - else + else { - /* - * We found a match! So lets pick up as many operands as the - * instruction wants, and even gripe if there are too many. - * We expect comma to seperate each operand. - * We let instring track the text, while p tracks a part of the - * struct vot. - */ - /* - * The lines below know about 2-byte opcodes starting FD,FE or FF. - * They also understand synthetic opcodes. Note: - * we return 32 bits of opcode, including bucky bits, BUT - * an opcode length is either 8 or 16 bits for vit_opcode_nbytes. - */ - oc = vwP->vot_code; /* The op-code. */ - vitP->vit_opcode_nbytes = (oc & 0xFF) >= 0xFD ? 2 : 1; - md_number_to_chars (vitP->vit_opcode, oc, 4); - count = 0; /* no operands seen yet */ - instring = p; /* point just past operation code */ - alloperr = ""; - for (p = vwP->vot_how, operandp = vitP->vit_operand; - !*alloperr && !*bug && *p; - operandp++, p += 2 - ) + /* + * We found a match! So lets pick up as many operands as the + * instruction wants, and even gripe if there are too many. + * We expect comma to seperate each operand. + * We let instring track the text, while p tracks a part of the + * struct vot. + */ + /* + * The lines below know about 2-byte opcodes starting FD,FE or FF. + * They also understand synthetic opcodes. Note: + * we return 32 bits of opcode, including bucky bits, BUT + * an opcode length is either 8 or 16 bits for vit_opcode_nbytes. + */ + oc = vwP->vot_code; /* The op-code. */ + vitP->vit_opcode_nbytes = (oc & 0xFF) >= 0xFD ? 2 : 1; + md_number_to_chars (vitP->vit_opcode, oc, 4); + count = 0; /* no operands seen yet */ + instring = p; /* point just past operation code */ + alloperr = ""; + for (p = vwP->vot_how, operandp = vitP->vit_operand; + !*alloperr && !*bug && *p; + operandp++, p += 2 + ) { - /* - * Here to parse one operand. Leave instring pointing just - * past any one ',' that marks the end of this operand. - */ - if (!p[1]) - bug = "p"; /* ODD(!!) number of bytes in vot_how?? */ - else if (*instring) + /* + * Here to parse one operand. Leave instring pointing just + * past any one ',' that marks the end of this operand. + */ + if (!p[1]) + bug = "p"; /* ODD(!!) number of bytes in vot_how?? */ + else if (*instring) { - for (q = instring; (c = *q) && c != ','; q++) - ; - /* - * Q points to ',' or '\0' that ends argument. C is that - * character. - */ - *q = 0; - operandp->vop_width = p[1]; - operandp->vop_nbytes = vax_operand_width_size[p[1]]; - operandp->vop_access = p[0]; - bug = vip_op (instring, operandp); - *q = c; /* Restore input text. */ - if (*(operandp->vop_error)) - alloperr = "Bad operand"; - instring = q + (c ? 1 : 0); /* next operand (if any) */ - count++; /* won another argument, may have an operr */ + for (q = instring; (c = *q) && c != ','; q++) + ; + /* + * Q points to ',' or '\0' that ends argument. C is that + * character. + */ + *q = 0; + operandp->vop_width = p[1]; + operandp->vop_nbytes = vax_operand_width_size[p[1]]; + operandp->vop_access = p[0]; + bug = vip_op (instring, operandp); + *q = c; /* Restore input text. */ + if (*(operandp->vop_error)) + alloperr = "Bad operand"; + instring = q + (c ? 1 : 0); /* next operand (if any) */ + count++; /* won another argument, may have an operr */ } - else - alloperr = "Not enough operands"; + else + alloperr = "Not enough operands"; } - if (!*alloperr) + if (!*alloperr) { - if (*instring == ' ') - instring++; /* Skip whitespace. */ - if (*instring) - alloperr = "Too many operands"; + if (*instring == ' ') + instring++; /* Skip whitespace. */ + if (*instring) + alloperr = "Too many operands"; } - vitP->vit_error = alloperr; + vitP->vit_error = alloperr; } } - vitP->vit_operands = count; - return (bug); + vitP->vit_operands = count; + return (bug); } #ifdef test @@ -1953,82 +1954,82 @@ char *vip (); main () { - char *p; - char *vip_begin (); - - printf ("0 means no synthetic instructions. "); - printf ("Value for vip_begin? "); - gets (answer); - sscanf (answer, "%d", &mysynth); - printf ("Synthetic opcodes %s be included.\n", mysynth ? "will" : "will not"); - printf ("enter immediate symbols eg enter # "); - gets (my_immediate); - printf ("enter indirect symbols eg enter @ "); - gets (my_indirect); - printf ("enter displen symbols eg enter ^ "); - gets (my_displen); - if (*(p = vip_begin (mysynth, my_immediate, my_indirect, my_displen))) + char *p; + char *vip_begin (); + + printf ("0 means no synthetic instructions. "); + printf ("Value for vip_begin? "); + gets (answer); + sscanf (answer, "%d", &mysynth); + printf ("Synthetic opcodes %s be included.\n", mysynth ? "will" : "will not"); + printf ("enter immediate symbols eg enter # "); + gets (my_immediate); + printf ("enter indirect symbols eg enter @ "); + gets (my_indirect); + printf ("enter displen symbols eg enter ^ "); + gets (my_displen); + if (*(p = vip_begin (mysynth, my_immediate, my_indirect, my_displen))) { - error ("vip_begin=%s", p); + error ("vip_begin=%s", p); } - printf ("An empty input line will quit you from the vax instruction parser\n"); - for (;;) + printf ("An empty input line will quit you from the vax instruction parser\n"); + for (;;) { - printf ("vax instruction: "); - fflush (stdout); - gets (answer); - if (!*answer) + printf ("vax instruction: "); + fflush (stdout); + gets (answer); + if (!*answer) { - break; /* out of for each input text loop */ + break; /* out of for each input text loop */ } - mybug = vip (&myvit, answer); - if (*mybug) + mybug = vip (&myvit, answer); + if (*mybug) { - printf ("BUG:\"%s\"\n", mybug); + printf ("BUG:\"%s\"\n", mybug); } - if (*myvit.vit_error) + if (*myvit.vit_error) { - printf ("ERR:\"%s\"\n", myvit.vit_error); + printf ("ERR:\"%s\"\n", myvit.vit_error); } - printf ("opcode="); - for (mycount = myvit.vit_opcode_nbytes, p = myvit.vit_opcode; - mycount; - mycount--, p++ - ) + printf ("opcode="); + for (mycount = myvit.vit_opcode_nbytes, p = myvit.vit_opcode; + mycount; + mycount--, p++ + ) { - printf ("%02x ", *p & 0xFF); + printf ("%02x ", *p & 0xFF); } - printf (" operand count=%d.\n", mycount = myvit.vit_operands); - for (myvop = myvit.vit_operand; mycount; mycount--, myvop++) + printf (" operand count=%d.\n", mycount = myvit.vit_operands); + for (myvop = myvit.vit_operand; mycount; mycount--, myvop++) { - printf ("mode=%xx reg=%xx ndx=%xx len='%c'=%c%c%d. expr=\"", - myvop->vop_mode, myvop->vop_reg, myvop->vop_ndx, - myvop->vop_short, myvop->vop_access, myvop->vop_width, - myvop->vop_nbytes); - for (p = myvop->vop_expr_begin; p <= myvop->vop_expr_end; p++) + printf ("mode=%xx reg=%xx ndx=%xx len='%c'=%c%c%d. expr=\"", + myvop->vop_mode, myvop->vop_reg, myvop->vop_ndx, + myvop->vop_short, myvop->vop_access, myvop->vop_width, + myvop->vop_nbytes); + for (p = myvop->vop_expr_begin; p <= myvop->vop_expr_end; p++) { - putchar (*p); + putchar (*p); } - printf ("\"\n"); - if (*myvop->vop_error) + printf ("\"\n"); + if (*myvop->vop_error) { - printf (" err:\"%s\"\n", myvop->vop_error); + printf (" err:\"%s\"\n", myvop->vop_error); } - if (*myvop->vop_warn) + if (*myvop->vop_warn) { - printf (" wrn:\"%s\"\n", myvop->vop_warn); + printf (" wrn:\"%s\"\n", myvop->vop_warn); } } } - vip_end (); - exit (); + vip_end (); + exit (); } #endif /* #ifdef test */ /* end of vax_ins_parse.c */ - /* JF this used to be a separate file also */ +/* JF this used to be a separate file also */ /* vax_reg_parse.c - convert a VAX register name to a number */ /* Copyright (C) 1987 Free Software Foundation, Inc. A part of GNU. */ @@ -2072,53 +2073,53 @@ main () #define PC (15) int /* return -1 or 0:15 */ -vax_reg_parse (c1, c2, c3) /* 3 chars of register name */ - char c1, c2, c3; /* c3 == 0 if 2-character reg name */ + vax_reg_parse (c1, c2, c3) /* 3 chars of register name */ +char c1, c2, c3; /* c3 == 0 if 2-character reg name */ { - register int retval; /* return -1:15 */ - - retval = -1; - - if (isupper (c1)) - c1 = tolower (c1); - if (isupper (c2)) - c2 = tolower (c2); - if (isdigit (c2) && c1 == 'r') + register int retval; /* return -1:15 */ + + retval = -1; + + if (isupper (c1)) + c1 = tolower (c1); + if (isupper (c2)) + c2 = tolower (c2); + if (isdigit (c2) && c1 == 'r') { - retval = c2 - '0'; - if (isdigit (c3)) + retval = c2 - '0'; + if (isdigit (c3)) { - retval = retval * 10 + c3 - '0'; - retval = (retval > 15) ? -1 : retval; - /* clamp the register value to 1 hex digit */ + retval = retval * 10 + c3 - '0'; + retval = (retval > 15) ? -1 : retval; + /* clamp the register value to 1 hex digit */ } - else if (c3) - retval = -1; /* c3 must be '\0' or a digit */ + else if (c3) + retval = -1; /* c3 must be '\0' or a digit */ } - else if (c3) /* There are no three letter regs */ - retval = -1; - else if (c2 == 'p') + else if (c3) /* There are no three letter regs */ + retval = -1; + else if (c2 == 'p') { - switch (c1) + switch (c1) { case 's': - retval = SP; - break; + retval = SP; + break; case 'f': - retval = FP; - break; + retval = FP; + break; case 'a': - retval = AP; - break; + retval = AP; + break; default: - retval = -1; + retval = -1; } } - else if (c1 == 'p' && c2 == 'c') - retval = PC; - else - retval = -1; - return (retval); + else if (c1 == 'p' && c2 == 'c') + retval = PC; + else + retval = -1; + return (retval); } /* @@ -2218,11 +2219,11 @@ vax_reg_parse (c1, c2, c3) /* 3 chars of register name */ */ - /* vax registers we need to know */ +/* vax registers we need to know */ /* JF #define SP (14) -/* JF for one big happy file #define PC (15) */ + /* JF for one big happy file #define PC (15) */ - /* useful ideas */ +/* useful ideas */ /* #define TRUE (1) */ /* #define FALSE (0) */ @@ -2235,7 +2236,7 @@ vax_reg_parse (c1, c2, c3) /* 3 chars of register name */ * 3 concepts that DEC writes '#', '@', '^'. */ - /* character tests */ +/* character tests */ #define VIP_IMMEDIATE 01 /* Character is like DEC # */ #define VIP_INDIRECT 02 /* Char is like DEC @ */ #define VIP_DISPLEN 04 /* Char is like DEC ^ */ @@ -2254,25 +2255,25 @@ vax_reg_parse (c1, c2, c3) /* 3 chars of register name */ #define S VIP_INDIRECT, #define D VIP_DISPLEN, static const char -vip_metacharacters[256] = { -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*^@ ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O*/ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_*/ -_ _ _ _ I _ _ _ _ _ S _ _ _ _ _/*sp ! " # $ % & ' ( ) * + , - . /*/ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*0 1 2 3 4 5 6 7 8 9 : ; < = > ?*/ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*@ A B C D E F G H I J K L M N O*/ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*P Q R S T U V W X Y Z [ \ ] ^ _*/ -D _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*` a b c d e f g h i j k l m n o*/ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*p q r s t u v w x y z { | } ~ ^?*/ - -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ -}; + vip_metacharacters[256] = { + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*^@ ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O*/ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_*/ + _ _ _ _ I _ _ _ _ _ S _ _ _ _ _/*sp ! " # $ % & ' ( ) * + , - . /*/ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*0 1 2 3 4 5 6 7 8 9 : ; < = > ?*/ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*@ A B C D E F G H I J K L M N O*/ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*P Q R S T U V W X Y Z [ \ ] ^ _*/ + D _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*` a b c d e f g h i j k l m n o*/ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*p q r s t u v w x y z { | } ~ ^?*/ + + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + }; #undef _ #undef I #undef S @@ -2284,34 +2285,34 @@ static char vip_metacharacters[256]; #if 0 static #ifdef __GNUC__ -inline + inline #endif -static void -vip_op_1(bit,syms) + static void + vip_op_1(bit,syms) int bit; char *syms; { - unsigned char t; - - while(t= *syms++) - vip_metacharacters[t]|=bit; + unsigned char t; + + while(t= *syms++) + vip_metacharacters[t]|=bit; } #else #define vip_op_1(bit,syms) { \ - unsigned char t; \ - char *table=vip_metacharacters; \ - while(t= *syms++) \ - table[t]|=bit; \ - } + unsigned char t; \ + char *table=vip_metacharacters; \ + while(t= *syms++) \ + table[t]|=bit; \ + } #endif vip_op_defaults (immediate, indirect, displen) /* can be called any time */ - char *immediate, /* Strings of characters for each job. */ - *indirect, *displen; /* more arguments may appear in future! */ + char *immediate, /* Strings of characters for each job. */ + *indirect, *displen; /* more arguments may appear in future! */ { - vip_op_1 (VIP_IMMEDIATE, immediate); - vip_op_1 (VIP_INDIRECT, indirect); - vip_op_1 (VIP_DISPLEN, displen); + vip_op_1 (VIP_IMMEDIATE, immediate); + vip_op_1 (VIP_INDIRECT, indirect); + vip_op_1 (VIP_DISPLEN, displen); } #endif @@ -2375,372 +2376,371 @@ vip_op_defaults (immediate, indirect, displen) /* can be called any time */ */ char * /* (code here) bug message, "" = OK */ - /* our code bug, NOT bad assembly language */ -vip_op (optext, vopP) - char *optext; /* user's input string e.g.: */ - /* "@B^foo@bar(AP)[FP]:" */ - struct vop *vopP; /* In: vop_access, vop_width. */ - /* Out: _ndx, _reg, _mode, _short, _warn, */ - /* _error _expr_begin, _expr_end, _nbytes. */ - /* vop_nbytes : number of bytes in a datum. */ -{ - char *p; /* track operand text forward */ - char *q; /* track operand text backward */ - int at; /* TRUE if leading '@' ('*') seen */ - char len; /* one of " bilsw" */ - int hash; /* TRUE if leading '#' ('$') seen */ - int sign; /* -1, 0 or +1 */ - int paren; /* TRUE if () surround register */ - int reg; /* register number, -1:absent */ - int ndx; /* index register number -1:absent */ - char *bug; /* report any logic error in here, ""==OK */ - char *err; /* report illegal operand, ""==OK */ - /* " " is a FAKE error: means we won */ - /* ANY err that begins with ' ' is a fake. */ - /* " " is converted to "" before return */ - char *wrn; /* warn about weird modes pf address */ - char *oldq; /* preserve q in case we backup */ - int mode; /* build up 4-bit operand mode here */ - /* note: index mode is in ndx, this is */ - /* the major mode of operand address */ -/* - * Notice how we move wrong-arg-type bugs INSIDE this module: if we - * get the types wrong below, we lose at compile time rather than at - * lint or run time. - */ - char access; /* vop_access. */ - char width; /* vop_width. */ - - int vax_reg_parse (); /* returns 0:15 or -1 if not a register */ - - access = vopP->vop_access; - width = vopP->vop_width; - bug = /* none of our code bugs (yet) */ - err = /* no user text errors */ - wrn = ""; /* no warnings even */ - - p = optext; - - if (*p == ' ') /* Expect all whitespace reduced to ' '. */ - p++; /* skip over whitespace */ - - if (at = INDIRECTP (*p)) - { /* TRUE if *p=='@'(or '*' for Un*x) */ - p++; /* at is determined */ - if (*p == ' ') /* Expect all whitespace reduced to ' '. */ + /* our code bug, NOT bad assembly language */ + vip_op (optext, vopP) + char *optext; /* user's input string e.g.: */ + /* "@B^foo@bar(AP)[FP]:" */ + struct vop *vopP; /* In: vop_access, vop_width. */ + /* Out: _ndx, _reg, _mode, _short, _warn, */ + /* _error _expr_begin, _expr_end, _nbytes. */ + /* vop_nbytes : number of bytes in a datum. */ +{ + char *p; /* track operand text forward */ + char *q; /* track operand text backward */ + int at; /* TRUE if leading '@' ('*') seen */ + char len; /* one of " bilsw" */ + int hash; /* TRUE if leading '#' ('$') seen */ + int sign; /* -1, 0 or +1 */ + int paren; /* TRUE if () surround register */ + int reg; /* register number, -1:absent */ + int ndx; /* index register number -1:absent */ + char *bug; /* report any logic error in here, ""==OK */ + char *err; /* report illegal operand, ""==OK */ + /* " " is a FAKE error: means we won */ + /* ANY err that begins with ' ' is a fake. */ + /* " " is converted to "" before return */ + char *wrn; /* warn about weird modes pf address */ + char *oldq; /* preserve q in case we backup */ + int mode; /* build up 4-bit operand mode here */ + /* note: index mode is in ndx, this is */ + /* the major mode of operand address */ + /* + * Notice how we move wrong-arg-type bugs INSIDE this module: if we + * get the types wrong below, we lose at compile time rather than at + * lint or run time. + */ + char access; /* vop_access. */ + char width; /* vop_width. */ + + int vax_reg_parse (); /* returns 0:15 or -1 if not a register */ + + access = vopP->vop_access; + width = vopP->vop_width; + bug = /* none of our code bugs (yet) */ + err = /* no user text errors */ + wrn = ""; /* no warnings even */ + + p = optext; + + if (*p == ' ') /* Expect all whitespace reduced to ' '. */ p++; /* skip over whitespace */ + + if (at = INDIRECTP (*p)) + { /* TRUE if *p=='@'(or '*' for Un*x) */ + p++; /* at is determined */ + if (*p == ' ') /* Expect all whitespace reduced to ' '. */ + p++; /* skip over whitespace */ } - - /* - * This code is subtle. It tries to detect all legal (letter)'^' - * but it doesn't waste time explicitly testing for premature '\0' because - * this case is rejected as a mismatch against either (letter) or '^'. - */ - { + + /* + * This code is subtle. It tries to detect all legal (letter)'^' + * but it doesn't waste time explicitly testing for premature '\0' because + * this case is rejected as a mismatch against either (letter) or '^'. + */ +{ register char c; - + c = *p; if (isupper (c)) - c = tolower (c); + c = tolower (c); if (DISPLENP (p[1]) && strchr ("bilws", len = c)) - p += 2; /* skip (letter) '^' */ + p += 2; /* skip (letter) '^' */ else /* no (letter) '^' seen */ - len = ' '; /* len is determined */ - } + len = ' '; /* len is determined */ +} - if (*p == ' ') /* Expect all whitespace reduced to ' '. */ +if (*p == ' ') /* Expect all whitespace reduced to ' '. */ p++; /* skip over whitespace */ - - if (hash = IMMEDIATEP (*p)) /* TRUE if *p=='#' ('$' for Un*x) */ + + if (hash = IMMEDIATEP (*p)) /* TRUE if *p=='#' ('$' for Un*x) */ p++; /* hash is determined */ - - /* - * p points to what may be the beginning of an expression. - * We have peeled off the front all that is peelable. - * We know at, len, hash. - * - * Lets point q at the end of the text and parse that (backwards). - */ - - for (q = p; *q; q++) + + /* + * p points to what may be the beginning of an expression. + * We have peeled off the front all that is peelable. + * We know at, len, hash. + * + * Lets point q at the end of the text and parse that (backwards). + */ + + for (q = p; *q; q++) ; - q--; /* now q points at last char of text */ - - if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */ + q--; /* now q points at last char of text */ + + if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */ q--; - /* reverse over whitespace, but don't */ - /* run back over *p */ - - /* - * As a matter of policy here, we look for [Rn], although both Rn and S^# - * forbid [Rn]. This is because it is easy, and because only a sick - * cyborg would have [...] trailing an expression in a VAX-like assembler. - * A meticulous parser would first check for Rn followed by '(' or '[' - * and not parse a trailing ']' if it found another. We just ban expressions - * ending in ']'. - */ - if (*q == ']') - { - while (q >= p && *q != '[') + /* reverse over whitespace, but don't */ + /* run back over *p */ + + /* + * As a matter of policy here, we look for [Rn], although both Rn and S^# + * forbid [Rn]. This is because it is easy, and because only a sick + * cyborg would have [...] trailing an expression in a VAX-like assembler. + * A meticulous parser would first check for Rn followed by '(' or '[' + * and not parse a trailing ']' if it found another. We just ban expressions + * ending in ']'. + */ + if (*q == ']') +{ + while (q >= p && *q != '[') q--; - /* either q<p or we got matching '[' */ - if (q < p) + /* either q<p or we got matching '[' */ + if (q < p) err = "no '[' to match ']'"; - else - { - /* - * Confusers like "[]" will eventually lose with a bad register - * name error. So again we don't need to check for early '\0'. - */ - if (q[3] == ']') + else + { + /* + * Confusers like "[]" will eventually lose with a bad register + * name error. So again we don't need to check for early '\0'. + */ + if (q[3] == ']') ndx = vax_reg_parse (q[1], q[2], 0); - else if (q[4] == ']') + else if (q[4] == ']') ndx = vax_reg_parse (q[1], q[2], q[3]); - else + else ndx = -1; - /* - * Since we saw a ']' we will demand a register name in the []. - * If luser hasn't given us one: be rude. - */ - if (ndx < 0) + /* + * Since we saw a ']' we will demand a register name in the []. + * If luser hasn't given us one: be rude. + */ + if (ndx < 0) err = "bad register in []"; - else if (ndx == PC) + else if (ndx == PC) err = "[PC] index banned"; - else + else q--; /* point q just before "[...]" */ - } } - else +} +else ndx = -1; /* no ']', so no iNDeX register */ - /* - * If err = "..." then we lost: run away. - * Otherwise ndx == -1 if there was no "[...]". - * Otherwise, ndx is index register number, and q points before "[...]". - */ +/* + * If err = "..." then we lost: run away. + * Otherwise ndx == -1 if there was no "[...]". + * Otherwise, ndx is index register number, and q points before "[...]". + */ - if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */ +if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */ q--; - /* reverse over whitespace, but don't */ - /* run back over *p */ - if (!*err) + /* reverse over whitespace, but don't */ + /* run back over *p */ + if (!*err) +{ + sign = 0; /* no ()+ or -() seen yet */ + + if (q > p + 3 && *q == '+' && q[-1] == ')') { - sign = 0; /* no ()+ or -() seen yet */ - - if (q > p + 3 && *q == '+' && q[-1] == ')') - { - sign = 1; /* we saw a ")+" */ - q--; /* q points to ')' */ - } - - if (*q == ')' && q > p + 2) - { - paren = TRUE; /* assume we have "(...)" */ - while (q >= p && *q != '(') + sign = 1; /* we saw a ")+" */ + q--; /* q points to ')' */ + } + + if (*q == ')' && q > p + 2) + { + paren = TRUE; /* assume we have "(...)" */ + while (q >= p && *q != '(') q--; - /* either q<p or we got matching '(' */ - if (q < p) + /* either q<p or we got matching '(' */ + if (q < p) err = "no '(' to match ')'"; - else - { - /* - * Confusers like "()" will eventually lose with a bad register - * name error. So again we don't need to check for early '\0'. - */ - if (q[3] == ')') + else + { + /* + * Confusers like "()" will eventually lose with a bad register + * name error. So again we don't need to check for early '\0'. + */ + if (q[3] == ')') reg = vax_reg_parse (q[1], q[2], 0); - else if (q[4] == ')') + else if (q[4] == ')') reg = vax_reg_parse (q[1], q[2], q[3]); - else + else reg = -1; - /* - * Since we saw a ')' we will demand a register name in the ')'. - * This is nasty: why can't our hypothetical assembler permit - * parenthesised expressions? BECAUSE I AM LAZY! That is why. - * Abuse luser if we didn't spy a register name. - */ - if (reg < 0) - { - /* JF allow parenthasized expressions. I hope this works */ - paren = FALSE; - while (*q != ')') + /* + * Since we saw a ')' we will demand a register name in the ')'. + * This is nasty: why can't our hypothetical assembler permit + * parenthesised expressions? BECAUSE I AM LAZY! That is why. + * Abuse luser if we didn't spy a register name. + */ + if (reg < 0) + { + /* JF allow parenthasized expressions. I hope this works */ + paren = FALSE; + while (*q != ')') q++; - /* err = "unknown register in ()"; */ - } - else - q--; /* point just before '(' of "(...)" */ - /* - * If err == "..." then we lost. Run away. - * Otherwise if reg >= 0 then we saw (Rn). - */ + /* err = "unknown register in ()"; */ } - /* - * If err == "..." then we lost. - * Otherwise paren==TRUE and reg = register in "()". - */ + else + q--; /* point just before '(' of "(...)" */ + /* + * If err == "..." then we lost. Run away. + * Otherwise if reg >= 0 then we saw (Rn). + */ } - else + /* + * If err == "..." then we lost. + * Otherwise paren==TRUE and reg = register in "()". + */ + } + else paren = FALSE; - /* - * If err == "..." then we lost. - * Otherwise, q points just before "(Rn)", if any. - * If there was a "(...)" then paren==TRUE, and reg is the register. - */ - - /* - * We should only seek '-' of "-(...)" if: - * we saw "(...)" paren == TRUE - * we have no errors so far ! *err - * we did not see '+' of "(...)+" sign < 1 - * We don't check len. We want a specific error message later if - * user tries "x^...-(Rn)". This is a feature not a bug. - */ - if (!*err) + /* + * If err == "..." then we lost. + * Otherwise, q points just before "(Rn)", if any. + * If there was a "(...)" then paren==TRUE, and reg is the register. + */ + + /* + * We should only seek '-' of "-(...)" if: + * we saw "(...)" paren == TRUE + * we have no errors so far ! *err + * we did not see '+' of "(...)+" sign < 1 + * We don't check len. We want a specific error message later if + * user tries "x^...-(Rn)". This is a feature not a bug. + */ + if (!*err) + { + if (paren && sign < 1)/* !sign is adequate test */ { - if (paren && sign < 1)/* !sign is adequate test */ + if (*q == '-') { - if (*q == '-') - { - sign = -1; - q--; - } + sign = -1; + q--; } - /* - * We have back-tracked over most - * of the crud at the end of an operand. - * Unless err, we know: sign, paren. If paren, we know reg. - * The last case is of an expression "Rn". - * This is worth hunting for if !err, !paren. - * We wouldn't be here if err. - * We remember to save q, in case we didn't want "Rn" anyway. - */ - if (!paren) - { - if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */ + } + /* + * We have back-tracked over most + * of the crud at the end of an operand. + * Unless err, we know: sign, paren. If paren, we know reg. + * The last case is of an expression "Rn". + * This is worth hunting for if !err, !paren. + * We wouldn't be here if err. + * We remember to save q, in case we didn't want "Rn" anyway. + */ + if (!paren) + { + if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */ q--; - /* reverse over whitespace, but don't */ - /* run back over *p */ - if (q > p && q < p + 3) /* room for Rn or Rnn exactly? */ + /* reverse over whitespace, but don't */ + /* run back over *p */ + if (q > p && q < p + 3) /* room for Rn or Rnn exactly? */ reg = vax_reg_parse (p[0], p[1], q < p + 2 ? 0 : p[2]); - else + else reg = -1; /* always comes here if no register at all */ - /* - * Here with a definitive reg value. - */ - if (reg >= 0) - { - oldq = q; - q = p - 1; - } + /* + * Here with a definitive reg value. + */ + if (reg >= 0) + { + oldq = q; + q = p - 1; } } } - /* - * have reg. -1:absent; else 0:15 - */ +} +/* + * have reg. -1:absent; else 0:15 + */ - /* - * We have: err, at, len, hash, ndx, sign, paren, reg. - * Also, any remaining expression is from *p through *q inclusive. - * Should there be no expression, q==p-1. So expression length = q-p+1. - * This completes the first part: parsing the operand text. - */ +/* + * We have: err, at, len, hash, ndx, sign, paren, reg. + * Also, any remaining expression is from *p through *q inclusive. + * Should there be no expression, q==p-1. So expression length = q-p+1. + * This completes the first part: parsing the operand text. + */ - /* - * We now want to boil the data down, checking consistency on the way. - * We want: len, mode, reg, ndx, err, p, q, wrn, bug. - * We will deliver a 4-bit reg, and a 4-bit mode. - */ +/* + * We now want to boil the data down, checking consistency on the way. + * We want: len, mode, reg, ndx, err, p, q, wrn, bug. + * We will deliver a 4-bit reg, and a 4-bit mode. + */ - /* - * Case of branch operand. Different. No L^B^W^I^S^ allowed for instance. - * - * in: at ? - * len ? - * hash ? - * p:q ? - * sign ? - * paren ? - * reg ? - * ndx ? - * - * out: mode 0 - * reg -1 - * len ' ' - * p:q whatever was input - * ndx -1 - * err " " or error message, and other outputs trashed - */ - /* branch operands have restricted forms */ - if (!*err && access == 'b') - { - if (at || hash || sign || paren || ndx >= 0 || reg >= 0 || len != ' ') +/* + * Case of branch operand. Different. No L^B^W^I^S^ allowed for instance. + * + * in: at ? + * len ? + * hash ? + * p:q ? + * sign ? + * paren ? + * reg ? + * ndx ? + * + * out: mode 0 + * reg -1 + * len ' ' + * p:q whatever was input + * ndx -1 + * err " " or error message, and other outputs trashed + */ +/* branch operands have restricted forms */ +if (!*err && access == 'b') +{ + if (at || hash || sign || paren || ndx >= 0 || reg >= 0 || len != ' ') err = "invalid branch operand"; - else + else err = " "; - } +} /* Since nobody seems to use it: comment this 'feature'(?) out for now. */ #ifdef NEVER - /* - * Case of stand-alone operand. e.g. ".long foo" - * - * in: at ? - * len ? - * hash ? - * p:q ? - * sign ? - * paren ? - * reg ? - * ndx ? - * - * out: mode 0 - * reg -1 - * len ' ' - * p:q whatever was input - * ndx -1 - * err " " or error message, and other outputs trashed - */ - if (!*err) - { - if (access == ' ') - { /* addresses have restricted forms */ - if (at) +/* + * Case of stand-alone operand. e.g. ".long foo" + * + * in: at ? + * len ? + * hash ? + * p:q ? + * sign ? + * paren ? + * reg ? + * ndx ? + * + * out: mode 0 + * reg -1 + * len ' ' + * p:q whatever was input + * ndx -1 + * err " " or error message, and other outputs trashed + */ +if (!*err) +{ + if (access == ' ') + { /* addresses have restricted forms */ + if (at) err = "address prohibits @"; - else - { - if (hash) + else + { + if (hash) err = "address prohibits #"; - else + else + { + if (sign) { - if (sign) - { - if (sign < 0) + if (sign < 0) err = "address prohibits -()"; - else + else err = "address prohibits ()+"; - } - else - { - if (paren) + } + else + { + if (paren) err = "address prohibits ()"; - else - { - if (ndx >= 0) + else + { + if (ndx >= 0) err = "address prohibits []"; - else - { - if (reg >= 0) + else + { + if (reg >= 0) err = "address prohibits register"; - else - { - if (len != ' ') + else + { + if (len != ' ') err = "address prohibits displacement length specifier"; - else - { - err = " "; /* succeed */ - mode = 0; - } + else + { + err = " "; /* succeed */ + mode = 0; } } } @@ -2749,312 +2749,313 @@ vip_op (optext, vopP) } } } +} #endif /*#Ifdef NEVER*/ - /* - * Case of S^#. - * - * in: at FALSE - * len 's' definition - * hash TRUE demand - * p:q demand not empty - * sign 0 by paren==FALSE - * paren FALSE by "()" scan logic because "S^" seen - * reg -1 or nn by mistake - * ndx -1 - * - * out: mode 0 - * reg -1 - * len 's' - * exp - * ndx -1 - */ - if (!*err && len == 's') - { - if (!hash || paren || at || ndx >= 0) +/* + * Case of S^#. + * + * in: at FALSE + * len 's' definition + * hash TRUE demand + * p:q demand not empty + * sign 0 by paren==FALSE + * paren FALSE by "()" scan logic because "S^" seen + * reg -1 or nn by mistake + * ndx -1 + * + * out: mode 0 + * reg -1 + * len 's' + * exp + * ndx -1 + */ +if (!*err && len == 's') +{ + if (!hash || paren || at || ndx >= 0) err = "invalid operand of S^#"; - else + else + { + if (reg >= 0) { - if (reg >= 0) - { - /* - * SHIT! we saw S^#Rnn ! put the Rnn back in - * expression. KLUDGE! Use oldq so we don't - * need to know exact length of reg name. - */ - q = oldq; - reg = 0; - } - /* - * We have all the expression we will ever get. - */ - if (p > q) + /* + * SHIT! we saw S^#Rnn ! put the Rnn back in + * expression. KLUDGE! Use oldq so we don't + * need to know exact length of reg name. + */ + q = oldq; + reg = 0; + } + /* + * We have all the expression we will ever get. + */ + if (p > q) err = "S^# needs expression"; - else if (access == 'r') - { - err = " "; /* WIN! */ - mode = 0; - } - else - err = "S^# may only read-access"; + else if (access == 'r') + { + err = " "; /* WIN! */ + mode = 0; } + else + err = "S^# may only read-access"; } +} - /* - * Case of -(Rn), which is weird case. - * - * in: at FALSE - * len ' - * hash FALSE - * p:q q<p - * sign -1 by definition - * paren TRUE by definition - * reg present by definition - * ndx optional - * - * out: mode 7 - * reg present - * len ' ' - * exp "" enforce empty expression - * ndx optional warn if same as reg - */ - if (!*err && sign < 0) - { - if (len != ' ' || hash || at || p <= q) +/* + * Case of -(Rn), which is weird case. + * + * in: at FALSE + * len ' + * hash FALSE + * p:q q<p + * sign -1 by definition + * paren TRUE by definition + * reg present by definition + * ndx optional + * + * out: mode 7 + * reg present + * len ' ' + * exp "" enforce empty expression + * ndx optional warn if same as reg + */ +if (!*err && sign < 0) +{ + if (len != ' ' || hash || at || p <= q) err = "invalid operand of -()"; - else - { - err = " "; /* win */ - mode = 7; - if (reg == PC) + else + { + err = " "; /* win */ + mode = 7; + if (reg == PC) wrn = "-(PC) unpredictable"; - else if (reg == ndx) + else if (reg == ndx) wrn = "[]index same as -()register: unpredictable"; - } } +} - /* - * We convert "(Rn)" to "@Rn" for our convenience. - * (I hope this is convenient: has someone got a better way to parse this?) - * A side-effect of this is that "@Rn" is a valid operand. - */ - if (paren && !sign && !hash && !at && len == ' ' && p > q) - { - at = TRUE; - paren = FALSE; - } +/* + * We convert "(Rn)" to "@Rn" for our convenience. + * (I hope this is convenient: has someone got a better way to parse this?) + * A side-effect of this is that "@Rn" is a valid operand. + */ +if (paren && !sign && !hash && !at && len == ' ' && p > q) +{ + at = TRUE; + paren = FALSE; +} - /* - * Case of (Rn)+, which is slightly different. - * - * in: at - * len ' ' - * hash FALSE - * p:q q<p - * sign +1 by definition - * paren TRUE by definition - * reg present by definition - * ndx optional - * - * out: mode 8+@ - * reg present - * len ' ' - * exp "" enforce empty expression - * ndx optional warn if same as reg - */ - if (!*err && sign > 0) - { - if (len != ' ' || hash || p <= q) +/* + * Case of (Rn)+, which is slightly different. + * + * in: at + * len ' ' + * hash FALSE + * p:q q<p + * sign +1 by definition + * paren TRUE by definition + * reg present by definition + * ndx optional + * + * out: mode 8+@ + * reg present + * len ' ' + * exp "" enforce empty expression + * ndx optional warn if same as reg + */ +if (!*err && sign > 0) +{ + if (len != ' ' || hash || p <= q) err = "invalid operand of ()+"; - else - { - err = " "; /* win */ - mode = 8 + (at ? 1 : 0); - if (reg == PC) + else + { + err = " "; /* win */ + mode = 8 + (at ? 1 : 0); + if (reg == PC) wrn = "(PC)+ unpredictable"; - else if (reg == ndx) + else if (reg == ndx) wrn = "[]index same as ()+register: unpredictable"; - } } +} - /* - * Case of #, without S^. - * - * in: at - * len ' ' or 'i' - * hash TRUE by definition - * p:q - * sign 0 - * paren FALSE - * reg absent - * ndx optional - * - * out: mode 8+@ - * reg PC - * len ' ' or 'i' - * exp - * ndx optional - */ - if (!*err && hash) - { - if (len != 'i' && len != ' ') +/* + * Case of #, without S^. + * + * in: at + * len ' ' or 'i' + * hash TRUE by definition + * p:q + * sign 0 + * paren FALSE + * reg absent + * ndx optional + * + * out: mode 8+@ + * reg PC + * len ' ' or 'i' + * exp + * ndx optional + */ +if (!*err && hash) +{ + if (len != 'i' && len != ' ') err = "# conflicts length"; - else if (paren) + else if (paren) err = "# bars register"; - else + else + { + if (reg >= 0) { - if (reg >= 0) - { - /* - * SHIT! we saw #Rnn! Put the Rnn back into the expression. - * By using oldq, we don't need to know how long Rnn was. - * KLUDGE! - */ - q = oldq; - reg = -1; /* no register any more */ - } - err = " "; /* win */ - - /* JF a bugfix, I think! */ - if(at && access=='a') + /* + * SHIT! we saw #Rnn! Put the Rnn back into the expression. + * By using oldq, we don't need to know how long Rnn was. + * KLUDGE! + */ + q = oldq; + reg = -1; /* no register any more */ + } + err = " "; /* win */ + + /* JF a bugfix, I think! */ + if(at && access=='a') vopP->vop_nbytes=4; - - mode = (at ? 9 : 8); - reg = PC; - if ((access == 'm' || access == 'w') && !at) + + mode = (at ? 9 : 8); + reg = PC; + if ((access == 'm' || access == 'w') && !at) wrn = "writing or modifying # is unpredictable"; - } } - /* - * If !*err, then sign == 0 - * hash == FALSE - */ +} +/* + * If !*err, then sign == 0 + * hash == FALSE + */ - /* - * Case of Rn. We seperate this one because it has a few special - * errors the remaining modes lack. - * - * in: at optional - * len ' ' - * hash FALSE by program logic - * p:q empty - * sign 0 by program logic - * paren FALSE by definition - * reg present by definition - * ndx optional - * - * out: mode 5+@ - * reg present - * len ' ' enforce no length - * exp "" enforce empty expression - * ndx optional warn if same as reg - */ - if (!*err && !paren && reg >= 0) - { - if (len != ' ') +/* + * Case of Rn. We seperate this one because it has a few special + * errors the remaining modes lack. + * + * in: at optional + * len ' ' + * hash FALSE by program logic + * p:q empty + * sign 0 by program logic + * paren FALSE by definition + * reg present by definition + * ndx optional + * + * out: mode 5+@ + * reg present + * len ' ' enforce no length + * exp "" enforce empty expression + * ndx optional warn if same as reg + */ +if (!*err && !paren && reg >= 0) +{ + if (len != ' ') err = "length not needed"; - else if (at) - { - err = " "; /* win */ - mode = 6; /* @Rn */ - } - else if (ndx >= 0) + else if (at) + { + err = " "; /* win */ + mode = 6; /* @Rn */ + } + else if (ndx >= 0) err = "can't []index a register, because it has no address"; - else if (access == 'a') + else if (access == 'a') err = "a register has no address"; - else - { - /* - * Idea here is to detect from length of datum - * and from register number if we will touch PC. - * Warn if we do. - * vop_nbytes is number of bytes in operand. - * Compute highest byte affected, compare to PC0. - */ - if ((vopP->vop_nbytes + reg * 4) > 60) + else + { + /* + * Idea here is to detect from length of datum + * and from register number if we will touch PC. + * Warn if we do. + * vop_nbytes is number of bytes in operand. + * Compute highest byte affected, compare to PC0. + */ + if ((vopP->vop_nbytes + reg * 4) > 60) wrn = "PC part of operand unpredictable"; - err = " "; /* win */ - mode = 5; /* Rn */ - } + err = " "; /* win */ + mode = 5; /* Rn */ } - /* - * If !*err, sign == 0 - * hash == FALSE - * paren == TRUE OR reg==-1 - */ +} +/* + * If !*err, sign == 0 + * hash == FALSE + * paren == TRUE OR reg==-1 + */ - /* - * Rest of cases fit into one bunch. - * - * in: at optional - * len ' ' or 'b' or 'w' or 'l' - * hash FALSE by program logic - * p:q expected (empty is not an error) - * sign 0 by program logic - * paren optional - * reg optional - * ndx optional - * - * out: mode 10 + @ + len - * reg optional - * len ' ' or 'b' or 'w' or 'l' - * exp maybe empty - * ndx optional warn if same as reg - */ - if (!*err) +/* + * Rest of cases fit into one bunch. + * + * in: at optional + * len ' ' or 'b' or 'w' or 'l' + * hash FALSE by program logic + * p:q expected (empty is not an error) + * sign 0 by program logic + * paren optional + * reg optional + * ndx optional + * + * out: mode 10 + @ + len + * reg optional + * len ' ' or 'b' or 'w' or 'l' + * exp maybe empty + * ndx optional warn if same as reg + */ +if (!*err) +{ + err = " "; /* win (always) */ + mode = 10 + (at ? 1 : 0); + switch (len) { - err = " "; /* win (always) */ - mode = 10 + (at ? 1 : 0); - switch (len) - { - case 'l': - mode += 2; - case 'w': - mode += 2; - case ' ': /* assumed B^ until our caller changes it */ - case 'b': - break; - } + case 'l': + mode += 2; + case 'w': + mode += 2; + case ' ': /* assumed B^ until our caller changes it */ + case 'b': + break; } +} - /* - * here with completely specified mode - * len - * reg - * expression p,q - * ndx - */ +/* + * here with completely specified mode + * len + * reg + * expression p,q + * ndx + */ - if (*err == ' ') +if (*err == ' ') err = ""; /* " " is no longer an error */ - - vopP->vop_mode = mode; - vopP->vop_reg = reg; - vopP->vop_short = len; - vopP->vop_expr_begin = p; - vopP->vop_expr_end = q; - vopP->vop_ndx = ndx; - vopP->vop_error = err; - vopP->vop_warn = wrn; - return (bug); - + + vopP->vop_mode = mode; + vopP->vop_reg = reg; + vopP->vop_short = len; + vopP->vop_expr_begin = p; + vopP->vop_expr_end = q; + vopP->vop_ndx = ndx; + vopP->vop_error = err; + vopP->vop_warn = wrn; + return (bug); + } /* vip_op() */ /* - -Summary of vip_op outputs. - - mode reg len ndx -(Rn) => @Rn -{@}Rn 5+@ n ' ' optional -branch operand 0 -1 ' ' -1 -S^#foo 0 -1 's' -1 --(Rn) 7 n ' ' optional -{@}(Rn)+ 8+@ n ' ' optional -{@}#foo, no S^ 8+@ PC " i" optional -{@}{q^}{(Rn)} 10+@+q option " bwl" optional - -*/ + + Summary of vip_op outputs. + + mode reg len ndx + (Rn) => @Rn + {@}Rn 5+@ n ' ' optional + branch operand 0 -1 ' ' -1 + S^#foo 0 -1 's' -1 + -(Rn) 7 n ' ' optional + {@}(Rn)+ 8+@ n ' ' optional + {@}#foo, no S^ 8+@ PC " i" optional + {@}{q^}{(Rn)} 10+@+q option " bwl" optional + + */ #ifdef TEST /* #Define to use this testbed. */ @@ -3086,102 +3087,102 @@ char my_displen[200]; main () { - char *vip_op (); /* make cc happy */ - - printf ("enter immediate symbols eg enter # "); - gets (my_immediate); - printf ("enter indirect symbols eg enter @ "); - gets (my_indirect); - printf ("enter displen symbols eg enter ^ "); - gets (my_displen); - vip_op_defaults (my_immediate, my_indirect, my_displen); - for (;;) + char *vip_op (); /* make cc happy */ + + printf ("enter immediate symbols eg enter # "); + gets (my_immediate); + printf ("enter indirect symbols eg enter @ "); + gets (my_indirect); + printf ("enter displen symbols eg enter ^ "); + gets (my_displen); + vip_op_defaults (my_immediate, my_indirect, my_displen); + for (;;) { - printf ("access,width (eg 'ab' or 'wh') [empty line to quit] : "); - fflush (stdout); - gets (answer); - if (!answer[0]) - exit (0); - myaccess = answer[0]; - mywidth = answer[1]; - switch (mywidth) + printf ("access,width (eg 'ab' or 'wh') [empty line to quit] : "); + fflush (stdout); + gets (answer); + if (!answer[0]) + exit (0); + myaccess = answer[0]; + mywidth = answer[1]; + switch (mywidth) { case 'b': - my_operand_length = 1; - break; + my_operand_length = 1; + break; case 'd': - my_operand_length = 8; - break; + my_operand_length = 8; + break; case 'f': - my_operand_length = 4; - break; + my_operand_length = 4; + break; case 'g': - my_operand_length = 16; - break; + my_operand_length = 16; + break; case 'h': - my_operand_length = 32; - break; + my_operand_length = 32; + break; case 'l': - my_operand_length = 4; - break; + my_operand_length = 4; + break; case 'o': - my_operand_length = 16; - break; + my_operand_length = 16; + break; case 'q': - my_operand_length = 8; - break; + my_operand_length = 8; + break; case 'w': - my_operand_length = 2; - break; + my_operand_length = 2; + break; case '!': case '?': case '-': - my_operand_length = 0; - break; - + my_operand_length = 0; + break; + default: - my_operand_length = 2; - printf ("I dn't understand access width %c\n", mywidth); - break; + my_operand_length = 2; + printf ("I dn't understand access width %c\n", mywidth); + break; } - printf ("VAX assembler instruction operand: "); - fflush (stdout); - gets (answer); - mybug = vip_op (answer, myaccess, mywidth, my_operand_length, - &mymode, &myreg, &mylen, &myleft, &myright, &myndx, - &myerr, &mywrn); - if (*myerr) + printf ("VAX assembler instruction operand: "); + fflush (stdout); + gets (answer); + mybug = vip_op (answer, myaccess, mywidth, my_operand_length, + &mymode, &myreg, &mylen, &myleft, &myright, &myndx, + &myerr, &mywrn); + if (*myerr) { - printf ("error: \"%s\"\n", myerr); - if (*mybug) - printf (" bug: \"%s\"\n", mybug); + printf ("error: \"%s\"\n", myerr); + if (*mybug) + printf (" bug: \"%s\"\n", mybug); } - else + else { - if (*mywrn) - printf ("warning: \"%s\"\n", mywrn); - mumble ("mode", mymode); - mumble ("register", myreg); - mumble ("index", myndx); - printf ("width:'%c' ", mylen); - printf ("expression: \""); - while (myleft <= myright) - putchar (*myleft++); - printf ("\"\n"); + if (*mywrn) + printf ("warning: \"%s\"\n", mywrn); + mumble ("mode", mymode); + mumble ("register", myreg); + mumble ("index", myndx); + printf ("width:'%c' ", mylen); + printf ("expression: \""); + while (myleft <= myright) + putchar (*myleft++); + printf ("\"\n"); } } } mumble (text, value) - char *text; - int value; -{ - printf ("%s:", text); - if (value >= 0) - printf ("%xx", value); - else - printf ("ABSENT"); - printf (" "); + char *text; + int value; +{ + printf ("%s:", text); + if (value >= 0) + printf ("%xx", value); + else + printf ("ABSENT"); + printf (" "); } #endif /* ifdef TEST */ @@ -3193,117 +3194,117 @@ const int md_long_jump_size = 6; const int md_reloc_size = 8; /* Size of relocation record */ void -md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; + md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) +char *ptr; +long from_addr, to_addr; +fragS *frag; +symbolS *to_symbol; { - long offset; - - offset = to_addr - (from_addr + 1); - *ptr++ = 0x31; - md_number_to_chars (ptr, offset, 2); + long offset; + + offset = to_addr - (from_addr + 1); + *ptr++ = 0x31; + md_number_to_chars (ptr, offset, 2); } void -md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - long from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; -{ - long offset; - - offset = to_addr - to_symbol->sy_value; - *ptr++ = 0x17; - *ptr++ = 0x9F; - md_number_to_chars (ptr, offset, 4); - fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, (symbolS *) 0, (long) 0, 0); + md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) +char *ptr; +long from_addr, to_addr; +fragS *frag; +symbolS *to_symbol; +{ + long offset; + + offset = to_addr - to_symbol->sy_value; + *ptr++ = 0x17; + *ptr++ = 0x9F; + md_number_to_chars (ptr, offset, 4); + fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, (symbolS *) 0, (long) 0, 0); } int -md_parse_option (argP, cntP, vecP) - char **argP; - int *cntP; - char ***vecP; + md_parse_option (argP, cntP, vecP) +char **argP; +int *cntP; +char ***vecP; { - char *temp_name; /* name for -t or -d options */ - char opt; - - switch (**argP) + char *temp_name; /* name for -t or -d options */ + char opt; + + switch (**argP) { case 'J': - /* as_warn ("I can do better than -J!"); */ - break; - + /* as_warn ("I can do better than -J!"); */ + break; + case 'S': - as_warn ("SYMBOL TABLE not implemented"); - break; /* SYMBOL TABLE not implemented */ - + as_warn ("SYMBOL TABLE not implemented"); + break; /* SYMBOL TABLE not implemented */ + case 'T': - as_warn ("TOKEN TRACE not implemented"); - break; /* TOKEN TRACE not implemented */ - + as_warn ("TOKEN TRACE not implemented"); + break; /* TOKEN TRACE not implemented */ + case 'd': case 't': - opt= **argP; - if (**argP) + opt= **argP; + if (**argP) { /* Rest of argument is filename. */ - temp_name = *argP; - while (**argP) - (*argP)++; + temp_name = *argP; + while (**argP) + (*argP)++; } - else if (*cntP) + else if (*cntP) { - while (**argP) - (*argP)++; - --(*cntP); - temp_name = *++(*vecP); - **vecP = NULL; /* Remember this is not a file-name. */ + while (**argP) + (*argP)++; + --(*cntP); + temp_name = *++(*vecP); + **vecP = NULL; /* Remember this is not a file-name. */ } - else + else { - as_warn ("I expected a filename after -%c.",opt); - temp_name = "{absent}"; + as_warn ("I expected a filename after -%c.",opt); + temp_name = "{absent}"; } - - if(opt=='d') - as_warn ("Displacement length %s ignored!", temp_name); - else - as_warn ("I don't need or use temp. file \"%s\".", temp_name); - break; - + + if(opt=='d') + as_warn ("Displacement length %s ignored!", temp_name); + else + as_warn ("I don't need or use temp. file \"%s\".", temp_name); + break; + case 'V': - as_warn ("I don't use an interpass file! -V ignored"); - break; - + as_warn ("I don't use an interpass file! -V ignored"); + break; + #ifdef VMS case '+': /* For g++ */ - break; - + break; + case 'h': /* No hashing of mixed-case names */ - break; - + break; + case 'H': /* Show new symbol after hash truncation */ - break; + break; #endif - + default: - return 0; - + return 0; + } - return 1; + return 1; } /* We have no need to default values of symbols. */ /* ARGSUSED */ symbolS * -md_undefined_symbol (name) - char *name; + md_undefined_symbol (name) +char *name; { - return 0; + return 0; } /* Parse an operand that is machine-specific. @@ -3312,26 +3313,26 @@ md_undefined_symbol (name) /* ARGSUSED */ void -md_operand (expressionP) - expressionS *expressionP; + md_operand (expressionP) +expressionS *expressionP; { } /* Round up a section size to the appropriate boundary. */ long -md_section_align (segment, size) - segT segment; - long size; + md_section_align (segment, size) +segT segment; +long size; { - return size; /* Byte alignment is fine */ + return size; /* Byte alignment is fine */ } /* Exactly what point is a PC-relative offset relative TO? On the vax, they're relative to the address of the offset, plus its size. (??? Is this right? FIXME-SOON) */ long -md_pcrel_from (fixP) - fixS *fixP; + md_pcrel_from (fixP) +fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } diff --git a/gas/config/te-generic.h b/gas/config/te-generic.h index 4b40d61..999a4d2 100644 --- a/gas/config/te-generic.h +++ b/gas/config/te-generic.h @@ -1,13 +1,20 @@ /* * This file is te-generic.h and is intended to be a template for * target environment specific header files. + * + * It is my intent that this file will evolve into a file suitable for config, + * compile, and copying as an aid for testing and porting. xoxorich. */ #define TE_GENERIC 1 - /* these define interfaces */ +/* these define interfaces */ #include "obj-format.h" +/* define this if you want gas to ignore the first underscore character of + each symbol */ +/* #define STRIP_UNDERSCORE */ + /* * Local Variables: * comment-column: 0 diff --git a/gas/config/te-ic960.h b/gas/config/te-ic960.h index 165a780..fbb7475 100644 --- a/gas/config/te-ic960.h +++ b/gas/config/te-ic960.h @@ -7,15 +7,15 @@ #define TE_IC960 1 - /* intel uses host byte order for headers */ +/* intel uses host byte order for headers */ #ifdef CROSS_COMPILE #undef CROSS_COMPILE #endif /* CROSS_COMPILE */ #define OBJ_COFF_OMIT_OPTIONAL_HEADER #define LOCAL_LABEL(name) ( (name[0] =='L') \ - || (name[0] =='.' \ - && (name[1]=='C' || name[1]=='I' || name[1]=='.'))) + || (name[0] =='.' \ + && (name[1]=='C' || name[1]=='I' || name[1]=='.'))) #include "obj-format.h" /* diff --git a/gas/config/te-sun3.h b/gas/config/te-sun3.h index 9d1ece4..9c86afe 100644 --- a/gas/config/te-sun3.h +++ b/gas/config/te-sun3.h @@ -1,21 +1,21 @@ /* te-sun3.h -- Sun-3 target environment declarations. Copyright (C) 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. */ + + 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. */ /* $Id$ */ @@ -31,10 +31,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define SUN_ASM_SYNTAX /* Could also be : -#define S_LOCAL_NAME(s) (S_GET_NAME(s)[0] == '.' && - S_GET_NAME(s)[1] == 'L' || - S_GET_NAME(s)[1] == '.') -*/ + #define S_LOCAL_NAME(s) (S_GET_NAME(s)[0] == '.' && + S_GET_NAME(s)[1] == 'L' || + S_GET_NAME(s)[1] == '.') + */ #include "obj-format.h" diff --git a/gas/config/vax-inst.h b/gas/config/vax-inst.h index 51b7c94..d518fc0 100644 --- a/gas/config/vax-inst.h +++ b/gas/config/vax-inst.h @@ -1,21 +1,21 @@ /* vax-inst.h - GNU - Part of vax.c Copyright (C) 1987 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. */ + + 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 is part of vax-ins-parse.c & friends. @@ -23,32 +23,32 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ */ #define VIT_MAX_OPERANDS (6) /* maximum number of operands in one */ - /* single vax instruction */ +/* single vax instruction */ struct vop /* vax instruction operand */ { - short int vop_ndx; /* -1, or index register. eg 7=[R7] */ - short int vop_reg; /* -1, or register number. eg @I^#=0xF */ - /* Helps distinguish "abs" from "abs(PC)". */ - short int vop_mode; /* addressing mode 4 bits. eg I^#=0x9 */ - char vop_short; /* operand displacement length as written */ - /* ' '=none, "bilsw"=B^I^L^S^W^. */ - char vop_access; /* 'b'branch ' 'no-instruction 'amrvw'norm */ - char vop_width; /* Operand width, one of "bdfghloqw" */ - char * vop_warn; /* warning message of this operand, if any */ - char * vop_error; /* say if operand is inappropriate */ - char * vop_expr_begin; /* Unparsed expression, 1st char ... */ - char * vop_expr_end; /* ... last char. */ - unsigned char vop_nbytes; /* number of bytes in datum */ + short int vop_ndx; /* -1, or index register. eg 7=[R7] */ + short int vop_reg; /* -1, or register number. eg @I^#=0xF */ + /* Helps distinguish "abs" from "abs(PC)". */ + short int vop_mode; /* addressing mode 4 bits. eg I^#=0x9 */ + char vop_short; /* operand displacement length as written */ + /* ' '=none, "bilsw"=B^I^L^S^W^. */ + char vop_access; /* 'b'branch ' 'no-instruction 'amrvw'norm */ + char vop_width; /* Operand width, one of "bdfghloqw" */ + char * vop_warn; /* warning message of this operand, if any */ + char * vop_error; /* say if operand is inappropriate */ + char * vop_expr_begin; /* Unparsed expression, 1st char ... */ + char * vop_expr_end; /* ... last char. */ + unsigned char vop_nbytes; /* number of bytes in datum */ }; typedef long vax_opcodeT; /* For initialising array of opcodes */ - /* Some synthetic opcodes > 16 bits! */ +/* Some synthetic opcodes > 16 bits! */ #define VIT_OPCODE_SYNTHETIC 0x80000000 /* Not real hardware instruction. */ #define VIT_OPCODE_SPECIAL 0x40000000 /* Not normal branch optimising. */ - /* Never set without ..._SYNTHETIC */ +/* Never set without ..._SYNTHETIC */ #define VAX_WIDTH_UNCONDITIONAL_JUMP '-' /* These are encoded into */ #define VAX_WIDTH_CONDITIONAL_JUMP '?' /* vop_width when vop_access=='b' */ @@ -62,16 +62,16 @@ typedef long vax_opcodeT; /* For initialising array of opcodes */ #define VAX_BRW (0x31) /* Another canonical branch */ #define VAX_WIDEN_WORD (0x20) /* Add this to byte branch to get word br. */ #define VAX_WIDEN_LONG (0x6) /* Add this to byte branch to get long jmp.*/ - /* Needs VAX_PC_RELATIVE_MODE byte after it*/ +/* Needs VAX_PC_RELATIVE_MODE byte after it*/ struct vit /* vax instruction tree */ { - /* vit_opcode is char[] for portability. */ - char vit_opcode [ sizeof (vax_opcodeT) ]; - unsigned char vit_opcode_nbytes; /* How long is _opcode? (chars) */ - unsigned char vit_operands;/* */ - struct vop vit_operand[VIT_MAX_OPERANDS]; /* operands */ - char * vit_error; /* "" or error text */ + /* vit_opcode is char[] for portability. */ + char vit_opcode [ sizeof (vax_opcodeT) ]; + unsigned char vit_opcode_nbytes; /* How long is _opcode? (chars) */ + unsigned char vit_operands;/* */ + struct vop vit_operand[VIT_MAX_OPERANDS]; /* operands */ + char * vit_error; /* "" or error text */ }; /* end: vax-inst.h */ diff --git a/gas/debug.c b/gas/debug.c index c1e1dbe..0b23c45 100644 --- a/gas/debug.c +++ b/gas/debug.c @@ -6,74 +6,74 @@ dmp_frags() { - frchainS *chp; - char *p; - - for ( chp=frchain_root; chp; chp = chp->frch_next ){ - switch ( chp->frch_seg ){ - case SEG_DATA: - p ="Data"; - break; - case SEG_TEXT: - p ="Text"; - break; - default: - p ="???"; - break; - } - printf("\nSEGMENT %s %d\n", p, chp->frch_subseg); - dmp_frag( chp->frch_root,"\t"); + frchainS *chp; + char *p; + + for ( chp=frchain_root; chp; chp = chp->frch_next ){ + switch ( chp->frch_seg ){ + case SEG_DATA: + p ="Data"; + break; + case SEG_TEXT: + p ="Text"; + break; + default: + p ="???"; + break; } + printf("\nSEGMENT %s %d\n", p, chp->frch_subseg); + dmp_frag( chp->frch_root,"\t"); + } } dmp_frag( fp, indent ) struct frag *fp; char *indent; { - for ( ; fp; fp = fp->fr_next ){ - printf("%sFRAGMENT @ 0x%x\n", indent, fp); - switch( fp->fr_type ){ - case rs_align: - printf("%srs_align(%d)\n",indent, fp->fr_offset); - break; - case rs_fill: - printf("%srs_fill(%d)\n",indent, fp->fr_offset); - printf("%s", indent); - var_chars( fp, fp->fr_var + fp->fr_fix ); - printf("%s\t repeated %d times,", - indent, fp->fr_offset); - printf(" fixed length if # chars == 0)\n"); - break; - case rs_org: - printf("%srs_org(%d+sym @0x%x)\n",indent, - fp->fr_offset, fp->fr_symbol); - printf("%sfill with ",indent); - var_chars( fp, 1 ); - printf("\n"); - break; - case rs_machine_dependent: - printf("%smachine_dep\n",indent); - break; - default: - printf("%sunknown type\n",indent); - break; - } - printf("%saddr=%d(0x%x)\n",indent,fp->fr_address,fp->fr_address); - printf("%sfr_fix=%d\n",indent,fp->fr_fix); - printf("%sfr_var=%d\n",indent,fp->fr_var); - printf("%sfr_offset=%d\n",indent,fp->fr_offset); - printf("%schars @ 0x%x\n",indent,fp->fr_literal); - printf("\n"); + for ( ; fp; fp = fp->fr_next ){ + printf("%sFRAGMENT @ 0x%x\n", indent, fp); + switch( fp->fr_type ){ + case rs_align: + printf("%srs_align(%d)\n",indent, fp->fr_offset); + break; + case rs_fill: + printf("%srs_fill(%d)\n",indent, fp->fr_offset); + printf("%s", indent); + var_chars( fp, fp->fr_var + fp->fr_fix ); + printf("%s\t repeated %d times,", + indent, fp->fr_offset); + printf(" fixed length if # chars == 0)\n"); + break; + case rs_org: + printf("%srs_org(%d+sym @0x%x)\n",indent, + fp->fr_offset, fp->fr_symbol); + printf("%sfill with ",indent); + var_chars( fp, 1 ); + printf("\n"); + break; + case rs_machine_dependent: + printf("%smachine_dep\n",indent); + break; + default: + printf("%sunknown type\n",indent); + break; } + printf("%saddr=%d(0x%x)\n",indent,fp->fr_address,fp->fr_address); + printf("%sfr_fix=%d\n",indent,fp->fr_fix); + printf("%sfr_var=%d\n",indent,fp->fr_var); + printf("%sfr_offset=%d\n",indent,fp->fr_offset); + printf("%schars @ 0x%x\n",indent,fp->fr_literal); + printf("\n"); + } } var_chars( fp, n ) struct frag *fp; int n; { - unsigned char *p; - - for ( p=(unsigned char*)fp->fr_literal; n; n-- , p++ ){ - printf("%02x ", *p ); - } + unsigned char *p; + + for ( p=(unsigned char*)fp->fr_literal; n; n-- , p++ ){ + printf("%02x ", *p ); + } } @@ -1,23 +1,21 @@ /* expr.c -operands, expressions- Copyright (C) 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. */ /* * This is really a branch office of as-read.c. I split it out to clearly @@ -56,16 +54,16 @@ extern int local_label_defined[]; for me to fix right. Thus a hack. JF: Just make generic_bignum bigger, and never write into the early words, thus they'll always be zero. I hate Dean's floating-point code. Bleh. - */ + */ LITTLENUM_TYPE generic_bignum [SIZE_OF_LARGE_NUMBER+6]; FLONUM_TYPE generic_floating_point_number = { - & generic_bignum [6], /* low (JF: Was 0) */ - & generic_bignum [SIZE_OF_LARGE_NUMBER+6 - 1], /* high JF: (added +6) */ - 0, /* leader */ - 0, /* exponent */ - 0 /* sign */ -}; + & generic_bignum [6], /* low (JF: Was 0) */ + & generic_bignum [SIZE_OF_LARGE_NUMBER+6 - 1], /* high JF: (added +6) */ + 0, /* leader */ + 0, /* exponent */ + 0 /* sign */ + }; /* If nonzero, we've been asked to assemble nan, +inf or -inf */ int generic_floating_point_magic; @@ -83,383 +81,388 @@ int generic_floating_point_magic; */ static segT -operand (expressionP) - register expressionS * expressionP; + operand (expressionP) +register expressionS * expressionP; { - register char c; - register char *name; /* points to name of symbol */ - register symbolS * symbolP; /* Points to symbol */ - - extern char hex_value[]; /* In hex_value.c */ - - SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ - c = * input_line_pointer ++; /* Input_line_pointer->past char in c. */ - if (isdigit(c)) + register char c; + register char *name; /* points to name of symbol */ + register symbolS * symbolP; /* Points to symbol */ + + extern char hex_value[]; /* In hex_value.c */ + + SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ + c = * input_line_pointer ++; /* Input_line_pointer->past char in c. */ + if (isdigit(c) || (c == 'H' && input_line_pointer[0] == '\'')) { - register valueT number; /* offset or (absolute) value */ - register short int digit; /* value of next digit in current radix */ - /* invented for humans only, hope */ - /* optimising compiler flushes it! */ - register short int radix; /* 2, 8, 10 or 16 */ - /* 0 means we saw start of a floating- */ - /* point constant. */ - register short int maxdig = 0;/* Highest permitted digit value. */ - register int too_many_digits = 0; /* If we see >= this number of */ - /* digits, assume it is a bignum. */ - register char * digit_2; /*->2nd digit of number. */ - int small; /* TRUE if fits in 32 bits. */ - - if (c == '0') { /* non-decimal radix */ - if ((c = *input_line_pointer ++)=='x' || c=='X') { - c = *input_line_pointer ++; /* read past "0x" or "0X" */ - maxdig = radix = 16; - too_many_digits = 9; - } else { - /* If it says '0f' and the line ends or it DOESN'T look like - a floating point #, its a local label ref. DTRT */ - /* likewise for the b's. xoxorich. */ - if ((c == 'f' || c == 'b' || c == 'B') - && (!*input_line_pointer || - (!strchr("+-.0123456789",*input_line_pointer) && - !strchr(EXP_CHARS,*input_line_pointer)))) { - maxdig = radix = 10; - too_many_digits = 11; - c = '0'; - input_line_pointer -= 2; - - } else if (c == 'b' || c == 'B') { - c = *input_line_pointer++; - maxdig = radix = 2; - too_many_digits = 33; - - } else if (c && strchr(FLT_CHARS,c)) { - radix = 0; /* Start of floating-point constant. */ - /* input_line_pointer->1st char of number. */ - expressionP->X_add_number = -(isupper(c) ? tolower(c) : c); - - } else { /* By elimination, assume octal radix. */ - radix = maxdig = 8; - too_many_digits = 11; - } - } /* c == char after "0" or "0x" or "0X" or "0e" etc. */ - } else { - maxdig = radix = 10; - too_many_digits = 11; - } /* if operand starts with a zero */ - - if (radix) { /* Fixed-point integer constant. */ - /* May be bignum, or may fit in 32 bits. */ -/* - * Most numbers fit into 32 bits, and we want this case to be fast. - * So we pretend it will fit into 32 bits. If, after making up a 32 - * bit number, we realise that we have scanned more digits than - * comfortably fit into 32 bits, we re-scan the digits coding - * them into a bignum. For decimal and octal numbers we are conservative: some - * numbers may be assumed bignums when in fact they do fit into 32 bits. - * Numbers of any radix can have excess leading zeros: we strive - * to recognise this and cast them back into 32 bits. - * We must check that the bignum really is more than 32 - * bits, and change it back to a 32-bit number if it fits. - * The number we are looking for is expected to be positive, but - * if it fits into 32 bits as an unsigned number, we let it be a 32-bit - * number. The cavalier approach is for speed in ordinary cases. - */ - digit_2 = input_line_pointer; - for (number=0; (digit=hex_value[c])<maxdig; c = * input_line_pointer ++) + register valueT number; /* offset or (absolute) value */ + register short int digit; /* value of next digit in current radix */ + /* invented for humans only, hope */ + /* optimising compiler flushes it! */ + register short int radix; /* 2, 8, 10 or 16 */ + /* 0 means we saw start of a floating- */ + /* point constant. */ + register short int maxdig = 0;/* Highest permitted digit value. */ + register int too_many_digits = 0; /* If we see >= this number of */ + /* digits, assume it is a bignum. */ + register char * digit_2; /*->2nd digit of number. */ + int small; /* TRUE if fits in 32 bits. */ + + + if (c == 'H' || c == '0') { /* non-decimal radix */ + if ((c = *input_line_pointer ++)=='x' || c=='X' || c=='\'') { + c = *input_line_pointer ++; /* read past "0x" or "0X" or H' */ + maxdig = radix = 16; + too_many_digits = 9; + } else { + /* If it says '0f' and the line ends or it DOESN'T look like + a floating point #, its a local label ref. DTRT */ + /* likewise for the b's. xoxorich. */ + if ((c == 'f' || c == 'b' || c == 'B') + && (!*input_line_pointer || + (!strchr("+-.0123456789",*input_line_pointer) && + !strchr(EXP_CHARS,*input_line_pointer)))) { + maxdig = radix = 10; + too_many_digits = 11; + c = '0'; + input_line_pointer -= 2; + + } else if (c == 'b' || c == 'B') { + c = *input_line_pointer++; + maxdig = radix = 2; + too_many_digits = 33; + + } else if (c && strchr(FLT_CHARS,c)) { + radix = 0; /* Start of floating-point constant. */ + /* input_line_pointer->1st char of number. */ + expressionP->X_add_number = -(isupper(c) ? tolower(c) : c); + + } else { /* By elimination, assume octal radix. */ + radix = maxdig = 8; + too_many_digits = 11; + } + } /* c == char after "0" or "0x" or "0X" or "0e" etc. */ + } else { + maxdig = radix = 10; + too_many_digits = 11; + } /* if operand starts with a zero */ + + if (radix) { /* Fixed-point integer constant. */ + /* May be bignum, or may fit in 32 bits. */ + /* + * Most numbers fit into 32 bits, and we want this case to be fast. + * So we pretend it will fit into 32 bits. If, after making up a 32 + * bit number, we realise that we have scanned more digits than + * comfortably fit into 32 bits, we re-scan the digits coding + * them into a bignum. For decimal and octal numbers we are conservative: some + * numbers may be assumed bignums when in fact they do fit into 32 bits. + * Numbers of any radix can have excess leading zeros: we strive + * to recognise this and cast them back into 32 bits. + * We must check that the bignum really is more than 32 + * bits, and change it back to a 32-bit number if it fits. + * The number we are looking for is expected to be positive, but + * if it fits into 32 bits as an unsigned number, we let it be a 32-bit + * number. The cavalier approach is for speed in ordinary cases. + */ + digit_2 = input_line_pointer; + for (number=0; (digit=hex_value[c])<maxdig; c = * input_line_pointer ++) { - number = number * radix + digit; + number = number * radix + digit; } - /* C contains character after number. */ - /* Input_line_pointer->char after C. */ - small = input_line_pointer - digit_2 < too_many_digits; - if (! small) + /* C contains character after number. */ + /* Input_line_pointer->char after C. */ + small = input_line_pointer - digit_2 < too_many_digits; + if (! small) { - /* - * We saw a lot of digits. Manufacture a bignum the hard way. - */ - LITTLENUM_TYPE * leader; /*->high order littlenum of the bignum. */ - LITTLENUM_TYPE * pointer; /*->littlenum we are frobbing now. */ - long carry; - - leader = generic_bignum; - generic_bignum [0] = 0; - generic_bignum [1] = 0; - /* We could just use digit_2, but lets be mnemonic. */ - input_line_pointer = -- digit_2; /*->1st digit. */ - c = *input_line_pointer ++; - for (; (carry = hex_value [c]) < maxdig; c = * input_line_pointer ++) + /* + * We saw a lot of digits. Manufacture a bignum the hard way. + */ + LITTLENUM_TYPE * leader; /*->high order littlenum of the bignum. */ + LITTLENUM_TYPE * pointer; /*->littlenum we are frobbing now. */ + long carry; + + leader = generic_bignum; + generic_bignum [0] = 0; + generic_bignum [1] = 0; + /* We could just use digit_2, but lets be mnemonic. */ + input_line_pointer = -- digit_2; /*->1st digit. */ + c = *input_line_pointer ++; + for (; (carry = hex_value [c]) < maxdig; c = * input_line_pointer ++) { - for (pointer = generic_bignum; - pointer <= leader; - pointer ++) + for (pointer = generic_bignum; + pointer <= leader; + pointer ++) { - long work; - - work = carry + radix * * pointer; - * pointer = work & LITTLENUM_MASK; - carry = work >> LITTLENUM_NUMBER_OF_BITS; + long work; + + work = carry + radix * * pointer; + * pointer = work & LITTLENUM_MASK; + carry = work >> LITTLENUM_NUMBER_OF_BITS; } - if (carry) + if (carry) { - if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1) + if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1) { /* Room to grow a longer bignum. */ - * ++ leader = carry; + * ++ leader = carry; } } } - /* Again, C is char after number, */ - /* input_line_pointer->after C. */ - know(sizeof (int) * 8 == 32); - know(LITTLENUM_NUMBER_OF_BITS == 16); - /* Hence the constant "2" in the next line. */ - if (leader < generic_bignum + 2) + /* Again, C is char after number, */ + /* input_line_pointer->after C. */ + know(sizeof (int) * 8 == 32); + know(LITTLENUM_NUMBER_OF_BITS == 16); + /* Hence the constant "2" in the next line. */ + if (leader < generic_bignum + 2) { /* Will fit into 32 bits. */ - number = - ((generic_bignum [1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) - | (generic_bignum [0] & LITTLENUM_MASK); - small = 1; + number = + ((generic_bignum [1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) + | (generic_bignum [0] & LITTLENUM_MASK); + small = 1; } - else + else { - number = leader - generic_bignum + 1; /* Number of littlenums in the bignum. */ + number = leader - generic_bignum + 1; /* Number of littlenums in the bignum. */ } } - if (small) + if (small) { - /* - * Here with number, in correct radix. c is the next char. - * Note that unlike Un*x, we allow "011f" "0x9f" to - * both mean the same as the (conventional) "9f". This is simply easier - * than checking for strict canonical form. Syntax sux! - */ - if (number<10) + /* + * Here with number, in correct radix. c is the next char. + * Note that unlike Un*x, we allow "011f" "0x9f" to + * both mean the same as the (conventional) "9f". This is simply easier + * than checking for strict canonical form. Syntax sux! + */ + if (number<10) { - if (0 + if (0 #ifdef LOCAL_LABELS_FB - || c=='b' + || c=='b' #endif #ifdef LOCAL_LABELS_DOLLAR - || (c=='$' && local_label_defined[number]) + || (c=='$' && local_label_defined[number]) #endif - ) + ) { - /* - * Backward ref to local label. - * Because it is backward, expect it to be DEFINED. - */ - /* - * Construct a local label. - */ - name = local_label_name ((int)number, 0); - if (((symbolP = symbol_find(name)) != NULL) /* seen before */ - && (S_IS_DEFINED(symbolP))) /* symbol is defined: OK */ + /* + * Backward ref to local label. + * Because it is backward, expect it to be DEFINED. + */ + /* + * Construct a local label. + */ + name = local_label_name ((int)number, 0); + if (((symbolP = symbol_find(name)) != NULL) /* seen before */ + && (S_IS_DEFINED(symbolP))) /* symbol is defined: OK */ { /* Expected path: symbol defined. */ - /* Local labels are never absolute. Don't waste time checking absoluteness. */ - know((S_GET_SEGMENT(symbolP) == SEG_DATA) || (S_GET_SEGMENT(symbolP) == SEG_TEXT)); - expressionP->X_add_symbol = symbolP; - expressionP->X_add_number = 0; - expressionP->X_seg = S_GET_SEGMENT(symbolP); + /* Local labels are never absolute. Don't waste time checking absoluteness. */ + know(SEG_NORMAL(S_GET_SEGMENT(symbolP))); + + expressionP->X_add_symbol = symbolP; + expressionP->X_add_number = 0; + expressionP->X_seg = S_GET_SEGMENT(symbolP); } - else + else { /* Either not seen or not defined. */ - as_bad("Backw. ref to unknown label \"%d:\", 0 assumed.", - number); - expressionP->X_add_number = 0; - expressionP->X_seg = SEG_ABSOLUTE; + as_bad("Backw. ref to unknown label \"%d:\", 0 assumed.", + number); + expressionP->X_add_number = 0; + expressionP->X_seg = SEG_ABSOLUTE; } } - else + else { - if (0 + if (0 #ifdef LOCAL_LABELS_FB - || c == 'f' + || c == 'f' #endif #ifdef LOCAL_LABELS_DOLLAR - || (c=='$' && !local_label_defined[number]) + || (c=='$' && !local_label_defined[number]) #endif - ) + ) { - /* - * Forward reference. Expect symbol to be undefined or - * unknown. Undefined: seen it before. Unknown: never seen - * it in this pass. - * Construct a local label name, then an undefined symbol. - * Don't create a XSEG frag for it: caller may do that. - * Just return it as never seen before. - */ - name = local_label_name((int)number, 1); - symbolP = symbol_find_or_make(name); - /* We have no need to check symbol properties. */ - know(S_GET_SEGMENT(symbolP) == SEG_UNKNOWN - || S_GET_SEGMENT(symbolP) == SEG_TEXT - || S_GET_SEGMENT(symbolP) == SEG_DATA); - expressionP->X_add_symbol = symbolP; - expressionP->X_seg = SEG_UNKNOWN; - expressionP->X_subtract_symbol = NULL; - expressionP->X_add_number = 0; + /* + * Forward reference. Expect symbol to be undefined or + * unknown. Undefined: seen it before. Unknown: never seen + * it in this pass. + * Construct a local label name, then an undefined symbol. + * Don't create a XSEG frag for it: caller may do that. + * Just return it as never seen before. + */ + name = local_label_name((int)number, 1); + symbolP = symbol_find_or_make(name); + /* We have no need to check symbol properties. */ +#ifndef MANY_SEGMENTS + /* Since "know" puts its arg into a "string", we + can't have newlines in the argument. */ + know(S_GET_SEGMENT(symbolP) == SEG_UNKNOWN || S_GET_SEGMENT(symbolP) == SEG_TEXT || S_GET_SEGMENT(symbolP) == SEG_DATA); +#endif + expressionP->X_add_symbol = symbolP; + expressionP->X_seg = SEG_UNKNOWN; + expressionP->X_subtract_symbol = NULL; + expressionP->X_add_number = 0; } - else + else { /* Really a number, not a local label. */ - expressionP->X_add_number = number; - expressionP->X_seg = SEG_ABSOLUTE; - input_line_pointer --; /* Restore following character. */ + expressionP->X_add_number = number; + expressionP->X_seg = SEG_ABSOLUTE; + input_line_pointer --; /* Restore following character. */ } /* if (c=='f') */ } /* if (c=='b') */ } - else + else { /* Really a number. */ - expressionP->X_add_number = number; - expressionP->X_seg = SEG_ABSOLUTE; - input_line_pointer --; /* Restore following character. */ + expressionP->X_add_number = number; + expressionP->X_seg = SEG_ABSOLUTE; + input_line_pointer --; /* Restore following character. */ } /* if (number<10) */ } - else + else { - expressionP->X_add_number = number; - expressionP->X_seg = SEG_BIG; - input_line_pointer --; /*->char following number. */ + expressionP->X_add_number = number; + expressionP->X_seg = SEG_BIG; + input_line_pointer --; /*->char following number. */ } /* if (small) */ } /* (If integer constant) */ - else + else { /* input_line_pointer->*/ - /* floating-point constant. */ - int error_code; - - error_code = atof_generic - (& input_line_pointer, ".", EXP_CHARS, - & generic_floating_point_number); - - if (error_code) + /* floating-point constant. */ + int error_code; + + error_code = atof_generic + (& input_line_pointer, ".", EXP_CHARS, + & generic_floating_point_number); + + if (error_code) { - if (error_code == ERROR_EXPONENT_OVERFLOW) + if (error_code == ERROR_EXPONENT_OVERFLOW) { - as_bad("Bad floating-point constant: exponent overflow, probably assembling junk"); + as_bad("Bad floating-point constant: exponent overflow, probably assembling junk"); } - else + else { - as_bad("Bad floating-point constant: unknown error code=%d.", error_code); + as_bad("Bad floating-point constant: unknown error code=%d.", error_code); } } - expressionP->X_seg = SEG_BIG; - /* input_line_pointer->just after constant, */ - /* which may point to whitespace. */ - know(expressionP->X_add_number < 0); /* < 0 means "floating point". */ + expressionP->X_seg = SEG_BIG; + /* input_line_pointer->just after constant, */ + /* which may point to whitespace. */ + know(expressionP->X_add_number < 0); /* < 0 means "floating point". */ } /* if (not floating-point constant) */ } - else if(c=='.' && !is_part_of_name(*input_line_pointer)) { - extern struct obstack frags; - - /* - JF: '.' is pseudo symbol with value of current location in current - segment. . . - */ - symbolP = symbol_new("L0\001", - now_seg, - (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), - frag_now); - - expressionP->X_add_number=0; - expressionP->X_add_symbol=symbolP; - expressionP->X_seg = now_seg; - - } else if (is_name_beginner(c)) /* here if did not begin with a digit */ + else if(c=='.' && !is_part_of_name(*input_line_pointer)) { + extern struct obstack frags; + + /* + JF: '.' is pseudo symbol with value of current location in current + segment. . . + */ + symbolP = symbol_new("L0\001", + now_seg, + (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), + frag_now); + + expressionP->X_add_number=0; + expressionP->X_add_symbol=symbolP; + expressionP->X_seg = now_seg; + + } else if (is_name_beginner(c)) /* here if did not begin with a digit */ { - /* - * Identifier begins here. - * This is kludged for speed, so code is repeated. - */ - name = -- input_line_pointer; - c = get_symbol_end(); - symbolP = symbol_find_or_make(name); - /* - * If we have an absolute symbol or a reg, then we know its value now. - */ - expressionP->X_seg = S_GET_SEGMENT(symbolP); - switch (expressionP->X_seg) + /* + * Identifier begins here. + * This is kludged for speed, so code is repeated. + */ + name = -- input_line_pointer; + c = get_symbol_end(); + symbolP = symbol_find_or_make(name); + /* + * If we have an absolute symbol or a reg, then we know its value now. + */ + expressionP->X_seg = S_GET_SEGMENT(symbolP); + switch (expressionP->X_seg) { case SEG_ABSOLUTE: case SEG_REGISTER: - expressionP->X_add_number = S_GET_VALUE(symbolP); - break; - - default: - expressionP->X_add_number = 0; - expressionP->X_add_symbol = symbolP; + expressionP->X_add_number = S_GET_VALUE(symbolP); + break; + + default: + expressionP->X_add_number = 0; + expressionP->X_add_symbol = symbolP; } - * input_line_pointer = c; - expressionP->X_subtract_symbol = NULL; + * input_line_pointer = c; + expressionP->X_subtract_symbol = NULL; } - else if (c=='(')/* didn't begin with digit & not a name */ + else if (c=='(')/* didn't begin with digit & not a name */ { - (void)expression(expressionP); - /* Expression() will pass trailing whitespace */ - if (* input_line_pointer ++ != ')') + (void)expression(expressionP); + /* Expression() will pass trailing whitespace */ + if (* input_line_pointer ++ != ')') { - as_bad("Missing ')' assumed"); - input_line_pointer --; + as_bad("Missing ')' assumed"); + input_line_pointer --; } - /* here with input_line_pointer->char after "(...)" */ + /* here with input_line_pointer->char after "(...)" */ } - else if (c == '~' || c == '-' || c == '+') { - /* unary operator: hope for SEG_ABSOLUTE */ - switch (operand (expressionP)) { - case SEG_ABSOLUTE: - /* input_line_pointer->char after operand */ - if (c=='-') { - expressionP->X_add_number = - expressionP->X_add_number; - /* - * Notice: '-' may overflow: no warning is given. This is compatible - * with other people's assemblers. Sigh. - */ - } else if (c == '~') { - expressionP->X_add_number = ~ expressionP->X_add_number; - } else if (c != '+') { - know(0); - } /* switch on unary operator */ - break; - - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_PASS1: - case SEG_UNKNOWN: - if(c=='-') { /* JF I hope this hack works */ - expressionP->X_subtract_symbol=expressionP->X_add_symbol; - expressionP->X_add_symbol=0; - expressionP->X_seg=SEG_DIFFERENCE; - break; + else if (c == '~' || c == '-' || c == '+') { + /* unary operator: hope for SEG_ABSOLUTE */ + switch (operand (expressionP)) { + case SEG_ABSOLUTE: + /* input_line_pointer->char after operand */ + if (c=='-') { + expressionP->X_add_number = - expressionP->X_add_number; + /* + * Notice: '-' may overflow: no warning is given. This is compatible + * with other people's assemblers. Sigh. + */ + } else if (c == '~') { + expressionP->X_add_number = ~ expressionP->X_add_number; + } else if (c != '+') { + know(0); + } /* switch on unary operator */ + break; + + default: /* unary on non-absolute is unsuported */ + if (!SEG_NORMAL(operand(expressionP))) + { + as_bad("Unary operator %c ignored because bad operand follows", c); + break; + } + /* Fall through for normal segments ****/ + case SEG_PASS1: + case SEG_UNKNOWN: + if(c=='-') { /* JF I hope this hack works */ + expressionP->X_subtract_symbol=expressionP->X_add_symbol; + expressionP->X_add_symbol=0; + expressionP->X_seg=SEG_DIFFERENCE; + break; + } + /* Expression undisturbed from operand(). */ } - default: /* unary on non-absolute is unsuported */ - as_bad("Unary operator %c ignored because bad operand follows", c); - break; - /* Expression undisturbed from operand(). */ - } } - else if (c=='\'') + else if (c=='\'') { -/* - * Warning: to conform to other people's assemblers NO ESCAPEMENT is permitted - * for a single quote. The next character, parity errors and all, is taken - * as the value of the operand. VERY KINKY. - */ - expressionP->X_add_number = * input_line_pointer ++; - expressionP->X_seg = SEG_ABSOLUTE; + /* + * Warning: to conform to other people's assemblers NO ESCAPEMENT is permitted + * for a single quote. The next character, parity errors and all, is taken + * as the value of the operand. VERY KINKY. + */ + expressionP->X_add_number = * input_line_pointer ++; + expressionP->X_seg = SEG_ABSOLUTE; } - else + else { - /* can't imagine any other kind of operand */ - expressionP->X_seg = SEG_ABSENT; - input_line_pointer --; - md_operand (expressionP); + /* can't imagine any other kind of operand */ + expressionP->X_seg = SEG_ABSENT; + input_line_pointer --; + md_operand (expressionP); } -/* - * It is more 'efficient' to clean up the expressions when they are created. - * Doing it here saves lines of code. - */ - clean_up_expression (expressionP); - SKIP_WHITESPACE(); /*->1st char after operand. */ - know(* input_line_pointer != ' '); - return (expressionP->X_seg); + /* + * It is more 'efficient' to clean up the expressions when they are created. + * Doing it here saves lines of code. + */ + clean_up_expression (expressionP); + SKIP_WHITESPACE(); /*->1st char after operand. */ + know(* input_line_pointer != ' '); + return (expressionP->X_seg); } /* operand() */ /* Internal. Simplify a struct expression for use by expr() */ @@ -476,57 +479,59 @@ operand (expressionP) */ static void -clean_up_expression (expressionP) - register expressionS * expressionP; + clean_up_expression (expressionP) +register expressionS * expressionP; { - switch (expressionP->X_seg) + switch (expressionP->X_seg) { case SEG_ABSENT: case SEG_PASS1: - expressionP->X_add_symbol = NULL; - expressionP->X_subtract_symbol = NULL; - expressionP->X_add_number = 0; - break; - + expressionP->X_add_symbol = NULL; + expressionP->X_subtract_symbol = NULL; + expressionP->X_add_number = 0; + break; + case SEG_BIG: case SEG_ABSOLUTE: - expressionP->X_subtract_symbol = NULL; - expressionP->X_add_symbol = NULL; - break; - - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: + expressionP->X_subtract_symbol = NULL; + expressionP->X_add_symbol = NULL; + break; + case SEG_UNKNOWN: - expressionP->X_subtract_symbol = NULL; - break; - + expressionP->X_subtract_symbol = NULL; + break; + case SEG_DIFFERENCE: - /* - * It does not hurt to 'cancel' NULL==NULL - * when comparing symbols for 'eq'ness. - * It is faster to re-cancel them to NULL - * than to check for this special case. - */ - if (expressionP->X_subtract_symbol == expressionP->X_add_symbol - || (expressionP->X_subtract_symbol - && expressionP->X_add_symbol - && expressionP->X_subtract_symbol->sy_frag==expressionP->X_add_symbol->sy_frag - && S_GET_VALUE(expressionP->X_subtract_symbol) == S_GET_VALUE(expressionP->X_add_symbol))) { - expressionP->X_subtract_symbol = NULL; - expressionP->X_add_symbol = NULL; - expressionP->X_seg = SEG_ABSOLUTE; - } - break; - + /* + * It does not hurt to 'cancel' NULL==NULL + * when comparing symbols for 'eq'ness. + * It is faster to re-cancel them to NULL + * than to check for this special case. + */ + if (expressionP->X_subtract_symbol == expressionP->X_add_symbol + || (expressionP->X_subtract_symbol + && expressionP->X_add_symbol + && expressionP->X_subtract_symbol->sy_frag==expressionP->X_add_symbol->sy_frag + && S_GET_VALUE(expressionP->X_subtract_symbol) == S_GET_VALUE(expressionP->X_add_symbol))) { + expressionP->X_subtract_symbol = NULL; + expressionP->X_add_symbol = NULL; + expressionP->X_seg = SEG_ABSOLUTE; + } + break; + case SEG_REGISTER: - expressionP->X_add_symbol = NULL; - expressionP->X_subtract_symbol = NULL; - break; - + expressionP->X_add_symbol = NULL; + expressionP->X_subtract_symbol = NULL; + break; + default: - BAD_CASE (expressionP->X_seg); - break; + if (SEG_NORMAL(expressionP->X_seg)) { + expressionP->X_subtract_symbol = NULL; + } + else { + BAD_CASE (expressionP->X_seg); + } + break; } } /* clean_up_expression() */ @@ -542,83 +547,72 @@ clean_up_expression (expressionP) */ static segT -expr_part (symbol_1_PP, symbol_2_P) - symbolS ** symbol_1_PP; - symbolS * symbol_2_P; + expr_part (symbol_1_PP, symbol_2_P) +symbolS ** symbol_1_PP; +symbolS * symbol_2_P; { - segT return_value; - - know((* symbol_1_PP) == NULL - || (S_GET_SEGMENT(*symbol_1_PP) == SEG_TEXT) - || (S_GET_SEGMENT(*symbol_1_PP) == SEG_DATA) - || (S_GET_SEGMENT(*symbol_1_PP) == SEG_BSS) - || (!S_IS_DEFINED(* symbol_1_PP))); - know(symbol_2_P == NULL - || (S_GET_SEGMENT(symbol_2_P) == SEG_TEXT) - || (S_GET_SEGMENT(symbol_2_P) == SEG_DATA) - || (S_GET_SEGMENT(symbol_2_P) == SEG_BSS) - || (!S_IS_DEFINED(symbol_2_P))); - if (* symbol_1_PP) + segT return_value; +#ifndef MANY_SEGMENTS + know((* symbol_1_PP) == NULL || (S_GET_SEGMENT(*symbol_1_PP) == SEG_TEXT) || (S_GET_SEGMENT(*symbol_1_PP) == SEG_DATA) || (S_GET_SEGMENT(*symbol_1_PP) == SEG_BSS) || (!S_IS_DEFINED(* symbol_1_PP))); + know(symbol_2_P == NULL || (S_GET_SEGMENT(symbol_2_P) == SEG_TEXT) || (S_GET_SEGMENT(symbol_2_P) == SEG_DATA) || (S_GET_SEGMENT(symbol_2_P) == SEG_BSS) || (!S_IS_DEFINED(symbol_2_P))); +#endif + if (* symbol_1_PP) { - if (!S_IS_DEFINED(* symbol_1_PP)) + if (!S_IS_DEFINED(* symbol_1_PP)) { - if (symbol_2_P) + if (symbol_2_P) { - return_value = SEG_PASS1; - * symbol_1_PP = NULL; + return_value = SEG_PASS1; + * symbol_1_PP = NULL; } - else + else { - know(!S_IS_DEFINED(* symbol_1_PP)); - return_value = SEG_UNKNOWN; + know(!S_IS_DEFINED(* symbol_1_PP)); + return_value = SEG_UNKNOWN; } } - else + else { - if (symbol_2_P) + if (symbol_2_P) { - if (!S_IS_DEFINED(symbol_2_P)) + if (!S_IS_DEFINED(symbol_2_P)) { - * symbol_1_PP = NULL; - return_value = SEG_PASS1; + * symbol_1_PP = NULL; + return_value = SEG_PASS1; } - else + else { - /* {seg1} - {seg2} */ - as_bad("Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"", - S_GET_NAME(* symbol_1_PP), S_GET_NAME(symbol_2_P)); - * symbol_1_PP = NULL; - return_value = SEG_ABSOLUTE; + /* {seg1} - {seg2} */ + as_bad("Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"", + S_GET_NAME(* symbol_1_PP), S_GET_NAME(symbol_2_P)); + * symbol_1_PP = NULL; + return_value = SEG_ABSOLUTE; } } - else + else { - return_value = S_GET_SEGMENT(* symbol_1_PP); + return_value = S_GET_SEGMENT(* symbol_1_PP); } } } - else + else { /* (* symbol_1_PP) == NULL */ - if (symbol_2_P) + if (symbol_2_P) { - * symbol_1_PP = symbol_2_P; - return_value = S_GET_SEGMENT(symbol_2_P); + * symbol_1_PP = symbol_2_P; + return_value = S_GET_SEGMENT(symbol_2_P); } - else + else { - * symbol_1_PP = NULL; - return_value = SEG_ABSOLUTE; + * symbol_1_PP = NULL; + return_value = SEG_ABSOLUTE; } } - know(return_value == SEG_ABSOLUTE - || return_value == SEG_TEXT - || return_value == SEG_DATA - || return_value == SEG_BSS - || return_value == SEG_UNKNOWN - || return_value == SEG_PASS1); - know((* symbol_1_PP) == NULL - || (S_GET_SEGMENT(* symbol_1_PP) == return_value)); - return (return_value); +#ifndef MANY_SEGMENTS + know(return_value == SEG_ABSOLUTE || return_value == SEG_TEXT || return_value == SEG_DATA || return_value == SEG_BSS || return_value == SEG_UNKNOWN || return_value == SEG_PASS1); +#endif + know((*symbol_1_PP) == NULL || (S_GET_SEGMENT(*symbol_1_PP) == return_value)); + return (return_value); } /* expr_part() */ /* Expression parser. */ @@ -643,51 +637,51 @@ expr_part (symbol_1_PP, symbol_2_P) typedef enum { -O_illegal, /* (0) what we get for illegal op */ - -O_multiply, /* (1) * */ -O_divide, /* (2) / */ -O_modulus, /* (3) % */ -O_left_shift, /* (4) < */ -O_right_shift, /* (5) > */ -O_bit_inclusive_or, /* (6) | */ -O_bit_or_not, /* (7) ! */ -O_bit_exclusive_or, /* (8) ^ */ -O_bit_and, /* (9) & */ -O_add, /* (10) + */ -O_subtract /* (11) - */ -} + O_illegal, /* (0) what we get for illegal op */ + + O_multiply, /* (1) * */ + O_divide, /* (2) / */ + O_modulus, /* (3) % */ + O_left_shift, /* (4) < */ + O_right_shift, /* (5) > */ + O_bit_inclusive_or, /* (6) | */ + O_bit_or_not, /* (7) ! */ + O_bit_exclusive_or, /* (8) ^ */ + O_bit_and, /* (9) & */ + O_add, /* (10) + */ + O_subtract /* (11) - */ + } operatorT; #define __ O_illegal static const operatorT op_encoding [256] = { /* maps ASCII->operators */ - -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - -__, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __, -__, __, O_multiply, O_add, __, O_subtract, __, O_divide, -__, __, __, __, __, __, __, __, -__, __, __, __, O_left_shift, __, O_right_shift, __, -__, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, -__, __, __, __, __, __, O_bit_exclusive_or, __, -__, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, -__, __, __, __, O_bit_inclusive_or, __, __, __, - -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ -}; + + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + + __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __, + __, __, O_multiply, O_add, __, O_subtract, __, O_divide, + __, __, __, __, __, __, __, __, + __, __, __, __, O_left_shift, __, O_right_shift, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, O_bit_exclusive_or, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, O_bit_inclusive_or, __, __, __, + + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ + }; /* @@ -698,236 +692,224 @@ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ * 3 * / % << >> */ static const operator_rankT -op_rank [] = { 0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1 }; + op_rank [] = { 0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1 }; /* Return resultP->X_seg. */ segT expr(rank, resultP) -register operator_rankT rank; /* Larger # is higher rank. */ -register expressionS *resultP; /* Deliver result here. */ + register operator_rankT rank; /* Larger # is higher rank. */ + register expressionS *resultP; /* Deliver result here. */ { - expressionS right; - register operatorT op_left; - register char c_left; /* 1st operator character. */ - register operatorT op_right; - register char c_right; - - know(rank >= 0); - (void)operand (resultP); - know(* input_line_pointer != ' '); /* Operand() gobbles spaces. */ - c_left = * input_line_pointer; /* Potential operator character. */ - op_left = op_encoding [c_left]; - while (op_left != O_illegal && op_rank [(int) op_left] > rank) + expressionS right; + register operatorT op_left; + register char c_left; /* 1st operator character. */ + register operatorT op_right; + register char c_right; + + know(rank >= 0); + (void)operand (resultP); + know(* input_line_pointer != ' '); /* Operand() gobbles spaces. */ + c_left = * input_line_pointer; /* Potential operator character. */ + op_left = op_encoding [c_left]; + while (op_left != O_illegal && op_rank [(int) op_left] > rank) { - input_line_pointer ++; /*->after 1st character of operator. */ - /* Operators "<<" and ">>" have 2 characters. */ - if (* input_line_pointer == c_left && (c_left == '<' || c_left == '>')) + input_line_pointer ++; /*->after 1st character of operator. */ + /* Operators "<<" and ">>" have 2 characters. */ + if (* input_line_pointer == c_left && (c_left == '<' || c_left == '>')) { - input_line_pointer ++; + input_line_pointer ++; } /*->after operator. */ - if (SEG_ABSENT == expr (op_rank[(int) op_left], &right)) + if (SEG_ABSENT == expr (op_rank[(int) op_left], &right)) { - as_warn("Missing operand value assumed absolute 0."); - resultP->X_add_number = 0; - resultP->X_subtract_symbol = NULL; - resultP->X_add_symbol = NULL; - resultP->X_seg = SEG_ABSOLUTE; + as_warn("Missing operand value assumed absolute 0."); + resultP->X_add_number = 0; + resultP->X_subtract_symbol = NULL; + resultP->X_add_symbol = NULL; + resultP->X_seg = SEG_ABSOLUTE; } - know(* input_line_pointer != ' '); - c_right = * input_line_pointer; - op_right = op_encoding [c_right]; - if (* input_line_pointer == c_right && (c_right == '<' || c_right == '>')) + know(* input_line_pointer != ' '); + c_right = * input_line_pointer; + op_right = op_encoding [c_right]; + if (* input_line_pointer == c_right && (c_right == '<' || c_right == '>')) { - input_line_pointer ++; + input_line_pointer ++; } /*->after operator. */ - know((int) op_right == 0 - || op_rank [(int) op_right] <= op_rank[(int) op_left]); - /* input_line_pointer->after right-hand quantity. */ - /* left-hand quantity in resultP */ - /* right-hand quantity in right. */ - /* operator in op_left. */ - if (resultP->X_seg == SEG_PASS1 || right . X_seg == SEG_PASS1) + know((int) op_right == 0 || op_rank [(int) op_right] <= op_rank[(int) op_left]); + /* input_line_pointer->after right-hand quantity. */ + /* left-hand quantity in resultP */ + /* right-hand quantity in right. */ + /* operator in op_left. */ + if (resultP->X_seg == SEG_PASS1 || right . X_seg == SEG_PASS1) { - resultP->X_seg = SEG_PASS1; + resultP->X_seg = SEG_PASS1; } - else + else { - if (resultP->X_seg == SEG_BIG) + if (resultP->X_seg == SEG_BIG) { - as_warn("Left operand of %c is a %s. Integer 0 assumed.", - c_left, resultP->X_add_number > 0 ? "bignum" : "float"); - resultP->X_seg = SEG_ABSOLUTE; - resultP->X_add_symbol = 0; - resultP->X_subtract_symbol = 0; - resultP->X_add_number = 0; + as_warn("Left operand of %c is a %s. Integer 0 assumed.", + c_left, resultP->X_add_number > 0 ? "bignum" : "float"); + resultP->X_seg = SEG_ABSOLUTE; + resultP->X_add_symbol = 0; + resultP->X_subtract_symbol = 0; + resultP->X_add_number = 0; } - if (right . X_seg == SEG_BIG) + if (right . X_seg == SEG_BIG) { - as_warn("Right operand of %c is a %s. Integer 0 assumed.", - c_left, right . X_add_number > 0 ? "bignum" : "float"); - right . X_seg = SEG_ABSOLUTE; - right . X_add_symbol = 0; - right . X_subtract_symbol = 0; - right . X_add_number = 0; + as_warn("Right operand of %c is a %s. Integer 0 assumed.", + c_left, right . X_add_number > 0 ? "bignum" : "float"); + right . X_seg = SEG_ABSOLUTE; + right . X_add_symbol = 0; + right . X_subtract_symbol = 0; + right . X_add_number = 0; } - if (op_left == O_subtract) + if (op_left == O_subtract) { - /* - * Convert - into + by exchanging symbols and negating number. - * I know -infinity can't be negated in 2's complement: - * but then it can't be subtracted either. This trick - * does not cause any further inaccuracy. - */ - - register symbolS * symbolP; - - right . X_add_number = - right . X_add_number; - symbolP = right . X_add_symbol; - right . X_add_symbol = right . X_subtract_symbol; - right . X_subtract_symbol = symbolP; - if (symbolP) + /* + * Convert - into + by exchanging symbols and negating number. + * I know -infinity can't be negated in 2's complement: + * but then it can't be subtracted either. This trick + * does not cause any further inaccuracy. + */ + + register symbolS * symbolP; + + right . X_add_number = - right . X_add_number; + symbolP = right . X_add_symbol; + right . X_add_symbol = right . X_subtract_symbol; + right . X_subtract_symbol = symbolP; + if (symbolP) { - right . X_seg = SEG_DIFFERENCE; + right . X_seg = SEG_DIFFERENCE; } - op_left = O_add; + op_left = O_add; } - - if (op_left == O_add) + + if (op_left == O_add) { - segT seg1; - segT seg2; - - know(resultP->X_seg == SEG_DATA - || resultP->X_seg == SEG_TEXT - || resultP->X_seg == SEG_BSS - || resultP->X_seg == SEG_UNKNOWN - || resultP->X_seg == SEG_DIFFERENCE - || resultP->X_seg == SEG_ABSOLUTE - || resultP->X_seg == SEG_PASS1); - know(right . X_seg == SEG_DATA - || right . X_seg == SEG_TEXT - || right . X_seg == SEG_BSS - || right . X_seg == SEG_UNKNOWN - || right . X_seg == SEG_DIFFERENCE - || right . X_seg == SEG_ABSOLUTE - || right . X_seg == SEG_PASS1); - - clean_up_expression (& right); - clean_up_expression (resultP); - - seg1 = expr_part (& resultP->X_add_symbol, right . X_add_symbol); - seg2 = expr_part (& resultP->X_subtract_symbol, right . X_subtract_symbol); - if (seg1 == SEG_PASS1 || seg2 == SEG_PASS1) { - need_pass_2 = 1; - resultP->X_seg = SEG_PASS1; - } else if (seg2 == SEG_ABSOLUTE) - resultP->X_seg = seg1; - else if (seg1 != SEG_UNKNOWN - && seg1 != SEG_ABSOLUTE - && seg2 != SEG_UNKNOWN - && seg1 != seg2) { - know(seg2 != SEG_ABSOLUTE); - know(resultP->X_subtract_symbol); - - know(seg1 == SEG_TEXT || seg1 == SEG_DATA || seg1== SEG_BSS); - know(seg2 == SEG_TEXT || seg2 == SEG_DATA || seg2== SEG_BSS); - know(resultP->X_add_symbol); - know(resultP->X_subtract_symbol); - as_bad("Expression too complex: forgetting %s - %s", - S_GET_NAME(resultP->X_add_symbol), - S_GET_NAME(resultP->X_subtract_symbol)); - resultP->X_seg = SEG_ABSOLUTE; - /* Clean_up_expression() will do the rest. */ - } else - resultP->X_seg = SEG_DIFFERENCE; - - resultP->X_add_number += right . X_add_number; - clean_up_expression (resultP); - } - else + segT seg1; + segT seg2; +#ifndef MANY_SEGMENTS + know(resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg == SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1); + know(right.X_seg == SEG_DATA || right.X_seg == SEG_TEXT || right.X_seg == SEG_BSS || right.X_seg == SEG_UNKNOWN || right.X_seg == SEG_DIFFERENCE || right.X_seg == SEG_ABSOLUTE || right.X_seg == SEG_PASS1); +#endif + clean_up_expression (& right); + clean_up_expression (resultP); + + seg1 = expr_part (& resultP->X_add_symbol, right . X_add_symbol); + seg2 = expr_part (& resultP->X_subtract_symbol, right . X_subtract_symbol); + if (seg1 == SEG_PASS1 || seg2 == SEG_PASS1) { + need_pass_2 = 1; + resultP->X_seg = SEG_PASS1; + } else if (seg2 == SEG_ABSOLUTE) + resultP->X_seg = seg1; + else if (seg1 != SEG_UNKNOWN + && seg1 != SEG_ABSOLUTE + && seg2 != SEG_UNKNOWN + && seg1 != seg2) { + know(seg2 != SEG_ABSOLUTE); + know(resultP->X_subtract_symbol); +#ifndef MANY_SEGMENTS + know(seg1 == SEG_TEXT || seg1 == SEG_DATA || seg1== SEG_BSS); + know(seg2 == SEG_TEXT || seg2 == SEG_DATA || seg2== SEG_BSS); +#endif + know(resultP->X_add_symbol); + know(resultP->X_subtract_symbol); + as_bad("Expression too complex: forgetting %s - %s", + S_GET_NAME(resultP->X_add_symbol), + S_GET_NAME(resultP->X_subtract_symbol)); + resultP->X_seg = SEG_ABSOLUTE; + /* Clean_up_expression() will do the rest. */ + } else + resultP->X_seg = SEG_DIFFERENCE; + + resultP->X_add_number += right . X_add_number; + clean_up_expression (resultP); + } + else { /* Not +. */ - if (resultP->X_seg == SEG_UNKNOWN || right . X_seg == SEG_UNKNOWN) + if (resultP->X_seg == SEG_UNKNOWN || right . X_seg == SEG_UNKNOWN) { - resultP->X_seg = SEG_PASS1; - need_pass_2 = 1; + resultP->X_seg = SEG_PASS1; + need_pass_2 = 1; } - else + else { - resultP->X_subtract_symbol = NULL; - resultP->X_add_symbol = NULL; - /* Will be SEG_ABSOLUTE. */ - if (resultP->X_seg != SEG_ABSOLUTE || right . X_seg != SEG_ABSOLUTE) + resultP->X_subtract_symbol = NULL; + resultP->X_add_symbol = NULL; + /* Will be SEG_ABSOLUTE. */ + if (resultP->X_seg != SEG_ABSOLUTE || right . X_seg != SEG_ABSOLUTE) { - as_bad("Relocation error. Absolute 0 assumed."); - resultP->X_seg = SEG_ABSOLUTE; - resultP->X_add_number = 0; + as_bad("Relocation error. Absolute 0 assumed."); + resultP->X_seg = SEG_ABSOLUTE; + resultP->X_add_number = 0; } - else + else { - switch (op_left) + switch (op_left) { case O_bit_inclusive_or: - resultP->X_add_number |= right . X_add_number; - break; - + resultP->X_add_number |= right . X_add_number; + break; + case O_modulus: - if (right . X_add_number) + if (right . X_add_number) { - resultP->X_add_number %= right . X_add_number; + resultP->X_add_number %= right . X_add_number; } - else + else { - as_warn("Division by 0. 0 assumed."); - resultP->X_add_number = 0; + as_warn("Division by 0. 0 assumed."); + resultP->X_add_number = 0; } - break; - + break; + case O_bit_and: - resultP->X_add_number &= right . X_add_number; - break; - + resultP->X_add_number &= right . X_add_number; + break; + case O_multiply: - resultP->X_add_number *= right . X_add_number; - break; - + resultP->X_add_number *= right . X_add_number; + break; + case O_divide: - if (right . X_add_number) + if (right . X_add_number) { - resultP->X_add_number /= right . X_add_number; + resultP->X_add_number /= right . X_add_number; } - else + else { - as_warn("Division by 0. 0 assumed."); - resultP->X_add_number = 0; + as_warn("Division by 0. 0 assumed."); + resultP->X_add_number = 0; } - break; - + break; + case O_left_shift: - resultP->X_add_number <<= right . X_add_number; - break; - + resultP->X_add_number <<= right . X_add_number; + break; + case O_right_shift: - resultP->X_add_number >>= right . X_add_number; - break; - + resultP->X_add_number >>= right . X_add_number; + break; + case O_bit_exclusive_or: - resultP->X_add_number ^= right . X_add_number; - break; - + resultP->X_add_number ^= right . X_add_number; + break; + case O_bit_or_not: - resultP->X_add_number |= ~ right . X_add_number; - break; - + resultP->X_add_number |= ~ right . X_add_number; + break; + default: - BAD_CASE(op_left); - break; + BAD_CASE(op_left); + break; } /* switch(operator) */ } } /* If we have to force need_pass_2. */ } /* If operator was +. */ } /* If we didn't set need_pass_2. */ - op_left = op_right; + op_left = op_right; } /* While next operator is >= this rank. */ - return (resultP->X_seg); + return (resultP->X_seg); } /* @@ -946,16 +928,24 @@ register expressionS *resultP; /* Deliver result here. */ * lines end in end-of-line. */ char -get_symbol_end() + get_symbol_end() { - register char c; - - while (is_part_of_name(c = * input_line_pointer ++)) - ; - * -- input_line_pointer = 0; - return (c); + register char c; + + while (is_part_of_name(c = * input_line_pointer ++)) + ; + * -- input_line_pointer = 0; + return (c); } + +unsigned int get_single_number() +{ + expressionS exp; + operand(&exp); + return exp.X_add_number; + +} /* * Local Variables: * comment-column: 0 @@ -1,21 +1,21 @@ /* expr.h -> header file for expr.c Copyright (C) 1987 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. */ + + 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. */ /* * Abbreviations (mnemonics). @@ -51,14 +51,14 @@ typedef struct } expressionS; - /* result should be type (expressionS *). */ +/* result should be type (expressionS *). */ #define expression(result) expr(0,result) - /* If an expression is SEG_BIG, look here */ - /* for its value. These common data may */ - /* be clobbered whenever expr() is called. */ +/* If an expression is SEG_BIG, look here */ +/* for its value. These common data may */ +/* be clobbered whenever expr() is called. */ extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */ - /* Enough to hold most precise flonum. */ +/* Enough to hold most precise flonum. */ extern LITTLENUM_TYPE generic_bignum []; /* Bignums returned here. */ #define SIZE_OF_LARGE_NUMBER (20) /* Number of littlenums in above. */ @@ -68,11 +68,13 @@ typedef char operator_rankT; char get_symbol_end(void); segT expr(int rank, expressionS *resultP); +unsigned int get_single_number(void); #else /* __STDC__ */ char get_symbol_end(); segT expr(); +unsigned int get_single_number(); #endif /* __STDC__ */ diff --git a/gas/flonum-const.c b/gas/flonum-const.c index f3736e5..2f7fdfe 100755 --- a/gas/flonum-const.c +++ b/gas/flonum-const.c @@ -1,21 +1,21 @@ /* flonum_const.c - Useful Flonum constants Copyright (C) 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 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. */ #include "flonum.h" /* JF: I added the last entry to this table, and I'm not @@ -28,125 +28,125 @@ const int table_size_of_flonum_powers_of_ten = 11; static const LITTLENUM_TYPE zero[] = { 1 }; /***********************************************************************\ -* * -* Warning: the low order bits may be WRONG here. * -* I took this from a suspect bc(1) script. * -* "minus_X"[] is supposed to be 10^(2^-X) expressed in base 2^16. * -* The radix point is just AFTER the highest element of the [] * -* * -* Because bc rounds DOWN for printing (I think), the lowest * -* significance littlenums should probably have 1 added to them. * -* * -\***********************************************************************/ + * * + * Warning: the low order bits may be WRONG here. * + * I took this from a suspect bc(1) script. * + * "minus_X"[] is supposed to be 10^(2^-X) expressed in base 2^16. * + * The radix point is just AFTER the highest element of the [] * + * * + * Because bc rounds DOWN for printing (I think), the lowest * + * significance littlenums should probably have 1 added to them. * + * * + \***********************************************************************/ /* JF: If this equals 6553/(2^16)+39321/(2^32)+... it approaches .1 */ static const LITTLENUM_TYPE minus_1 [] = { - 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, - 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 6553 }; + 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, + 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 6553 }; static const LITTLENUM_TYPE plus_1 [] = { 10 }; /* JF: If this equals 655/(2^16) + 23592/(2^32) + ... it approaches .01 */ static const LITTLENUM_TYPE minus_2 [] = { - 10485, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 49807, - 10485, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 655 }; + 10485, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 49807, + 10485, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 655 }; static const LITTLENUM_TYPE plus_2 [] = { 100 }; /* This approaches .0001 */ static const LITTLENUM_TYPE minus_3 [] = { - 52533, 20027, 37329, 65116, 64067, 60397, 14784, 18979, 33659, 19503, - 2726, 9542, 629, 2202, 40475, 10590, 4299, 47815, 36280, 6 }; + 52533, 20027, 37329, 65116, 64067, 60397, 14784, 18979, 33659, 19503, + 2726, 9542, 629, 2202, 40475, 10590, 4299, 47815, 36280, 6 }; static const LITTLENUM_TYPE plus_3 [] = { 10000 }; /* JF: this approaches 1e-8 */ static const LITTLENUM_TYPE minus_4 [] = { - 22516, 49501, 54293, 19424, 60699, 6716, 24348, 22618, 23904, 21327, - 3919, 44703, 19149, 28803, 48959, 6259, 50273, 62237, 42 }; + 22516, 49501, 54293, 19424, 60699, 6716, 24348, 22618, 23904, 21327, + 3919, 44703, 19149, 28803, 48959, 6259, 50273, 62237, 42 }; /* This equals 1525 * 2^16 + 57600 */ static const LITTLENUM_TYPE plus_4 [] = { 57600, 1525 }; /* This approaches 1e-16 */ static const LITTLENUM_TYPE minus_5 [] = { - 22199, 45957, 17005, 26266, 10526, 16260, 55017, 35680, 40443, 19789, - 17356, 30195, 55905, 28426, 63010, 44197, 1844 }; + 22199, 45957, 17005, 26266, 10526, 16260, 55017, 35680, 40443, 19789, + 17356, 30195, 55905, 28426, 63010, 44197, 1844 }; static const LITTLENUM_TYPE plus_5 [] = { 28609, 34546, 35 }; static const LITTLENUM_TYPE minus_6 [] = { - 30926, 26518, 13110, 43018, 54982, 48258, 24658, 15209, 63366, 11929, - 20069, 43857, 60487, 51 }; + 30926, 26518, 13110, 43018, 54982, 48258, 24658, 15209, 63366, 11929, + 20069, 43857, 60487, 51 }; static const LITTLENUM_TYPE plus_6 [] = { 61313, 34220, 16731, 11629, 1262 }; static const LITTLENUM_TYPE minus_7 [] = { - 29819, 14733, 21490, 40602, 31315, 65186, 2695 }; + 29819, 14733, 21490, 40602, 31315, 65186, 2695 }; static const LITTLENUM_TYPE plus_7 [] = { - 7937, 49002, 60772, 28216, 38893, 55975, 63988, 59711, 20227, 24 }; + 7937, 49002, 60772, 28216, 38893, 55975, 63988, 59711, 20227, 24 }; static const LITTLENUM_TYPE minus_8 [] = { - 45849, 19069, 18068, 36324, 37948, 48745, 10873, 64360, 15961, 20566, - 24178, 15922, 59427, 110 }; + 45849, 19069, 18068, 36324, 37948, 48745, 10873, 64360, 15961, 20566, + 24178, 15922, 59427, 110 }; static const LITTLENUM_TYPE plus_8 [] = { - 15873, 11925, 39177, 991, 14589, 19735, 25347, 65086, 53853, 938, - 37209, 47086, 33626, 23253, 32586, 42547, 9731, 59679, 590 }; + 15873, 11925, 39177, 991, 14589, 19735, 25347, 65086, 53853, 938, + 37209, 47086, 33626, 23253, 32586, 42547, 9731, 59679, 590 }; static const LITTLENUM_TYPE minus_9 [] = { - 63601, 55221, 43562, 33661, 29067, 28203, 65417, 64352, 22462, 41110, - 12570, 28635, 23199, 50572, 28471, 27074, 46375, 64028, 13106, 63700, - 32698, 17493, 32420, 34382, 22750, 20681, 12300 }; + 63601, 55221, 43562, 33661, 29067, 28203, 65417, 64352, 22462, 41110, + 12570, 28635, 23199, 50572, 28471, 27074, 46375, 64028, 13106, 63700, + 32698, 17493, 32420, 34382, 22750, 20681, 12300 }; static const LITTLENUM_TYPE plus_9 [] = { - 63564, 61556, 29377, 54467, 18621, 28141, 36415, 61241, 47119, 30026, - 19740, 46002, 13541, 61413, 30480, 38664, 32205, 50593, 51112, 48904, - 48263, 43814, 286, 30826, 52813, 62575, 61390, 24540, 21495, 5 }; + 63564, 61556, 29377, 54467, 18621, 28141, 36415, 61241, 47119, 30026, + 19740, 46002, 13541, 61413, 30480, 38664, 32205, 50593, 51112, 48904, + 48263, 43814, 286, 30826, 52813, 62575, 61390, 24540, 21495, 5 }; static const LITTLENUM_TYPE minus_10 [] = { - 50313, 34681, 1464, 25889, 19575, 41125, 17635, 4598, 49708, 13427, - 17287, 56115, 53783, 38255, 32415, 17778, 31596, 7557, 20951, 18477, - 40353, 1178, 44405, 11837, 11571, 50963, 15649, 11698, 40675, 2308, }; + 50313, 34681, 1464, 25889, 19575, 41125, 17635, 4598, 49708, 13427, + 17287, 56115, 53783, 38255, 32415, 17778, 31596, 7557, 20951, 18477, + 40353, 1178, 44405, 11837, 11571, 50963, 15649, 11698, 40675, 2308, }; static const LITTLENUM_TYPE plus_10[] = { -18520, 53764, 54535, 61910, 61962, 59843, 46270, 58053, 12473, 63785, - 2449, 43230, 50044, 47595, 10403, 35766, 32607, 1124, 24966, 35044, -25524, 23631, 18826, 14518, 58448, 14562, 49618, 5588, 25396, 28 }; + 18520, 53764, 54535, 61910, 61962, 59843, 46270, 58053, 12473, 63785, + 2449, 43230, 50044, 47595, 10403, 35766, 32607, 1124, 24966, 35044, + 25524, 23631, 18826, 14518, 58448, 14562, 49618, 5588, 25396, 28 }; static const LITTLENUM_TYPE minus_11 [] = { - 6223, 59909, 62437, 59960, 14652, 45336, 48800, 7647, 51962, 37982, - 60436, 58176, 26767, 8440, 9831, 48556, 20994, 14148, 6757, 17221, - 60624, 46129, 53210, 44085, 54016, 24259, 11232, 21229, 21313, 81, }; + 6223, 59909, 62437, 59960, 14652, 45336, 48800, 7647, 51962, 37982, + 60436, 58176, 26767, 8440, 9831, 48556, 20994, 14148, 6757, 17221, + 60624, 46129, 53210, 44085, 54016, 24259, 11232, 21229, 21313, 81, }; static const LITTLENUM_TYPE plus_11 [] = { - 36159, 2055, 33615, 61362, 23581, 62454, 9748, 15275, 39284, 58636, - 16269, 42793, 47240, 45774, 50861, 48400, 9413, 40281, 4030, 9572, - 7984, 33038, 59522, 19450, 40593, 24486, 54320, 6661, 55766, 805, }; + 36159, 2055, 33615, 61362, 23581, 62454, 9748, 15275, 39284, 58636, + 16269, 42793, 47240, 45774, 50861, 48400, 9413, 40281, 4030, 9572, + 7984, 33038, 59522, 19450, 40593, 24486, 54320, 6661, 55766, 805, }; /* Shut up complaints about differing pointer types. They only differ in the const attribute, but there isn't any easy way to do this - */ + */ #define X (LITTLENUM_TYPE *) const FLONUM_TYPE flonum_negative_powers_of_ten [] = { - {X zero, X zero, X zero, 0, '+'}, - {X minus_1, X minus_1 +19, X minus_1 + 19, -20, '+'}, - {X minus_2, X minus_2 +19, X minus_2 + 19, -20, '+'}, - {X minus_3, X minus_3 +19, X minus_3 + 19, -20, '+'}, - {X minus_4, X minus_4 +18, X minus_4 + 18, -20, '+'}, - {X minus_5, X minus_5 +16, X minus_5 + 16, -20, '+'}, - {X minus_6, X minus_6 +13, X minus_6 + 13, -20, '+'}, - {X minus_7, X minus_7 + 6, X minus_7 + 6, -20, '+'}, - {X minus_8, X minus_8 +13, X minus_8 + 13, -40, '+'}, - {X minus_9, X minus_9 +26, X minus_9 + 26, -80, '+'}, - {X minus_10, X minus_10+29, X minus_10 + 29,-136, '+'}, - {X minus_11, X minus_11+29, X minus_11 + 29,-242, '+'}, + {X zero, X zero, X zero, 0, '+'}, + {X minus_1, X minus_1 +19, X minus_1 + 19, -20, '+'}, + {X minus_2, X minus_2 +19, X minus_2 + 19, -20, '+'}, + {X minus_3, X minus_3 +19, X minus_3 + 19, -20, '+'}, + {X minus_4, X minus_4 +18, X minus_4 + 18, -20, '+'}, + {X minus_5, X minus_5 +16, X minus_5 + 16, -20, '+'}, + {X minus_6, X minus_6 +13, X minus_6 + 13, -20, '+'}, + {X minus_7, X minus_7 + 6, X minus_7 + 6, -20, '+'}, + {X minus_8, X minus_8 +13, X minus_8 + 13, -40, '+'}, + {X minus_9, X minus_9 +26, X minus_9 + 26, -80, '+'}, + {X minus_10, X minus_10+29, X minus_10 + 29,-136, '+'}, + {X minus_11, X minus_11+29, X minus_11 + 29,-242, '+'}, }; const FLONUM_TYPE flonum_positive_powers_of_ten [] = { - {X zero, X zero, X zero, 0, '+'}, - {X plus_1, X plus_1 + 0, X plus_1 + 0, 0, '+'}, - {X plus_2, X plus_2 + 0, X plus_2 + 0, 0, '+'}, - {X plus_3, X plus_3 + 0, X plus_3 + 0, 0, '+'}, - {X plus_4, X plus_4 + 1, X plus_4 + 1, 0, '+'}, - {X plus_5, X plus_5 + 2, X plus_5 + 2, 1, '+'}, - {X plus_6, X plus_6 + 4, X plus_6 + 4, 2, '+'}, - {X plus_7, X plus_7 + 9, X plus_7 + 9, 4, '+'}, - {X plus_8, X plus_8 + 18, X plus_8 + 18, 8, '+'}, - {X plus_9, X plus_9 + 29, X plus_9 + 29, 24, '+'}, - {X plus_10, X plus_10 + 29, X plus_10 + 29, 77, '+'}, - {X plus_11, X plus_11 + 29, X plus_11 + 29, 183, '+'}, + {X zero, X zero, X zero, 0, '+'}, + {X plus_1, X plus_1 + 0, X plus_1 + 0, 0, '+'}, + {X plus_2, X plus_2 + 0, X plus_2 + 0, 0, '+'}, + {X plus_3, X plus_3 + 0, X plus_3 + 0, 0, '+'}, + {X plus_4, X plus_4 + 1, X plus_4 + 1, 0, '+'}, + {X plus_5, X plus_5 + 2, X plus_5 + 2, 1, '+'}, + {X plus_6, X plus_6 + 4, X plus_6 + 4, 2, '+'}, + {X plus_7, X plus_7 + 9, X plus_7 + 9, 4, '+'}, + {X plus_8, X plus_8 + 18, X plus_8 + 18, 8, '+'}, + {X plus_9, X plus_9 + 29, X plus_9 + 29, 24, '+'}, + {X plus_10, X plus_10 + 29, X plus_10 + 29, 77, '+'}, + {X plus_11, X plus_11 + 29, X plus_11 + 29, 183, '+'}, }; #ifdef VMS diff --git a/gas/flonum-copy.c b/gas/flonum-copy.c index 6678bdf..8f28be8 100644 --- a/gas/flonum-copy.c +++ b/gas/flonum-copy.c @@ -1,23 +1,21 @@ /* flonum_copy.c - copy a flonum Copyright (C) 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. */ #include "as.h" @@ -27,53 +25,53 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif void -flonum_copy (in, out) - FLONUM_TYPE * in; - FLONUM_TYPE * out; + flonum_copy (in, out) +FLONUM_TYPE * in; +FLONUM_TYPE * out; { - int in_length; /* 0 origin */ - int out_length; /* 0 origin */ - - out -> sign = in -> sign; - in_length = in -> leader - in -> low; - if (in_length < 0) - { - out -> leader = out -> low - 1; /* 0.0 case */ - } - else - { - out_length = out -> high - out -> low; - /* - * Assume no GAPS in packing of littlenums. - * I.e. sizeof(array) == sizeof(element) * number_of_elements. - */ - if (in_length <= out_length) - { - { - /* - * For defensive programming, zero any high-order littlenums we don't need. - * This is destroying evidence and wasting time, so why bother??? - */ - if (in_length < out_length) - { - bzero ((char *)(out->low + in_length + 1), out_length - in_length); - } - } - bcopy ((char *)(in->low), (char *)(out->low), (int)((in_length + 1) * sizeof(LITTLENUM_TYPE))); - out -> exponent = in -> exponent; - out -> leader = in -> leader - in -> low + out -> low; - } - else - { - int shorten; /* 1-origin. Number of littlenums we drop. */ - - shorten = in_length - out_length; - /* Assume out_length >= 0 ! */ - bcopy ((char *)(in->low + shorten),(char *)( out->low), (int)((out_length + 1) * sizeof(LITTLENUM_TYPE))); - out -> leader = out -> high; - out -> exponent = in -> exponent + shorten; - } - } /* if any significant bits */ + int in_length; /* 0 origin */ + int out_length; /* 0 origin */ + + out -> sign = in -> sign; + in_length = in -> leader - in -> low; + if (in_length < 0) + { + out -> leader = out -> low - 1; /* 0.0 case */ + } + else + { + out_length = out -> high - out -> low; + /* + * Assume no GAPS in packing of littlenums. + * I.e. sizeof(array) == sizeof(element) * number_of_elements. + */ + if (in_length <= out_length) + { + { + /* + * For defensive programming, zero any high-order littlenums we don't need. + * This is destroying evidence and wasting time, so why bother??? + */ + if (in_length < out_length) + { + bzero ((char *)(out->low + in_length + 1), out_length - in_length); + } + } + bcopy ((char *)(in->low), (char *)(out->low), (int)((in_length + 1) * sizeof(LITTLENUM_TYPE))); + out -> exponent = in -> exponent; + out -> leader = in -> leader - in -> low + out -> low; + } + else + { + int shorten; /* 1-origin. Number of littlenums we drop. */ + + shorten = in_length - out_length; + /* Assume out_length >= 0 ! */ + bcopy ((char *)(in->low + shorten),(char *)( out->low), (int)((out_length + 1) * sizeof(LITTLENUM_TYPE))); + out -> leader = out -> high; + out -> exponent = in -> exponent + shorten; + } + } /* if any significant bits */ } /* end: flonum_copy.c */ diff --git a/gas/flonum-mult.c b/gas/flonum-mult.c index b01f93b..c5aa0e8 100644 --- a/gas/flonum-mult.c +++ b/gas/flonum-mult.c @@ -1,201 +1,199 @@ /* flonum_multip.c - multiply two flonums Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc. - -This file is part of Gas, the GNU Assembler. - -The GNU assembler is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY. No author or distributor -accepts responsibility to anyone for the consequences of using it -or for whether it serves any particular purpose or works at all, -unless he says so in writing. Refer to the GNU Assembler General -Public License for full details. - -Everyone is granted permission to copy, modify and redistribute -the GNU Assembler, but only under the conditions described in the -GNU Assembler General Public License. A copy of this license is -supposed to have been given to you along with the GNU Assembler -so you can know your rights and responsibilities. It should be -in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. */ - -/* static const char rcsid[] = "$Id$"; */ + + This file is part of Gas, the GNU Assembler. + + The GNU assembler is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the GNU Assembler General + Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + the GNU Assembler, but only under the conditions described in the + GNU Assembler General Public License. A copy of this license is + supposed to have been given to you along with the GNU Assembler + so you can know your rights and responsibilities. It should be + in a file named COPYING. Among other things, the copyright + notice and this notice must be preserved on all copies. */ #include "flonum.h" /* plan for a . b => p(roduct) - - + + +-------+-------+-/ /-+-------+-------+ | a | a | ... | a | a | | A | A-1 | | 1 | 0 | +-------+-------+-/ /-+-------+-------+ - - + + +-------+-------+-/ /-+-------+-------+ | b | b | ... | b | b | | B | B-1 | | 1 | 0 | +-------+-------+-/ /-+-------+-------+ - - + + +-------+-------+-/ /-+-------+-/ /-+-------+-------+ | p | p | ... | p | ... | p | p | | A+B+1| A+B | | N | | 1 | 0 | +-------+-------+-/ /-+-------+-/ /-+-------+-------+ - - /^\ - (carry) a .b ... | ... a .b a .b - A B | 0 1 0 0 - | - ... | ... a .b - | 1 0 - | - | ... - | - | - | - | ___ - | \ - +----- P = > a .b - N /__ i j - - N = 0 ... A+B - - for all i,j where i+j=N - [i,j integers > 0] - -a[], b[], p[] may not intersect. -Zero length factors signify 0 significant bits: treat as 0.0. -0.0 factors do the right thing. -Zero length product OK. - -I chose the ForTran accent "foo[bar]" instead of the C accent "*garply" -because I felt the ForTran way was more intuitive. The C way would -probably yield better code on most C compilers. Dean Elsner. -(C style also gives deeper insight [to me] ... oh well ...) -*/ + + /^\ + (carry) a .b ... | ... a .b a .b + A B | 0 1 0 0 + | + ... | ... a .b + | 1 0 + | + | ... + | + | + | + | ___ + | \ + +----- P = > a .b + N /__ i j + + N = 0 ... A+B + + for all i,j where i+j=N + [i,j integers > 0] + + a[], b[], p[] may not intersect. + Zero length factors signify 0 significant bits: treat as 0.0. + 0.0 factors do the right thing. + Zero length product OK. + + I chose the ForTran accent "foo[bar]" instead of the C accent "*garply" + because I felt the ForTran way was more intuitive. The C way would + probably yield better code on most C compilers. Dean Elsner. + (C style also gives deeper insight [to me] ... oh well ...) + */ void flonum_multip (a, b, product) const FLONUM_TYPE *a; const FLONUM_TYPE *b; FLONUM_TYPE *product; { - int size_of_a; /* 0 origin */ - int size_of_b; /* 0 origin */ - int size_of_product; /* 0 origin */ - int size_of_sum; /* 0 origin */ - int extra_product_positions;/* 1 origin */ - unsigned long work; - unsigned long carry; - long exponent; - LITTLENUM_TYPE * q; - long significant; /* TRUE when we emit a non-0 littlenum */ - /* ForTran accent follows. */ - int P; /* Scan product low-order -> high. */ - int N; /* As in sum above. */ - int A; /* Which [] of a? */ - int B; /* Which [] of b? */ - - if((a->sign!='-' && a->sign!='+') || (b->sign!='-' && b->sign!='+')) { - /* ... - Got to fail somehow. Any suggestions? */ - product->sign=0; - return; - } - product -> sign = (a->sign == b->sign) ? '+' : '-'; - size_of_a = a -> leader - a -> low; - size_of_b = b -> leader - b -> low; - exponent = a -> exponent + b -> exponent; - size_of_product = product -> high - product -> low; - size_of_sum = size_of_a + size_of_b; - extra_product_positions = size_of_product - size_of_sum; - if (extra_product_positions < 0) - { - P = extra_product_positions; /* P < 0 */ - exponent -= extra_product_positions; /* Increases exponent. */ - } - else - { - P = 0; - } - carry = 0; - significant = 0; - for (N = 0; - N <= size_of_sum; - N++) - { - work = carry; - carry = 0; - for (A = 0; - A <= N; - A ++) - { - B = N - A; - if (A <= size_of_a && B <= size_of_b && B >= 0) + int size_of_a; /* 0 origin */ + int size_of_b; /* 0 origin */ + int size_of_product; /* 0 origin */ + int size_of_sum; /* 0 origin */ + int extra_product_positions;/* 1 origin */ + unsigned long work; + unsigned long carry; + long exponent; + LITTLENUM_TYPE * q; + long significant; /* TRUE when we emit a non-0 littlenum */ + /* ForTran accent follows. */ + int P; /* Scan product low-order -> high. */ + int N; /* As in sum above. */ + int A; /* Which [] of a? */ + int B; /* Which [] of b? */ + + if((a->sign!='-' && a->sign!='+') || (b->sign!='-' && b->sign!='+')) { + /* ... + Got to fail somehow. Any suggestions? */ + product->sign=0; + return; + } + product -> sign = (a->sign == b->sign) ? '+' : '-'; + size_of_a = a -> leader - a -> low; + size_of_b = b -> leader - b -> low; + exponent = a -> exponent + b -> exponent; + size_of_product = product -> high - product -> low; + size_of_sum = size_of_a + size_of_b; + extra_product_positions = size_of_product - size_of_sum; + if (extra_product_positions < 0) + { + P = extra_product_positions; /* P < 0 */ + exponent -= extra_product_positions; /* Increases exponent. */ + } + else { + P = 0; + } + carry = 0; + significant = 0; + for (N = 0; + N <= size_of_sum; + N++) + { + work = carry; + carry = 0; + for (A = 0; + A <= N; + A ++) + { + B = N - A; + if (A <= size_of_a && B <= size_of_b && B >= 0) + { #ifdef TRACE -printf("a:low[%d.]=%04x b:low[%d.]=%04x work_before=%08x\n", A, a->low[A], B, b->low[B], work); + printf("a:low[%d.]=%04x b:low[%d.]=%04x work_before=%08x\n", A, a->low[A], B, b->low[B], work); #endif - work += a -> low [A] * b -> low [B]; - carry += work >> LITTLENUM_NUMBER_OF_BITS; - work &= LITTLENUM_MASK; + work += a -> low [A] * b -> low [B]; + carry += work >> LITTLENUM_NUMBER_OF_BITS; + work &= LITTLENUM_MASK; #ifdef TRACE -printf("work=%08x carry=%04x\n", work, carry); + printf("work=%08x carry=%04x\n", work, carry); #endif - } - } - significant |= work; - if (significant || P<0) - { - if (P >= 0) - { - product -> low [P] = work; + } + } + significant |= work; + if (significant || P<0) + { + if (P >= 0) + { + product -> low [P] = work; #ifdef TRACE -printf("P=%d. work[p]:=%04x\n", P, work); + printf("P=%d. work[p]:=%04x\n", P, work); #endif + } + P ++; + } + else + { + extra_product_positions ++; + exponent ++; + } } - P ++; - } - else - { - extra_product_positions ++; - exponent ++; - } - } - /* - * [P]-> position # size_of_sum + 1. - * This is where 'carry' should go. - */ + /* + * [P]-> position # size_of_sum + 1. + * This is where 'carry' should go. + */ #ifdef TRACE -printf("final carry =%04x\n", carry); + printf("final carry =%04x\n", carry); #endif - if (carry) - { - if (extra_product_positions > 0) - { - product -> low [P] = carry; - } - else - { - /* No room at high order for carry littlenum. */ - /* Shift right 1 to make room for most significant littlenum. */ - exponent ++; - P --; - for (q = product -> low + P; - q >= product -> low; - q --) + if (carry) { - work = * q; - * q = carry; - carry = work; + if (extra_product_positions > 0) + { + product -> low [P] = carry; + } + else + { + /* No room at high order for carry littlenum. */ + /* Shift right 1 to make room for most significant littlenum. */ + exponent ++; + P --; + for (q = product -> low + P; + q >= product -> low; + q --) + { + work = * q; + * q = carry; + carry = work; + } + } } - } - } - else - { - P --; - } - product -> leader = product -> low + P; - product -> exponent = exponent; + else + { + P --; + } + product -> leader = product -> low + P; + product -> exponent = exponent; } /* end: flonum_multip.c */ diff --git a/gas/flonum.h b/gas/flonum.h index 570bd3a..45dcbae 100644 --- a/gas/flonum.h +++ b/gas/flonum.h @@ -1,36 +1,36 @@ /* flonum.h - Floating point package Copyright (C) 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. */ + + 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. */ /* $Id$ */ /***********************************************************************\ -* * -* Arbitrary-precision floating point arithmetic. * -* * -* * -* Notation: a floating point number is expressed as * -* MANTISSA * (2 ** EXPONENT). * -* * -* If this offends more traditional mathematicians, then * -* please tell me your nomenclature for flonums! * -* * -\***********************************************************************/ + * * + * Arbitrary-precision floating point arithmetic. * + * * + * * + * Notation: a floating point number is expressed as * + * MANTISSA * (2 ** EXPONENT). * + * * + * If this offends more traditional mathematicians, then * + * please tell me your nomenclature for flonums! * + * * + \***********************************************************************/ #if !defined(__STDC__) && !defined(const) #define const /* empty */ #endif @@ -38,60 +38,60 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bignum.h" /***********************************************************************\ -* * -* Variable precision floating point numbers. * -* * -* Exponent is the place value of the low littlenum. E.g.: * -* If 0: low points to the units littlenum. * -* If 1: low points to the LITTLENUM_RADIX littlenum. * -* If -1: low points to the 1/LITTLENUM_RADIX littlenum. * -* * -\***********************************************************************/ + * * + * Variable precision floating point numbers. * + * * + * Exponent is the place value of the low littlenum. E.g.: * + * If 0: low points to the units littlenum. * + * If 1: low points to the LITTLENUM_RADIX littlenum. * + * If -1: low points to the 1/LITTLENUM_RADIX littlenum. * + * * + \***********************************************************************/ /* JF: A sign value of 0 means we have been asked to assemble NaN A sign value of 'P' means we've been asked to assemble +Inf A sign value of 'N' means we've been asked to assemble -Inf - */ + */ struct FLONUM_STRUCT { - LITTLENUM_TYPE * low; /* low order littlenum of a bignum */ - LITTLENUM_TYPE * high; /* high order littlenum of a bignum */ - LITTLENUM_TYPE * leader; /* -> 1st non-zero littlenum */ - /* If flonum is 0.0, leader==low-1 */ - long exponent; /* base LITTLENUM_RADIX */ - char sign; /* '+' or '-' */ + LITTLENUM_TYPE * low; /* low order littlenum of a bignum */ + LITTLENUM_TYPE * high; /* high order littlenum of a bignum */ + LITTLENUM_TYPE * leader; /* -> 1st non-zero littlenum */ + /* If flonum is 0.0, leader==low-1 */ + long exponent; /* base LITTLENUM_RADIX */ + char sign; /* '+' or '-' */ }; typedef struct FLONUM_STRUCT FLONUM_TYPE; /***********************************************************************\ -* * -* Since we can (& do) meet with exponents like 10^5000, it * -* is silly to make a table of ~ 10,000 entries, one for each * -* power of 10. We keep a table where item [n] is a struct * -* FLONUM_FLOATING_POINT representing 10^(2^n). We then * -* multiply appropriate entries from this table to get any * -* particular power of 10. For the example of 10^5000, a table * -* of just 25 entries suffices: 10^(2^-12)...10^(2^+12). * -* * -\***********************************************************************/ + * * + * Since we can (& do) meet with exponents like 10^5000, it * + * is silly to make a table of ~ 10,000 entries, one for each * + * power of 10. We keep a table where item [n] is a struct * + * FLONUM_FLOATING_POINT representing 10^(2^n). We then * + * multiply appropriate entries from this table to get any * + * particular power of 10. For the example of 10^5000, a table * + * of just 25 entries suffices: 10^(2^-12)...10^(2^+12). * + * * + \***********************************************************************/ extern const FLONUM_TYPE flonum_positive_powers_of_ten[]; extern const FLONUM_TYPE flonum_negative_powers_of_ten[]; extern const int table_size_of_flonum_powers_of_ten; - /* Flonum_XXX_powers_of_ten[] table has */ - /* legal indices from 0 to */ - /* + this number inclusive. */ +/* Flonum_XXX_powers_of_ten[] table has */ +/* legal indices from 0 to */ +/* + this number inclusive. */ /***********************************************************************\ -* * -* Declare worker functions. * -* * -\***********************************************************************/ + * * + * Declare worker functions. * + * * + \***********************************************************************/ #ifdef __STDC__ @@ -112,10 +112,10 @@ void flonum_multip(); #endif /* __STDC__ */ /***********************************************************************\ -* * -* Declare error codes. * -* * -\***********************************************************************/ + * * + * Declare error codes. * + * * + \***********************************************************************/ #define ERROR_EXPONENT_OVERFLOW (2) diff --git a/gas/frags.c b/gas/frags.c index 3526603..3f4663c 100644 --- a/gas/frags.c +++ b/gas/frags.c @@ -1,23 +1,21 @@ /* frags.c - manage frags - Copyright (C) 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. */ #include "as.h" #include "subsegs.h" @@ -38,7 +36,7 @@ fragS zero_address_frag = { 0, /* fr_pcrel_adjust */ 0, /* fr_bsr */ 0 /* fr_literal [0] */ -}; + }; fragS bss_address_frag = { 0, /* fr_address. Gets filled in to make up @@ -54,7 +52,7 @@ fragS bss_address_frag = { 0, /* fr_pcrel_adjust */ 0, /* fr_bsr */ 0 /* fr_literal [0] */ -}; + }; /* * frag_grow() @@ -68,24 +66,24 @@ fragS bss_address_frag = { static void frag_grow(nchars) unsigned int nchars; { - if (obstack_room (&frags) < nchars) { - unsigned int n,oldn; - long oldc; - - frag_wane(frag_now); - frag_new(0); - oldn=(unsigned)-1; - oldc=frags.chunk_size; - frags.chunk_size=2*nchars; - while((n=obstack_room(&frags))<nchars && n<oldn) { + if (obstack_room (&frags) < nchars) { + unsigned int n,oldn; + long oldc; + frag_wane(frag_now); frag_new(0); - oldn=n; + oldn=(unsigned)-1; + oldc=frags.chunk_size; + frags.chunk_size=2*nchars; + while((n=obstack_room(&frags))<nchars && n<oldn) { + frag_wane(frag_now); + frag_new(0); + oldn=n; + } + frags.chunk_size=oldc; } - frags.chunk_size=oldc; - } - if (obstack_room (&frags) < nchars) - as_fatal("Can't extend frag %d. chars", nchars); + if (obstack_room (&frags) < nchars) + as_fatal("Can't extend frag %d. chars", nchars); } /* frag_grow() */ /* @@ -108,51 +106,59 @@ unsigned int nchars; void frag_new(old_frags_var_max_size) int old_frags_var_max_size; /* Number of chars (already allocated on obstack frags) */ - /* in variable_length part of frag. */ +/* in variable_length part of frag. */ { - register fragS * former_last_fragP; -/* char *throw_away_pointer; JF unused */ - register frchainS * frchP; - long tmp; /* JF */ - - frag_now->fr_fix = (char *) (obstack_next_free (&frags)) - - (frag_now->fr_literal) - old_frags_var_max_size; - /* Fix up old frag's fr_fix. */ - - obstack_finish (&frags); - /* This will align the obstack so the */ - /* next struct we allocate on it will */ - /* begin at a correct boundary. */ - frchP = frchain_now; - know (frchP); - former_last_fragP = frchP->frch_last; - know (former_last_fragP); - know (former_last_fragP == frag_now); - obstack_blank (&frags, SIZEOF_STRUCT_FRAG); - /* We expect this will begin at a correct */ - /* boundary for a struct. */ - tmp=obstack_alignment_mask(&frags); - obstack_alignment_mask(&frags)=0; /* Turn off alignment */ - /* If we ever hit a machine - where strings must be - aligned, we Lose Big */ - frag_now=(fragS *)obstack_finish(&frags); - obstack_alignment_mask(&frags)=tmp; /* Restore alignment */ - - /* Just in case we don't get zero'd bytes */ - bzero(frag_now, SIZEOF_STRUCT_FRAG); - -/* obstack_unaligned_done (&frags, &frag_now); */ -/* know (frags.obstack_c_next_free == frag_now->fr_literal); */ - /* Generally, frag_now->points to an */ - /* address rounded up to next alignment. */ - /* However, characters will add to obstack */ - /* frags IMMEDIATELY after the struct frag, */ - /* even if they are not starting at an */ - /* alignment address. */ - former_last_fragP->fr_next = frag_now; - frchP->frch_last = frag_now; - frag_now->fr_next = NULL; + register fragS * former_last_fragP; + /* char *throw_away_pointer; JF unused */ + register frchainS * frchP; + long tmp; /* JF */ + + frag_now->fr_fix = (char *) (obstack_next_free (&frags)) - + (frag_now->fr_literal) - old_frags_var_max_size; + /* Fix up old frag's fr_fix. */ + + obstack_finish (&frags); + /* This will align the obstack so the */ + /* next struct we allocate on it will */ + /* begin at a correct boundary. */ + frchP = frchain_now; + know (frchP); + former_last_fragP = frchP->frch_last; + know (former_last_fragP); + know (former_last_fragP == frag_now); + obstack_blank (&frags, SIZEOF_STRUCT_FRAG); + /* We expect this will begin at a correct */ + /* boundary for a struct. */ + tmp=obstack_alignment_mask(&frags); + obstack_alignment_mask(&frags)=0; /* Turn off alignment */ + /* If we ever hit a machine + where strings must be + aligned, we Lose Big */ + frag_now=(fragS *)obstack_finish(&frags); + obstack_alignment_mask(&frags)=tmp; /* Restore alignment */ + + /* Just in case we don't get zero'd bytes */ + bzero(frag_now, SIZEOF_STRUCT_FRAG); + + /* obstack_unaligned_done (&frags, &frag_now); */ + /* know (frags.obstack_c_next_free == frag_now->fr_literal); */ + /* Generally, frag_now->points to an */ + /* address rounded up to next alignment. */ + /* However, characters will add to obstack */ + /* frags IMMEDIATELY after the struct frag, */ + /* even if they are not starting at an */ + /* alignment address. */ + former_last_fragP->fr_next = frag_now; + frchP->frch_last = frag_now; + +#ifndef NO_LISTING + { + extern struct list_info_struct *listing_tail; + frag_now->line = listing_tail; + } +#endif + + frag_now->fr_next = NULL; } /* frag_new() */ /* @@ -168,12 +174,12 @@ int old_frags_var_max_size; /* Number of chars (already allocated on char *frag_more (nchars) int nchars; { - register char *retval; - - frag_grow (nchars); - retval = obstack_next_free (&frags); - obstack_blank_fast (&frags, nchars); - return (retval); + register char *retval; + + frag_grow (nchars); + retval = obstack_next_free (&frags); + obstack_blank_fast (&frags, nchars); + return (retval); } /* frag_more() */ /* @@ -196,22 +202,22 @@ symbolS *symbol; long offset; char *opcode; { - register char *retval; - - frag_grow (max_chars); - retval = obstack_next_free (&frags); - obstack_blank_fast (&frags, max_chars); - frag_now->fr_var = var; - frag_now->fr_type = type; - frag_now->fr_subtype = subtype; - frag_now->fr_symbol = symbol; - frag_now->fr_offset = offset; - frag_now->fr_opcode = opcode; - /* default these to zero. */ - frag_now->fr_pcrel_adjust = 0; - frag_now->fr_bsr = 0; - frag_new (max_chars); - return (retval); + register char *retval; + + frag_grow (max_chars); + retval = obstack_next_free (&frags); + obstack_blank_fast (&frags, max_chars); + frag_now->fr_var = var; + frag_now->fr_type = type; + frag_now->fr_subtype = subtype; + frag_now->fr_symbol = symbol; + frag_now->fr_offset = offset; + frag_now->fr_opcode = opcode; + /* default these to zero. */ + frag_now->fr_pcrel_adjust = 0; + frag_now->fr_bsr = 0; + frag_new (max_chars); + return (retval); } /* frag_var() */ /* @@ -224,31 +230,31 @@ char *opcode; */ char *frag_variant(type, max_chars, var, subtype, symbol, offset, opcode, pcrel_adjust,bsr) - relax_stateT type; - int max_chars; - int var; - relax_substateT subtype; - symbolS *symbol; - long offset; - char *opcode; - int pcrel_adjust; - char bsr; +relax_stateT type; +int max_chars; +int var; +relax_substateT subtype; +symbolS *symbol; +long offset; +char *opcode; +int pcrel_adjust; +char bsr; { - register char *retval; - -/* frag_grow (max_chars); */ - retval = obstack_next_free (&frags); -/* obstack_blank_fast (&frags, max_chars); */ /* OVE: so far the only diff */ - frag_now->fr_var = var; - frag_now->fr_type = type; - frag_now->fr_subtype = subtype; - frag_now->fr_symbol = symbol; - frag_now->fr_offset = offset; - frag_now->fr_opcode = opcode; - frag_now->fr_pcrel_adjust = pcrel_adjust; - frag_now->fr_bsr = bsr; - frag_new (max_chars); - return (retval); + register char *retval; + + /* frag_grow (max_chars); */ + retval = obstack_next_free (&frags); + /* obstack_blank_fast (&frags, max_chars); */ /* OVE: so far the only diff */ + frag_now->fr_var = var; + frag_now->fr_type = type; + frag_now->fr_subtype = subtype; + frag_now->fr_symbol = symbol; + frag_now->fr_offset = offset; + frag_now->fr_opcode = opcode; + frag_now->fr_pcrel_adjust = pcrel_adjust; + frag_now->fr_bsr = bsr; + frag_new (max_chars); + return (retval); } /* frag_variant() */ /* @@ -259,9 +265,9 @@ char *frag_variant(type, max_chars, var, subtype, symbol, offset, opcode, pcrel_ void frag_wane(fragP) register fragS * fragP; { - fragP->fr_type = rs_fill; - fragP->fr_offset = 0; - fragP->fr_var = 0; + fragP->fr_type = rs_fill; + fragP->fr_offset = 0; + fragP->fr_var = 0; } /* @@ -278,8 +284,8 @@ void frag_align(alignment, fill_character) int alignment; int fill_character; { - *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0, - (long)alignment, (char *)0)) = fill_character; + *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0, + (long)alignment, (char *)0)) = fill_character; } /* frag_align() */ /* end: frags.c */ diff --git a/gas/frags.h b/gas/frags.h index aa08995..feceec8 100644 --- a/gas/frags.h +++ b/gas/frags.h @@ -1,27 +1,27 @@ /* frags.h - Header file for the frag concept. Copyright (C) 1987 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. */ + + 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. */ extern struct obstack frags; - /* Frags ONLY live in this obstack. */ - /* We use obstack_next_free() macro */ - /* so please don't put any other objects */ - /* on this stack! */ +/* Frags ONLY live in this obstack. */ +/* We use obstack_next_free() macro */ +/* so please don't put any other objects */ +/* on this stack! */ /* * A macro to speed up appending exactly 1 char @@ -30,13 +30,13 @@ extern struct obstack frags; /* JF changed < 1 to <= 1 to avoid a race conditon */ #define FRAG_APPEND_1_CHAR(datum) \ { \ - if (obstack_room( &frags ) <= 1) {\ - frag_wane (frag_now); \ - frag_new (0); \ - } \ - obstack_1grow( &frags, datum ); \ -} - + if (obstack_room( &frags ) <= 1) {\ + frag_wane (frag_now); \ + frag_new (0); \ + } \ + obstack_1grow( &frags, datum ); \ + } + #ifdef __STDC__ @@ -1,23 +1,21 @@ /* hash.c - hash table lookup strings - Copyright (C) 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. */ /* * BUGS, GRIPES, APOLOGIA etc. @@ -144,26 +142,26 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* #define START_SIZE (64) / * 2 ** START_POWER */ /* #define START_FULL (32) / * number of entries before table expands */ #define islive(ptr) (ptr->hash_string && ptr->hash_string!=DELETED) - /* above TRUE if a symbol is in entry @ ptr */ +/* above TRUE if a symbol is in entry @ ptr */ #define STAT_SIZE (0) /* number of slots in hash table */ - /* the wall does not count here */ - /* we expect this is always a power of 2 */ +/* the wall does not count here */ +/* we expect this is always a power of 2 */ #define STAT_ACCESS (1) /* number of hash_ask()s */ #define STAT__READ (0) /* reading */ #define STAT__WRITE (1) /* writing */ #define STAT_COLLIDE (3) /* number of collisions (total) */ - /* this may exceed STAT_ACCESS if we have */ - /* lots of collisions/access */ +/* this may exceed STAT_ACCESS if we have */ +/* lots of collisions/access */ #define STAT_USED (5) /* slots used right now */ #define STATLENGTH (6) /* size of statistics block */ #if STATLENGTH != HASH_STATLENGTH Panic! Please make #include "stat.h" agree with previous definitions! #endif - -/* #define SUSPECT to do runtime checks */ -/* #define TEST to be a test jig for hash...() */ - + + /* #define SUSPECT to do runtime checks */ + /* #define TEST to be a test jig for hash...() */ + #ifdef TEST /* TEST: use smaller hash table */ #undef START_POWER #define START_POWER (3) @@ -174,71 +172,71 @@ Panic! Please make #include "stat.h" agree with previous definitions! #endif /*------------------ plan ---------------------------------- i = internal - -struct hash_control * c; -struct hash_entry * e; i -int b[z]; buffer for statistics - z size of b -char * s; symbol string (address) [ key ] -char * v; value string (address) [datum] -boolean f; TRUE if we found s in hash table i -char * t; error string; "" means OK -int a; access type [0...n) i - -c=hash_new () create new hash_control - -hash_die (c) destroy hash_control (and hash table) - table should be empty. - doesn't check if table is empty. - c has no meaning after this. - -hash_say (c,b,z) report statistics of hash_control. - also report number of available statistics. - -v=hash_delete (c,s) delete symbol, return old value if any. - ask() NULL means no old value. - f - -v=hash_replace (c,s,v) replace old value of s with v. - ask() NULL means no old value: no table change. - f - -t=hash_insert (c,s,v) insert (s,v) in c. - ask() return error string. - f it is an error to insert if s is already - in table. - if any error, c is unchanged. - -t=hash_jam (c,s,v) assert that new value of s will be v. i - ask() it may decide to GROW the table. i - f i - grow() i -t=hash_grow (c) grow the hash table. i - jam() will invoke JAM. i - -?=hash_apply (c,y) apply y() to every symbol in c. - y evtries visited in 'unspecified' order. - -v=hash_find (c,s) return value of s, or NULL if s not in c. - ask() - f - -f,e=hash_ask() (c,s,a) return slot where s SHOULD live. i - code() maintain collision stats in c. i - -.=hash_code (c,s) compute hash-code for s, i - from parameters of c. i - -*/ + + struct hash_control * c; + struct hash_entry * e; i + int b[z]; buffer for statistics + z size of b + char * s; symbol string (address) [ key ] + char * v; value string (address) [datum] + boolean f; TRUE if we found s in hash table i + char * t; error string; "" means OK + int a; access type [0...n) i + + c=hash_new () create new hash_control + + hash_die (c) destroy hash_control (and hash table) + table should be empty. + doesn't check if table is empty. + c has no meaning after this. + + hash_say (c,b,z) report statistics of hash_control. + also report number of available statistics. + + v=hash_delete (c,s) delete symbol, return old value if any. + ask() NULL means no old value. + f + + v=hash_replace (c,s,v) replace old value of s with v. + ask() NULL means no old value: no table change. + f + + t=hash_insert (c,s,v) insert (s,v) in c. + ask() return error string. + f it is an error to insert if s is already + in table. + if any error, c is unchanged. + + t=hash_jam (c,s,v) assert that new value of s will be v. i + ask() it may decide to GROW the table. i + f i + grow() i + t=hash_grow (c) grow the hash table. i + jam() will invoke JAM. i + + ?=hash_apply (c,y) apply y() to every symbol in c. + y evtries visited in 'unspecified' order. + + v=hash_find (c,s) return value of s, or NULL if s not in c. + ask() + f + + f,e=hash_ask() (c,s,a) return slot where s SHOULD live. i + code() maintain collision stats in c. i + + .=hash_code (c,s) compute hash-code for s, i + from parameters of c. i + + */ static char hash_found; /* returned by hash_ask() to stop extra */ - /* testing. hash_ask() wants to return both */ - /* a slot and a status. This is the status. */ - /* TRUE: found symbol */ - /* FALSE: absent: empty or deleted slot */ - /* Also returned by hash_jam(). */ - /* TRUE: we replaced a value */ - /* FALSE: we inserted a value */ +/* testing. hash_ask() wants to return both */ +/* a slot and a status. This is the status. */ +/* TRUE: found symbol */ +/* FALSE: absent: empty or deleted slot */ +/* Also returned by hash_jam(). */ +/* TRUE: we replaced a value */ +/* FALSE: we inserted a value */ static struct hash_entry * hash_ask(); static int hash_code (); @@ -249,49 +247,49 @@ static char * hash_grow(); * */ struct hash_control * -hash_new() /* create a new hash table */ - /* return NULL if failed */ - /* return handle (address of struct hash) */ + hash_new() /* create a new hash table */ +/* return NULL if failed */ +/* return handle (address of struct hash) */ { - register struct hash_control * retval; - register struct hash_entry * room; /* points to hash table */ - register struct hash_entry * wall; - register struct hash_entry * entry; - register int * ip; /* scan stats block of struct hash_control */ - register int * nd; /* limit of stats block */ - - if (( room = (struct hash_entry *) malloc( sizeof(struct - hash_entry)*((1<<START_POWER) + 1) ) ) != NULL) - /* +1 for the wall entry */ - { - if (( retval = (struct hash_control *) malloc(sizeof(struct - hash_control)) ) != NULL) - { - nd = retval->hash_stat + STATLENGTH; - for (ip=retval->hash_stat; ip<nd; ip++) + register struct hash_control * retval; + register struct hash_entry * room; /* points to hash table */ + register struct hash_entry * wall; + register struct hash_entry * entry; + register int * ip; /* scan stats block of struct hash_control */ + register int * nd; /* limit of stats block */ + + if (( room = (struct hash_entry *) malloc( sizeof(struct + hash_entry)*((1<<START_POWER) + 1) ) ) != NULL) + /* +1 for the wall entry */ { - *ip = 0; - } - - retval -> hash_stat[STAT_SIZE] = 1<<START_POWER; - retval -> hash_mask = (1<<START_POWER) - 1; - retval -> hash_sizelog = START_POWER; + if (( retval = (struct hash_control *) malloc(sizeof(struct + hash_control)) ) != NULL) + { + nd = retval->hash_stat + STATLENGTH; + for (ip=retval->hash_stat; ip<nd; ip++) + { + *ip = 0; + } + + retval -> hash_stat[STAT_SIZE] = 1<<START_POWER; + retval -> hash_mask = (1<<START_POWER) - 1; + retval -> hash_sizelog = START_POWER; /* works for 1's compl ok */ - retval -> hash_where = room; - retval -> hash_wall = - wall = room + (1<<START_POWER); - retval -> hash_full = (1<<START_POWER)/2; - for (entry=room; entry<=wall; entry++) + retval -> hash_where = room; + retval -> hash_wall = + wall = room + (1<<START_POWER); + retval -> hash_full = (1<<START_POWER)/2; + for (entry=room; entry<=wall; entry++) + { + entry->hash_string = NULL; + } + } + } + else { - entry->hash_string = NULL; + retval = NULL; /* no room for table: fake a failure */ } - } - } - else - { - retval = NULL; /* no room for table: fake a failure */ - } - return(retval); /* return NULL or set-up structs */ + return(retval); /* return NULL or set-up structs */ } /* @@ -305,11 +303,11 @@ hash_new() /* create a new hash table */ * No errors are recoverable. */ void -hash_die(handle) - struct hash_control * handle; + hash_die(handle) +struct hash_control * handle; { - free((char *)handle->hash_where); - free((char *)handle); + free((char *)handle->hash_where); + free((char *)handle); } /* @@ -326,24 +324,24 @@ hash_die(handle) * until your buffer or hash_stat[] is exausted. */ void -hash_say(handle,buffer,bufsiz) - register struct hash_control * handle; - register int buffer[/*bufsiz*/]; - register int bufsiz; + hash_say(handle,buffer,bufsiz) +register struct hash_control * handle; +register int buffer[/*bufsiz*/]; +register int bufsiz; { - register int * nd; /* limit of statistics block */ - register int * ip; /* scan statistics */ - - ip = handle -> hash_stat; - nd = ip + min(bufsiz-1,STATLENGTH); - if (bufsiz>0) /* trust nothing! bufsiz<=0 is dangerous */ - { - *buffer++ = STATLENGTH; - for (; ip<nd; ip++,buffer++) - { - *buffer = *ip; - } - } + register int * nd; /* limit of statistics block */ + register int * ip; /* scan statistics */ + + ip = handle -> hash_stat; + nd = ip + min(bufsiz-1,STATLENGTH); + if (bufsiz>0) /* trust nothing! bufsiz<=0 is dangerous */ + { + *buffer++ = STATLENGTH; + for (; ip<nd; ip++,buffer++) + { + *buffer = *ip; + } + } } /* @@ -356,32 +354,32 @@ hash_say(handle,buffer,bufsiz) * */ char * /* NULL if string not in table, else */ - /* returns value of deleted symbol */ -hash_delete(handle,string) - register struct hash_control * handle; - register char * string; + /* returns value of deleted symbol */ + hash_delete(handle,string) +register struct hash_control * handle; +register char * string; { - register char * retval; /* NULL if string not in table */ - register struct hash_entry * entry; /* NULL or entry of this symbol */ - - entry = hash_ask(handle,string,STAT__WRITE); - if (hash_found) - { - retval = entry -> hash_value; - entry -> hash_string = DELETED; /* mark as deleted */ - handle -> hash_stat[STAT_USED] -= 1; /* slots-in-use count */ + register char * retval; /* NULL if string not in table */ + register struct hash_entry * entry; /* NULL or entry of this symbol */ + + entry = hash_ask(handle,string,STAT__WRITE); + if (hash_found) + { + retval = entry -> hash_value; + entry -> hash_string = DELETED; /* mark as deleted */ + handle -> hash_stat[STAT_USED] -= 1; /* slots-in-use count */ #ifdef SUSPECT - if (handle->hash_stat[STAT_USED]<0) + if (handle->hash_stat[STAT_USED]<0) + { + error("hash_delete"); + } +#endif /* def SUSPECT */ + } + else { - error("hash_delete"); + retval = NULL; } -#endif /* def SUSPECT */ - } - else - { - retval = NULL; - } - return(retval); + return(retval); } /* @@ -393,26 +391,26 @@ hash_delete(handle,string) * in the table. */ char * -hash_replace(handle,string,value) - register struct hash_control * handle; - register char * string; - register char * value; + hash_replace(handle,string,value) +register struct hash_control * handle; +register char * string; +register char * value; { - register struct hash_entry * entry; - register char * retval; - - entry = hash_ask(handle,string,STAT__WRITE); - if (hash_found) - { - retval = entry -> hash_value; - entry -> hash_value = value; - } - else - { - retval = NULL; - } - ; - return (retval); + register struct hash_entry * entry; + register char * retval; + + entry = hash_ask(handle,string,STAT__WRITE); + if (hash_found) + { + retval = entry -> hash_value; + entry -> hash_value = value; + } + else + { + retval = NULL; + } + ; + return (retval); } /* @@ -424,34 +422,34 @@ hash_replace(handle,string,value) */ char * /* return error string */ -hash_insert(handle,string,value) - register struct hash_control * handle; - register char * string; - register char * value; + hash_insert(handle,string,value) +register struct hash_control * handle; +register char * string; +register char * value; { - register struct hash_entry * entry; - register char * retval; - - retval = ""; - if (handle->hash_stat[STAT_USED] > handle->hash_full) - { - retval = hash_grow(handle); - } - if ( ! * retval) - { - entry = hash_ask(handle,string,STAT__WRITE); - if (hash_found) - { - retval = "exists"; - } - else - { - entry -> hash_value = value; - entry -> hash_string = string; - handle-> hash_stat[STAT_USED] += 1; - } - } - return(retval); + register struct hash_entry * entry; + register char * retval; + + retval = ""; + if (handle->hash_stat[STAT_USED] > handle->hash_full) + { + retval = hash_grow(handle); + } + if ( ! * retval) + { + entry = hash_ask(handle,string,STAT__WRITE); + if (hash_found) + { + retval = "exists"; + } + else + { + entry -> hash_value = value; + entry -> hash_string = string; + handle-> hash_stat[STAT_USED] += 1; + } + } + return(retval); } /* @@ -469,30 +467,30 @@ hash_insert(handle,string,value) * false if we inserted. */ char * -hash_jam(handle,string,value) - register struct hash_control * handle; - register char * string; - register char * value; + hash_jam(handle,string,value) +register struct hash_control * handle; +register char * string; +register char * value; { - register char * retval; - register struct hash_entry * entry; - - retval = ""; - if (handle->hash_stat[STAT_USED] > handle->hash_full) - { - retval = hash_grow(handle); - } - if (! * retval) - { - entry = hash_ask(handle,string,STAT__WRITE); - if ( ! hash_found) - { - entry -> hash_string = string; - handle->hash_stat[STAT_USED] += 1; - } - entry -> hash_value = value; - } - return(retval); + register char * retval; + register struct hash_entry * entry; + + retval = ""; + if (handle->hash_stat[STAT_USED] > handle->hash_full) + { + retval = hash_grow(handle); + } + if (! * retval) + { + entry = hash_ask(handle,string,STAT__WRITE); + if ( ! hash_found) + { + entry -> hash_string = string; + handle->hash_stat[STAT_USED] += 1; + } + entry -> hash_value = value; + } + return(retval); } /* @@ -507,99 +505,99 @@ hash_jam(handle,string,value) * Internal. */ static char * -hash_grow(handle) /* make a hash table grow */ - struct hash_control * handle; + hash_grow(handle) /* make a hash table grow */ +struct hash_control * handle; { - register struct hash_entry * newwall; - register struct hash_entry * newwhere; - struct hash_entry * newtrack; - register struct hash_entry * oldtrack; - register struct hash_entry * oldwhere; - register struct hash_entry * oldwall; - register int temp; - int newsize; - char * string; - char * retval; + register struct hash_entry * newwall; + register struct hash_entry * newwhere; + struct hash_entry * newtrack; + register struct hash_entry * oldtrack; + register struct hash_entry * oldwhere; + register struct hash_entry * oldwall; + register int temp; + int newsize; + char * string; + char * retval; #ifdef SUSPECT - int oldused; + int oldused; #endif - - /* - * capture info about old hash table - */ - oldwhere = handle -> hash_where; - oldwall = handle -> hash_wall; + + /* + * capture info about old hash table + */ + oldwhere = handle -> hash_where; + oldwall = handle -> hash_wall; #ifdef SUSPECT - oldused = handle -> hash_stat[STAT_USED]; + oldused = handle -> hash_stat[STAT_USED]; #endif - /* - * attempt to get enough room for a hash table twice as big - */ - temp = handle->hash_stat[STAT_SIZE]; - if (( newwhere = (struct hash_entry *) - xmalloc((long)((temp+temp+1)*sizeof(struct hash_entry)))) != NULL) - /* +1 for wall slot */ - { - retval = ""; /* assume success until proven otherwise */ - /* - * have enough room: now we do all the work. - * double the size of everything in handle, - * note: hash_mask frob works for 1's & for 2's complement machines - */ - handle->hash_mask = handle->hash_mask + handle->hash_mask + 1; - handle->hash_stat[STAT_SIZE] <<= 1; - newsize = handle->hash_stat[STAT_SIZE]; - handle->hash_where = newwhere; - handle->hash_full <<= 1; - handle->hash_sizelog += 1; - handle->hash_stat[STAT_USED] = 0; - handle->hash_wall = - newwall = newwhere + newsize; - /* - * set all those pesky new slots to vacant. - */ - for (newtrack=newwhere; newtrack <= newwall; newtrack++) - { - newtrack -> hash_string = NULL; - } - /* - * we will do a scan of the old table, the hard way, using the - * new control block to re-insert the data into new hash table. - */ - handle -> hash_stat[STAT_USED] = 0; /* inserts will bump it up to correct */ - for (oldtrack=oldwhere; oldtrack < oldwall; oldtrack++) - { - if ( ((string=oldtrack->hash_string) != NULL) && string!=DELETED ) + /* + * attempt to get enough room for a hash table twice as big + */ + temp = handle->hash_stat[STAT_SIZE]; + if (( newwhere = (struct hash_entry *) + xmalloc((long)((temp+temp+1)*sizeof(struct hash_entry)))) != NULL) + /* +1 for wall slot */ { - if ( * (retval = hash_jam(handle,string,oldtrack->hash_value) ) ) - { - break; - } - } - } + retval = ""; /* assume success until proven otherwise */ + /* + * have enough room: now we do all the work. + * double the size of everything in handle, + * note: hash_mask frob works for 1's & for 2's complement machines + */ + handle->hash_mask = handle->hash_mask + handle->hash_mask + 1; + handle->hash_stat[STAT_SIZE] <<= 1; + newsize = handle->hash_stat[STAT_SIZE]; + handle->hash_where = newwhere; + handle->hash_full <<= 1; + handle->hash_sizelog += 1; + handle->hash_stat[STAT_USED] = 0; + handle->hash_wall = + newwall = newwhere + newsize; + /* + * set all those pesky new slots to vacant. + */ + for (newtrack=newwhere; newtrack <= newwall; newtrack++) + { + newtrack -> hash_string = NULL; + } + /* + * we will do a scan of the old table, the hard way, using the + * new control block to re-insert the data into new hash table. + */ + handle -> hash_stat[STAT_USED] = 0; /* inserts will bump it up to correct */ + for (oldtrack=oldwhere; oldtrack < oldwall; oldtrack++) + { + if ( ((string=oldtrack->hash_string) != NULL) && string!=DELETED ) + { + if ( * (retval = hash_jam(handle,string,oldtrack->hash_value) ) ) + { + break; + } + } + } #ifdef SUSPECT - if ( !*retval && handle->hash_stat[STAT_USED] != oldused) - { - retval = "hash_used"; - } + if ( !*retval && handle->hash_stat[STAT_USED] != oldused) + { + retval = "hash_used"; + } #endif - if (!*retval) - { - /* - * we have a completely faked up control block. - * return the old hash table. - */ - free((char *)oldwhere); - /* - * Here with success. retval is already "". - */ - } - } - else - { - retval = "no room"; - } - return(retval); + if (!*retval) + { + /* + * we have a completely faked up control block. + * return the old hash table. + */ + free((char *)oldwhere); + /* + * Here with success. retval is already "". + */ + } + } + else + { + retval = "no room"; + } + return(retval); } /* @@ -649,22 +647,22 @@ hash_grow(handle) /* make a hash table grow */ * yet. (The function has no graceful failures.) */ char * -hash_apply(handle,function) - struct hash_control * handle; - char* (*function)(); + hash_apply(handle,function) +struct hash_control * handle; +char* (*function)(); { - register struct hash_entry * entry; - register struct hash_entry * wall; - - wall = handle->hash_wall; - for (entry = handle->hash_where; entry < wall; entry++) - { - if (islive(entry)) /* silly code: tests entry->string twice! */ - { - (*function)(entry->hash_string,entry->hash_value); - } - } - return (NULL); + register struct hash_entry * entry; + register struct hash_entry * wall; + + wall = handle->hash_wall; + for (entry = handle->hash_where; entry < wall; entry++) + { + if (islive(entry)) /* silly code: tests entry->string twice! */ + { + (*function)(entry->hash_string,entry->hash_value); + } + } + return (NULL); } /* @@ -674,23 +672,23 @@ hash_apply(handle,function) * Return found value or NULL. */ char * -hash_find(handle,string) /* return char* or NULL */ - struct hash_control * handle; - char * string; + hash_find(handle,string) /* return char* or NULL */ +struct hash_control * handle; +char * string; { - register struct hash_entry * entry; - register char * retval; - - entry = hash_ask(handle,string,STAT__READ); - if (hash_found) - { - retval = entry->hash_value; - } - else - { - retval = NULL; - } - return(retval); + register struct hash_entry * entry; + register char * retval; + + entry = hash_ask(handle,string,STAT__READ); + if (hash_found) + { + retval = entry->hash_value; + } + else + { + retval = NULL; + } + return(retval); } /* @@ -703,72 +701,72 @@ hash_find(handle,string) /* return char* or NULL */ * Internal. */ static struct hash_entry * /* string slot, may be empty or deleted */ -hash_ask(handle,string,access) - struct hash_control * handle; - char * string; - int access; /* access type */ + hash_ask(handle,string,access) +struct hash_control * handle; +char * string; +int access; /* access type */ { - register char *string1; /* JF avoid strcmp calls */ - register char * s; - register int c; - register struct hash_entry * slot; - register int collision; /* count collisions */ - - slot = handle->hash_where + hash_code(handle,string); /* start looking here */ - handle->hash_stat[STAT_ACCESS+access] += 1; - collision = 0; - hash_found = FALSE; - while ( ((s = slot->hash_string) != NULL) && s!=DELETED ) - { - for(string1=string;;) { - if((c= *s++) == 0) { - if(!*string1) - hash_found = TRUE; - break; - } - if(*string1++!=c) + register char *string1; /* JF avoid strcmp calls */ + register char * s; + register int c; + register struct hash_entry * slot; + register int collision; /* count collisions */ + + slot = handle->hash_where + hash_code(handle,string); /* start looking here */ + handle->hash_stat[STAT_ACCESS+access] += 1; + collision = 0; + hash_found = FALSE; + while ( ((s = slot->hash_string) != NULL) && s!=DELETED ) + { + for(string1=string;;) { + if((c= *s++) == 0) { + if(!*string1) + hash_found = TRUE; + break; + } + if(*string1++!=c) + break; + } + if(hash_found) break; - } - if(hash_found) - break; - collision++; - slot++; - } - /* - * slot: return: - * in use: we found string slot - * at empty: - * at wall: we fell off: wrap round ???? - * in table: dig here slot - * at DELETED: dig here slot - */ - if (slot==handle->hash_wall) - { - slot = handle->hash_where; /* now look again */ - while( ((s = slot->hash_string) != NULL) && s!=DELETED ) - { - for(string1=string;*s;string1++,s++) { - if(*string1!=*s) - break; - } - if(*s==*string1) { - hash_found = TRUE; - break; + collision++; + slot++; + } + /* + * slot: return: + * in use: we found string slot + * at empty: + * at wall: we fell off: wrap round ???? + * in table: dig here slot + * at DELETED: dig here slot + */ + if (slot==handle->hash_wall) + { + slot = handle->hash_where; /* now look again */ + while( ((s = slot->hash_string) != NULL) && s!=DELETED ) + { + for(string1=string;*s;string1++,s++) { + if(*string1!=*s) + break; + } + if(*s==*string1) { + hash_found = TRUE; + break; + } + collision++; + slot++; + } + /* + * slot: return: + * in use: we found it slot + * empty: wall: ERROR IMPOSSIBLE !!!! + * in table: dig here slot + * DELETED:dig here slot + */ } - collision++; - slot++; - } - /* - * slot: return: - * in use: we found it slot - * empty: wall: ERROR IMPOSSIBLE !!!! - * in table: dig here slot - * DELETED:dig here slot - */ - } -/* fprintf(stderr,"hash_ask(%s)->%d(%d)\n",string,hash_code(handle,string),collision); */ - handle -> hash_stat[STAT_COLLIDE+access] += collision; - return(slot); /* also return hash_found */ + /* fprintf(stderr,"hash_ask(%s)->%d(%d)\n",string,hash_code(handle,string),collision); */ + handle -> hash_stat[STAT_COLLIDE+access] += collision; + return(slot); /* also return hash_found */ } /* @@ -778,22 +776,22 @@ hash_ask(handle,string,access) * Internal. */ static int -hash_code(handle,string) - struct hash_control * handle; - register char * string; + hash_code(handle,string) +struct hash_control * handle; +register char * string; { - register long h; /* hash code built here */ - register long c; /* each character lands here */ - register int n; /* Amount to shift h by */ - - n = (handle->hash_sizelog - 3); - h = 0; - while ((c = *string++) != 0) - { - h += c; - h = (h<<3) + (h>>n) + c; - } - return (h & handle->hash_mask); + register long h; /* hash code built here */ + register long c; /* each character lands here */ + register int n; /* Amount to shift h by */ + + n = (handle->hash_sizelog - 3); + h = 0; + while ((c = *string++) != 0) + { + h += c; + h = (h<<3) + (h>>n) + c; + } + return (h & handle->hash_mask); } /* @@ -802,7 +800,7 @@ hash_code(handle,string) #ifdef TEST #define TABLES (6) /* number of hash tables to maintain */ - /* (at once) in any testing */ +/* (at once) in any testing */ #define STATBUFSIZE (12) /* we can have 12 statistics */ int statbuf[STATBUFSIZE]; /* display statistics here */ @@ -817,170 +815,170 @@ int size; int used; char command; int number; /* number 0:TABLES-1 of current hashed */ - /* symbol table */ +/* symbol table */ main() { - char (*applicatee()); - char * hash_find(); - char * destroy(); - char * what(); - struct hash_control * hash_new(); - char * hash_replace(); - int * ip; - - number = 0; - h = 0; - printf("type h <RETURN> for help\n"); - for(;;) - { - printf("hash_test command: "); - gets(answer); - command = answer[0]; - if (isupper(command)) command = tolower(command); /* ecch! */ - switch (command) - { - case '#': - printf("old hash table #=%d.\n",number); - whattable(); - break; - case '?': - for (pp=hashtable; pp<hashtable+TABLES; pp++) + char (*applicatee()); + char * hash_find(); + char * destroy(); + char * what(); + struct hash_control * hash_new(); + char * hash_replace(); + int * ip; + + number = 0; + h = 0; + printf("type h <RETURN> for help\n"); + for(;;) { - printf("address of hash table #%d control block is %xx\n" - ,pp-hashtable,*pp); + printf("hash_test command: "); + gets(answer); + command = answer[0]; + if (isupper(command)) command = tolower(command); /* ecch! */ + switch (command) + { + case '#': + printf("old hash table #=%d.\n",number); + whattable(); + break; + case '?': + for (pp=hashtable; pp<hashtable+TABLES; pp++) + { + printf("address of hash table #%d control block is %xx\n" + ,pp-hashtable,*pp); + } + break; + case 'a': + hash_apply(h,applicatee); + break; + case 'd': + hash_apply(h,destroy); + hash_die(h); + break; + case 'f': + p = hash_find(h,name=what("symbol")); + printf("value of \"%s\" is \"%s\"\n",name,p?p:"NOT-PRESENT"); + break; + case 'h': + printf("# show old, select new default hash table number\n"); + printf("? display all hashtable control block addresses\n"); + printf("a apply a simple display-er to each symbol in table\n"); + printf("d die: destroy hashtable\n"); + printf("f find value of nominated symbol\n"); + printf("h this help\n"); + printf("i insert value into symbol\n"); + printf("j jam value into symbol\n"); + printf("n new hashtable\n"); + printf("r replace a value with another\n"); + printf("s say what %% of table is used\n"); + printf("q exit this program\n"); + printf("x delete a symbol from table, report its value\n"); + break; + case 'i': + p = hash_insert(h,name=what("symbol"),value=what("value")); + if (*p) + { + printf("symbol=\"%s\" value=\"%s\" error=%s\n",name,value,p); + } + break; + case 'j': + p = hash_jam(h,name=what("symbol"),value=what("value")); + if (*p) + { + printf("symbol=\"%s\" value=\"%s\" error=%s\n",name,value,p); + } + break; + case 'n': + h = hashtable[number] = (char *) hash_new(); + break; + case 'q': + exit(); + case 'r': + p = hash_replace(h,name=what("symbol"),value=what("value")); + printf("old value was \"%s\"\n",p?p:"{}"); + break; + case 's': + hash_say(h,statbuf,STATBUFSIZE); + for (ip=statbuf; ip<statbuf+STATBUFSIZE; ip++) + { + printf("%d ",*ip); + } + printf("\n"); + break; + case 'x': + p = hash_delete(h,name=what("symbol")); + printf("old value was \"%s\"\n",p?p:"{}"); + break; + default: + printf("I can't understand command \"%c\"\n",command); + break; + } } - break; - case 'a': - hash_apply(h,applicatee); - break; - case 'd': - hash_apply(h,destroy); - hash_die(h); - break; - case 'f': - p = hash_find(h,name=what("symbol")); - printf("value of \"%s\" is \"%s\"\n",name,p?p:"NOT-PRESENT"); - break; - case 'h': - printf("# show old, select new default hash table number\n"); - printf("? display all hashtable control block addresses\n"); - printf("a apply a simple display-er to each symbol in table\n"); - printf("d die: destroy hashtable\n"); - printf("f find value of nominated symbol\n"); - printf("h this help\n"); - printf("i insert value into symbol\n"); - printf("j jam value into symbol\n"); - printf("n new hashtable\n"); - printf("r replace a value with another\n"); - printf("s say what %% of table is used\n"); - printf("q exit this program\n"); - printf("x delete a symbol from table, report its value\n"); - break; - case 'i': - p = hash_insert(h,name=what("symbol"),value=what("value")); - if (*p) - { - printf("symbol=\"%s\" value=\"%s\" error=%s\n",name,value,p); - } - break; - case 'j': - p = hash_jam(h,name=what("symbol"),value=what("value")); - if (*p) - { - printf("symbol=\"%s\" value=\"%s\" error=%s\n",name,value,p); - } - break; - case 'n': - h = hashtable[number] = (char *) hash_new(); - break; - case 'q': - exit(); - case 'r': - p = hash_replace(h,name=what("symbol"),value=what("value")); - printf("old value was \"%s\"\n",p?p:"{}"); - break; - case 's': - hash_say(h,statbuf,STATBUFSIZE); - for (ip=statbuf; ip<statbuf+STATBUFSIZE; ip++) - { - printf("%d ",*ip); - } - printf("\n"); - break; - case 'x': - p = hash_delete(h,name=what("symbol")); - printf("old value was \"%s\"\n",p?p:"{}"); - break; - default: - printf("I can't understand command \"%c\"\n",command); - break; - } - } } char * -what(description) - char * description; + what(description) +char * description; { - char * retval; - char * malloc(); - - printf(" %s : ",description); - gets(answer); - /* will one day clean up answer here */ - retval = malloc(strlen(answer)+1); - if (!retval) - { - error("room"); - } - (void)strcpy(retval,answer); - return(retval); + char * retval; + char * malloc(); + + printf(" %s : ",description); + gets(answer); + /* will one day clean up answer here */ + retval = malloc(strlen(answer)+1); + if (!retval) + { + error("room"); + } + (void)strcpy(retval,answer); + return(retval); } char * -destroy(string,value) - char * string; - char * value; + destroy(string,value) +char * string; +char * value; { - free(string); - free(value); - return(NULL); + free(string); + free(value); + return(NULL); } char * -applicatee(string,value) - char * string; - char * value; + applicatee(string,value) +char * string; +char * value; { - printf("%.20s-%.20s\n",string,value); - return(NULL); + printf("%.20s-%.20s\n",string,value); + return(NULL); } whattable() /* determine number: what hash table to use */ - /* also determine h: points to hash_control */ +/* also determine h: points to hash_control */ { - - for (;;) - { - printf(" what hash table (%d:%d) ? ",0,TABLES-1); - gets(answer); - sscanf(answer,"%d",&number); - if (number>=0 && number<TABLES) - { - h = hashtable[number]; - if (!h) + + for (;;) { - printf("warning: current hash-table-#%d. has no hash-control\n",number); + printf(" what hash table (%d:%d) ? ",0,TABLES-1); + gets(answer); + sscanf(answer,"%d",&number); + if (number>=0 && number<TABLES) + { + h = hashtable[number]; + if (!h) + { + printf("warning: current hash-table-#%d. has no hash-control\n",number); + } + return; + } + else + { + printf("invalid hash table number: %d\n",number); + } } - return; - } - else - { - printf("invalid hash table number: %d\n",number); - } - } } @@ -1,46 +1,46 @@ /* hash.h - for hash.c Copyright (C) 1987 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. */ + + 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. */ #ifndef hashH #define hashH struct hash_entry { - char * hash_string; /* points to where the symbol string is */ - /* NULL means slot is not used */ - /* DELETED means slot was deleted */ - char * hash_value; /* user's datum, associated with symbol */ + char * hash_string; /* points to where the symbol string is */ + /* NULL means slot is not used */ + /* DELETED means slot was deleted */ + char * hash_value; /* user's datum, associated with symbol */ }; #define HASH_STATLENGTH (6) struct hash_control { - struct hash_entry * hash_where; /* address of hash table */ - int hash_sizelog; /* Log of ( hash_mask + 1 ) */ - int hash_mask; /* masks a hash into index into table */ - int hash_full; /* when hash_stat[STAT_USED] exceeds this, */ - /* grow table */ - struct hash_entry * hash_wall; /* point just after last (usable) entry */ - /* here we have some statistics */ - int hash_stat[HASH_STATLENGTH]; /* lies & statistics */ - /* we need STAT_USED & STAT_SIZE */ + struct hash_entry * hash_where; /* address of hash table */ + int hash_sizelog; /* Log of ( hash_mask + 1 ) */ + int hash_mask; /* masks a hash into index into table */ + int hash_full; /* when hash_stat[STAT_USED] exceeds this, */ + /* grow table */ + struct hash_entry * hash_wall; /* point just after last (usable) entry */ + /* here we have some statistics */ + int hash_stat[HASH_STATLENGTH]; /* lies & statistics */ + /* we need STAT_USED & STAT_SIZE */ }; diff --git a/gas/hex-value.c b/gas/hex-value.c index e16d3c3..b4307a2 100644 --- a/gas/hex-value.c +++ b/gas/hex-value.c @@ -1,21 +1,21 @@ /* hex_value.c - char=>radix-value - Copyright (C) 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 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. */ /* * Export: Hex_value[]. Converts digits to their radix-values. @@ -23,29 +23,29 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ */ #define __ (42) /* blatently illegal digit value */ - /* exceeds any normal radix */ +/* exceeds any normal radix */ #if !defined(__STDC__) && !defined(const) #define const /* empty */ #endif const char -hex_value [256] = { /* for fast ASCII -> binary */ - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, __, __, __, __, __, __, - __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ - }; + hex_value [256] = { /* for fast ASCII -> binary */ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, __, __, __, __, __, __, + __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ + }; #ifdef VMS dummy2() diff --git a/gas/input-file.c b/gas/input-file.c index cf1a4c3..7ed492e 100644 --- a/gas/input-file.c +++ b/gas/input-file.c @@ -1,23 +1,21 @@ /* input_file.c - Deal with Input Files - Copyright (C) 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. */ /* * Confines all details of reading source bytes to this module. @@ -39,7 +37,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This variable is non-zero if the file currently being read should be preprocessed by app. It is zero if the file can be read straight in. - */ + */ int preprocess = 0; /* @@ -62,150 +60,150 @@ char * file_name; /* Struct for saving the state of this module for file includes. */ struct saved_file { - FILE *f_in; - char *file_name; - int preprocess; - char *app_save; + FILE *f_in; + char *file_name; + int preprocess; + char *app_save; }; /* These hooks accomodate most operating systems. */ void input_file_begin() { - f_in = (FILE *)0; + f_in = (FILE *)0; } void input_file_end () { } - /* Return BUFFER_SIZE. */ +/* Return BUFFER_SIZE. */ int input_file_buffer_size() { - return (BUFFER_SIZE); + return (BUFFER_SIZE); } int input_file_is_open() { - return f_in!=(FILE *)0; + return f_in!=(FILE *)0; } /* Push the state of our input, returning a pointer to saved info that can be restored with input_file_pop (). */ char *input_file_push () { - register struct saved_file *saved; - - saved = (struct saved_file *)xmalloc (sizeof *saved); - - saved->f_in = f_in; - saved->file_name = file_name; - saved->preprocess = preprocess; - if (preprocess) - saved->app_save = app_push (); - - input_file_begin (); /* Initialize for new file */ - - return (char *)saved; + register struct saved_file *saved; + + saved = (struct saved_file *)xmalloc (sizeof *saved); + + saved->f_in = f_in; + saved->file_name = file_name; + saved->preprocess = preprocess; + if (preprocess) + saved->app_save = app_push (); + + input_file_begin (); /* Initialize for new file */ + + return (char *)saved; } void -input_file_pop (arg) - char *arg; + input_file_pop (arg) +char *arg; { - register struct saved_file *saved = (struct saved_file *)arg; - - input_file_end (); /* Close out old file */ - - f_in = saved->f_in; - file_name = saved->file_name; - preprocess = saved->preprocess; - if (preprocess) - app_pop (saved->app_save); - - free(arg); + register struct saved_file *saved = (struct saved_file *)arg; + + input_file_end (); /* Close out old file */ + + f_in = saved->f_in; + file_name = saved->file_name; + preprocess = saved->preprocess; + if (preprocess) + app_pop (saved->app_save); + + free(arg); } #ifdef DONTDEF /* JF save old version in case we need it */ void -input_file_open (filename, preprocess, debugging) - char * filename; /* "" means use stdin. Must not be 0. */ - int preprocess; /* TRUE if needs app. */ - int debugging; /* TRUE if we are debugging assembler. */ + input_file_open (filename, preprocess, debugging) +char * filename; /* "" means use stdin. Must not be 0. */ +int preprocess; /* TRUE if needs app. */ +int debugging; /* TRUE if we are debugging assembler. */ { - assert( filename != 0 ); /* Filename may not be NULL. */ - if (filename [0]) - { /* We have a file name. Suck it and see. */ - file_handle = open (filename, O_RDONLY, 0); - file_name = filename; - } - else - { /* use stdin for the input file. */ - file_handle = fileno (stdin); - file_name = "{standard input}"; /* For error messages. */ - } - if (file_handle < 0) - as_perror ("Can't open %s for reading", file_name); - if ( preprocess ) - { -/* - * This code was written in haste for a frobbed BSD 4.2. - * I have a flight to catch: will someone please do proper - * error checks? - Dean. - */ - int pid; - char temporary_file_name [12]; - int fd; - union wait status; - - (void)strcpy (temporary_file_name, "#appXXXXXX"); - (void)mktemp (temporary_file_name); - pid = vfork (); - if (pid == -1) - { - as_perror ("Vfork failed", file_name); - _exit (144); - } - if (pid == 0) - { - (void)dup2 (file_handle, fileno(stdin)); - fd = open (temporary_file_name, O_WRONLY + O_TRUNC + O_CREAT, 0666); - if (fd == -1) - { - (void)write(2,"Can't open temporary\n",21); - _exit (99); + assert( filename != 0 ); /* Filename may not be NULL. */ + if (filename [0]) + { /* We have a file name. Suck it and see. */ + file_handle = open (filename, O_RDONLY, 0); + file_name = filename; } - (void)dup2 (fd, fileno(stdout)); -/* JF for testing #define PREPROCESSOR "/lib/app" */ + else + { /* use stdin for the input file. */ + file_handle = fileno (stdin); + file_name = "{standard input}"; /* For error messages. */ + } + if (file_handle < 0) + as_perror ("Can't open %s for reading", file_name); + if ( preprocess ) + { + /* + * This code was written in haste for a frobbed BSD 4.2. + * I have a flight to catch: will someone please do proper + * error checks? - Dean. + */ + int pid; + char temporary_file_name [12]; + int fd; + union wait status; + + (void)strcpy (temporary_file_name, "#appXXXXXX"); + (void)mktemp (temporary_file_name); + pid = vfork (); + if (pid == -1) + { + as_perror ("Vfork failed", file_name); + _exit (144); + } + if (pid == 0) + { + (void)dup2 (file_handle, fileno(stdin)); + fd = open (temporary_file_name, O_WRONLY + O_TRUNC + O_CREAT, 0666); + if (fd == -1) + { + (void)write(2,"Can't open temporary\n",21); + _exit (99); + } + (void)dup2 (fd, fileno(stdout)); + /* JF for testing #define PREPROCESSOR "/lib/app" */ #define PREPROCESSOR "./app" - execl (PREPROCESSOR, PREPROCESSOR, 0); - execl ("app","app",0); - (void)write(2,"Exec of app failed. Get help.\n",31); - (void)unlink(temporary_file_name); - _exit (11); - } - (void)wait (& status); - if (status.w_status & 0xFF00) /* JF was 0xF000, was wrong */ - { - file_handle = -1; - as_bad( "Can't preprocess file \"%s\", status = %xx", file_name, status.w_status ); - } - else - { - file_handle = open (temporary_file_name, O_RDONLY, 0); - if ( ! debugging && unlink(temporary_file_name)) - as_perror ("Can't delete temp file %s", temporary_file_name); - } - if (file_handle == -1) - as_perror ("Can't retrieve temp file %s", temporary_file_name); - } + execl (PREPROCESSOR, PREPROCESSOR, 0); + execl ("app","app",0); + (void)write(2,"Exec of app failed. Get help.\n",31); + (void)unlink(temporary_file_name); + _exit (11); + } + (void)wait (& status); + if (status.w_status & 0xFF00) /* JF was 0xF000, was wrong */ + { + file_handle = -1; + as_bad( "Can't preprocess file \"%s\", status = %xx", file_name, status.w_status ); + } + else + { + file_handle = open (temporary_file_name, O_RDONLY, 0); + if ( ! debugging && unlink(temporary_file_name)) + as_perror ("Can't delete temp file %s", temporary_file_name); + } + if (file_handle == -1) + as_perror ("Can't retrieve temp file %s", temporary_file_name); + } } #else void -input_file_open (filename,pre) - char * filename; /* "" means use stdin. Must not be 0. */ - int pre; + input_file_open (filename,pre) +char * filename; /* "" means use stdin. Must not be 0. */ +int pre; { int c; char buf[80]; - + preprocess = pre; - + assert( filename != 0 ); /* Filename may not be NULL. */ if (filename [0]) { /* We have a file name. Suck it and see. */ f_in=fopen(filename,"r"); @@ -218,44 +216,44 @@ input_file_open (filename,pre) as_perror ("Can't open %s for reading", file_name); return; } - + #ifndef VMS /* Ask stdio to buffer our input at BUFFER_SIZE, with a dynamically allocated buffer. */ setvbuf(f_in, (char *)NULL, _IOFBF, BUFFER_SIZE); #endif /* VMS */ - + c = getc(f_in); if (c == '#') { /* Begins with comment, may not want to preprocess */ c = getc(f_in); if (c == 'N') { fgets(buf,80,f_in); if (!strcmp(buf,"O_APP\n")) - preprocess=0; + preprocess=0; if (!strchr(buf,'\n')) - ungetc('#',f_in); /* It was longer */ + ungetc('#',f_in); /* It was longer */ else - ungetc('\n',f_in); + ungetc('\n',f_in); } else if(c=='\n') - ungetc('\n',f_in); + ungetc('\n',f_in); else - ungetc('#',f_in); + ungetc('#',f_in); } else - ungetc(c,f_in); - + ungetc(c,f_in); + #ifdef DONTDEF if ( preprocess ) { char temporary_file_name [17]; FILE *f_out; - + (void)strcpy (temporary_file_name, "/tmp/#appXXXXXX"); (void)mktemp (temporary_file_name); f_out=fopen(temporary_file_name,"w+"); if(f_out==(FILE *)0) - as_perror("Can't open temp file %s",temporary_file_name); - - /* JF this will have to be moved on any system that - does not support removal of open files. */ + as_perror("Can't open temp file %s",temporary_file_name); + + /* JF this will have to be moved on any system that + does not support removal of open files. */ (void)unlink(temporary_file_name);/* JF do it NOW */ do_scrub(f_in,f_out); (void)fclose(f_in); /* All done with it */ @@ -268,55 +266,57 @@ input_file_open (filename,pre) /* Close input file. */ void input_file_close() { - fclose (f_in); - f_in = 0; -} + if (f_in != NULL) { + fclose (f_in); + } /* don't close a null file pointer */ + f_in = 0; +} /* input_file_close() */ char * -input_file_give_next_buffer (where) - char * where; /* Where to place 1st character of new buffer. */ + input_file_give_next_buffer (where) +char * where; /* Where to place 1st character of new buffer. */ { - char * return_value; /* -> Last char of what we read, + 1. */ - register int size; - - if (f_in == (FILE *)0) - return 0; - /* - * fflush (stdin); could be done here if you want to synchronise - * stdin and stdout, for the case where our input file is stdin. - * Since the assembler shouldn't do any output to stdout, we - * don't bother to synch output and input. - */ - if(preprocess) { - char *p; - int n; - int ch; - extern FILE *scrub_file; - - scrub_file=f_in; - for (p = where, n = BUFFER_SIZE; n; --n) { - - ch = do_scrub_next_char(scrub_from_file, scrub_to_file); - if (ch == EOF) - break; - *p++=ch; - } - size=BUFFER_SIZE-n; - } else - size= fread(where,sizeof(char),BUFFER_SIZE,f_in); - if (size < 0) - { - as_perror ("Can't read from %s", file_name); - size = 0; - } - if (size) - return_value = where + size; - else - { - if (fclose (f_in)) - as_perror ("Can't close %s", file_name); - f_in = (FILE *)0; - return_value = 0; - } - return (return_value); + char * return_value; /* -> Last char of what we read, + 1. */ + register int size; + + if (f_in == (FILE *)0) + return 0; + /* + * fflush (stdin); could be done here if you want to synchronise + * stdin and stdout, for the case where our input file is stdin. + * Since the assembler shouldn't do any output to stdout, we + * don't bother to synch output and input. + */ + if(preprocess) { + char *p; + int n; + int ch; + extern FILE *scrub_file; + + scrub_file=f_in; + for (p = where, n = BUFFER_SIZE; n; --n) { + + ch = do_scrub_next_char(scrub_from_file, scrub_to_file); + if (ch == EOF) + break; + *p++=ch; + } + size=BUFFER_SIZE-n; + } else + size= fread(where,sizeof(char),BUFFER_SIZE,f_in); + if (size < 0) + { + as_perror ("Can't read from %s", file_name); + size = 0; + } + if (size) + return_value = where + size; + else + { + if (fclose (f_in)) + as_perror ("Can't close %s", file_name); + f_in = (FILE *)0; + return_value = 0; + } + return (return_value); } diff --git a/gas/input-file.h b/gas/input-file.h index 703d4c5..683f73d 100644 --- a/gas/input-file.h +++ b/gas/input-file.h @@ -1,21 +1,21 @@ /* input_file.h header for input-file.c Copyright (C) 1987 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. */ + + 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. */ /*"input_file.c":Operating-system dependant functions to read source files.*/ diff --git a/gas/input-scrub.c b/gas/input-scrub.c index a710913..c058ef8 100644 --- a/gas/input-scrub.c +++ b/gas/input-scrub.c @@ -1,23 +1,21 @@ /* input_scrub.c - Break up input buffers into whole numbers of lines. Copyright (C) 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. */ #include <errno.h> /* Need this to make errno declaration right */ #include "as.h" @@ -58,48 +56,38 @@ static char * buffer_start; /*->1st char of full buffer area. */ static char * partial_where; /*->after last full line in buffer. */ static int partial_size; /* >=0. Number of chars in partial line in buffer. */ static char save_source [AFTER_SIZE]; - /* Because we need AFTER_STRING just after last */ - /* full line, it clobbers 1st part of partial */ - /* line. So we preserve 1st part of partial */ - /* line here. */ +/* Because we need AFTER_STRING just after last */ +/* full line, it clobbers 1st part of partial */ +/* line. So we preserve 1st part of partial */ +/* line here. */ static int buffer_length; /* What is the largest size buffer that */ - /* input_file_give_next_buffer() could */ - /* return to us? */ +/* input_file_give_next_buffer() could */ +/* return to us? */ -/* Saved information about the file that .include'd this one. When we - hit EOF, we automatically pop to that file. */ +/* Saved information about the file that .include'd this one. When we hit EOF, + we automatically pop to that file. */ static char *next_saved_file; -/* -We can have more than one source file open at once, though the info for -all but the latest one are saved off in a struct input_save. These -files remain open, so we are limited by the number of open files allowed -by the underlying OS. -We may also sequentially read more than one source file in an assembly. - */ +/* We can have more than one source file open at once, though the info for all + but the latest one are saved off in a struct input_save. These files remain + open, so we are limited by the number of open files allowed by the + underlying OS. We may also sequentially read more than one source file in an + assembly. */ +/* We must track the physical file and line number for error messages. We also + track a "logical" file and line number corresponding to (C?) compiler + source line numbers. Whenever we open a file we must fill in + physical_input_file. So if it is NULL we have not opened any files yet. */ -/* -We must track the physical file and line number for error messages. -We also track a "logical" file and line number corresponding to (C?) -compiler source line numbers. -Whenever we open a file we must fill in physical_input_file. So if it is NULL -we have not opened any files yet. - */ +char *physical_input_file; +char *logical_input_file; -static -char * physical_input_file, - * logical_input_file; +typedef unsigned int line_numberT; /* 1-origin line number in a source file. */ +/* A line ends in '\n' or eof. */ - - -typedef unsigned int line_numberT; /* 1-origin line number in a source file. */ - /* A line ends in '\n' or eof. */ - -static -line_numberT physical_input_line, - logical_input_line; +line_numberT physical_input_line; +line_numberT logical_input_line; /* Struct used to save the state of the input handler during include files */ struct input_save { @@ -126,14 +114,13 @@ static void as_1_char(); /* Push the state of input reading and scrubbing so that we can #include. The return value is a 'void *' (fudged for old compilers) to a save area, which can be restored by passing it to input_scrub_pop(). */ -char * -input_scrub_push(saved_position) - char *saved_position; +char *input_scrub_push(saved_position) +char *saved_position; { register struct input_save *saved; - + saved = (struct input_save *) xmalloc(sizeof *saved); - + saved->saved_position = saved_position; saved->buffer_start = buffer_start; saved->partial_where = partial_where; @@ -143,26 +130,26 @@ input_scrub_push(saved_position) saved->logical_input_file = logical_input_file; saved->physical_input_line = physical_input_line; saved->logical_input_line = logical_input_line; - bcopy (saved->save_source, save_source, sizeof (save_source)); + bcopy(saved->save_source, save_source, sizeof(save_source)); saved->next_saved_file = next_saved_file; - saved->input_file_save = input_file_push (); - - input_scrub_begin (); /* Reinitialize! */ - - return (char *)saved; -} + saved->input_file_save = input_file_push(); + + input_scrub_begin(); /* Reinitialize! */ + + return((char *) saved); +} /* input_scrub_push() */ char * -input_scrub_pop (arg) - char *arg; + input_scrub_pop (arg) +char *arg; { register struct input_save *saved; char *saved_position; - + input_scrub_end (); /* Finish off old buffer */ - + saved = (struct input_save *)arg; - + input_file_pop (saved->input_file_save); saved_position = saved->saved_position; buffer_start = saved->buffer_start; @@ -175,57 +162,56 @@ input_scrub_pop (arg) partial_size = saved->partial_size; next_saved_file = saved->next_saved_file; bcopy (save_source, saved->save_source, sizeof (save_source)); - + free(arg); return saved_position; } void -input_scrub_begin () + input_scrub_begin () { - know(strlen(BEFORE_STRING) == BEFORE_SIZE); - know(strlen(AFTER_STRING) == AFTER_SIZE - || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1)); - - input_file_begin (); - - buffer_length = input_file_buffer_size (); - - buffer_start = xmalloc((long)(BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); - bcopy (BEFORE_STRING, buffer_start, (int)BEFORE_SIZE); - - /* Line number things. */ - logical_input_line = 0; - logical_input_file = (char *)NULL; - physical_input_file = NULL; /* No file read yet. */ - next_saved_file = NULL; /* At EOF, don't pop to any other file */ - do_scrub_begin(); + know(strlen(BEFORE_STRING) == BEFORE_SIZE); + know(strlen(AFTER_STRING) == AFTER_SIZE || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1)); + + input_file_begin (); + + buffer_length = input_file_buffer_size (); + + buffer_start = xmalloc((long)(BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); + bcopy (BEFORE_STRING, buffer_start, (int)BEFORE_SIZE); + + /* Line number things. */ + logical_input_line = 0; + logical_input_file = (char *)NULL; + physical_input_file = NULL; /* No file read yet. */ + next_saved_file = NULL; /* At EOF, don't pop to any other file */ + do_scrub_begin(); } void -input_scrub_end () + input_scrub_end () { - if (buffer_start) - { - free (buffer_start); - buffer_start = 0; - input_file_end (); - } + if (buffer_start) + { + free (buffer_start); + buffer_start = 0; + input_file_end (); + } } /* Start reading input from a new file. */ char * /* Return start of caller's part of buffer. */ -input_scrub_new_file (filename) - char * filename; + input_scrub_new_file (filename) +char * filename; { - input_file_open (filename, !flagseen['f']); - physical_input_file = filename[0] ? filename : "{standard input}"; - physical_input_line = 0; - - partial_size = 0; - return (buffer_start + BEFORE_SIZE); + input_file_open (filename, !flagseen['f']); + physical_input_file = filename[0] ? filename : "{standard input}"; + physical_input_line = 0; + + partial_size = 0; + return (buffer_start + BEFORE_SIZE); } @@ -234,102 +220,102 @@ input_scrub_new_file (filename) input_scrub_new_file. */ char * -input_scrub_include_file (filename, position) - char *filename; - char *position; + input_scrub_include_file (filename, position) +char *filename; +char *position; { - next_saved_file = input_scrub_push (position); - return input_scrub_new_file (filename); + next_saved_file = input_scrub_push(position); + return input_scrub_new_file (filename); } void -input_scrub_close () + input_scrub_close () { - input_file_close (); + input_file_close (); } char * -input_scrub_next_buffer (bufp) + input_scrub_next_buffer (bufp) char **bufp; { - register char * limit; /*->just after last char of buffer. */ - - *bufp = buffer_start + BEFORE_SIZE; - + register char * limit; /*->just after last char of buffer. */ + + *bufp = buffer_start + BEFORE_SIZE; + #ifdef DONTDEF - if(preprocess) { - if(save_buffer) { - *bufp = save_buffer; - save_buffer = 0; - } - limit = input_file_give_next_buffer(buffer_start+BEFORE_SIZE); - if (!limit) { - partial_where = 0; - if(partial_size) - as_warn("Partial line at end of file ignored"); - return partial_where; - } - - if(partial_size) - bcopy(save_source, partial_where,(int)AFTER_SIZE); - do_scrub(partial_where,partial_size,buffer_start+BEFORE_SIZE,limit-(buffer_start+BEFORE_SIZE),&out_string,&out_length); - limit=out_string + out_length; - for(p=limit;*--p!='\n';) - ; - p++; - if(p<=buffer_start+BEFORE_SIZE) - as_fatal("Source line too long. Please change file '%s' and re-make the assembler.", __FILE__); - - partial_where = p; - partial_size = limit-p; - bcopy(partial_where, save_source,(int)AFTER_SIZE); - bcopy(AFTER_STRING, partial_where, (int)AFTER_SIZE); - - save_buffer = *bufp; - *bufp = out_string; - - return partial_where; - } - - /* We're not preprocessing. Do the right thing */ -#endif - if (partial_size) - { - bcopy (partial_where, buffer_start + BEFORE_SIZE, (int)partial_size); - bcopy (save_source, buffer_start + BEFORE_SIZE, (int)AFTER_SIZE); - } - limit = input_file_give_next_buffer (buffer_start + BEFORE_SIZE + partial_size); - if (limit) - { - register char * p; /* Find last newline. */ - - for (p = limit; * -- p != '\n';) - { - } - ++ p; - if (p <= buffer_start + BEFORE_SIZE) - { - as_fatal("Source line too long. Please change file %s then rebuild assembler.", __FILE__); + if(preprocess) { + if(save_buffer) { + *bufp = save_buffer; + save_buffer = 0; + } + limit = input_file_give_next_buffer(buffer_start+BEFORE_SIZE); + if (!limit) { + partial_where = 0; + if(partial_size) + as_warn("Partial line at end of file ignored"); + return partial_where; + } + + if(partial_size) + bcopy(save_source, partial_where,(int)AFTER_SIZE); + do_scrub(partial_where,partial_size,buffer_start+BEFORE_SIZE,limit-(buffer_start+BEFORE_SIZE),&out_string,&out_length); + limit=out_string + out_length; + for(p=limit;*--p!='\n';) + ; + p++; + if(p<=buffer_start+BEFORE_SIZE) + as_fatal("Source line too long. Please change file '%s' and re-make the assembler.", __FILE__); + + partial_where = p; + partial_size = limit-p; + bcopy(partial_where, save_source,(int)AFTER_SIZE); + bcopy(AFTER_STRING, partial_where, (int)AFTER_SIZE); + + save_buffer = *bufp; + *bufp = out_string; + + return partial_where; } - partial_where = p; - partial_size = limit - p; - bcopy (partial_where, save_source, (int)AFTER_SIZE); - bcopy (AFTER_STRING, partial_where, (int)AFTER_SIZE); - } - else - { - partial_where = 0; - if (partial_size > 0) - { - as_warn("Partial line at end of file ignored"); - } - /* If we should pop to another file at EOF, do it. */ - if (next_saved_file) - { - *bufp = input_scrub_pop (next_saved_file); /* Pop state */ - /* partial_where is now correct to return, since we popped it. */ - } - } - return (partial_where); + + /* We're not preprocessing. Do the right thing */ +#endif + if (partial_size) + { + bcopy (partial_where, buffer_start + BEFORE_SIZE, (int)partial_size); + bcopy (save_source, buffer_start + BEFORE_SIZE, (int)AFTER_SIZE); + } + limit = input_file_give_next_buffer (buffer_start + BEFORE_SIZE + partial_size); + if (limit) + { + register char * p; /* Find last newline. */ + + for (p = limit; * -- p != '\n';) + { + } + ++ p; + if (p <= buffer_start + BEFORE_SIZE) + { + as_fatal("Source line too long. Please change file %s then rebuild assembler.", __FILE__); + } + partial_where = p; + partial_size = limit - p; + bcopy (partial_where, save_source, (int)AFTER_SIZE); + bcopy (AFTER_STRING, partial_where, (int)AFTER_SIZE); + } + else + { + partial_where = 0; + if (partial_size > 0) + { + as_warn("Partial line at end of file ignored"); + } + /* If we should pop to another file at EOF, do it. */ + if (next_saved_file) + { + *bufp = input_scrub_pop (next_saved_file); /* Pop state */ + /* partial_where is now correct to return, since we popped it. */ + } + } + return (partial_where); } /* @@ -339,16 +325,16 @@ char **bufp; int -seen_at_least_1_file () /* TRUE if we opened any file. */ + seen_at_least_1_file () /* TRUE if we opened any file. */ { - return (physical_input_file != NULL); + return (physical_input_file != NULL); } void -bump_line_counters () + bump_line_counters () { - ++ physical_input_line; - ++ logical_input_line; + ++ physical_input_line; + /* ++ logical_input_line; FIXME-now remove this. */ } /* @@ -359,8 +345,8 @@ bump_line_counters () * If the fname is NULL, we don't change the current logical file name. */ void new_logical_line(fname, line_number) - char *fname; /* DON'T destroy it! We point to it! */ - int line_number; +char *fname; /* DON'T destroy it! We point to it! */ +int line_number; { if (fname) { logical_input_file = fname; @@ -378,49 +364,40 @@ void new_logical_line(fname, line_number) * input source files. * As a sop to the debugger of AS, pretty-print the offending line. */ -void -as_where() -{ - char *p; - line_numberT line; - - if (physical_input_file) - { /* we tried to read SOME source */ - if (input_file_is_open()) - { /* we can still read lines from source */ -#ifdef DONTDEF - fprintf (stderr," @ physical line %ld., file \"%s\"", - (long) physical_input_line, physical_input_file); - fprintf (stderr," @ logical line %ld., file \"%s\"\n", - (long) logical_input_line, logical_input_file); - (void)putc(' ', stderr); - as_howmuch (stderr); - (void)putc('\n', stderr); -#else - p = logical_input_file ? logical_input_file : physical_input_file; - line = logical_input_line ? logical_input_line : physical_input_line; - fprintf(stderr,"%s:%u: ", p, line); -#endif - } - else - { -#ifdef DONTDEF - fprintf (stderr," After reading source.\n"); -#else - p = logical_input_file ? logical_input_file : physical_input_file; - line = logical_input_line ? logical_input_line : physical_input_line; - fprintf(stderr, "%s:%d:", p, (int) line); -#endif - } - } - else - { +void as_where() { + char *p; + line_numberT line; + + if (logical_input_file && (logical_input_line > 0)) { + p = logical_input_file; + line = logical_input_line; + } else { + p = physical_input_file; + line = physical_input_line; + } /* line number should match file name */ + + fprintf(stderr, "%s:%u: ", p, line); + #ifdef DONTDEF - fprintf (stderr," Before reading source.\n"); -#else -#endif - } -} + if (physical_input_file) { + if (input_file_is_open()) { /* we can still read lines from source */ + fprintf (stderr," @ physical line %ld., file \"%s\"", + (long) physical_input_line, physical_input_file); + fprintf (stderr," @ logical line %ld., file \"%s\"\n", + (long) logical_input_line, logical_input_file); + (void)putc(' ', stderr); + as_howmuch (stderr); + (void)putc('\n', stderr); + } else { + fprintf(stderr, " After reading source.\n"); + } /* input file is still open */ + } else { + fprintf(stderr, " Before reading source.\n"); + } /* we tried to read SOME source */ +#endif /* DONTDEF */ + + return; +} /* as_where() */ @@ -433,39 +410,39 @@ as_where() * No free '\n' at end of line. */ void -as_howmuch (stream) - FILE * stream; /* Opened for write please. */ + as_howmuch (stream) +FILE * stream; /* Opened for write please. */ { - register char * p; /* Scan input line. */ - /* register char c; JF unused */ - - for (p = input_line_pointer - 1; * p != '\n'; --p) - { - } - ++ p; /* p->1st char of line. */ - for (; p <= input_line_pointer; p++) - { - /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */ - /* c = *p & 0xFF; JF unused */ - as_1_char(*p, stream); - } + register char * p; /* Scan input line. */ + /* register char c; JF unused */ + + for (p = input_line_pointer - 1; * p != '\n'; --p) + { + } + ++ p; /* p->1st char of line. */ + for (; p <= input_line_pointer; p++) + { + /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */ + /* c = *p & 0xFF; JF unused */ + as_1_char(*p, stream); + } } static void as_1_char (c,stream) unsigned int c; FILE *stream; { - if (c > 127) - { - (void)putc('%', stream); - c -= 128; - } - if (c < 32) - { - (void)putc('^', stream); - c += '@'; - } - (void)putc(c, stream); + if (c > 127) + { + (void)putc('%', stream); + c -= 128; + } + if (c < 32) + { + (void)putc('^', stream); + c += '@'; + } + (void)putc(c, stream); } /* diff --git a/gas/listing.c b/gas/listing.c index ce0983c..343aa62 100644 --- a/gas/listing.c +++ b/gas/listing.c @@ -1,95 +1,95 @@ /* listing.c - mainting assembly listings Copyright (C) 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. */ /* - Contributed by Steve Chamberlain - sac@cygnus.com - - - A listing page looks like: - - LISTING_HEADER sourcefilename pagenumber - TITLE LINE - SUBTITLE LINE - linenumber address data source - linenumber address data source - linenumber address data source - linenumber address data source - - If not overridden, the listing commands are: - - .title "stuff" - Put "stuff" onto the title line - .sbttl "stuff" - Put stuff onto the subtitle line - + Contributed by Steve Chamberlain + sac@cygnus.com + + + A listing page looks like: + + LISTING_HEADER sourcefilename pagenumber + TITLE LINE + SUBTITLE LINE + linenumber address data source + linenumber address data source + linenumber address data source + linenumber address data source + + If not overridden, the listing commands are: + + .title "stuff" + Put "stuff" onto the title line + .sbttl "stuff" + Put stuff onto the subtitle line + If these commands come within 10 lines of the top of the page, they will affect the page they are on, as well as any subsequent page - - .eject - Thow a page - .list - Increment the enable listing counter - .nolist - Decrement the enable listing counter - - .psize Y[,X] - Set the paper size to X wide and Y high. Setting a psize Y of - zero will suppress form feeds except where demanded by .eject - - If the counter goes below zero, listing is suppressed. - - - Listings are a maintained by read calling various listing_<foo> - functions. What happens most is that the macro NO_LISTING is not - defined (from the Makefile), then the macro LISTING_NEWLINE expands - into a call to listing_newline. The call is done from read.c, every - time it sees a newline, and -l is on the command line. - - The function listing_newline remembers the frag associated with the - newline, and creates a new frag - note that this is wasteful, but not - a big deal, since listing slows things down a lot anyway. The - function also rememebers when the filename changes. - - When all the input has finished, and gas has had a chance to settle - down, the listing is output. This is done by running down the list of - frag/source file records, and opening the files as needed and printing - out the bytes and chars associated with them. - - The only things which the architecture can change about the listing - are defined in these macros: - - LISTING_HEADER The name of the architecture - LISTING_WORD_SIZE The make of the number of bytes in a word, this determines - the clumping of the output data. eg a value of - 2 makes words look like 1234 5678, whilst 1 - would make the same value look like 12 34 56 - 78 - LISTING_LHS_WIDTH Number of words of above size for the lhs - - LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs - for the second line - - LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation - LISTING_RHS_WIDTH Number of chars from the input file to print - on a line -*/ + + .eject + Thow a page + .list + Increment the enable listing counter + .nolist + Decrement the enable listing counter + + .psize Y[,X] + Set the paper size to X wide and Y high. Setting a psize Y of + zero will suppress form feeds except where demanded by .eject + + If the counter goes below zero, listing is suppressed. + + + Listings are a maintained by read calling various listing_<foo> + functions. What happens most is that the macro NO_LISTING is not + defined (from the Makefile), then the macro LISTING_NEWLINE expands + into a call to listing_newline. The call is done from read.c, every + time it sees a newline, and -l is on the command line. + + The function listing_newline remembers the frag associated with the + newline, and creates a new frag - note that this is wasteful, but not + a big deal, since listing slows things down a lot anyway. The + function also rememebers when the filename changes. + + When all the input has finished, and gas has had a chance to settle + down, the listing is output. This is done by running down the list of + frag/source file records, and opening the files as needed and printing + out the bytes and chars associated with them. + + The only things which the architecture can change about the listing + are defined in these macros: + + LISTING_HEADER The name of the architecture + LISTING_WORD_SIZE The make of the number of bytes in a word, this determines + the clumping of the output data. eg a value of + 2 makes words look like 1234 5678, whilst 1 + would make the same value look like 12 34 56 + 78 + LISTING_LHS_WIDTH Number of words of above size for the lhs + + LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs + for the second line + + LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation + LISTING_RHS_WIDTH Number of chars from the input file to print + on a line + */ #include "as.h" #include <obstack.h> @@ -122,51 +122,53 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This structure remembers which .s were used */ typedef struct file_info_struct { - char *filename; - int linenum; - FILE *file; - struct file_info_struct *next; + char *filename; + int linenum; + FILE *file; + struct file_info_struct *next; + int end_pending; + } file_info_type ; - + /* this structure rememebrs which line from which file goes into which frag */ typedef struct list_info_struct { - /* Frag which this line of source is nearest to */ - fragS *frag; - /* The actual line in the source file */ - unsigned int line; - /* Pointer to the file info struct for the file which this line - belongs to */ - file_info_type *file; - - /* Next in list */ - struct list_info_struct *next; - - - /* Pointer to the file info struct for the high level language - source line that belongs here */ - file_info_type *hll_file; - - /* High level language source line */ - unsigned int hll_line; - - - /* Pointer to any error message associated with this line */ - char *message; - - enum - { - EDICT_NONE, - EDICT_SBTTL, - EDICT_TITLE, - EDICT_NOLIST, - EDICT_LIST, - EDICT_EJECT - } edict; - char *edict_arg; - + /* Frag which this line of source is nearest to */ + fragS *frag; + /* The actual line in the source file */ + unsigned int line; + /* Pointer to the file info struct for the file which this line + belongs to */ + file_info_type *file; + + /* Next in list */ + struct list_info_struct *next; + + + /* Pointer to the file info struct for the high level language + source line that belongs here */ + file_info_type *hll_file; + + /* High level language source line */ + int hll_line; + + + /* Pointer to any error message associated with this line */ + char *message; + + enum + { + EDICT_NONE, + EDICT_SBTTL, + EDICT_TITLE, + EDICT_NOLIST, + EDICT_LIST, + EDICT_EJECT + } edict; + char *edict_arg; + } list_info_type; @@ -183,45 +185,45 @@ static int paper_height = 60; /* this static array is used to keep the text of data to be printed before the start of the line. - It is stored so we can give a bit more info on the next line. To much, and large + It is stored so we can give a bit more info on the next line. To much, and large initialized arrays will use up lots of paper. - */ + */ static char data_buffer[100]; static unsigned int data_buffer_size; - + static void -DEFUN(listing_message,(name, message), - char *name AND - char *message) -{ - unsigned int l = strlen(name) + strlen(message)+1; - char *n = malloc(l); - strcpy(n,name); - strcat(n,message); - if(listing_tail != (list_info_type *)NULL) - { - listing_tail->message = n; - } - + DEFUN(listing_message,(name, message), + char *name AND + char *message) +{ + unsigned int l = strlen(name) + strlen(message)+1; + char *n = malloc(l); + strcpy(n,name); + strcat(n,message); + if(listing_tail != (list_info_type *)NULL) + { + listing_tail->message = n; + } + } void -DEFUN(listing_warning,(message), - char *message) + DEFUN(listing_warning,(message), + char *message) { - listing_message("Warning:", message); + listing_message("Warning:", message); } void -DEFUN(listing_error,(message), - char *message) + DEFUN(listing_error,(message), + char *message) { - listing_message("Error:", message); + listing_message("Error:", message); } @@ -230,115 +232,133 @@ DEFUN(listing_error,(message), static file_info_type *file_info_head; static file_info_type * -DEFUN(file_info, (file_name), - char *file_name) + DEFUN(file_info, (file_name), + char *file_name) { - /* Find an entry with this file name */ - file_info_type *p = file_info_head; - - while (p != (file_info_type *)NULL) - { - if (strcmp(p->filename, file_name) == 0) - return p; - p = p->next; - } - - /* Make new entry */ - - p = (file_info_type *)xmalloc(sizeof(file_info_type)); - p->next = file_info_head; - file_info_head = p; - p->filename = xmalloc(strlen(file_name)+1); - strcpy(p->filename, file_name); - p->linenum = 0; - p->file = fopen(p->filename,"r"); - return p; - + /* Find an entry with this file name */ + file_info_type *p = file_info_head; + + while (p != (file_info_type *)NULL) + { + if (strcmp(p->filename, file_name) == 0) + return p; + p = p->next; + } + + /* Make new entry */ + + p = (file_info_type *)xmalloc(sizeof(file_info_type)); + p->next = file_info_head; + file_info_head = p; + p->filename = xmalloc(strlen(file_name)+1); + strcpy(p->filename, file_name); + p->linenum = 0; + p->end_pending = 0; + + p->file = fopen(p->filename,"r"); + return p; + } static void -DEFUN_VOID(new_frag) + DEFUN_VOID(new_frag) { - - frag_wane(frag_now); - frag_new(0); - + + frag_wane(frag_now); + frag_new(0); + } void -DEFUN(listing_newline,(ps), - char *ps) + DEFUN(listing_newline,(ps), + char *ps) { - char *s = ps; - extern char *file_name; - static unsigned int last_line =0xffff ; - - - list_info_type *new; - if (physical_input_line != last_line) - { - last_line = physical_input_line; - new_frag(); - - new = (list_info_type *)malloc(sizeof(list_info_type)); - new->frag = frag_now; - new->line = physical_input_line ; - new->file = file_info(file_name); - - if (listing_tail) - { - listing_tail->next = new; - } - else - { - head = new; - } - listing_tail = new; - new->next = (list_info_type *)NULL; - new->message = (char *)NULL; - new->edict = EDICT_NONE; - new_frag(); - } + char *s = ps; + extern char *file_name; + static unsigned int last_line =0xffff ; + + + list_info_type *new; + if (physical_input_line != last_line) + { + last_line = physical_input_line; + new_frag(); + + new = (list_info_type *)malloc(sizeof(list_info_type)); + new->frag = frag_now; + new->line = physical_input_line ; + new->file = file_info(file_name); + + if (listing_tail) + { + listing_tail->next = new; + } + else + { + head = new; + } + listing_tail = new; + new->next = (list_info_type *)NULL; + new->message = (char *)NULL; + new->edict = EDICT_NONE; + new->hll_file = (file_info_type*)NULL; + new->hll_line = 0; + new_frag(); + } } - +/* + This function returns the next source line from the file supplied, + truncated to size. It appends a fake line to the end of each input + file to make + */ static char * -DEFUN(buffer_line,(file, line, size), - file_info_type *file AND - char *line AND - unsigned int size) + DEFUN(buffer_line,(file, line, size), + file_info_type *file AND + char *line AND + unsigned int size) { - unsigned int count = 0; - int c; - - char *p = line; - if (file->file == (FILE*)NULL) - { - return ""; - } - - c = fgetc(file->file); - size -= 1; /* leave room for null */ - while (c != EOF && c != '\n') - { - if (count < size) - *p++ = c; - count++; - - c= fgetc(file->file); - } - if (c == EOF) - { - rewind(file->file); - file->linenum = 0; - - } - file->linenum++; - *p++ = 0; - return line; + unsigned int count = 0; + int c; + + char *p = line; + + /* If we couldn't open the file, return an empty line */ + if (file->file == (FILE*)NULL) + { + return ""; + } + + if (file->end_pending == 10) { + *p ++ = '\n'; + rewind(file->file); + file->linenum = 0; + file->end_pending = 0; + } + c = fgetc(file->file); + size -= 1; /* leave room for null */ + + while (c != EOF && c != '\n') + { + if (count < size) + *p++ = c; + count++; + + c= fgetc(file->file); + } + if (c == EOF) + { + file->end_pending ++; + *p++ = 'E'; + *p++ = 'O'; + *p++ = 'F'; + } + file->linenum++; + *p++ = 0; + return line; } @@ -352,106 +372,108 @@ static unsigned int on_page; /* number of lines printed on current page */ static void -DEFUN(listing_page,(list), - list_info_type *list) -{ - /* Grope around, see if we can see a title or subtitle edict coming up - soon (we look down 10 lines of the page and see if it's there)*/ - if ((eject || (on_page >= paper_height)) && paper_height != 0) - { - unsigned int c = 10; - int had_title = 0; - int had_subtitle = 0; - - page++; - - while (c != 0 && list) - { - if (list->edict == EDICT_SBTTL && !had_subtitle) - { - had_subtitle = 1; - subtitle = list->edict_arg; - } - if (list->edict == EDICT_TITLE && !had_title) - { - had_title = 1; - title = list->edict_arg; - } - list = list->next; - c--; - } - - - if (page > 1) - { - printf("\f"); - } - - printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); - printf("%s\n", title); - printf("%s\n", subtitle); - on_page = 3; - eject = 0; - } + DEFUN(listing_page,(list), + list_info_type *list) +{ + /* Grope around, see if we can see a title or subtitle edict coming up + soon (we look down 10 lines of the page and see if it's there)*/ + if ((eject || (on_page >= paper_height)) && paper_height != 0) + { + unsigned int c = 10; + int had_title = 0; + int had_subtitle = 0; + + page++; + + while (c != 0 && list) + { + if (list->edict == EDICT_SBTTL && !had_subtitle) + { + had_subtitle = 1; + subtitle = list->edict_arg; + } + if (list->edict == EDICT_TITLE && !had_title) + { + had_title = 1; + title = list->edict_arg; + } + list = list->next; + c--; + } + + + if (page > 1) + { + printf("\f"); + } + + printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); + printf("%s\n", title); + printf("%s\n", subtitle); + on_page = 3; + eject = 0; + } } static unsigned int -DEFUN(calc_hex,(list), - list_info_type *list) + DEFUN(calc_hex,(list), + list_info_type *list) { - list_info_type *first = list; - list_info_type *last = first; - unsigned int address = ~0; - - fragS *frag; - fragS *frag_ptr; - - unsigned int byte_in_frag = 0; - - int anything = 0; - - /* Find first frag which says it belongs to this line */ - frag = list->frag; - while (frag && frag->line != list) - frag = frag->fr_next; - - frag_ptr = frag; - - data_buffer_size = 0; - - /* Dump all the frags which belong to this line */ - while (frag_ptr != (fragS *)NULL && frag_ptr->line == first) - { - /* Print as many bytes from the fixed part as is sensible */ - while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10) - { - if (address == ~0) - { - address = frag_ptr->fr_address; - } - - sprintf(data_buffer + data_buffer_size, "%02X",(frag_ptr->fr_literal[byte_in_frag]) & 0xff); - data_buffer_size += 2; - byte_in_frag++; - } - /* Print as many bytes from the variable part as is sensible */ - while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset - && data_buffer_size < sizeof(data_buffer)-10) - { - if (address == ~0) - { - address = frag_ptr->fr_address; - } - data_buffer[data_buffer_size++] = '*'; - data_buffer[data_buffer_size++] = '*'; - - byte_in_frag++; - } - frag_ptr = frag_ptr->fr_next; - } - data_buffer[data_buffer_size++] = 0; - return address; + list_info_type *first = list; + list_info_type *last = first; + unsigned int address = ~0; + + fragS *frag; + fragS *frag_ptr; + + unsigned int byte_in_frag = 0; + + int anything = 0; + + /* Find first frag which says it belongs to this line */ + frag = list->frag; + while (frag && frag->line != list) + frag = frag->fr_next; + + frag_ptr = frag; + + data_buffer_size = 0; + + /* Dump all the frags which belong to this line */ + while (frag_ptr != (fragS *)NULL && frag_ptr->line == first) + { + /* Print as many bytes from the fixed part as is sensible */ + while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10) + { + if (address == ~0) + { + address = frag_ptr->fr_address; + } + + sprintf(data_buffer + data_buffer_size, + "%02X", + (frag_ptr->fr_literal[byte_in_frag]) & 0xff); + data_buffer_size += 2; + byte_in_frag++; + } + /* Print as many bytes from the variable part as is sensible */ + while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset + && data_buffer_size < sizeof(data_buffer)-10) + { + if (address == ~0) + { + address = frag_ptr->fr_address; + } + data_buffer[data_buffer_size++] = '*'; + data_buffer[data_buffer_size++] = '*'; + + byte_in_frag++; + } + frag_ptr = frag_ptr->fr_next; + } + data_buffer[data_buffer_size++] = 0; + return address; } @@ -460,460 +482,492 @@ DEFUN(calc_hex,(list), static void -DEFUN(print_lines,(list, string, address), -list_info_type *list AND -char *string AND -unsigned int address) -{ - unsigned int idx; - unsigned int nchars; - unsigned int lines; - unsigned int byte_in_word =0; - char *src = data_buffer; - - /* Print the stuff on the first line */ - listing_page(list); - nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ; - /* Print the hex for the first line */ - if (address == ~0) - { - printf("% 4d ", list->line); - for (idx = 0; idx < nchars; idx++) - printf(" "); - - printf("\t%s\n", string ? string : ""); - on_page++; - listing_page(0); - - } - else - { - if (had_errors()) - { - printf("% 4d ???? ", list->line); - } - else - { - printf("% 4d %04x ", list->line, address); - } - - /* And the data to go along with it */ - idx = 0; - - while (*src && idx < nchars) - { - printf("%c%c", src[0], src[1]); - src += 2; - byte_in_word++; - if (byte_in_word == LISTING_WORD_SIZE) - { - printf(" "); - idx++; - byte_in_word = 0; - } - idx+=2; - } - - for (;idx < nchars; idx++) - printf(" "); - - printf("\t%s\n", string ? string : ""); - on_page++; - listing_page(list); - if (list->message) - { - printf("**** %s\n",list->message); - listing_page(list); - on_page++; - } - - for (lines = 0; - lines < LISTING_LHS_CONT_LINES - && *src; - lines++) { - nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1; - idx = 0; - /* Print any more lines of data, but more compactly */ - printf("% 4d ", list->line); - - while (*src && idx < nchars) - { - printf("%c%c", src[0], src[1]); - src+=2; - idx+=2; - byte_in_word++; - if (byte_in_word == LISTING_WORD_SIZE) - { - printf(" "); - idx++; - byte_in_word = 0; - } - } + DEFUN(print_lines,(list, string, address), + list_info_type *list AND + char *string AND + unsigned int address) +{ + unsigned int idx; + unsigned int nchars; + unsigned int lines; + unsigned int byte_in_word =0; + char *src = data_buffer; - printf("\n"); - on_page++; + /* Print the stuff on the first line */ listing_page(list); - - } - - - } + nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ; + /* Print the hex for the first line */ + if (address == ~0) + { + printf("% 4d ", list->line); + for (idx = 0; idx < nchars; idx++) + printf(" "); + + printf("\t%s\n", string ? string : ""); + on_page++; + listing_page(0); + + } + else + { + if (had_errors()) + { + printf("% 4d ???? ", list->line); + } + else + { + printf("% 4d %04x ", list->line, address); + } + + /* And the data to go along with it */ + idx = 0; + + while (*src && idx < nchars) + { + printf("%c%c", src[0], src[1]); + src += 2; + byte_in_word++; + if (byte_in_word == LISTING_WORD_SIZE) + { + printf(" "); + idx++; + byte_in_word = 0; + } + idx+=2; + } + + for (;idx < nchars; idx++) + printf(" "); + + printf("\t%s\n", string ? string : ""); + on_page++; + listing_page(list); + if (list->message) + { + printf("**** %s\n",list->message); + listing_page(list); + on_page++; + } + + for (lines = 0; + lines < LISTING_LHS_CONT_LINES + && *src; + lines++) { + nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1; + idx = 0; + /* Print any more lines of data, but more compactly */ + printf("% 4d ", list->line); + + while (*src && idx < nchars) + { + printf("%c%c", src[0], src[1]); + src+=2; + idx+=2; + byte_in_word++; + if (byte_in_word == LISTING_WORD_SIZE) + { + printf(" "); + idx++; + byte_in_word = 0; + } + } + + printf("\n"); + on_page++; + listing_page(list); + + } + + + } } - - - + + + static void -DEFUN_VOID(list_symbol_table) + DEFUN_VOID(list_symbol_table) { - extern symbolS *symbol_rootP; - - symbolS *ptr ; - eject = 1; - listing_page(0); - printf("DEFINED SYMBOLS\n"); - on_page++; - - for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) - { - if (ptr->sy_frag->line) - { - if (strlen(S_GET_NAME(ptr))) - { - printf("%20s:%-5d %2d:%08x %s \n", - ptr->sy_frag->line->file->filename, - ptr->sy_frag->line->line, - S_GET_SEGMENT(ptr), - S_GET_VALUE(ptr), - S_GET_NAME(ptr)); - + extern symbolS *symbol_rootP; + + symbolS *ptr ; + eject = 1; + listing_page(0); + printf("DEFINED SYMBOLS\n"); + on_page++; + + for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) + { + if (ptr->sy_frag->line) + { + if (strlen(S_GET_NAME(ptr))) + { + printf("%20s:%-5d %2d:%08x %s \n", + ptr->sy_frag->line->file->filename, + ptr->sy_frag->line->line, + S_GET_SEGMENT(ptr), + S_GET_VALUE(ptr), + S_GET_NAME(ptr)); + + on_page++; + listing_page(0); + } + } + + } + printf("\n"); on_page++; listing_page(0); - } - } - - } - printf("\n"); - on_page++; - listing_page(0); - printf("UNDEFINED SYMBOLS\n"); - on_page++; - listing_page(0); - - for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) - { - if (ptr && strlen(S_GET_NAME(ptr)) != 0) - { - if (ptr->sy_frag->line == 0) - { - printf("%s\n", S_GET_NAME(ptr)); + printf("UNDEFINED SYMBOLS\n"); on_page++; listing_page(0); - } - } - } + + for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) + { + if (ptr && strlen(S_GET_NAME(ptr)) != 0) + { + if (ptr->sy_frag->line == 0) + { + printf("%s\n", S_GET_NAME(ptr)); + on_page++; + listing_page(0); + } + } + } } void -DEFUN(print_source,(current_file, list, buffer, width), - file_info_type *current_file AND - list_info_type *list AND - char *buffer AND - unsigned int width) -{ - if (current_file->file) { - while (current_file->linenum < list->hll_line) - { - char* p = buffer_line(current_file, buffer, width); - printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p); - on_page++; - listing_page(list); - } - } + DEFUN(print_source,(current_file, list, buffer, width), + file_info_type *current_file AND + list_info_type *list AND + char *buffer AND + unsigned int width) +{ + if (current_file->file) { + while (current_file->linenum < list->hll_line) + { + char * p = buffer_line(current_file, buffer, width); + printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p); + on_page++; + listing_page(list); + } + } } -void -DEFUN(listing_listing,(name), - char *name) -{ - list_info_type *list = head; - file_info_type *current_hll_file = (file_info_type *)NULL; - - unsigned int page= 1; - unsigned int prev = 0; - char *message; - char *buffer; - char *p; - unsigned int addr = 0; - int on_page = 0; - int show_listing = 1; - unsigned int width; - - buffer = malloc(LISTING_RHS_WIDTH); - eject = 1; - list = head; - - while (list != (list_info_type *)NULL && 0) - { - if (list->next) - list->frag = list->next->frag; - list = list->next; - - } - - list = head->next; - - - while ( list) - { - width = LISTING_RHS_WIDTH > paper_width ? paper_width : - LISTING_RHS_WIDTH; - - switch (list->edict) { - case EDICT_LIST: - show_listing++; - break; - case EDICT_NOLIST: - show_listing--; - break; - case EDICT_EJECT: - break; - case EDICT_NONE: - break; - case EDICT_TITLE: - title = list->edict_arg; - break; - case EDICT_SBTTL: - subtitle = list->edict_arg; - break; - default: - abort(); - } - - if (show_listing > 0) - { - /* Scan down the list and print all the stuff which can be done - with this line (or lines) */ - message = 0; - - if (list->hll_file) - { - current_hll_file = list->hll_file; - } - - if (current_hll_file && list->hll_line && listing & LISTING_HLL) - { - print_source(current_hll_file, list, buffer, width); - } - - p = buffer_line(list->file, buffer, width); +/* Sometimes the user doesn't want to be bothered by the debugging + records inserted by the compiler, see if the line is suspicioous */ - print_lines(list, p, calc_hex(list)); +static int + DEFUN(debugging_pseudo,(line), + char *line) +{ + while (isspace(*line)) + line++; + + if(*line != '.') return 0; + + line++; + + if (strncmp(line, "def",3) == 0) return 1; + if (strncmp(line, "val",3) == 0) return 1; + if (strncmp(line, "scl",3) == 0) return 1; + if (strncmp(line, "line",4) == 0) return 1; + if (strncmp(line, "endef",5) == 0) return 1; + if (strncmp(line, "ln",2) ==0) return 1; + if (strncmp(line, "type",4) ==0) return 1; + if (strncmp(line, "size",4) == 0) return 1; + if (strncmp(line, "dim",3) ==0) return 1; + if (strncmp(line, "tag",3) == 0) return 1; + + return 0; + +} - if (list->edict == EDICT_EJECT) - { +void + DEFUN(listing_listing,(name), + char *name) +{ + list_info_type *list = head; + file_info_type *current_hll_file = (file_info_type *)NULL; + + unsigned int page= 1; + unsigned int prev = 0; + char *message; + char *buffer; + char *p; + unsigned int addr = 0; + int on_page = 0; + int show_listing = 1; + unsigned int width; + + buffer = malloc(LISTING_RHS_WIDTH); eject = 1; - } - } - else - { - - p = buffer_line(list->file, buffer, width); - } - - list = list->next; - } - free(buffer); + list = head; + + while (list != (list_info_type *)NULL && 0) + { + if (list->next) + list->frag = list->next->frag; + list = list->next; + + } + + list = head->next; + + + while ( list) + { + width = LISTING_RHS_WIDTH > paper_width ? paper_width : + LISTING_RHS_WIDTH; + + switch (list->edict) { + case EDICT_LIST: + show_listing++; + break; + case EDICT_NOLIST: + show_listing--; + break; + case EDICT_EJECT: + break; + case EDICT_NONE: + break; + case EDICT_TITLE: + title = list->edict_arg; + break; + case EDICT_SBTTL: + subtitle = list->edict_arg; + break; + default: + abort(); + } + + if (show_listing > 0) + { + /* Scan down the list and print all the stuff which can be done + with this line (or lines) */ + message = 0; + + if (list->hll_file) + { + current_hll_file = list->hll_file; + } + + if (current_hll_file && list->hll_line && listing & LISTING_HLL) + { + print_source(current_hll_file, list, buffer, width); + } + + p = buffer_line(list->file, buffer, width); + + if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p))) + { + print_lines(list, p, calc_hex(list)); + } + + if (list->edict == EDICT_EJECT) + { + eject = 1; + } + } + else + { + + p = buffer_line(list->file, buffer, width); + } + + list = list->next; + } + free(buffer); } void -DEFUN(listing_print,(name), - char *name) + DEFUN(listing_print,(name), + char *name) { - title = ""; - subtitle = ""; - - if (listing & LISTING_NOFORM) - { - paper_height = 0; - } - - if (listing & LISTING_LISTING) - { - listing_listing(name); - - } - if (listing & LISTING_SYMBOLS) - { - list_symbol_table(); - } + title = ""; + subtitle = ""; + + if (listing & LISTING_NOFORM) + { + paper_height = 0; + } + + if (listing & LISTING_LISTING) + { + listing_listing(name); + + } + if (listing & LISTING_SYMBOLS) + { + list_symbol_table(); + } } void -DEFUN(listing_file,(name), -char *name) + DEFUN(listing_file,(name), + char *name) { - fn = name; + fn = name; } void -DEFUN_VOID(listing_eject) + DEFUN_VOID(listing_eject) { - listing_tail->edict = EDICT_EJECT; + listing_tail->edict = EDICT_EJECT; } void -DEFUN_VOID(listing_flags) + DEFUN_VOID(listing_flags) { - + } void -DEFUN(listing_list,(on), - unsigned int on) + DEFUN(listing_list,(on), + unsigned int on) { - listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; + listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; } void -DEFUN_VOID(listing_psize) -{ - paper_height = get_absolute_expression(); - - if (paper_height < 0 || paper_height > 1000) - { - paper_height = 0; - as_warn("strantge paper height, set to no form"); - } - if (*input_line_pointer == ',') - { - input_line_pointer++; - paper_width = get_absolute_expression(); - } + DEFUN_VOID(listing_psize) +{ + paper_height = get_absolute_expression(); + + if (paper_height < 0 || paper_height > 1000) + { + paper_height = 0; + as_warn("strantge paper height, set to no form"); + } + if (*input_line_pointer == ',') + { + input_line_pointer++; + paper_width = get_absolute_expression(); + } } void -DEFUN(listing_title,(depth), - unsigned int depth) + DEFUN(listing_title,(depth), + unsigned int depth) { - char *start; - char *title; - unsigned int length; - - SKIP_WHITESPACE(); - if (*input_line_pointer=='\"') { - input_line_pointer++; - start = input_line_pointer; - - while (*input_line_pointer) - { - if (*input_line_pointer == '\"') - { - length = input_line_pointer - start; - title = malloc(length + 1); - memcpy(title, start, length); - title[length] = 0; - listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; - listing_tail->edict_arg = title; - input_line_pointer++; - demand_empty_rest_of_line(); - return; - } - else if (*input_line_pointer == '\n') - { - as_bad("New line in title"); - demand_empty_rest_of_line(); - return; + char *start; + char *title; + unsigned int length; + + SKIP_WHITESPACE(); + if (*input_line_pointer=='\"') { + input_line_pointer++; + start = input_line_pointer; + + while (*input_line_pointer) + { + if (*input_line_pointer == '\"') + { + length = input_line_pointer - start; + title = malloc(length + 1); + memcpy(title, start, length); + title[length] = 0; + listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; + listing_tail->edict_arg = title; + input_line_pointer++; + demand_empty_rest_of_line(); + return; + } + else if (*input_line_pointer == '\n') + { + as_bad("New line in title"); + demand_empty_rest_of_line(); + return; + } + else + { + input_line_pointer++; + } + } } else - { - input_line_pointer++; - } - } - } - else - { - as_bad("expecting title in quotes"); - } + { + as_bad("expecting title in quotes"); + } } void -DEFUN(listing_source_line,(line), - unsigned int line) + DEFUN(listing_source_line,(line), + unsigned int line) { - new_frag(); - listing_tail->hll_line = line; - new_frag(); - + new_frag(); + listing_tail->hll_line = line; + new_frag(); + } void -DEFUN(listing_source_file,(file), - char *file) + DEFUN(listing_source_file,(file), + char *file) { - listing_tail->hll_file = file_info(file); + listing_tail->hll_file = file_info(file); } - + #else /* Dummy functions for when compiled without listing enabled */ void -DEFUN_VOID(listing_flags) + DEFUN_VOID(listing_flags) { - s_ignore(); + s_ignore(); } void DEFUN_VOID(listing_list) { - s_ignore(); + s_ignore(); } void DEFUN_VOID(listing_eject) { - s_ignore(); + s_ignore(); } void DEFUN(listing_psize) { - s_ignore(); + s_ignore(); } void DEFUN(listing_title, (depth), -unsigned int depth) + unsigned int depth) { - s_ignore(); + s_ignore(); } void -DEFUN(listing_file,(name), -char *name) + DEFUN(listing_file,(name), + char *name) { - + } void DEFUN(listing_newline,(name), -char *name) + char *name) { - + } void DEFUN(listing_source_line,(n), -unsigned int n) + unsigned int n) { - + } void DEFUN(listing_source_file, (n), -char *n) + char *n) { - + } diff --git a/gas/messages.c b/gas/messages.c index 90e1f95..837df93 100644 --- a/gas/messages.c +++ b/gas/messages.c @@ -1,18 +1,18 @@ /* messages.c - error reporter - Copyright (C) 1987, 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) + 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. */ @@ -72,10 +72,10 @@ /* ERRORS - + JF: this is now bogus. We now print more standard error messages that try to look like everyone else's. - + We print the error message 1st, beginning in column 1. All ancillary info starts in column 2 on lines after the key error text. @@ -83,16 +83,16 @@ just after the main error text. Caller then prints any appendices after that, begining all lines with at least 1 space. - + Optionally, we may die. There is no need for a trailing '\n' in your error text format because we supply one. - + as_warn(fmt,args) Like fprintf(stderr,fmt,args) but also call errwhere(). - + as_fatal(fmt,args) Like as_warn() but exit with a fatal status. - - */ + + */ static int warning_count = 0; /* Count of number of warnings issued */ @@ -121,10 +121,10 @@ char *filename; { extern int sys_nerr; extern char *sys_errlist[]; - + as_where(); fprintf(stderr,gripe,filename); - + if (errno > sys_nerr) fprintf(stderr, "Unknown error #%d.\n", errno); else @@ -203,12 +203,18 @@ void as_warn(Format) const char *Format; { va_list args; + char buffer[200]; if(!flagseen['W']) { ++warning_count; as_where(); va_start(args, Format); - vfprintf(stderr, Format, args); + fprintf(stderr,"Warning: "); + vsprintf(buffer, Format, args); + fprintf(stderr, buffer); +#ifndef NO_LISTING + listing_warning(buffer); +#endif va_end(args); (void) putc('\n', stderr); } @@ -220,12 +226,18 @@ char *Format; va_dcl { va_list args; + char buffer[200]; if(!flagseen['W']) { ++warning_count; as_where(); va_start(args); - vfprintf(stderr, Format, args); + fprintf(stderr,"Warning: "); + vsprintf(buffer, Format, args); + fprintf(stderr,buffer); +#ifndef NO_LISTING + listing_warning(buffer); +#endif va_end(args); (void) putc('\n', stderr); } @@ -274,11 +286,18 @@ void as_bad(Format) const char *Format; { va_list args; - + char buffer[200]; + ++error_count; as_where(); va_start(args, Format); - vfprintf(stderr, Format, args); + fprintf(stderr,"Error: "); + + vsprintf(buffer, Format, args); + fprintf(stderr,buffer); +#ifndef NO_LISTING + listing_error(buffer); +#endif va_end(args); (void) putc('\n', stderr); } /* as_bad() */ @@ -289,21 +308,29 @@ char *Format; va_dcl { va_list args; - + char buffer[200]; + ++error_count; as_where(); va_start(args); - vfprintf(stderr, Format, args); + vsprintf(buffer, Format, args); + fprintf(stderr,buffer); +#ifndef NO_LISTING + listing_error(buffer); +#endif + va_end(args); (void) putc('\n', stderr); -} /* as_bad() */ +} /* as_bad() */ #else /*VARARGS1 */ as_bad(Format,args) char *Format; { ++error_count; + as_where(); + fprintf(stderr,"Error: "); _doprnt (Format, &args, stderr); (void)putc ('\n', stderr); /* as_where(); */ @@ -336,14 +363,14 @@ void as_fatal(Format) const char *Format; { va_list args; - + as_where(); va_start(args, Format); fprintf (stderr, "FATAL:"); vfprintf(stderr, Format, args); (void) putc('\n', stderr); va_end(args); - exit(42); + exit(33); } /* as_fatal() */ #else #ifndef NO_VARARGS @@ -352,14 +379,14 @@ char *Format; va_dcl { va_list args; - + as_where(); va_start(args); fprintf (stderr, "FATAL:"); vfprintf(stderr, Format, args); (void) putc('\n', stderr); va_end(args); - exit(42); + exit(33); } /* as_fatal() */ #else /*VARARGS1 */ @@ -371,7 +398,7 @@ char *Format; _doprnt (Format, &args, stderr); (void)putc ('\n', stderr); /* as_where(); */ - exit(42); /* What is a good exit status? */ + exit(33); /* What is a good exit status? */ } /* as_fatal() */ #endif /* not NO_VARARGS */ #endif /* not NO_STDARG */ @@ -384,7 +411,7 @@ char *Format; fprintf (stderr, "FATAL:"); fprintf(stderr, Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an); (void) putc('\n', stderr); - exit(42); + exit(33); } /* as_fatal() */ #endif @@ -1,25 +1,23 @@ /* obj.h - defines the object dependent hooks for all object format backends. - + Copyright (C) 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. */ #ifdef __STDC__ @@ -30,7 +28,11 @@ void obj_emit_strings(char **where); void obj_emit_symbols(char **where, symbolS *symbol_rootP); void obj_header_append(char **where, object_headers *headers); void obj_read_begin_hook(void); + +#ifndef obj_symbol_new_hook void obj_symbol_new_hook(symbolS *symbolP); +#endif /* obj_symbol_new_hook */ + void obj_symbol_to_chars(char **where, symbolS *symbolP); #ifndef obj_pre_write_hook @@ -46,7 +48,11 @@ void obj_emit_strings(); void obj_emit_symbols(); void obj_header_append(); void obj_read_begin_hook(); + +#ifndef obj_symbol_new_hook void obj_symbol_new_hook(); +#endif /* obj_symbol_new_hook */ + void obj_symbol_to_chars(); #ifndef obj_pre_write_hook diff --git a/gas/output-file.c b/gas/output-file.c index 423bab2..940a0c1 100644 --- a/gas/output-file.c +++ b/gas/output-file.c @@ -1,23 +1,21 @@ /* output-file.c - Deal with the output file Copyright (C) 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. */ /* * Confines all details of emitting object bytes to this module. @@ -26,7 +24,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * Note we don't need to #include the "as.h" file. No common coupling! */ - /* note that we do need config info. xoxorich. */ +/* note that we do need config info. xoxorich. */ /* #include "style.h" */ #include <stdio.h> @@ -34,19 +32,59 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "as.h" #include "output-file.h" +#ifdef BFD_HEADERS +#include "bfd.h" +bfd *stdoutput; +void output_file_create(name) +char *name; +{ + if(name[0]=='-' && name[1]=='\0') { + as_perror("FATAL: Can't open a bfd on stdout %s ", name); + } + else if ( ! (stdoutput = bfd_openw( name, TARGET_FORMAT )) ) + { + as_perror ("FATAL: Can't create %s", name); + exit(42); + } + bfd_set_format(stdoutput, bfd_object); +} +/* output_file_create() */ + + +void output_file_close(filename) +char *filename; +{ + /* Close the bfd without getting bfd to write out anything by itself */ + if ( bfd_close_all_done( stdoutput ) == 0 ) + { + as_perror ("FATAL: Can't close %s\n", filename); + exit(42); + } + stdoutput = NULL; /* Trust nobody! */ +} /* output_file_close() */ + +void output_file_append(where, length, filename) +char *where; +long length; +char *filename; +{ + abort(); /* Never do this */ +} + +#else static FILE *stdoutput; void output_file_create(name) char *name; { - if(name[0]=='-' && name[1]=='\0') - stdoutput=stdout; - else if ( ! (stdoutput = fopen( name, "w" )) ) - { - as_perror ("FATAL: Can't create %s", name); - exit(42); - } + if(name[0]=='-' && name[1]=='\0') + stdoutput=stdout; + else if ( ! (stdoutput = fopen( name, "w" )) ) + { + as_perror ("FATAL: Can't create %s", name); + exit(42); + } } /* output_file_create() */ @@ -54,12 +92,12 @@ char *name; void output_file_close(filename) char *filename; { - if ( EOF == fclose( stdoutput ) ) - { - as_perror ("FATAL: Can't close %s", filename); - exit(42); - } - stdoutput = NULL; /* Trust nobody! */ + if ( EOF == fclose( stdoutput ) ) + { + as_perror ("FATAL: Can't close %s", filename); + exit(42); + } + stdoutput = NULL; /* Trust nobody! */ } /* output_file_close() */ void output_file_append(where, length, filename) @@ -67,17 +105,18 @@ char *where; long length; char *filename; { - - for (; length; length--,where++) - { - (void)putc(*where,stdoutput); - if(ferror(stdoutput)) - /* if ( EOF == (putc( *where, stdoutput )) ) */ - { - as_perror("Failed to emit an object byte", filename); - as_fatal("Can't continue"); - } - } + + for (; length; length--,where++) + { + (void)putc(*where,stdoutput); + if(ferror(stdoutput)) + /* if ( EOF == (putc( *where, stdoutput )) ) */ + { + as_perror("Failed to emit an object byte", filename); + as_fatal("Can't continue"); + } + } } /* output_file_append() */ /* end: output-file.c */ +#endif @@ -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() */ @@ -1,31 +1,31 @@ /* read.h - of read.c Copyright (C) 1986, 1990 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. */ + + 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. */ /* $Id$ */ extern char *input_line_pointer; /* -> char we are parsing now. */ #define PERMIT_WHITESPACE /* Define to make whitespace be allowed in */ - /* many syntactically unnecessary places. */ - /* Normally undefined. For compatibility */ - /* with ancient GNU cc. */ -#undef PERMIT_WHITESPACE +/* many syntactically unnecessary places. */ +/* Normally undefined. For compatibility */ +/* with ancient GNU cc. */ +/* #undef PERMIT_WHITESPACE */ #ifdef PERMIT_WHITESPACE #define SKIP_WHITESPACE() {if (* input_line_pointer == ' ') ++ input_line_pointer;} @@ -36,7 +36,7 @@ extern char *input_line_pointer; /* -> char we are parsing now. */ #define LEX_NAME (1) /* may continue a name */ #define LEX_BEGIN_NAME (2) /* may begin a name */ - + #define is_name_beginner(c) ( lex_type[c] & LEX_BEGIN_NAME ) #define is_part_of_name(c) ( lex_type[c] & LEX_NAME ) diff --git a/gas/strstr.c b/gas/strstr.c index 1415c22..cab18fc 100644 --- a/gas/strstr.c +++ b/gas/strstr.c @@ -1,23 +1,23 @@ /* strstr - find first occurrence of wanted in s Copyright (C) 1989, 1990, 1991 Free Software Foundation. - -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. */ - - /* If your compiler is really ansi, then you don't need this. */ + + 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. */ + +/* If your compiler is really ansi, then you don't need this. */ #ifndef __STDC__ #define SIZET int @@ -27,14 +27,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <string.h> char * /* found string, or NULL if none */ -strstr(s, wanted) + strstr(s, wanted) char *s; char *wanted; { register char *scan; register SIZET len; register char firstc; - + /* * The odd placement of the two tests is so "" is findable. * Also, we inline the first char for speed. @@ -43,8 +43,8 @@ char *wanted; firstc = *wanted; len = strlen(wanted); for (scan = s; *scan != firstc || strncmp(scan, wanted, len) != 0; ) - if (*scan++ == '\0') - return(NULL); + if (*scan++ == '\0') + return(NULL); return(scan); } /* strstr() */ diff --git a/gas/struc-symbol.h b/gas/struc-symbol.h index 2827648..b47b03b 100644 --- a/gas/struc-symbol.h +++ b/gas/struc-symbol.h @@ -1,39 +1,39 @@ /* struct_symbol.h - Internal symbol structure Copyright (C) 1987 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. */ + + 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. + + oYou 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. */ struct symbol /* our version of an nlist node */ { - obj_symbol_type sy_symbol; /* what we write in .o file (if permitted) */ - unsigned long sy_name_offset; /* 4-origin position of sy_name in symbols */ - /* part of object file. */ - /* 0 for (nameless) .stabd symbols. */ - /* Not used until write_object_file() time. */ - long sy_number; /* 24 bit symbol number. */ - /* Symbol numbers start at 0 and are */ - /* unsigned. */ - struct symbol *sy_next; /* forward chain, or NULL */ + obj_symbol_type sy_symbol; /* what we write in .o file (if permitted) */ + unsigned long sy_name_offset; /* 4-origin position of sy_name in symbols */ + /* part of object file. */ + /* 0 for (nameless) .stabd symbols. */ + /* Not used until write_object_file() time. */ + long sy_number; /* 24 bit symbol number. */ + /* Symbol numbers start at 0 and are */ + /* unsigned. */ + struct symbol *sy_next; /* forward chain, or NULL */ #ifdef SYMBOLS_NEED_BACKPOINTERS - struct symbol *sy_previous; /* backward chain, or NULL */ + struct symbol *sy_previous; /* backward chain, or NULL */ #endif /* SYMBOLS_NEED_BACKPOINTERS */ - struct frag *sy_frag; /* NULL or -> frag this symbol attaches to. */ - struct symbol *sy_forward; /* value is really that of this other symbol */ -/* We will probably want to add a sy_segment here soon. */ + struct frag *sy_frag; /* NULL or -> frag this symbol attaches to. */ + struct symbol *sy_forward; /* value is really that of this other symbol */ + /* We will probably want to add a sy_segment here soon. */ }; typedef struct symbol symbolS; @@ -50,8 +50,8 @@ struct broken_word { symbolS *sub; /* - symbol_y */ long addnum; /* + addnum */ int added; /* nasty thing happend yet? */ - /* 1: added and has a long-jump */ - /* 2: added but uses someone elses long-jump */ + /* 1: added and has a long-jump */ + /* 2: added but uses someone elses long-jump */ struct broken_word *use_jump; /* points to broken_word with a similar long-jump */ }; diff --git a/gas/subsegs.c b/gas/subsegs.c index 00937ea..e872a83 100644 --- a/gas/subsegs.c +++ b/gas/subsegs.c @@ -1,23 +1,21 @@ /* subsegs.c - subsegments - Copyright (C) 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. */ /* * Segments & sub-segments. @@ -28,65 +26,90 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "subsegs.h" #include "obstack.h" +#ifdef MANY_SEGMENTS +segment_info_type segment_info[SEG_MAXIMUM_ORDINAL]; + frchainS* frchain_root, - * frchain_now, /* Commented in "subsegs.h". */ - * data0_frchainP; + * frchain_now; +#else +frchainS* frchain_root, + * frchain_now, /* Commented in "subsegs.h". */ + * data0_frchainP; +#endif char * const /* in: segT out: char* */ -seg_name[] = { - "absolute", - "text", - "data", - "bss", - "unknown", - "absent", - "pass1", - "ASSEMBLER-INTERNAL-LOGIC-ERROR!", - "bignum/flonum", - "difference", - "debug", - "transfert vector preload", - "transfert vector postload", - "register", - "", -}; /* Used by error reporters, dumpers etc. */ + seg_name[] = { + "absolute", +#ifdef MANY_SEGMENTS + "e0","e1","e2","e3","e4","e5","e6","e7","e8","e9", +#else + "text", + "data", + "bss", +#endif + "unknown", + "absent", + "pass1", + "ASSEMBLER-INTERNAL-LOGIC-ERROR!", + "bignum/flonum", + "difference", + "debug", + "transfert vector preload", + "transfert vector postload", + "register", + "", + }; /* Used by error reporters, dumpers etc. */ void -subsegs_begin() + subsegs_begin() { - /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */ - know( SEG_ABSOLUTE == 0 ); - know( SEG_TEXT == 1 ); - know( SEG_DATA == 2 ); - know( SEG_BSS == 3 ); - know( SEG_UNKNOWN == 4 ); - know( SEG_ABSENT == 5 ); - know( SEG_PASS1 == 6 ); - know( SEG_GOOF == 7 ); - know( SEG_BIG == 8 ); - know( SEG_DIFFERENCE == 9 ); - know( SEG_DEBUG == 10 ); - know( SEG_NTV == 11 ); - know( SEG_PTV == 12 ); - know( SEG_REGISTER == 13 ); - know( SEG_MAXIMUM_ORDINAL == SEG_REGISTER ); - know( segment_name (SEG_MAXIMUM_ORDINAL + 1) [0] == 0 ); - - obstack_begin( &frags, 5000); - frchain_root = NULL; - frchain_now = NULL; /* Warn new_subseg() that we are booting. */ - /* Fake up 1st frag. */ - /* It won't be used=> is ok if obstack... */ - /* pads the end of it for alignment. */ - frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); - /* obstack_1blank( &frags, SIZEOF_STRUCT_FRAG, & frag_now ); */ - /* This 1st frag will not be in any frchain. */ - /* We simply give subseg_new somewhere to scribble. */ - now_subseg = 42; /* Lie for 1st call to subseg_new. */ - subseg_new (SEG_DATA, 0); /* .data 0 */ - data0_frchainP = frchain_now; + /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */ +#ifdef MANY_SEGMENTS +#else + know( SEG_ABSOLUTE == 0 ); + know( SEG_TEXT == 1 ); + know( SEG_DATA == 2 ); + know( SEG_BSS == 3 ); + know( SEG_UNKNOWN == 4 ); + know( SEG_ABSENT == 5 ); + know( SEG_PASS1 == 6 ); + know( SEG_GOOF == 7 ); + know( SEG_BIG == 8 ); + know( SEG_DIFFERENCE == 9 ); + know( SEG_DEBUG == 10 ); + know( SEG_NTV == 11 ); + know( SEG_PTV == 12 ); + know( SEG_REGISTER == 13 ); + know( SEG_MAXIMUM_ORDINAL == SEG_REGISTER ); + /* know( segment_name (SEG_MAXIMUM_ORDINAL + 1) [0] == 0 );*/ +#endif + + obstack_begin( &frags, 5000); + frchain_root = NULL; + frchain_now = NULL; /* Warn new_subseg() that we are booting. */ + /* Fake up 1st frag. */ + /* It won't be used=> is ok if obstack... */ + /* pads the end of it for alignment. */ + frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); + memset(frag_now, SIZEOF_STRUCT_FRAG, 0); + /* This 1st frag will not be in any frchain. */ + /* We simply give subseg_new somewhere to scribble. */ + now_subseg = 42; /* Lie for 1st call to subseg_new. */ +#ifdef MANY_SEGMENTS + { + int i; + for (i = SEG_E0; i < SEG_UNKNOWN; i++) { + subseg_new(i, 0); + segment_info[i].frchainP = frchain_now; + } + } +#else + subseg_new (SEG_DATA, 0); /* .data 0 */ + data0_frchainP = frchain_now; +#endif + } /* @@ -100,23 +123,28 @@ subsegs_begin() * segment context correct. */ void -subseg_change (seg, subseg) - register segT seg; - register int subseg; + subseg_change (seg, subseg) +register segT seg; +register int subseg; { - now_seg = seg; - now_subseg = subseg; - if (seg == SEG_DATA) - { - seg_fix_rootP = & data_fix_root; - seg_fix_tailP = & data_fix_tail; - } - else - { - know (seg == SEG_TEXT); - seg_fix_rootP = & text_fix_root; - seg_fix_tailP = & text_fix_tail; - } + now_seg = seg; + now_subseg = subseg; +#ifdef MANY_SEGMENTS + seg_fix_rootP = & segment_info[seg].fix_root; + seg_fix_tailP = & segment_info[seg].fix_tail; +#else + if (seg == SEG_DATA) + { + seg_fix_rootP = & data_fix_root; + seg_fix_tailP = & data_fix_tail; + } + else + { + know (seg == SEG_TEXT); + seg_fix_rootP = & text_fix_root; + seg_fix_tailP = & text_fix_tail; + } +#endif } /* @@ -136,137 +164,137 @@ subseg_change (seg, subseg) */ void -subseg_new (seg, subseg) /* begin assembly for a new sub-segment */ - register segT seg; /* SEG_DATA or SEG_TEXT */ - register subsegT subseg; + subseg_new (seg, subseg) /* begin assembly for a new sub-segment */ +register segT seg; /* SEG_DATA or SEG_TEXT */ +register subsegT subseg; { - long tmp; /* JF for obstack alignment hacking */ - - know( seg == SEG_DATA || seg == SEG_TEXT ); - - if (seg != now_seg || subseg != now_subseg) - { /* we just changed sub-segments */ - register frchainS * frcP; /* crawl frchain chain */ - register frchainS** lastPP; /* address of last pointer */ - frchainS * newP; /* address of new frchain */ - register fragS * former_last_fragP; - register fragS * new_fragP; - - if (frag_now) /* If not bootstrapping. */ - { - frag_now -> fr_fix = obstack_next_free(& frags) - frag_now -> fr_literal; - frag_wane(frag_now); /* Close off any frag in old subseg. */ - } -/* - * It would be nice to keep an obstack for each subsegment, if we swap - * subsegments a lot. Hence we would have much fewer frag_wanes(). - */ - { - - obstack_finish( &frags); - /* - * If we don't do the above, the next object we put on obstack frags - * will appear to start at the fr_literal of the current frag. - * Also, above ensures that the next object will begin on a - * address that is aligned correctly for the engine that runs - * this program. - */ - } - subseg_change (seg, (int)subseg); - /* - * Attempt to find or make a frchain for that sub seg. - * Crawl along chain of frchainSs, begins @ frchain_root. - * If we need to make a frchainS, link it into correct - * position of chain rooted in frchain_root. - */ - for (frcP = * (lastPP = & frchain_root); - frcP - && (int)(frcP -> frch_seg) <= (int)seg; - frcP = * ( lastPP = & frcP -> frch_next) - ) - { - if ( (int)(frcP -> frch_seg) == (int)seg - && frcP -> frch_subseg >= subseg) - { - break; - } - } - /* - * frcP: Address of the 1st frchainS in correct segment with - * frch_subseg >= subseg. - * We want to either use this frchainS, or we want - * to insert a new frchainS just before it. - * - * If frcP==NULL, then we are at the end of the chain - * of frchainS-s. A NULL frcP means we fell off the end - * of the chain looking for a - * frch_subseg >= subseg, so we - * must make a new frchainS. - * - * If we ever maintain a pointer to - * the last frchainS in the chain, we change that pointer - * ONLY when frcP==NULL. - * - * lastPP: Address of the pointer with value frcP; - * Never NULL. - * May point to frchain_root. - * - */ - if ( ! frcP - || ( (int)(frcP -> frch_seg) > (int)seg - || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */ - { - /* - * This should be the only code that creates a frchainS. - */ - newP=(frchainS *)obstack_alloc(&frags,sizeof(frchainS)); - /* obstack_1blank( &frags, sizeof(frchainS), &newP); */ + long tmp; /* JF for obstack alignment hacking */ +#ifndef MANY_SEGMENTS + know( seg == SEG_DATA || seg == SEG_TEXT ); +#endif + if (seg != now_seg || subseg != now_subseg) + { /* we just changed sub-segments */ + register frchainS * frcP; /* crawl frchain chain */ + register frchainS** lastPP; /* address of last pointer */ + frchainS * newP; /* address of new frchain */ + register fragS * former_last_fragP; + register fragS * new_fragP; + + if (frag_now) /* If not bootstrapping. */ + { + frag_now -> fr_fix = obstack_next_free(& frags) - frag_now -> fr_literal; + frag_wane(frag_now); /* Close off any frag in old subseg. */ + } + /* + * It would be nice to keep an obstack for each subsegment, if we swap + * subsegments a lot. Hence we would have much fewer frag_wanes(). + */ + { + + obstack_finish( &frags); + /* + * If we don't do the above, the next object we put on obstack frags + * will appear to start at the fr_literal of the current frag. + * Also, above ensures that the next object will begin on a + * address that is aligned correctly for the engine that runs + * this program. + */ + } + subseg_change (seg, (int)subseg); + /* + * Attempt to find or make a frchain for that sub seg. + * Crawl along chain of frchainSs, begins @ frchain_root. + * If we need to make a frchainS, link it into correct + * position of chain rooted in frchain_root. + */ + for (frcP = * (lastPP = & frchain_root); + frcP + && (int)(frcP -> frch_seg) <= (int)seg; + frcP = * ( lastPP = & frcP -> frch_next) + ) + { + if ( (int)(frcP -> frch_seg) == (int)seg + && frcP -> frch_subseg >= subseg) + { + break; + } + } + /* + * frcP: Address of the 1st frchainS in correct segment with + * frch_subseg >= subseg. + * We want to either use this frchainS, or we want + * to insert a new frchainS just before it. + * + * If frcP==NULL, then we are at the end of the chain + * of frchainS-s. A NULL frcP means we fell off the end + * of the chain looking for a + * frch_subseg >= subseg, so we + * must make a new frchainS. + * + * If we ever maintain a pointer to + * the last frchainS in the chain, we change that pointer + * ONLY when frcP==NULL. + * + * lastPP: Address of the pointer with value frcP; + * Never NULL. + * May point to frchain_root. + * + */ + if ( ! frcP + || ( (int)(frcP -> frch_seg) > (int)seg + || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */ + { + /* + * This should be the only code that creates a frchainS. + */ + newP=(frchainS *)obstack_alloc(&frags,sizeof(frchainS)); + memset(newP, sizeof(frchainS), 0); /* This begines on a good boundary */ /* because a obstack_done() preceeded it. */ /* It implies an obstack_done(), so we */ /* expect the next object allocated to */ /* begin on a correct boundary. */ - *lastPP = newP; - newP -> frch_next = frcP; /* perhaps NULL */ - (frcP = newP) -> frch_subseg = subseg; - newP -> frch_seg = seg; - newP -> frch_last = NULL; - } - /* - * Here with frcP ->ing to the frchainS for subseg. - */ - frchain_now = frcP; - /* - * Make a fresh frag for the subsegment. - */ - /* We expect this to happen on a correct */ - /* boundary since it was proceeded by a */ - /* obstack_done(). */ - tmp=obstack_alignment_mask(&frags); /* JF disable alignment */ - obstack_alignment_mask(&frags)=0; - frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); - obstack_alignment_mask(&frags)=tmp; - /* know( frags . obstack_c_next_free == frag_now -> fr_literal ); */ - /* But we want any more chars to come */ - /* immediately after the structure we just made. */ - new_fragP = frag_now; - new_fragP -> fr_next = NULL; - /* - * Append new frag to current frchain. - */ - former_last_fragP = frcP -> frch_last; - if (former_last_fragP) - { - know( former_last_fragP -> fr_next == NULL ); - know( frchain_now -> frch_root ); - former_last_fragP -> fr_next = new_fragP; - } - else - { - frcP -> frch_root = new_fragP; - } - frcP -> frch_last = new_fragP; - } /* if (changing subsegments) */ + *lastPP = newP; + newP -> frch_next = frcP; /* perhaps NULL */ + (frcP = newP) -> frch_subseg = subseg; + newP -> frch_seg = seg; + newP -> frch_last = NULL; + } + /* + * Here with frcP ->ing to the frchainS for subseg. + */ + frchain_now = frcP; + /* + * Make a fresh frag for the subsegment. + */ + /* We expect this to happen on a correct */ + /* boundary since it was proceeded by a */ + /* obstack_done(). */ + tmp=obstack_alignment_mask(&frags); /* JF disable alignment */ + obstack_alignment_mask(&frags)=0; + frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); + obstack_alignment_mask(&frags)=tmp; + /* know( frags . obstack_c_next_free == frag_now -> fr_literal ); */ + /* But we want any more chars to come */ + /* immediately after the structure we just made. */ + new_fragP = frag_now; + new_fragP -> fr_next = NULL; + /* + * Append new frag to current frchain. + */ + former_last_fragP = frcP -> frch_last; + if (former_last_fragP) + { + know( former_last_fragP -> fr_next == NULL ); + know( frchain_now -> frch_root ); + former_last_fragP -> fr_next = new_fragP; + } + else + { + frcP -> frch_root = new_fragP; + } + frcP -> frch_last = new_fragP; + } /* if (changing subsegments) */ } /* subseg_new() */ /* diff --git a/gas/subsegs.h b/gas/subsegs.h index fa0f499..27201d6 100644 --- a/gas/subsegs.h +++ b/gas/subsegs.h @@ -1,21 +1,21 @@ /* subsegs.h -> subsegs.c Copyright (C) 1987 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. */ /* * For every sub-segment the user mentions in the ASsembler program, @@ -38,49 +38,49 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ struct frchain /* control building of a frag chain */ { /* FRCH = FRagment CHain control */ - struct frag * frch_root; /* 1st struct frag in chain, or NULL */ - struct frag * frch_last; /* last struct frag in chain, or NULL */ - struct frchain * frch_next; /* next in chain of struct frchain-s */ - segT frch_seg; /* SEG_TEXT or SEG_DATA. */ - subsegT frch_subseg; /* subsegment number of this chain */ + struct frag * frch_root; /* 1st struct frag in chain, or NULL */ + struct frag * frch_last; /* last struct frag in chain, or NULL */ + struct frchain * frch_next; /* next in chain of struct frchain-s */ + segT frch_seg; /* SEG_TEXT or SEG_DATA. */ + subsegT frch_subseg; /* subsegment number of this chain */ }; typedef struct frchain frchainS; extern frchainS * frchain_root; /* NULL means no frchains yet. */ - /* all subsegments' chains hang off here */ +/* all subsegments' chains hang off here */ extern frchainS * frchain_now; - /* Frchain we are assembling into now */ - /* That is, the current segment's frag */ - /* chain, even if it contains no (complete) */ - /* frags. */ +/* Frchain we are assembling into now */ +/* That is, the current segment's frag */ +/* chain, even if it contains no (complete) */ +/* frags. */ #ifdef MANY_SEGMENTS typedef struct { - frchainS *frchainP; - int hadone; - int user_stuff; - struct frag *frag_root; - struct frag *last_frag; - fixS *fix_root; - fixS *fix_tail; - struct internal_scnhdr scnhdr; - symbolS *dot; - - struct lineno_list *lineno_list_head; - struct lineno_list *lineno_list_tail; - + frchainS *frchainP; + int hadone; + int user_stuff; + /* struct frag *frag_root;*/ + /* struct frag *last_frag;*/ + fixS *fix_root; + fixS *fix_tail; + struct internal_scnhdr scnhdr; + symbolS *dot; + + struct lineno_list *lineno_list_head; + struct lineno_list *lineno_list_tail; + } segment_info_type; segment_info_type segment_info[]; #else extern frchainS * data0_frchainP; - /* Sentinel for frchain crawling. */ - /* Points to the 1st data-segment frchain. */ - /* (Which is pointed to by the last text- */ - /* segment frchain.) */ +/* Sentinel for frchain crawling. */ +/* Points to the 1st data-segment frchain. */ +/* (Which is pointed to by the last text- */ +/* segment frchain.) */ #endif diff --git a/gas/symbols.c b/gas/symbols.c index 2ac48c1..a8f99b3 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1,23 +1,21 @@ /* symbols.c -symbol table- Copyright (C) 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 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. */ - -/* 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. */ #include "as.h" @@ -32,10 +30,10 @@ extern char const_flag; #endif static -struct hash_control * -sy_hash; /* symbol-name => struct symbol pointer */ + struct hash_control * + sy_hash; /* symbol-name => struct symbol pointer */ - /* Below are commented in "symbols.h". */ +/* Below are commented in "symbols.h". */ unsigned int local_bss_counter; symbolS * symbol_rootP; symbolS * symbol_lastP; @@ -67,13 +65,13 @@ struct obstack notes; */ typedef short unsigned int -local_label_countT; + local_label_countT; static local_label_countT -local_label_counter[10]; + local_label_counter[10]; static /* Returned to caller, then copied. */ - char symbol_name_build[12]; /* used for created names ("4f") */ + char symbol_name_build[12]; /* used for created names ("4f") */ #ifdef LOCAL_LABELS_DOLLAR int local_label_defined[10]; @@ -81,15 +79,15 @@ int local_label_defined[10]; void -symbol_begin() + symbol_begin() { - symbol_lastP = NULL; - symbol_rootP = NULL; /* In case we have 0 symbols (!!) */ - sy_hash = hash_new(); - bzero ((char *)(& abs_symbol), sizeof(abs_symbol)); - S_SET_SEGMENT(&abs_symbol, SEG_ABSOLUTE); /* Can't initialise a union. Sigh. */ - bzero ((char *)(local_label_counter), sizeof(local_label_counter) ); - local_bss_counter = 0; + symbol_lastP = NULL; + symbol_rootP = NULL; /* In case we have 0 symbols (!!) */ + sy_hash = hash_new(); + bzero ((char *)(& abs_symbol), sizeof(abs_symbol)); + S_SET_SEGMENT(&abs_symbol, SEG_ABSOLUTE); /* Can't initialise a union. Sigh. */ + bzero ((char *)(local_label_counter), sizeof(local_label_counter) ); + local_bss_counter = 0; } /* @@ -99,49 +97,49 @@ symbol_begin() */ char * /* Return local label name. */ -local_label_name(n, augend) - register int n; /* we just saw "n:", "nf" or "nb" : n a digit */ - register int augend; /* 0 for nb, 1 for n:, nf */ + local_label_name(n, augend) +register int n; /* we just saw "n:", "nf" or "nb" : n a digit */ +register int augend; /* 0 for nb, 1 for n:, nf */ { - register char * p; - register char * q; - char symbol_name_temporary[10]; /* build up a number, BACKWARDS */ - - know( n >= 0 ); - know( augend == 0 || augend == 1 ); - p = symbol_name_build; - * p ++ = 'L'; - * p ++ = n + '0'; /* Make into ASCII */ - * p ++ = 1; /* ^A */ - n = local_label_counter [ n ] + augend; - /* version number of this local label */ - /* - * Next code just does sprintf( {}, "%d", n); - * It is more elegant to do the next part recursively, but a procedure - * call for each digit emitted is considered too costly. - */ - q = symbol_name_temporary; - for (*q++=0; n; q++) /* emits NOTHING if n starts as 0 */ - { - know(n>0); /* We expect n > 0 always */ - *q = n % 10 + '0'; - n /= 10; - } - while (( * p ++ = * -- q ) != '\0') ;; - - /* The label, as a '\0' ended string, starts at symbol_name_build. */ - return(symbol_name_build); + register char * p; + register char * q; + char symbol_name_temporary[10]; /* build up a number, BACKWARDS */ + + know( n >= 0 ); + know( augend == 0 || augend == 1 ); + p = symbol_name_build; + * p ++ = 'L'; + * p ++ = n + '0'; /* Make into ASCII */ + * p ++ = 1; /* ^A */ + n = local_label_counter [ n ] + augend; + /* version number of this local label */ + /* + * Next code just does sprintf( {}, "%d", n); + * It is more elegant to do the next part recursively, but a procedure + * call for each digit emitted is considered too costly. + */ + q = symbol_name_temporary; + for (*q++=0; n; q++) /* emits NOTHING if n starts as 0 */ + { + know(n>0); /* We expect n > 0 always */ + *q = n % 10 + '0'; + n /= 10; + } + while (( * p ++ = * -- q ) != '\0') ;; + + /* The label, as a '\0' ended string, starts at symbol_name_build. */ + return(symbol_name_build); } /* local_label_name() */ void local_colon (n) int n; /* just saw "n:" */ { - local_label_counter [n] ++; + local_label_counter [n] ++; #ifdef LOCAL_LABELS_DOLLAR - local_label_defined[n]=1; + local_label_defined[n]=1; #endif - colon (local_label_name (n, 0)); + colon (local_label_name (n, 0)); } /* @@ -175,39 +173,39 @@ fragS *frag; /* Associated fragment */ obstack_grow(¬es, name, name_length); preserved_copy_of_name = obstack_finish(¬es); symbolP = (symbolS *)obstack_alloc(¬es, sizeof(symbolS)); - - /* symbol must be born in some fixed state. This seems as good as any. */ + + /* symbol must be born in some fixed state. This seems as good as any. */ memset(symbolP, 0, sizeof(symbolS)); - + #ifdef STRIP_UNDERSCORE S_SET_NAME(symbolP, (*preserved_copy_of_name == '_' - ? preserved_copy_of_name + 1 - : preserved_copy_of_name)); + ? preserved_copy_of_name + 1 + : preserved_copy_of_name)); #else /* STRIP_UNDERSCORE */ S_SET_NAME(symbolP, preserved_copy_of_name); #endif /* STRIP_UNDERSCORE */ - + S_SET_SEGMENT(symbolP, segment); S_SET_VALUE(symbolP, value); -/* symbol_clear_list_pointers(symbolP); uneeded if symbol is born zeroed. */ - + /* symbol_clear_list_pointers(symbolP); uneeded if symbol is born zeroed. */ + symbolP->sy_frag = frag; /* krm: uneeded if symbol is born zeroed. symbolP->sy_forward = NULL; */ /* JF */ symbolP->sy_number = ~0; symbolP->sy_name_offset = ~0; - + /* * Link to end of symbol chain. */ symbol_append(symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP); - + obj_symbol_new_hook(symbolP); #ifdef DEBUG -/* verify_symbol_chain(symbol_rootP, symbol_lastP); */ + /* verify_symbol_chain(symbol_rootP, symbol_lastP); */ #endif /* DEBUG */ - + return(symbolP); } /* symbol_new() */ @@ -222,173 +220,173 @@ fragS *frag; /* Associated fragment */ * */ void colon(sym_name) /* just seen "x:" - rattle symbols & frags */ - register char * sym_name; /* symbol name, as a cannonical string */ - /* We copy this string: OK to alter later. */ +register char * sym_name; /* symbol name, as a cannonical string */ +/* We copy this string: OK to alter later. */ { - register symbolS * symbolP; /* symbol we are working with */ - + register symbolS * symbolP; /* symbol we are working with */ + #ifdef LOCAL_LABELS_DOLLAR - /* Sun local labels go out of scope whenever a non-local symbol is defined. */ - - if(*sym_name !='L') - bzero((void *) local_label_defined, sizeof(local_label_defined)); + /* Sun local labels go out of scope whenever a non-local symbol is defined. */ + + if(*sym_name !='L') + bzero((void *) local_label_defined, sizeof(local_label_defined)); #endif - + #ifndef WORKING_DOT_WORD - if(new_broken_words) { - struct broken_word *a; - int possible_bytes; - fragS *frag_tmp; - char *frag_opcode; - - extern md_short_jump_size; - extern md_long_jump_size; - possible_bytes=md_short_jump_size + new_broken_words * md_long_jump_size; - - frag_tmp=frag_now; - frag_opcode=frag_var(rs_broken_word, - possible_bytes, - possible_bytes, - (relax_substateT) 0, - (symbolS *) broken_words, - 0L, - NULL); - - /* We want to store the pointer to where to insert the jump table in the - fr_opcode of the rs_broken_word frag. This requires a little hackery */ - while(frag_tmp && (frag_tmp->fr_type!=rs_broken_word || frag_tmp->fr_opcode)) - frag_tmp=frag_tmp->fr_next; - know(frag_tmp); - frag_tmp->fr_opcode=frag_opcode; - new_broken_words = 0; - - for(a=broken_words;a && a->dispfrag==0;a=a->next_broken_word) - a->dispfrag=frag_tmp; - } + if(new_broken_words) { + struct broken_word *a; + int possible_bytes; + fragS *frag_tmp; + char *frag_opcode; + + extern md_short_jump_size; + extern md_long_jump_size; + possible_bytes=md_short_jump_size + new_broken_words * md_long_jump_size; + + frag_tmp=frag_now; + frag_opcode=frag_var(rs_broken_word, + possible_bytes, + possible_bytes, + (relax_substateT) 0, + (symbolS *) broken_words, + 0L, + NULL); + + /* We want to store the pointer to where to insert the jump table in the + fr_opcode of the rs_broken_word frag. This requires a little hackery */ + while(frag_tmp && (frag_tmp->fr_type!=rs_broken_word || frag_tmp->fr_opcode)) + frag_tmp=frag_tmp->fr_next; + know(frag_tmp); + frag_tmp->fr_opcode=frag_opcode; + new_broken_words = 0; + + for(a=broken_words;a && a->dispfrag==0;a=a->next_broken_word) + a->dispfrag=frag_tmp; + } #endif - if ((symbolP = symbol_find(sym_name)) != 0) { + if ((symbolP = symbol_find(sym_name)) != 0) { #ifdef VMS - /* - * If the new symbol is .comm AND it has a size of zero, - * we ignore it (i.e. the old symbol overrides it) - */ - if ((SEGMENT_TO_SYMBOL_TYPE((int) now_seg) == (N_UNDF | N_EXT)) && - ((obstack_next_free(& frags) - frag_now->fr_literal) == 0)) - return; - /* - * If the old symbol is .comm and it has a size of zero, - * we override it with the new symbol value. - */ - if ((symbolP->sy_type == (N_UNDF | N_EXT)) - && (S_GET_VALUE(symbolP) == 0)) { - symbolP->sy_frag = frag_now; - symbolP->sy_other = const_flag; - S_SET_VALUE(symbolP, obstack_next_free(& frags) - frag_now->fr_literal); - symbolP->sy_type |= SEGMENT_TO_SYMBOL_TYPE((int) now_seg); /* keep N_EXT bit */ - return; - } + /* + * If the new symbol is .comm AND it has a size of zero, + * we ignore it (i.e. the old symbol overrides it) + */ + if ((SEGMENT_TO_SYMBOL_TYPE((int) now_seg) == (N_UNDF | N_EXT)) && + ((obstack_next_free(& frags) - frag_now->fr_literal) == 0)) + return; + /* + * If the old symbol is .comm and it has a size of zero, + * we override it with the new symbol value. + */ + if ((symbolP->sy_type == (N_UNDF | N_EXT)) + && (S_GET_VALUE(symbolP) == 0)) { + symbolP->sy_frag = frag_now; + symbolP->sy_other = const_flag; + S_SET_VALUE(symbolP, obstack_next_free(& frags) - frag_now->fr_literal); + symbolP->sy_type |= SEGMENT_TO_SYMBOL_TYPE((int) now_seg); /* keep N_EXT bit */ + return; + } #endif /* VMS */ - /* - * Now check for undefined symbols - */ - if (!S_IS_DEFINED(symbolP)) { - if (S_GET_VALUE(symbolP) == 0) { - symbolP->sy_frag = frag_now; + /* + * Now check for undefined symbols + */ + if (!S_IS_DEFINED(symbolP)) { + if (S_GET_VALUE(symbolP) == 0) { + symbolP->sy_frag = frag_now; #ifdef VMS - symbolP->sy_other = const_flag; + symbolP->sy_other = const_flag; #endif - S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal); - S_SET_SEGMENT(symbolP, now_seg); + S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal); + S_SET_SEGMENT(symbolP, now_seg); #ifdef N_UNDF - know(N_UNDF == 0); + know(N_UNDF == 0); #endif /* if we have one, it better be zero. */ - - } else { - /* - * There are still several cases to check: - * A .comm/.lcomm symbol being redefined as - * initialized data is OK - * A .comm/.lcomm symbol being redefined with - * a larger size is also OK - * - * This only used to be allowed on VMS gas, but Sun cc - * on the sparc also depends on it. - */ -/* char New_Type = SEGMENT_TO_SYMBOL_TYPE((int) now_seg); */ + + } else { + /* + * There are still several cases to check: + * A .comm/.lcomm symbol being redefined as + * initialized data is OK + * A .comm/.lcomm symbol being redefined with + * a larger size is also OK + * + * This only used to be allowed on VMS gas, but Sun cc + * on the sparc also depends on it. + */ + /* char New_Type = SEGMENT_TO_SYMBOL_TYPE((int) now_seg); */ #ifdef MANY_SEGMENTS #define SEG_BSS SEG_E2 #define SEG_DATA SEG_E1 #endif - - if (((!S_IS_DEBUG(symbolP) && !S_IS_DEFINED(symbolP) && S_IS_EXTERNAL(symbolP)) - || (S_GET_SEGMENT(symbolP) == SEG_BSS)) - && ((now_seg == SEG_DATA) - || (now_seg == S_GET_SEGMENT(symbolP)))) { - /* - * Select which of the 2 cases this is - */ - if (now_seg != SEG_DATA) { - /* - * New .comm for prev .comm symbol. - * If the new size is larger we just - * change its value. If the new size - * is smaller, we ignore this symbol - */ - if (S_GET_VALUE(symbolP) - < ((unsigned) (obstack_next_free(& frags) - frag_now->fr_literal))) { - S_SET_VALUE(symbolP, - obstack_next_free(& frags) - - frag_now->fr_literal); - } - } else { - /* - * It is a .comm/.lcomm being converted - * to initialized data. - */ - symbolP->sy_frag = frag_now; + + if (((!S_IS_DEBUG(symbolP) && !S_IS_DEFINED(symbolP) && S_IS_EXTERNAL(symbolP)) + || (S_GET_SEGMENT(symbolP) == SEG_BSS)) + && ((now_seg == SEG_DATA) + || (now_seg == S_GET_SEGMENT(symbolP)))) { + /* + * Select which of the 2 cases this is + */ + if (now_seg != SEG_DATA) { + /* + * New .comm for prev .comm symbol. + * If the new size is larger we just + * change its value. If the new size + * is smaller, we ignore this symbol + */ + if (S_GET_VALUE(symbolP) + < ((unsigned) (obstack_next_free(& frags) - frag_now->fr_literal))) { + S_SET_VALUE(symbolP, + obstack_next_free(& frags) - + frag_now->fr_literal); + } + } else { + /* + * It is a .comm/.lcomm being converted + * to initialized data. + */ + symbolP->sy_frag = frag_now; #ifdef VMS - symbolP->sy_other = const_flag; + symbolP->sy_other = const_flag; #endif /* VMS */ - S_SET_VALUE(symbolP, obstack_next_free(& frags) - frag_now->fr_literal); - S_SET_SEGMENT(symbolP, now_seg); /* keep N_EXT bit */ - } - } else { + S_SET_VALUE(symbolP, obstack_next_free(& frags) - frag_now->fr_literal); + S_SET_SEGMENT(symbolP, now_seg); /* keep N_EXT bit */ + } + } else { #ifdef OBJ_COFF - as_fatal("Symbol \"%s\" is already defined as \"%s\"/%d.", - sym_name, - segment_name(S_GET_SEGMENT(symbolP)), - S_GET_VALUE(symbolP)); + as_fatal("Symbol \"%s\" is already defined as \"%s\"/%d.", + sym_name, + segment_name(S_GET_SEGMENT(symbolP)), + S_GET_VALUE(symbolP)); #else /* OBJ_COFF */ - as_fatal("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%d.", - sym_name, - segment_name(S_GET_SEGMENT(symbolP)), - S_GET_OTHER(symbolP), S_GET_DESC(symbolP), - S_GET_VALUE(symbolP)); + as_fatal("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%d.", + sym_name, + segment_name(S_GET_SEGMENT(symbolP)), + S_GET_OTHER(symbolP), S_GET_DESC(symbolP), + S_GET_VALUE(symbolP)); #endif /* OBJ_COFF */ - } - } /* if the undefined symbol has no value */ - } else - { - /* Don't blow up if the definition is the same */ - if (!(frag_now == symbolP->sy_frag - && S_GET_VALUE(symbolP) == obstack_next_free(&frags) - frag_now->fr_literal - && S_GET_SEGMENT(symbolP) == now_seg) ) - as_fatal("Symbol %s already defined.", sym_name); - } /* if this symbol is not yet defined */ - - } else { - symbolP = symbol_new(sym_name, - now_seg, - (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), - frag_now); + } + } /* if the undefined symbol has no value */ + } else + { + /* Don't blow up if the definition is the same */ + if (!(frag_now == symbolP->sy_frag + && S_GET_VALUE(symbolP) == obstack_next_free(&frags) - frag_now->fr_literal + && S_GET_SEGMENT(symbolP) == now_seg) ) + as_fatal("Symbol %s already defined.", sym_name); + } /* if this symbol is not yet defined */ + + } else { + symbolP = symbol_new(sym_name, + now_seg, + (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), + frag_now); #ifdef VMS - S_SET_OTHER(symbolP, const_flag); + S_SET_OTHER(symbolP, const_flag); #endif /* VMS */ - - symbol_table_insert(symbolP); - } /* if we have seen this symbol before */ - - return; + + symbol_table_insert(symbolP); + } /* if we have seen this symbol before */ + + return; } /* colon() */ @@ -428,10 +426,10 @@ char *name; if (symbolP == NULL) { symbolP = symbol_make(name); - + symbol_table_insert(symbolP); } /* if symbol wasn't found */ - + return(symbolP); } /* symbol_find_or_make() */ @@ -439,7 +437,7 @@ symbolS *symbol_make(name) char *name; { symbolS *symbolP; - + /* Let the machine description default it, e.g. for register names. */ symbolP = md_undefined_symbol(name); @@ -449,7 +447,7 @@ char *name; 0, &zero_address_frag); } /* if md didn't build us a symbol */ - + return(symbolP); } /* symbol_make() */ @@ -476,8 +474,8 @@ symbolS *symbol_find_base(name, strip_underscore) char *name; int strip_underscore; { - if(strip_underscore && *name == '_') name++; - return ( (symbolS *) hash_find( sy_hash, name )); + if(strip_underscore && *name == '_') name++; + return ( (symbolS *) hash_find( sy_hash, name )); } /* @@ -502,7 +500,7 @@ symbolS **lastPP; *lastPP = addme; return; } /* if the list is empty */ - + if (target->sy_next != NULL) { #ifdef SYMBOLS_NEED_BACKPOINTERS target->sy_next->sy_previous = addme; @@ -514,15 +512,15 @@ symbolS **lastPP; addme->sy_next = target->sy_next; target->sy_next = addme; - + #ifdef SYMBOLS_NEED_BACKPOINTERS addme->sy_previous = target; #endif /* SYMBOLS_NEED_BACKPOINTERS */ - + #ifdef DEBUG -/* verify_symbol_chain(*rootPP, *lastPP); */ + /* verify_symbol_chain(*rootPP, *lastPP); */ #endif /* DEBUG */ - + return; } /* symbol_append() */ @@ -536,11 +534,11 @@ symbolS **lastPP; if (symbolP == *rootPP) { *rootPP = symbolP->sy_next; } /* if it was the root */ - + if (symbolP == *lastPP) { *lastPP = symbolP->sy_previous; } /* if it was the tail */ - + if (symbolP->sy_next != NULL) { symbolP->sy_next->sy_previous = symbolP->sy_previous; } /* if not last */ @@ -552,7 +550,7 @@ symbolS **lastPP; #ifdef DEBUG verify_symbol_chain(*rootPP, *lastPP); #endif /* DEBUG */ - + return; } /* symbol_remove() */ @@ -560,8 +558,8 @@ symbolS **lastPP; void symbol_clear_list_pointers(symbolP) symbolS *symbolP; { - symbolP->sy_next = NULL; - symbolP->sy_previous = NULL; + symbolP->sy_next = NULL; + symbolP->sy_previous = NULL; } /* symbol_clear_list_pointers() */ /* Link symbol ADDME before symbol TARGET in the chain. */ @@ -571,22 +569,22 @@ symbolS *target; symbolS **rootPP; symbolS **lastPP; { - if (target->sy_previous != NULL) { - target->sy_previous->sy_next = addme; - } else { - know(*rootPP == target); - *rootPP = addme; - } /* if not first */ - - addme->sy_previous = target->sy_previous; - target->sy_previous = addme; - addme->sy_next = target; - + if (target->sy_previous != NULL) { + target->sy_previous->sy_next = addme; + } else { + know(*rootPP == target); + *rootPP = addme; + } /* if not first */ + + addme->sy_previous = target->sy_previous; + target->sy_previous = addme; + addme->sy_next = target; + #ifdef DEBUG - verify_symbol_chain(*rootPP, *lastPP); + verify_symbol_chain(*rootPP, *lastPP); #endif /* DEBUG */ - - return; + + return; } /* symbol_insert() */ #endif /* SYMBOLS_NEED_BACKPOINTERS */ @@ -595,26 +593,26 @@ symbolS *rootP; symbolS *lastP; { symbolS *symbolP = rootP; - + if (symbolP == NULL) { return; } /* empty chain */ - + for ( ; symbol_next(symbolP) != NULL; symbolP = symbol_next(symbolP)) { #ifdef SYMBOLS_NEED_BACKPOINTERS /*$if (symbolP->sy_previous) { - know(symbolP->sy_previous->sy_next == symbolP); - } else { - know(symbolP == rootP); - }$*/ /* both directions */ + know(symbolP->sy_previous->sy_next == symbolP); + } else { + know(symbolP == rootP); + }$*/ /* both directions */ know(symbolP->sy_next->sy_previous == symbolP); #else /* SYMBOLS_NEED_BACKPOINTERS */ ; #endif /* SYMBOLS_NEED_BACKPOINTERS */ } /* verify pointers */ - + know(lastP == symbolP); - + return; } /* verify_symbol_chain() */ @@ -624,25 +622,25 @@ symbolS *lastP; * the name wasn't generated by local_label_name(), then return it unaltered. * This is used for error messages. */ - + char *decode_local_label_name(s) char *s; { char *symbol_decode; int label_number; - /* int label_version; */ + /* int label_version; */ char *message_format = "\"%d\" (instance number %s of a local label)"; - + if (s[0] != 'L' || s[2] != 1) { return(s); } /* not a local_label_name() generated name. */ - + label_number = s[1] - '0'; - + (void) sprintf(symbol_decode = obstack_alloc(¬es, strlen(s + 3) + strlen(message_format) + 10), - message_format, label_number, s + 3); - + message_format, label_number, s + 3); + return(symbol_decode); } /* decode_local_label_name() */ diff --git a/gas/symbols.h b/gas/symbols.h index 8ced0d4..b609015 100644 --- a/gas/symbols.h +++ b/gas/symbols.h @@ -1,31 +1,31 @@ /* symbols.h - Copyright (C) 1987, 1990 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. */ + + 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. */ /* $Id$ */ extern struct obstack notes; /* eg FixS live here. */ extern struct obstack cond_obstack; /* this is where we track .ifdef/.endif - (if we do that at all). */ + (if we do that at all). */ extern unsigned int local_bss_counter; /* Zeroed before a pass. */ - /* Only used by .lcomm directive. */ +/* Only used by .lcomm directive. */ extern symbolS * symbol_rootP; /* all the symbol nodes */ extern symbolS * symbol_lastP; /* last struct symbol we made, or NULL */ @@ -38,6 +38,7 @@ extern symbolS* dot_bss_symbol; #ifdef __STDC__ +char *decode_local_label_name(char *s); char *local_label_name(int n, int augend); symbolS *symbol_find(char *name); symbolS *symbol_find_base(char *name, int strip_underscore); @@ -52,6 +53,7 @@ void verify_symbol_chain(symbolS *rootP, symbolS *lastP); #else +char *decode_local_label_name(); char *local_label_name(); symbolS *symbol_find(); symbolS *symbol_find_base(); @@ -1,24 +1,22 @@ /* tc.h -target cpu dependent- */ /* Copyright (C) 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. */ /* In theory (mine, at least!) the machine dependent part of the assembler should only have to include one file. This one. -- JF */ @@ -34,7 +32,7 @@ typedef struct long rlx_backward; /* Backward reach. Signed number. < 0. */ unsigned char rlx_length; /* Bytes length of this address. */ relax_substateT rlx_more; /* Next longer relax-state. */ - /* 0 means there is no 'next' relax-state. */ + /* 0 means there is no 'next' relax-state. */ } relax_typeS; @@ -47,7 +45,7 @@ extern void (*md_emit_relocations)(); #ifdef __STDC__ char *md_atof(int what_statement_type, char *literalP, int *sizeP); -int md_estimate_size_before_relax(fragS *fragP, segT segtype); +int md_estimate_size_before_relax(fragS *fragP, segT segment); int md_parse_option(char **argP, int *cntP, char ***vecP); long md_pcrel_from(fixS *fixP); long md_section_align(segT seg, long align); @@ -56,13 +54,12 @@ symbolS *md_undefined_symbol(char *name); void md_apply_fix(fixS *fixP, long val); void md_assemble(char *str); void md_begin(void); -void md_convert_frag(fragS *fragP); +void md_convert_frag(object_headers *headers, fragS *fragP); void md_create_long_jump(char *ptr, long from_addr, long to_addr, fragS *frag, symbolS *to_symbol); void md_create_short_jump(char *ptr, long from_addr, long to_addr, fragS *frag, symbolS *to_symbol); void md_end(void); void md_number_to_chars(char *buf, long val, int n); void md_operand(expressionS *expressionP); -void md_ri_to_chars(char *the_bytes, struct reloc_info_generic *ri); #ifndef tc_crawl_symbol_chain void tc_crawl_symbol_chain(object_headers *headers); @@ -90,7 +87,6 @@ void md_create_short_jump(); void md_end(); void md_number_to_chars(); void md_operand(); -void md_ri_to_chars(); #ifndef tc_headers_hook void tc_headers_hook(); diff --git a/gas/version.c b/gas/version.c index 1e6f853..1f6363d 100644 --- a/gas/version.c +++ b/gas/version.c @@ -1,20 +1,20 @@ #if defined(__STDC__) || defined(const) const #endif -char version_string[] = "GNU assembler version 1.90.1 (Cygnus Support pre-release)\n"; + char version_string[] = "GNU assembler version 1.90.1 (Cygnus Support pre-release)\n"; /* DO NOT PUT COMMENTS ABOUT CHANGES IN THIS FILE. - + This file exists only to define `version_string'. - + Log changes in ChangeLog. The easiest way to do this is with the Emacs command `add-change-log-entry'. If you don't use Emacs, add entries of the form: - -Thu Jan 1 00:00:00 1970 Dennis Ritchie (dmr at alice) - - * universe.c (temporal_reality): Began Time. -*/ + + Thu Jan 1 00:00:00 1970 Dennis Ritchie (dmr at alice) + + * universe.c (temporal_reality): Began Time. + */ #ifdef VMS dummy3() diff --git a/gas/write.c b/gas/write.c index 702f1a0..b8eeb6e 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1,35 +1,33 @@ /* write.c - emit .o 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 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. */ - -/* 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. */ /* - - This thing should be set up to do byteordering correctly. But... - - In order to cross-assemble the target machine must have an a.out header - similar to the one in a.out.h on THIS machine. Byteorder doesn't matter, - we take special care of it, but the numbers must be the same SIZE (# of - bytes) and in the same PLACE. If this is not true, you will have some - trouble. - */ + + This thing should be set up to do byteordering correctly. But... + + In order to cross-assemble the target machine must have an a.out header + similar to the one in a.out.h on THIS machine. Byteorder doesn't matter, + we take special care of it, but the numbers must be the same SIZE (# of + bytes) and in the same PLACE. If this is not true, you will have some + trouble. + */ #include "as.h" #include "subsegs.h" @@ -62,14 +60,14 @@ int magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE; static int is_dnrange(struct frag *f1, struct frag *f2); static long fixup_segment(fixS *fixP, segT this_segment_type); static relax_addressT relax_align(relax_addressT address, long alignment); - void relax_segment(struct frag *segment_frag_root, segT segment_type); +void relax_segment(struct frag *segment_frag_root, segT segment_type); #else static int is_dnrange(); static long fixup_segment(); static relax_addressT relax_align(); - void relax_segment(); +void relax_segment(); #endif /* __STDC__ */ @@ -88,501 +86,501 @@ long offset; /* X_add_number. */ int pcrel; /* TRUE if PC-relative relocation. */ enum reloc_type r_type; /* Relocation type */ { - register fixS * fixP; - - fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS)); - - fixP->fx_frag = frag; - fixP->fx_where = where; - fixP->fx_size = size; - fixP->fx_addsy = add_symbol; - fixP->fx_subsy = sub_symbol; - fixP->fx_offset = offset; - fixP->fx_pcrel = pcrel; - fixP->fx_r_type = r_type; - - /* JF these 'cuz of the NS32K stuff */ - fixP->fx_im_disp = 0; - fixP->fx_pcrel_adjust = 0; - fixP->fx_bsr = 0; - fixP->fx_bit_fixP = 0; - - /* usually, we want relocs sorted numerically, but while - comparing to older versions of gas that have relocs - reverse sorted, it is convenient to have this compile - time option. xoxorich. */ - + register fixS * fixP; + + fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS)); + + fixP->fx_frag = frag; + fixP->fx_where = where; + fixP->fx_size = size; + fixP->fx_addsy = add_symbol; + fixP->fx_subsy = sub_symbol; + fixP->fx_offset = offset; + fixP->fx_pcrel = pcrel; + fixP->fx_r_type = r_type; + + /* JF these 'cuz of the NS32K stuff */ + fixP->fx_im_disp = 0; + fixP->fx_pcrel_adjust = 0; + fixP->fx_bsr = 0; + fixP->fx_bit_fixP = 0; + + /* usually, we want relocs sorted numerically, but while + comparing to older versions of gas that have relocs + reverse sorted, it is convenient to have this compile + time option. xoxorich. */ + #ifdef REVERSE_SORT_RELOCS - - fixP->fx_next = *seg_fix_rootP; - *seg_fix_rootP = fixP; - + + fixP->fx_next = *seg_fix_rootP; + *seg_fix_rootP = fixP; + #else /* REVERSE_SORT_RELOCS */ - - fixP->fx_next = NULL; - - if (*seg_fix_tailP) - (*seg_fix_tailP)->fx_next = fixP; - else - *seg_fix_rootP = fixP; - *seg_fix_tailP = fixP; - + + fixP->fx_next = NULL; + + if (*seg_fix_tailP) + (*seg_fix_tailP)->fx_next = fixP; + else + *seg_fix_rootP = fixP; + *seg_fix_tailP = fixP; + #endif /* REVERSE_SORT_RELOCS */ - - fixP->fx_callj = 0; - return fixP; + + fixP->fx_callj = 0; + return fixP; } #ifndef BFD void write_object_file() { - register struct frchain * frchainP; /* Track along all frchains. */ - register fragS * fragP; /* Track along all frags. */ - register struct frchain * next_frchainP; - register fragS * * prev_fragPP; -/* register char * name; */ -/* symbolS *symbolP; */ -/* register symbolS ** symbolPP; */ - /* register fixS * fixP; JF unused */ - unsigned int data_siz; - + register struct frchain * frchainP; /* Track along all frchains. */ + register fragS * fragP; /* Track along all frags. */ + register struct frchain * next_frchainP; + register fragS * * prev_fragPP; + /* register char * name; */ + /* symbolS *symbolP; */ + /* register symbolS ** symbolPP; */ + /* register fixS * fixP; JF unused */ + unsigned int data_siz; + #ifdef DONTDEF - void gdb_emit(); - void gdb_end(); + void gdb_emit(); + void gdb_end(); #endif - long object_file_size; - + long object_file_size; + #ifdef VMS - /* - * Under VMS we try to be compatible with VAX-11 "C". Thus, we - * call a routine to check for the definition of the procedure - * "_main", and if so -- fix it up so that it can be program - * entry point. - */ - VMS_Check_For_Main(); + /* + * Under VMS we try to be compatible with VAX-11 "C". Thus, we + * call a routine to check for the definition of the procedure + * "_main", and if so -- fix it up so that it can be program + * entry point. + */ + VMS_Check_For_Main(); #endif /* VMS */ - /* - * After every sub-segment, we fake an ".align ...". This conforms to BSD4.2 - * brane-damage. We then fake ".fill 0" because that is the kind of frag - * that requires least thought. ".align" frags like to have a following - * frag since that makes calculating their intended length trivial. - */ + /* + * After every sub-segment, we fake an ".align ...". This conforms to BSD4.2 + * brane-damage. We then fake ".fill 0" because that is the kind of frag + * that requires least thought. ".align" frags like to have a following + * frag since that makes calculating their intended length trivial. + */ #define SUB_SEGMENT_ALIGN (2) - for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next) { + for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next) { #ifdef VMS - /* - * Under VAX/VMS, the linker (and PSECT specifications) - * take care of correctly aligning the segments. - * Doing the alignment here (on initialized data) can - * mess up the calculation of global data PSECT sizes. - */ + /* + * Under VAX/VMS, the linker (and PSECT specifications) + * take care of correctly aligning the segments. + * Doing the alignment here (on initialized data) can + * mess up the calculation of global data PSECT sizes. + */ #undef SUB_SEGMENT_ALIGN #define SUB_SEGMENT_ALIGN ((frchainP->frch_seg != SEG_DATA) ? 2 : 0) #endif /* VMS */ - subseg_new (frchainP->frch_seg, frchainP->frch_subseg); - frag_align (SUB_SEGMENT_ALIGN, 0); - /* frag_align will have left a new frag. */ - /* Use this last frag for an empty ".fill". */ - /* - * For this segment ... - * Create a last frag. Do not leave a "being filled in frag". - */ - frag_wane (frag_now); - frag_now->fr_fix = 0; - know( frag_now->fr_next == NULL ); - /* know( frags . obstack_c_base == frags . obstack_c_next_free ); */ - /* Above shows we haven't left a half-completed object on obstack. */ - } /* walk the frag chain */ - - /* - * From now on, we don't care about sub-segments. - * Build one frag chain for each segment. Linked thru fr_next. - * We know that there is at least 1 text frchain & at least 1 data frchain. - */ - prev_fragPP = &text_frag_root; - for (frchainP = frchain_root; frchainP; frchainP = next_frchainP) { - know( frchainP->frch_root ); - * prev_fragPP = frchainP->frch_root; - prev_fragPP = & frchainP->frch_last->fr_next; - - if (((next_frchainP = frchainP->frch_next) == NULL) - || next_frchainP == data0_frchainP) { - prev_fragPP = & data_frag_root; - if (next_frchainP) { - text_last_frag = frchainP->frch_last; - } else { - data_last_frag = frchainP->frch_last; - } - } - } /* walk the frag chain */ - - /* - * We have two segments. If user gave -R flag, then we must put the - * data frags into the text segment. Do this before relaxing so - * we know to take advantage of -R and make shorter addresses. - */ - if (flagseen[ 'R' ]) { - fixS *tmp; - - text_last_frag->fr_next = data_frag_root; - text_last_frag = data_last_frag; - data_last_frag = NULL; - data_frag_root = NULL; - if (text_fix_root) { - for (tmp = text_fix_root; tmp->fx_next; tmp = tmp->fx_next) ;; - tmp->fx_next=data_fix_root; - } else - text_fix_root=data_fix_root; - data_fix_root=NULL; - } - - relax_segment(text_frag_root, SEG_TEXT); - relax_segment(data_frag_root, SEG_DATA); - /* - * Now the addresses of frags are correct within the segment. - */ - - know(text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0); - H_SET_TEXT_SIZE(&headers, text_last_frag->fr_address); - text_last_frag->fr_address = H_GET_TEXT_SIZE(&headers); - - /* - * Join the 2 segments into 1 huge segment. - * To do this, re-compute every rn_address in the SEG_DATA frags. - * Then join the data frags after the text frags. - * - * Determine a_data [length of data segment]. - */ - if (data_frag_root) { - register relax_addressT slide; - - know((text_last_frag->fr_type == rs_fill) && (text_last_frag->fr_offset == 0)); - - H_SET_DATA_SIZE(&headers, data_last_frag->fr_address); - data_last_frag->fr_address = H_GET_DATA_SIZE(&headers); - slide = H_GET_TEXT_SIZE(&headers); /* & in file of the data segment. */ - - for (fragP = data_frag_root; fragP; fragP = fragP->fr_next) { - fragP->fr_address += slide; - } /* for each data frag */ - - know(text_last_frag != 0); - text_last_frag->fr_next = data_frag_root; - } else { - H_SET_DATA_SIZE(&headers,0); - data_siz = 0; - } - - bss_address_frag.fr_address = H_GET_TEXT_SIZE(&headers) + - H_GET_DATA_SIZE(&headers); - - H_SET_BSS_SIZE(&headers,local_bss_counter); - - /* - * - * Crawl the symbol chain. - * - * For each symbol whose value depends on a frag, take the address of - * that frag and subsume it into the value of the symbol. - * After this, there is just one way to lookup a symbol value. - * Values are left in their final state for object file emission. - * We adjust the values of 'L' local symbols, even if we do - * not intend to emit them to the object file, because their values - * are needed for fix-ups. - * - * Unless we saw a -L flag, remove all symbols that begin with 'L' - * from the symbol chain. (They are still pointed to by the fixes.) - * - * Count the remaining symbols. - * Assign a symbol number to each symbol. - * Count the number of string-table chars we will emit. - * Put this info into the headers as appropriate. - * - */ - know(zero_address_frag.fr_address == 0); - string_byte_count = sizeof(string_byte_count); - - obj_crawl_symbol_chain(&headers); - - if (string_byte_count == sizeof(string_byte_count)) { - string_byte_count = 0; - } /* if no strings, then no count. */ - - H_SET_STRING_SIZE(&headers, string_byte_count); - - /* - * Addresses of frags now reflect addresses we use in the object file. - * Symbol values are correct. - * Scan the frags, converting any ".org"s and ".align"s to ".fill"s. - * Also converting any machine-dependent frags using md_convert_frag(); - */ - subseg_change(SEG_TEXT, 0); - - for (fragP = text_frag_root; fragP; fragP = fragP->fr_next) { - switch (fragP->fr_type) { - case rs_align: - case rs_org: - fragP->fr_type = rs_fill; - know(fragP->fr_var == 1); - know(fragP->fr_next != NULL); - - fragP->fr_offset = (fragP->fr_next->fr_address - - fragP->fr_address - - fragP->fr_fix); - break; - - case rs_fill: - break; - - case rs_machine_dependent: - md_convert_frag(&headers, fragP); - - know((fragP->fr_next == NULL) || ((fragP->fr_next->fr_address - fragP->fr_address) == fragP->fr_fix)); - - /* - * After md_convert_frag, we make the frag into a ".space 0". - * Md_convert_frag() should set up any fixSs and constants - * required. - */ - frag_wane(fragP); - break; - + subseg_new (frchainP->frch_seg, frchainP->frch_subseg); + frag_align (SUB_SEGMENT_ALIGN, 0); + /* frag_align will have left a new frag. */ + /* Use this last frag for an empty ".fill". */ + /* + * For this segment ... + * Create a last frag. Do not leave a "being filled in frag". + */ + frag_wane (frag_now); + frag_now->fr_fix = 0; + know( frag_now->fr_next == NULL ); + /* know( frags . obstack_c_base == frags . obstack_c_next_free ); */ + /* Above shows we haven't left a half-completed object on obstack. */ + } /* walk the frag chain */ + + /* + * From now on, we don't care about sub-segments. + * Build one frag chain for each segment. Linked thru fr_next. + * We know that there is at least 1 text frchain & at least 1 data frchain. + */ + prev_fragPP = &text_frag_root; + for (frchainP = frchain_root; frchainP; frchainP = next_frchainP) { + know( frchainP->frch_root ); + * prev_fragPP = frchainP->frch_root; + prev_fragPP = & frchainP->frch_last->fr_next; + + if (((next_frchainP = frchainP->frch_next) == NULL) + || next_frchainP == data0_frchainP) { + prev_fragPP = & data_frag_root; + if (next_frchainP) { + text_last_frag = frchainP->frch_last; + } else { + data_last_frag = frchainP->frch_last; + } + } + } /* walk the frag chain */ + + /* + * We have two segments. If user gave -R flag, then we must put the + * data frags into the text segment. Do this before relaxing so + * we know to take advantage of -R and make shorter addresses. + */ + if (flagseen[ 'R' ]) { + fixS *tmp; + + text_last_frag->fr_next = data_frag_root; + text_last_frag = data_last_frag; + data_last_frag = NULL; + data_frag_root = NULL; + if (text_fix_root) { + for (tmp = text_fix_root; tmp->fx_next; tmp = tmp->fx_next) ;; + tmp->fx_next=data_fix_root; + } else + text_fix_root=data_fix_root; + data_fix_root=NULL; + } + + relax_segment(text_frag_root, SEG_TEXT); + relax_segment(data_frag_root, SEG_DATA); + /* + * Now the addresses of frags are correct within the segment. + */ + + know(text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0); + H_SET_TEXT_SIZE(&headers, text_last_frag->fr_address); + text_last_frag->fr_address = H_GET_TEXT_SIZE(&headers); + + /* + * Join the 2 segments into 1 huge segment. + * To do this, re-compute every rn_address in the SEG_DATA frags. + * Then join the data frags after the text frags. + * + * Determine a_data [length of data segment]. + */ + if (data_frag_root) { + register relax_addressT slide; + + know((text_last_frag->fr_type == rs_fill) && (text_last_frag->fr_offset == 0)); + + H_SET_DATA_SIZE(&headers, data_last_frag->fr_address); + data_last_frag->fr_address = H_GET_DATA_SIZE(&headers); + slide = H_GET_TEXT_SIZE(&headers); /* & in file of the data segment. */ + + for (fragP = data_frag_root; fragP; fragP = fragP->fr_next) { + fragP->fr_address += slide; + } /* for each data frag */ + + know(text_last_frag != 0); + text_last_frag->fr_next = data_frag_root; + } else { + H_SET_DATA_SIZE(&headers,0); + data_siz = 0; + } + + bss_address_frag.fr_address = H_GET_TEXT_SIZE(&headers) + + H_GET_DATA_SIZE(&headers); + + H_SET_BSS_SIZE(&headers,local_bss_counter); + + /* + * + * Crawl the symbol chain. + * + * For each symbol whose value depends on a frag, take the address of + * that frag and subsume it into the value of the symbol. + * After this, there is just one way to lookup a symbol value. + * Values are left in their final state for object file emission. + * We adjust the values of 'L' local symbols, even if we do + * not intend to emit them to the object file, because their values + * are needed for fix-ups. + * + * Unless we saw a -L flag, remove all symbols that begin with 'L' + * from the symbol chain. (They are still pointed to by the fixes.) + * + * Count the remaining symbols. + * Assign a symbol number to each symbol. + * Count the number of string-table chars we will emit. + * Put this info into the headers as appropriate. + * + */ + know(zero_address_frag.fr_address == 0); + string_byte_count = sizeof(string_byte_count); + + obj_crawl_symbol_chain(&headers); + + if (string_byte_count == sizeof(string_byte_count)) { + string_byte_count = 0; + } /* if no strings, then no count. */ + + H_SET_STRING_SIZE(&headers, string_byte_count); + + /* + * Addresses of frags now reflect addresses we use in the object file. + * Symbol values are correct. + * Scan the frags, converting any ".org"s and ".align"s to ".fill"s. + * Also converting any machine-dependent frags using md_convert_frag(); + */ + subseg_change(SEG_TEXT, 0); + + for (fragP = text_frag_root; fragP; fragP = fragP->fr_next) { + switch (fragP->fr_type) { + case rs_align: + case rs_org: + fragP->fr_type = rs_fill; + know(fragP->fr_var == 1); + know(fragP->fr_next != NULL); + + fragP->fr_offset = (fragP->fr_next->fr_address + - fragP->fr_address + - fragP->fr_fix); + break; + + case rs_fill: + break; + + case rs_machine_dependent: + md_convert_frag(&headers, fragP); + + know((fragP->fr_next == NULL) || ((fragP->fr_next->fr_address - fragP->fr_address) == fragP->fr_fix)); + + /* + * After md_convert_frag, we make the frag into a ".space 0". + * Md_convert_frag() should set up any fixSs and constants + * required. + */ + frag_wane(fragP); + break; + #ifndef WORKING_DOT_WORD - case rs_broken_word: { - struct broken_word *lie; - extern md_short_jump_size; - extern md_long_jump_size; - - if (fragP->fr_subtype) { - fragP->fr_fix+=md_short_jump_size; - for (lie=(struct broken_word *)(fragP->fr_symbol);lie && lie->dispfrag==fragP;lie=lie->next_broken_word) - if (lie->added==1) - fragP->fr_fix+=md_long_jump_size; - } - frag_wane(fragP); - } - break; + case rs_broken_word: { + struct broken_word *lie; + extern md_short_jump_size; + extern md_long_jump_size; + + if (fragP->fr_subtype) { + fragP->fr_fix+=md_short_jump_size; + for (lie=(struct broken_word *)(fragP->fr_symbol);lie && lie->dispfrag==fragP;lie=lie->next_broken_word) + if (lie->added==1) + fragP->fr_fix+=md_long_jump_size; + } + frag_wane(fragP); + } + break; #endif - - default: - BAD_CASE( fragP->fr_type ); - break; - } /* switch (fr_type) */ - - know((fragP->fr_next == NULL) || ((fragP->fr_next->fr_address - fragP->fr_address) == (fragP->fr_fix + (fragP->fr_offset * fragP->fr_var)))); - } /* for each frag. */ - + + default: + BAD_CASE( fragP->fr_type ); + break; + } /* switch (fr_type) */ + + know((fragP->fr_next == NULL) || ((fragP->fr_next->fr_address - fragP->fr_address) == (fragP->fr_fix + (fragP->fr_offset * fragP->fr_var)))); + } /* for each frag. */ + #ifndef WORKING_DOT_WORD - { - struct broken_word *lie; - struct broken_word **prevP; - - prevP= &broken_words; - for (lie=broken_words; lie; lie=lie->next_broken_word) - if (!lie->added) { + { + struct broken_word *lie; + struct broken_word **prevP; + + prevP= &broken_words; + for (lie=broken_words; lie; lie=lie->next_broken_word) + if (!lie->added) { #ifdef TC_NS32K - fix_new_ns32k(lie->frag, - lie->word_goes_here - lie->frag->fr_literal, - 2, - lie->add, - lie->sub, - lie->addnum, - 0, 0, 2, 0, 0); + fix_new_ns32k(lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, + lie->add, + lie->sub, + lie->addnum, + 0, 0, 2, 0, 0); #else /* TC_NS32K */ - fix_new( lie->frag, lie->word_goes_here - lie->frag->fr_literal, - 2, lie->add, - lie->sub, lie->addnum, - 0, NO_RELOC); + fix_new( lie->frag, lie->word_goes_here - lie->frag->fr_literal, + 2, lie->add, + lie->sub, lie->addnum, + 0, NO_RELOC); #endif /* TC_NS32K */ - /* md_number_to_chars(lie->word_goes_here, - S_GET_VALUE(lie->add) - + lie->addnum - - S_GET_VALUE(lie->sub), - 2); */ - *prevP=lie->next_broken_word; - } else - prevP= &(lie->next_broken_word); - - for (lie=broken_words;lie;) { - struct broken_word *untruth; - char *table_ptr; - long table_addr; - long from_addr, - to_addr; - int n, - m; - - extern md_short_jump_size; - extern md_long_jump_size; - - fragP=lie->dispfrag; - - /* Find out how many broken_words go here */ - n=0; - for (untruth=lie;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word) - if (untruth->added==1) - n++; - - table_ptr=lie->dispfrag->fr_opcode; - table_addr=lie->dispfrag->fr_address+(table_ptr - lie->dispfrag->fr_literal); - /* Create the jump around the long jumps */ - /* This is a short jump from table_ptr+0 to table_ptr+n*long_jump_size */ - from_addr=table_addr; - to_addr = table_addr + md_short_jump_size + n * md_long_jump_size; - md_create_short_jump(table_ptr, from_addr, to_addr, lie->dispfrag, lie->add); - table_ptr+=md_short_jump_size; - table_addr+=md_short_jump_size; - - for (m=0;lie && lie->dispfrag==fragP;m++,lie=lie->next_broken_word) { - if (lie->added==2) - continue; - /* Patch the jump table */ - /* This is the offset from ??? to table_ptr+0 */ - to_addr = table_addr - - S_GET_VALUE(lie->sub); - md_number_to_chars(lie->word_goes_here,to_addr,2); - for (untruth=lie->next_broken_word;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word) { - if (untruth->use_jump==lie) - md_number_to_chars(untruth->word_goes_here,to_addr,2); - } - - /* Install the long jump */ - /* this is a long jump from table_ptr+0 to the final target */ - from_addr=table_addr; - to_addr=S_GET_VALUE(lie->add) + lie->addnum; - md_create_long_jump(table_ptr,from_addr,to_addr,lie->dispfrag,lie->add); - table_ptr+=md_long_jump_size; - table_addr+=md_long_jump_size; - } - } - } + /* md_number_to_chars(lie->word_goes_here, + S_GET_VALUE(lie->add) + + lie->addnum + - S_GET_VALUE(lie->sub), + 2); */ + *prevP=lie->next_broken_word; + } else + prevP= &(lie->next_broken_word); + + for (lie=broken_words;lie;) { + struct broken_word *untruth; + char *table_ptr; + long table_addr; + long from_addr, + to_addr; + int n, + m; + + extern md_short_jump_size; + extern md_long_jump_size; + + fragP=lie->dispfrag; + + /* Find out how many broken_words go here */ + n=0; + for (untruth=lie;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word) + if (untruth->added==1) + n++; + + table_ptr=lie->dispfrag->fr_opcode; + table_addr=lie->dispfrag->fr_address+(table_ptr - lie->dispfrag->fr_literal); + /* Create the jump around the long jumps */ + /* This is a short jump from table_ptr+0 to table_ptr+n*long_jump_size */ + from_addr=table_addr; + to_addr = table_addr + md_short_jump_size + n * md_long_jump_size; + md_create_short_jump(table_ptr, from_addr, to_addr, lie->dispfrag, lie->add); + table_ptr+=md_short_jump_size; + table_addr+=md_short_jump_size; + + for (m=0;lie && lie->dispfrag==fragP;m++,lie=lie->next_broken_word) { + if (lie->added==2) + continue; + /* Patch the jump table */ + /* This is the offset from ??? to table_ptr+0 */ + to_addr = table_addr + - S_GET_VALUE(lie->sub); + md_number_to_chars(lie->word_goes_here,to_addr,2); + for (untruth=lie->next_broken_word;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word) { + if (untruth->use_jump==lie) + md_number_to_chars(untruth->word_goes_here,to_addr,2); + } + + /* Install the long jump */ + /* this is a long jump from table_ptr+0 to the final target */ + from_addr=table_addr; + to_addr=S_GET_VALUE(lie->add) + lie->addnum; + md_create_long_jump(table_ptr,from_addr,to_addr,lie->dispfrag,lie->add); + table_ptr+=md_long_jump_size; + table_addr+=md_long_jump_size; + } + } + } #endif /* not WORKING_DOT_WORD */ - + #ifndef VMS - { /* not vms */ - /* - * Scan every FixS performing fixups. We had to wait until now to do - * this because md_convert_frag() may have made some fixSs. - */ - - H_SET_RELOCATION_SIZE(&headers, - md_reloc_size * fixup_segment(text_fix_root, SEG_TEXT), - md_reloc_size * fixup_segment(data_fix_root, SEG_DATA)); - - - /* FIXME move this stuff into the pre-write-hook */ - H_SET_MAGIC_NUMBER(&headers, magic_number_for_object_file); - H_SET_ENTRY_POINT(&headers, 0); - - obj_pre_write_hook(&headers); /* extra coff stuff */ - if ((had_warnings() && flagseen['Z']) - || had_errors() > 0) { - if (flagseen['Z']) { - as_warn("%d error%s, %d warning%s, generating bad object file.\n", - had_errors(), had_errors() == 1 ? "" : "s", - had_warnings(), had_warnings() == 1 ? "" : "s"); - } else { - as_fatal("%d error%s, %d warning%s, no object file generated.\n", - had_errors(), had_errors() == 1 ? "" : "s", - had_warnings(), had_warnings() == 1 ? "" : "s"); - } /* on want output */ - } /* on error condition */ - - object_file_size = H_GET_FILE_SIZE(&headers); - next_object_file_charP = the_object_file = xmalloc(object_file_size); - - output_file_create(out_file_name); - - obj_header_append(&next_object_file_charP, &headers); - - know((next_object_file_charP - the_object_file) == H_GET_HEADER_SIZE(&headers)); - - /* - * Emit code. - */ - for (fragP = text_frag_root; fragP; fragP = fragP->fr_next) { - register long count; - register char *fill_literal; - register long fill_size; - - know(fragP->fr_type == rs_fill); - append(&next_object_file_charP, fragP->fr_literal, (unsigned long) fragP->fr_fix); - fill_literal = fragP->fr_literal + fragP->fr_fix; - fill_size = fragP->fr_var; - know(fragP->fr_offset >= 0); - - for (count = fragP->fr_offset; count; count--) { - append(&next_object_file_charP, fill_literal, (unsigned long) fill_size); - } /* for each */ - - } /* for each code frag. */ - - know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers))); - - /* - * Emit relocations. - */ - obj_emit_relocations(&next_object_file_charP, text_fix_root, (relax_addressT)0); - know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers))); + { /* not vms */ + /* + * Scan every FixS performing fixups. We had to wait until now to do + * this because md_convert_frag() may have made some fixSs. + */ + + H_SET_RELOCATION_SIZE(&headers, + md_reloc_size * fixup_segment(text_fix_root, SEG_TEXT), + md_reloc_size * fixup_segment(data_fix_root, SEG_DATA)); + + + /* FIXME move this stuff into the pre-write-hook */ + H_SET_MAGIC_NUMBER(&headers, magic_number_for_object_file); + H_SET_ENTRY_POINT(&headers, 0); + + obj_pre_write_hook(&headers); /* extra coff stuff */ + if ((had_warnings() && flagseen['Z']) + || had_errors() > 0) { + if (flagseen['Z']) { + as_warn("%d error%s, %d warning%s, generating bad object file.\n", + had_errors(), had_errors() == 1 ? "" : "s", + had_warnings(), had_warnings() == 1 ? "" : "s"); + } else { + as_fatal("%d error%s, %d warning%s, no object file generated.\n", + had_errors(), had_errors() == 1 ? "" : "s", + had_warnings(), had_warnings() == 1 ? "" : "s"); + } /* on want output */ + } /* on error condition */ + + object_file_size = H_GET_FILE_SIZE(&headers); + next_object_file_charP = the_object_file = xmalloc(object_file_size); + + output_file_create(out_file_name); + + obj_header_append(&next_object_file_charP, &headers); + + know((next_object_file_charP - the_object_file) == H_GET_HEADER_SIZE(&headers)); + + /* + * Emit code. + */ + for (fragP = text_frag_root; fragP; fragP = fragP->fr_next) { + register long count; + register char *fill_literal; + register long fill_size; + + know(fragP->fr_type == rs_fill); + append(&next_object_file_charP, fragP->fr_literal, (unsigned long) fragP->fr_fix); + fill_literal = fragP->fr_literal + fragP->fr_fix; + fill_size = fragP->fr_var; + know(fragP->fr_offset >= 0); + + for (count = fragP->fr_offset; count; count--) { + append(&next_object_file_charP, fill_literal, (unsigned long) fill_size); + } /* for each */ + + } /* for each code frag. */ + + know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers))); + + /* + * Emit relocations. + */ + obj_emit_relocations(&next_object_file_charP, text_fix_root, (relax_addressT)0); + know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers))); #ifdef TC_I960 - /* Make addresses in data relocation directives relative to beginning of - * first data fragment, not end of last text fragment: alignment of the - * start of the data segment may place a gap between the segments. - */ - obj_emit_relocations(&next_object_file_charP, data_fix_root, data0_frchainP->frch_root->fr_address); + /* Make addresses in data relocation directives relative to beginning of + * first data fragment, not end of last text fragment: alignment of the + * start of the data segment may place a gap between the segments. + */ + obj_emit_relocations(&next_object_file_charP, data_fix_root, data0_frchainP->frch_root->fr_address); #else /* TC_I960 */ - obj_emit_relocations(&next_object_file_charP, data_fix_root, text_last_frag->fr_address); + obj_emit_relocations(&next_object_file_charP, data_fix_root, text_last_frag->fr_address); #endif /* TC_I960 */ - - know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers))); - - /* - * Emit line number entries. - */ - OBJ_EMIT_LINENO(&next_object_file_charP, lineno_rootP, the_object_file); - know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers) + H_GET_LINENO_SIZE(&headers))); - - /* - * Emit symbols. - */ - obj_emit_symbols(&next_object_file_charP, symbol_rootP); - know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers) + H_GET_LINENO_SIZE(&headers) + H_GET_SYMBOL_TABLE_SIZE(&headers))); - - /* - * Emit strings. - */ - - if (string_byte_count > 0) { - obj_emit_strings(&next_object_file_charP); - } /* only if we have a string table */ - -/* know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers) + H_GET_LINENO_SIZE(&headers) + H_GET_SYMBOL_TABLE_SIZE(&headers) + H_GET_STRING_SIZE(&headers))); -*/ -/* know(next_object_file_charP == the_object_file + object_file_size);*/ - + + know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers))); + + /* + * Emit line number entries. + */ + OBJ_EMIT_LINENO(&next_object_file_charP, lineno_rootP, the_object_file); + know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers) + H_GET_LINENO_SIZE(&headers))); + + /* + * Emit symbols. + */ + obj_emit_symbols(&next_object_file_charP, symbol_rootP); + know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers) + H_GET_LINENO_SIZE(&headers) + H_GET_SYMBOL_TABLE_SIZE(&headers))); + + /* + * Emit strings. + */ + + if (string_byte_count > 0) { + obj_emit_strings(&next_object_file_charP); + } /* only if we have a string table */ + + /* know((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE(&headers) + H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers) + H_GET_TEXT_RELOCATION_SIZE(&headers) + H_GET_DATA_RELOCATION_SIZE(&headers) + H_GET_LINENO_SIZE(&headers) + H_GET_SYMBOL_TABLE_SIZE(&headers) + H_GET_STRING_SIZE(&headers))); + */ + /* know(next_object_file_charP == the_object_file + object_file_size);*/ + #ifdef BFD_HEADERS - bfd_seek(stdoutput, 0, 0); - bfd_write(the_object_file, 1, object_file_size, stdoutput); + bfd_seek(stdoutput, 0, 0); + bfd_write(the_object_file, 1, object_file_size, stdoutput); #else - - /* Write the data to the file */ - output_file_append(the_object_file,object_file_size,out_file_name); + + /* Write the data to the file */ + output_file_append(the_object_file,object_file_size,out_file_name); #endif - + #ifdef DONTDEF - if (flagseen['G']) /* GDB symbol file to be appended? */ - { - gdb_emit (out_file_name); - gdb_end (); - } + if (flagseen['G']) /* GDB symbol file to be appended? */ + { + gdb_emit (out_file_name); + gdb_end (); + } #endif /* DONTDEF */ - - output_file_close(out_file_name); - } /* non vms output */ + + output_file_close(out_file_name); + } /* non vms output */ #else /* VMS */ - /* - * Now do the VMS-dependent part of writing the object file - */ - VMS_write_object_file(text_siz, data_siz, text_frag_root, data_frag_root); + /* + * Now do the VMS-dependent part of writing the object file + */ + VMS_write_object_file(text_siz, data_siz, text_frag_root, data_frag_root); #endif /* VMS */ } /* write_object_file() */ #else @@ -604,8 +602,8 @@ void write_object_file() void relax_segment(segment_frag_root, segment) - struct frag * segment_frag_root; - segT segment; /* SEG_DATA or SEG_TEXT */ +struct frag * segment_frag_root; +segT segment; /* SEG_DATA or SEG_TEXT */ { register struct frag * fragP; register relax_addressT address; @@ -687,7 +685,7 @@ void relax_segment(segment_frag_root, segment) symbolP = fragP->fr_symbol; offset = fragP->fr_offset; /* var = fragP->fr_var; */ - + switch (fragP->fr_type) { case rs_fill: /* .fill never relaxes. */ growth = 0; @@ -715,7 +713,7 @@ void relax_segment(segment_frag_root, segment) if (lie->added) continue; - + offset= lie->add->sy_frag->fr_address+ S_GET_VALUE(lie->add) + lie->addnum - (lie->sub->sy_frag->fr_address+ S_GET_VALUE(lie->sub)); if (offset<=-32768 || offset>=32767) { @@ -749,7 +747,7 @@ void relax_segment(segment_frag_root, segment) case rs_org: target = offset; - + if (symbolP) { #ifdef MANY_SEGMENTS #else @@ -760,7 +758,7 @@ void relax_segment(segment_frag_root, segment) target += S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address; } /* if we have a symbol */ - + know(fragP->fr_next); after = fragP->fr_next->fr_address; growth = ((target - after ) > 0) ? (target - after) : 0; @@ -779,10 +777,10 @@ void relax_segment(segment_frag_root, segment) start_type = this_type = md_relax_table + (this_state = fragP->fr_subtype); target = offset; - + if (symbolP) { #ifndef MANY_SEGMENTS - know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || (S_GET_SEGMENT(symbolP) == SEG_DATA) || (S_GET_SEGMENT(symbolP) == SEG_TEXT)) + know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || (S_GET_SEGMENT(symbolP) == SEG_DATA) || (S_GET_SEGMENT(symbolP) == SEG_TEXT)); #endif know(symbolP->sy_frag); know(!(S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || symbolP->sy_frag==&zero_address_frag ); @@ -823,7 +821,7 @@ void relax_segment(segment_frag_root, segment) } /* */ } /* if there's a symbol attached */ - + aim = target - address - fragP->fr_fix; /* The displacement is affected by the instruction size * for the 32k architecture. I think we ought to be able @@ -853,6 +851,9 @@ void relax_segment(segment_frag_root, segment) aim=this_type->rlx_forward+1; /* Force relaxation into word mode */ } #endif +#ifdef M68K_AIM_KLUDGE + M68K_AIM_KLUDGE(aim, this_state, this_type); +#endif /* JF end of 68020 code */ /* Look forwards. */ for (next_state = this_type->rlx_more; next_state; ) { @@ -864,10 +865,10 @@ void relax_segment(segment_frag_root, segment) } } } - + if ((growth = this_type->rlx_length - start_type->rlx_length) != 0) fragP->fr_subtype = this_state; - + break; } /* case rs_machine_dependent */ @@ -898,26 +899,26 @@ void relax_segment(segment_frag_root, segment) * lowest order bits all 0s. */ - /* How many addresses does the .align take? */ +/* How many addresses does the .align take? */ static relax_addressT relax_align(address, alignment) register relax_addressT address; /* Address now. */ register long alignment; /* Alignment (binary). */ { - relax_addressT mask; - relax_addressT new_address; - - mask = ~ ( (~0) << alignment ); - new_address = (address + mask) & (~ mask); - return (new_address - address); + relax_addressT mask; + relax_addressT new_address; + + mask = ~ ( (~0) << alignment ); + new_address = (address + mask) & (~ mask); + return (new_address - address); } /* relax_align() */ /* fixup_segment() - + Go through all the fixS's in a segment and see which ones can be handled now. (These consist of fixS where we have since discovered the value of a symbol, or the address of the frag involved.) For each one, call md_apply_fix to put the fix into the frag data. - + Result is a count of how many relocation structs will be needed to handle the remaining fixS's that we couldn't completely handle here. These will be output later by emit_relocations(). */ @@ -937,7 +938,7 @@ segT this_segment_type; /* N_TYPE bits for segment. */ register fragS *fragP; register segT add_symbol_segment = SEG_ABSOLUTE; -/* FIXME: remove this line */ /* fixS *orig = fixP; */ + /* FIXME: remove this line */ /* fixS *orig = fixP; */ seg_reloc_count = 0; for ( ; fixP; fixP = fixP->fx_next) { @@ -952,10 +953,10 @@ segT this_segment_type; /* N_TYPE bits for segment. */ /* Relocation should be done via the associated 'bal' entry point symbol. */ - + if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) { as_bad("No 'bal' entry point for leafproc %s", - S_GET_NAME(add_symbolP)); + S_GET_NAME(add_symbolP)); continue; } fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP); @@ -964,7 +965,7 @@ segT this_segment_type; /* N_TYPE bits for segment. */ sub_symbolP = fixP->fx_subsy; add_number = fixP->fx_offset; pcrel = fixP->fx_pcrel; - + if (add_symbolP) { add_symbol_segment = S_GET_SEGMENT(add_symbolP); } /* if there is an addend */ @@ -981,8 +982,8 @@ segT this_segment_type; /* N_TYPE bits for segment. */ /* if sub_symbol is in the same segment that add_symbol and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */ } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment) - && (SEG_NORMAL(add_symbol_segment) - || (add_symbol_segment == SEG_ABSOLUTE))) { + && (SEG_NORMAL(add_symbol_segment) + || (add_symbol_segment == SEG_ABSOLUTE))) { /* Difference of 2 symbols from same segment. */ /* Can't make difference of 2 undefineds: 'value' means */ /* something different for N_UNDF. */ @@ -1007,12 +1008,12 @@ segT this_segment_type; /* N_TYPE bits for segment. */ add_number -= S_GET_VALUE(sub_symbolP); } else { as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.", - segment_name(S_GET_SEGMENT(sub_symbolP)), - S_GET_NAME(sub_symbolP), fragP->fr_address + where); + segment_name(S_GET_SEGMENT(sub_symbolP)), + S_GET_NAME(sub_symbolP), fragP->fr_address + where); } /* if absolute */ } } /* if sub_symbolP */ - + if (add_symbolP) { if (add_symbol_segment == this_segment_type && pcrel) { /* @@ -1061,23 +1062,23 @@ segT this_segment_type; /* N_TYPE bits for segment. */ continue; } /* COBR */ #endif /* TC_I960 */ - /* FIXME-SOON: I think this is trash, but I'm not sure. xoxorich. */ + /* FIXME-SOON: I think this is trash, but I'm not sure. xoxorich. */ #ifdef comment #ifdef OBJ_COFF if (S_IS_COMMON(add_symbolP)) add_number += S_GET_VALUE(add_symbolP); #endif /* OBJ_COFF */ #endif /* comment */ - + ++seg_reloc_count; - + break; - + } /* switch on symbol seg */ } /* if not in local seg */ } /* if there was a + symbol */ - + if (pcrel) { add_number -= md_pcrel_from(fixP); if (add_symbolP == 0) { @@ -1092,7 +1093,7 @@ segT this_segment_type; /* N_TYPE bits for segment. */ (size==2 && (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) { as_bad("Value of %d too large for field of %d bytes at 0x%x", - add_number, size, fragP->fr_address + where); + add_number, size, fragP->fr_address + where); } /* generic error checking */ } /* not a bit fix */ @@ -1112,7 +1113,7 @@ segT this_segment_type; /* N_TYPE bits for segment. */ } /* for each fix */ } #endif /* TC_I960 */ - + #endif /* OBJ_COFF */ return(seg_reloc_count); } /* fixup_segment() */ @@ -1124,7 +1125,7 @@ struct frag *f2; { while (f1) { if (f1->fr_next==f2) - return 1; + return 1; f1=f1->fr_next; } return 0; @@ -1132,7 +1133,7 @@ struct frag *f2; /* Append a string onto another string, bumping the pointer along. */ void -append (charPP, fromP, length) + append (charPP, fromP, length) char **charPP; char *fromP; unsigned long length; diff --git a/gas/write.h b/gas/write.h index 1eecdc0..d3f3072 100644 --- a/gas/write.h +++ b/gas/write.h @@ -3,22 +3,22 @@ /* MODIFIED BY CHRIS BENENATI, FOR INTEL CORPORATION, 4/89 */ /* write.h -> write.c Copyright (C) 1987 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. */ + + 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. */ #ifndef TC_I960 #ifdef hpux @@ -29,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef LOCAL_LABEL #ifdef DOT_LABEL_PREFIX #define LOCAL_LABEL(name) (name[0] =='.' \ - && ( name [1] == 'L' || name [1] == '.' )) + && ( name [1] == 'L' || name [1] == '.' )) #else /* not defined DOT_LABEL_PREFIX */ #define LOCAL_LABEL(name) (name [0] == 'L' ) #endif /* not defined DOT_LABEL_PREFIX */ @@ -41,55 +41,56 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ to be inserted in bitfields other than 1, 2 and 4 bytes. Furthermore it gives us a possibillity to mask in bits in the symbol when it's fixed in the objectcode and check the symbols limits. - + The or-mask is used to set the huffman bits in displacements for the ns32k port. The acbi, addqi, movqi, cmpqi instruction requires an assembler that can handle bitfields. Ie handle an expression, evaluate it and insert the result in an some bitfield. ( ex: 5 bits in a short field of a opcode) - */ + */ struct bit_fix { - int fx_bit_size; /* Length of bitfield */ - int fx_bit_offset; /* Bit offset to bitfield */ - long fx_bit_base; /* Where do we apply the bitfix. - If this is zero, default is assumed. */ - long fx_bit_base_adj;/* Adjustment of base */ - long fx_bit_max; /* Signextended max for bitfield */ - long fx_bit_min; /* Signextended min for bitfield */ - long fx_bit_add; /* Or mask, used for huffman prefix */ + int fx_bit_size; /* Length of bitfield */ + int fx_bit_offset; /* Bit offset to bitfield */ + long fx_bit_base; /* Where do we apply the bitfix. + If this is zero, default is assumed. */ + long fx_bit_base_adj;/* Adjustment of base */ + long fx_bit_max; /* Signextended max for bitfield */ + long fx_bit_min; /* Signextended min for bitfield */ + long fx_bit_add; /* Or mask, used for huffman prefix */ }; typedef struct bit_fix bit_fixS; /* * FixSs may be built up in any order. */ -struct fix -{ - fragS * fx_frag; /* Which frag? */ - long fx_where; /* Where is the 1st byte to fix up? */ - symbolS * fx_addsy; /* NULL or Symbol whose value we add in. */ - symbolS * fx_subsy; /* NULL or Symbol whose value we subtract. */ - long fx_offset; /* Absolute number we add in. */ - struct fix * fx_next; /* NULL or -> next fixS. */ - short int fx_size; /* How many bytes are involved? */ - char fx_pcrel; /* TRUE: pc-relative. */ - char fx_pcrel_adjust;/* pc-relative offset adjust */ - char fx_im_disp; /* TRUE: value is a displacement */ - bit_fixS * fx_bit_fixP; /* IF NULL no bitfix's to do */ - char fx_bsr; /* sequent-hack */ - enum reloc_type fx_r_type; /* Sparc hacks */ - char fx_callj; /* TRUE if target is a 'callj' - (used by i960) */ - long fx_addnumber; +struct fix { + fragS *fx_frag; /* Which frag? */ + long fx_where; /* Where is the 1st byte to fix up? */ + symbolS *fx_addsy; /* NULL or Symbol whose value we add in. */ + symbolS *fx_subsy; /* NULL or Symbol whose value we subtract. */ + long fx_offset; /* Absolute number we add in. */ + struct fix *fx_next; /* NULL or -> next fixS. */ + short int fx_size; /* How many bytes are involved? */ + char fx_pcrel; /* TRUE: pc-relative. */ + char fx_pcrel_adjust;/* pc-relative offset adjust */ + char fx_im_disp; /* TRUE: value is a displacement */ + bit_fixS *fx_bit_fixP; /* IF NULL no bitfix's to do */ + char fx_bsr; /* sequent-hack */ + enum reloc_type fx_r_type; /* Sparc hacks */ + char fx_callj; /* TRUE if target is a 'callj' + (used by i960) */ + long fx_addnumber; }; -typedef struct fix fixS; +typedef struct fix fixS; COMMON char *next_object_file_charP; +#ifndef MANY_SEGMENTS COMMON fixS *text_fix_root, *text_fix_tail; /* Chains fixSs. */ COMMON fixS *data_fix_root, *data_fix_tail; /* Chains fixSs. */ +#endif COMMON fixS **seg_fix_rootP, **seg_fix_tailP; /* -> one of above. */ extern long string_byte_count; extern int section_alignment[]; diff --git a/gas/xmalloc.c b/gas/xmalloc.c index 426b171..fad8618 100644 --- a/gas/xmalloc.c +++ b/gas/xmalloc.c @@ -1,44 +1,44 @@ /* xmalloc.c - get memory or bust Copyright (C) 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 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. */ /* -NAME - xmalloc() - get memory or bust -INDEX - xmalloc() uses malloc() - -SYNOPSIS - char * my_memory; - - my_memory = xmalloc(42); / * my_memory gets address of 42 chars * / - -DESCRIPTION - - Use xmalloc() as an "error-free" malloc(). It does almost the same job. - When it cannot honour your request for memory it BOMBS your program - with a "virtual memory exceeded" message. Malloc() returns NULL and - does not bomb your program. - -SEE ALSO - malloc() - -*/ + NAME + xmalloc() - get memory or bust + INDEX + xmalloc() uses malloc() + + SYNOPSIS + char * my_memory; + + my_memory = xmalloc(42); / * my_memory gets address of 42 chars * / + + DESCRIPTION + + Use xmalloc() as an "error-free" malloc(). It does almost the same job. + When it cannot honour your request for memory it BOMBS your program + with a "virtual memory exceeded" message. Malloc() returns NULL and + does not bomb your program. + + SEE ALSO + malloc() + + */ #include <stdio.h> #ifdef __STDC__ @@ -47,23 +47,23 @@ SEE ALSO #ifdef USG #include <malloc.h> #else - char * malloc(); +char * malloc(); #endif /* USG */ #endif /* __STDC__ */ #define error as_fatal char * xmalloc(n) - long n; +long n; { - char * retval; - void error(); - - if ((retval = malloc ((unsigned)n)) == NULL) - { - error("virtual memory exceeded"); - } - return (retval); + char * retval; + void error(); + + if ((retval = malloc ((unsigned)n)) == NULL) + { + error("virtual memory exceeded"); + } + return (retval); } /* end: xmalloc.c */ diff --git a/gas/xrealloc.c b/gas/xrealloc.c index f184243..b31f182 100644 --- a/gas/xrealloc.c +++ b/gas/xrealloc.c @@ -1,45 +1,45 @@ /* xrealloc.c -new memory or bust- Copyright (C) 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 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. */ /* - -NAME - xrealloc () - get more memory or bust -INDEX - xrealloc () uses realloc () -SYNOPSIS - char *my_memory; - - my_memory = xrealloc (my_memory, 42); - / * my_memory gets (perhaps new) address of 42 chars * / - -DESCRIPTION - - Use xrealloc () as an "error-free" realloc ().It does almost the same - job. When it cannot honour your request for memory it BOMBS your - program with a "virtual memory exceeded" message. Realloc() returns - NULL and does not bomb your program. - -SEE ALSO - realloc () -*/ + + NAME + xrealloc () - get more memory or bust + INDEX + xrealloc () uses realloc () + SYNOPSIS + char *my_memory; + + my_memory = xrealloc (my_memory, 42); + / * my_memory gets (perhaps new) address of 42 chars * / + + DESCRIPTION + + Use xrealloc () as an "error-free" realloc ().It does almost the same + job. When it cannot honour your request for memory it BOMBS your + program with a "virtual memory exceeded" message. Realloc() returns + NULL and does not bomb your program. + + SEE ALSO + realloc () + */ #ifdef __STDC__ #include <stdlib.h> @@ -47,22 +47,22 @@ SEE ALSO #ifdef USG #include <malloc.h> #else - char *realloc (); +char *realloc (); #endif /* USG */ #endif /* __STDC__ */ #define error as_fatal char * -xrealloc (ptr, n) + xrealloc (ptr, n) register char *ptr; long n; { - void error(); - - if ((ptr = realloc (ptr, (unsigned)n)) == 0) - error ("virtual memory exceeded"); - return (ptr); + void error(); + + if ((ptr = realloc (ptr, (unsigned)n)) == 0) + error ("virtual memory exceeded"); + return (ptr); } /* end: xrealloc.c */ |