X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-tahoe.c;h=6bef4be983f0094b76bfe993ffedf44d8339f43e;hb=d01ecef67288811d520d1ffe26ac36350882b213;hp=034df4827dba0260556710750adb417e6083d881;hpb=2ee563b53258d390d7446e90a67f465d504ae44c;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-tahoe.c b/gas/config/tc-tahoe.c index 034df4827d..6bef4be983 100644 --- a/gas/config/tc-tahoe.c +++ b/gas/config/tc-tahoe.c @@ -1,7 +1,7 @@ /* This file is tc-tahoe.c - Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1995, 2000, 2001, 2002 - Free Software Foundation, Inc. + Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1995, 2000, 2001, 2002, + 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -17,8 +17,9 @@ 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, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + #include "as.h" #include "safe-ctype.h" #include "obstack.h" @@ -31,51 +32,51 @@ typedef byte tahoe_opcodeT; /* This is part of tahoe-ins-parse.c & friends. We want to parse a tahoe instruction text into a tree defined here. */ -#define TIT_MAX_OPERANDS (4) /* maximum number of operands in one - single tahoe instruction */ +#define TIT_MAX_OPERANDS 4 /* Maximum number of operands in one + single tahoe instruction. */ -struct top /* tahoe instruction operand */ +struct top /* Tahoe instruction operand. */ { - int top_ndx; /* -1, or index register. eg 7=[R7] */ - int top_reg; /* -1, or register number. eg 7 = R7 or (R7) */ + int top_ndx; /* -1, or index register. eg 7=[R7]. */ + int top_reg; /* -1, or register number. eg 7 = R7 or (R7). */ byte top_mode; /* Addressing mode byte. This byte, defines which of the 11 modes opcode is. */ - char top_access; /* Access type wanted for this opperand - 'b'branch ' 'no-instruction 'amrvw' */ - char top_width; /* Operand width expected, one of "bwlq?-:!" */ + char top_access; /* Access type wanted for this operand + 'b'branch ' 'no-instruction 'amrvw'. */ + char top_width; /* Operand width expected, one of "bwlq?-:!". */ - char * top_error; /* Say if operand is inappropriate */ + char * top_error; /* Say if operand is inappropriate. */ - segT seg_of_operand; /* segment as returned by expression()*/ + segT seg_of_operand; /* Segment as returned by expression(). */ - expressionS exp_of_operand; /* The expression as parsed by expression()*/ + expressionS exp_of_operand; /* The expression as parsed by expression(). */ byte top_dispsize; /* Number of bytes in the displacement if we - can figure it out */ + can figure it out. */ }; -/* The addressing modes for an operand. These numbers are the acutal values - for certain modes, so be carefull if you screw with them. */ -#define TAHOE_DIRECT_REG (0x50) -#define TAHOE_REG_DEFERRED (0x60) +/* The addressing modes for an operand. These numbers are the actual values + for certain modes, so be careful if you screw with them. */ +#define TAHOE_DIRECT_REG 0x50 +#define TAHOE_REG_DEFERRED 0x60 -#define TAHOE_REG_DISP (0xE0) -#define TAHOE_REG_DISP_DEFERRED (0xF0) +#define TAHOE_REG_DISP 0xE0 +#define TAHOE_REG_DISP_DEFERRED 0xF0 -#define TAHOE_IMMEDIATE (0x8F) -#define TAHOE_IMMEDIATE_BYTE (0x88) -#define TAHOE_IMMEDIATE_WORD (0x89) -#define TAHOE_IMMEDIATE_LONGWORD (0x8F) -#define TAHOE_ABSOLUTE_ADDR (0x9F) +#define TAHOE_IMMEDIATE 0x8F +#define TAHOE_IMMEDIATE_BYTE 0x88 +#define TAHOE_IMMEDIATE_WORD 0x89 +#define TAHOE_IMMEDIATE_LONGWORD 0x8F +#define TAHOE_ABSOLUTE_ADDR 0x9F -#define TAHOE_DISPLACED_RELATIVE (0xEF) -#define TAHOE_DISP_REL_DEFERRED (0xFF) +#define TAHOE_DISPLACED_RELATIVE 0xEF +#define TAHOE_DISP_REL_DEFERRED 0xFF -#define TAHOE_AUTO_DEC (0x7E) -#define TAHOE_AUTO_INC (0x8E) -#define TAHOE_AUTO_INC_DEFERRED (0x9E) -/* INDEXED_REG is decided by the existance or lack of a [reg]. */ +#define TAHOE_AUTO_DEC 0x7E +#define TAHOE_AUTO_INC 0x8E +#define TAHOE_AUTO_INC_DEFERRED 0x9E +/* INDEXED_REG is decided by the existence or lack of a [reg]. */ /* These are encoded into top_width when top_access=='b' and it's a psuedo op. */ @@ -86,34 +87,33 @@ struct top /* tahoe instruction operand */ /* The hex code for certain tahoe commands and modes. This is just for readability. */ -#define TAHOE_JMP (0x71) -#define TAHOE_PC_REL_LONG (0xEF) -#define TAHOE_BRB (0x11) -#define TAHOE_BRW (0x13) +#define TAHOE_JMP 0x71 +#define TAHOE_PC_REL_LONG 0xEF +#define TAHOE_BRB 0x11 +#define TAHOE_BRW 0x13 /* These, when 'ored' with, or added to, a register number, set up the number for the displacement mode. */ -#define TAHOE_PC_OR_BYTE (0xA0) -#define TAHOE_PC_OR_WORD (0xC0) -#define TAHOE_PC_OR_LONG (0xE0) +#define TAHOE_PC_OR_BYTE 0xA0 +#define TAHOE_PC_OR_WORD 0xC0 +#define TAHOE_PC_OR_LONG 0xE0 struct tit /* Get it out of the sewer, it stands for tahoe instruction tree (Geeze!). */ { tahoe_opcodeT tit_opcode; /* The opcode. */ byte tit_operands; /* How many operands are here. */ - struct top tit_operand[TIT_MAX_OPERANDS]; /* Operands */ - char *tit_error; /* "" or fatal error text */ + struct top tit_operand[TIT_MAX_OPERANDS]; /* Operands. */ + char *tit_error; /* "" or fatal error text. */ }; /* end: tahoe-inst.h */ /* tahoe.c - tahoe-specific - - Not part of gas yet. - */ + Not part of gas yet. */ #include "opcode/tahoe.h" -/* This is the number to put at the beginning of the a.out file */ +/* This is the number to put at the beginning of the a.out file. */ long omagic = OMAGIC; /* These chars start a comment anywhere in a source file (except inside @@ -123,21 +123,20 @@ const char comment_chars[] = "#;"; /* These chars only start a comment at the beginning of a line. */ const char line_comment_chars[] = "#"; -/* Chars that can be used to separate mant from exp in floating point nums */ +/* Chars that can be used to separate mant from exp in floating point nums. */ const char EXP_CHARS[] = "eE"; /* Chars that mean this number is a floating point constant as in 0f123.456 or 0d1.234E-12 (see exp chars above) Note: The Tahoe port doesn't support floating point constants. This is - consistant with 'as' If it's needed, I can always add it later. */ + consistent with 'as' If it's needed, I can always add it later. */ const char FLT_CHARS[] = "df"; /* 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. - (The tahoe has plenty of room, so the change currently isn't needed.) - */ + (The tahoe has plenty of room, so the change currently isn't needed.) */ static struct tit t; /* A tahoe instruction after decoding. */ @@ -152,27 +151,25 @@ const pseudo_typeS md_pseudo_table[] = {0} }; -/* - * For Tahoe, relative addresses of "just the right length" are pretty easy. - * The branch displacement is always the last operand, even in - * synthetic instructions. - * For Tahoe, we encode the relax_substateTs (in e.g. fr_substate) as: - * - * 4 3 2 1 0 bit number - * ---/ /--+-------+-------+-------+-------+-------+ - * | what state ? | how long ? | - * ---/ /--+-------+-------+-------+-------+-------+ - * - * The "how long" bits are 00=byte, 01=word, 10=long. - * This is a Un*x convention. - * Not all lengths are legit for a given value of (what state). - * The four states are listed below. - * The "how long" refers merely to the displacement length. - * The address usually has some constant bytes in it as well. - * - -States for Tahoe address relaxing. -1. TAHOE_WIDTH_ALWAYS_JUMP (-) +/* For Tahoe, relative addresses of "just the right length" are pretty easy. + The branch displacement is always the last operand, even in + synthetic instructions. + For Tahoe, we encode the relax_substateTs (in e.g. fr_substate) as: + + 4 3 2 1 0 bit number + ---/ /--+-------+-------+-------+-------+-------+ + | what state ? | how long ? | + ---/ /--+-------+-------+-------+-------+-------+ + + The "how long" bits are 00=byte, 01=word, 10=long. + This is a Un*x convention. + Not all lengths are legit for a given value of (what state). + The four states are listed below. + The "how long" refers merely to the displacement length. + The address usually has some constant bytes in it as well. + + States for Tahoe address relaxing. + 1. TAHOE_WIDTH_ALWAYS_JUMP (-) Format: "b-" Tahoe opcodes are: (Hex) jr 11 @@ -181,7 +178,7 @@ States for Tahoe address relaxing. Always, 1 byte opcode, then displacement/absolute. If word or longword, change opcode to brw or jmp. -2. TAHOE_WIDTH_CONDITIONAL_JUMP (?) + 2. TAHOE_WIDTH_CONDITIONAL_JUMP (?) J where is a simple flag test. Format: "b?" Tahoe opcodes are: (Hex) @@ -200,7 +197,7 @@ States for Tahoe address relaxing. Always, you complement 4th bit to reverse the condition. Always, 1-byte opcode, then 1-byte displacement. -3. TAHOE_WIDTH_BIG_REV_JUMP (!) + 3. TAHOE_WIDTH_BIG_REV_JUMP (!) Jbc/Jbs where cond tests a memory bit. Format: "rlvlb!" Tahoe opcodes are: (Hex) @@ -209,7 +206,7 @@ States for Tahoe address relaxing. Always, you complement 4th bit to reverse the condition. Always, 1-byte opcde, longword, longword-address, 1-word-displacement -4. TAHOE_WIDTH_BIG_NON_REV_JUMP (:) + 4. TAHOE_WIDTH_BIG_NON_REV_JUMP (:) JaoblXX/Jbssi Format: "rlmlb:" Tahoe opcodes are: (Hex) @@ -221,13 +218,13 @@ States for Tahoe address relaxing. Always, we cannot reverse the sense of the branch; we have a word displacement. -We need to modify the opcode is for class 1, 2 and 3 instructions. -After relax() we may complement the 4th bit of 2 or 3 to reverse sense of -branch. + We need to modify the opcode is for class 1, 2 and 3 instructions. + After relax() we may complement the 4th bit of 2 or 3 to reverse sense of + branch. -We sometimes store context in the operand literal. This way we can figure out -after relax() what the original addressing mode was. (Was is pc_rel, or -pc_rel_disp? That sort of thing.) */ + We sometimes store context in the operand literal. This way we can figure out + after relax() what the original addressing mode was. (Was is pc_rel, or + pc_rel_disp? That sort of thing.) */ /* These displacements are relative to the START address of the displacement which is at the start of the displacement, not the end of @@ -237,28 +234,28 @@ pc_rel_disp? That sort of thing.) */ 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) +#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.] */ -#define C(a,b) ENCODE_RELAX(a,b) +#define C(a,b) ENCODE_RELAX(a, b) /* This macro has no side-effects. */ #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) -#define RELAX_STATE(s) ((s) >> 2) -#define RELAX_LENGTH(s) ((s) & 3) +#define RELAX_STATE(s) ((s) >> 2) +#define RELAX_LENGTH(s) ((s) & 3) -#define STATE_ALWAYS_BRANCH (1) -#define STATE_CONDITIONAL_BRANCH (2) -#define STATE_BIG_REV_BRANCH (3) -#define STATE_BIG_NON_REV_BRANCH (4) -#define STATE_PC_RELATIVE (5) +#define STATE_ALWAYS_BRANCH 1 +#define STATE_CONDITIONAL_BRANCH 2 +#define STATE_BIG_REV_BRANCH 3 +#define STATE_BIG_NON_REV_BRANCH 4 +#define STATE_PC_RELATIVE 5 -#define STATE_BYTE (0) -#define STATE_WORD (1) -#define STATE_LONG (2) -#define STATE_UNDF (3) /* Symbol undefined in pass1 */ +#define STATE_BYTE 0 +#define STATE_WORD 1 +#define STATE_LONG 2 +#define STATE_UNDF 3 /* Symbol undefined in pass1. */ /* This is the table used by gas to figure out relaxing modes. The fields are forward_branch reach, backward_branch reach, number of bytes it would take, @@ -267,30 +264,30 @@ const relax_typeS 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 */ /* Unconditional branch cases "jrb" The relax part is the actual displacement */ { BF, BB, 1, C (1, 1) - }, /* brb B`foo 1,0 */ + }, /* Brb B`foo 1,0 */ { WF, WB, 2, C (1, 2) - }, /* brw W`foo 1,1 */ + }, /* Brw W`foo 1,1 */ { 0, 0, 5, 0 }, /* Jmp L`foo 1,2 */ { 1, 1, 0, 0 - }, /* unused 1,3 */ + }, /* Unused 1,3 */ /* Reversible Conditional Branch. If the branch won't reach, reverse it, and jump over a brw or a jmp that will reach. The relax part is the actual address. */ @@ -305,12 +302,12 @@ const relax_typeS md_relax_table[] = }, /* brev over, jmp L`foo, over: 2,2 */ { 1, 1, 0, 0 - }, /* unused 2,3 */ -/* Another type of reversable branch. But this only has a word + }, /* Unused 2,3 */ +/* Another type of reversible branch. But this only has a word displacement. */ { 1, 1, 0, 0 - }, /* unused 3,0 */ + }, /* Unused 3,0 */ { WF, WB, 2, C (3, 2) }, /* jbX W`foo 3,1 */ @@ -319,15 +316,15 @@ const relax_typeS md_relax_table[] = }, /* jrevX over, jmp L`foo, over: 3,2 */ { 1, 1, 0, 0 - }, /* unused 3,3 */ -/* These are the non reversable branches, all of which have a word + }, /* Unused 3,3 */ +/* These are the non reversible branches, all of which have a word displacement. If I can't reach, branch over a byte branch, to a jump that will reach. The jumped branch jumps over the reaching branch, to continue with the flow of the program. It's like playing leap frog. */ { 1, 1, 0, 0 - }, /* unused 4,0 */ + }, /* Unused 4,0 */ { WF, WB, 2, C (4, 2) }, /* aobl_ W`foo 4,1 */ @@ -336,7 +333,7 @@ const relax_typeS md_relax_table[] = }, /*aobl_ W`hop,br over,hop: jmp L^foo,over 4,2*/ { 1, 1, 0, 0 - }, /* unused 4,3 */ + }, /* Unused 4,3 */ /* Normal displacement mode, no jumping or anything like that. The relax points to one byte before the address, thats why all the numbers are up by one. */ @@ -351,7 +348,7 @@ const relax_typeS md_relax_table[] = }, /* L^"foo" 5,2 */ { 1, 1, 0, 0 - }, /* unused 5,3 */ + }, /* Unused 5,3 */ }; #undef C @@ -359,15 +356,16 @@ const relax_typeS md_relax_table[] = #undef BB #undef WF #undef WB -/* End relax stuff */ +/* End relax stuff. */ /* Handle of the OPCODE hash table. NULL means any use before md_begin() will crash. */ static struct hash_control *op_hash; /* Init function. Build the hash table. */ + void -md_begin () +md_begin (void) { struct tot *tP; char *errorval = 0; @@ -387,15 +385,16 @@ md_begin () } const char *md_shortopts = "ad:STt:V"; -struct option md_longopts[] = { + +struct option md_longopts[] = +{ {NULL, no_argument, NULL, 0} }; + size_t md_longopts_size = sizeof (md_longopts); int -md_parse_option (c, arg) - int c; - char *arg; +md_parse_option (int c, char *arg) { switch (c) { @@ -431,8 +430,7 @@ md_parse_option (c, arg) } void -md_show_usage (stream) - FILE *stream; +md_show_usage (FILE *stream) { fprintf (stream, _("\ Tahoe options:\n\ @@ -447,88 +445,42 @@ Tahoe options:\n\ /* The functions in this section take numbers in the machine format, and munges them into Tahoe byte order. - They exist primarily for cross assembly purpose. */ -void /* Knows about order of bytes in address. */ -md_number_to_chars (con, value, nbytes) - char con[]; /* Return 'nbytes' of chars here. */ - valueT value; /* The value of the bits. */ - int nbytes; /* Number of bytes in the output. */ -{ - number_to_chars_bigendian (con, value, nbytes); -} + They exist primarily for cross assembly purpose. + Knows about order of bytes in address. */ -#ifdef comment -void /* Knows about order of bytes in address. */ -md_number_to_imm (con, value, nbytes) - char con[]; /* Return 'nbytes' of chars here. */ - long int value; /* The value of the bits. */ - int nbytes; /* Number of bytes in the output. */ +void +md_number_to_chars (char con[], /* Return 'nbytes' of chars here. */ + valueT value, /* The value of the bits. */ + int nbytes) /* Number of bytes in the output. */ { - md_number_to_chars (con, value, nbytes); + number_to_chars_bigendian (con, value, nbytes); } -#endif /* comment */ - void -md_apply_fix3 (fixP, valP, seg) - fixS *fixP ATTRIBUTE_UNUSED; - valueT * valP ATTRIBUTE_UNUSED; - segT seg ATTRIBUTE_UNUSED: +md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED, + valueT * valP ATTRIBUTE_UNUSED, + segT seg ATTRIBUTE_UNUSED) { /* Should never be called. */ know (0); } -void /* Knows about order of bytes in address. */ -md_number_to_disp (con, value, nbytes) - char con[]; /* Return 'nbytes' of chars here. */ - long int value; /* The value of the bits. */ - int nbytes; /* Number of bytes in the output. */ -{ - md_number_to_chars (con, value, nbytes); -} - -void /* Knows about order of bytes in address. */ -md_number_to_field (con, value, nbytes) - char con[]; /* Return 'nbytes' of chars here. */ - long int value; /* The value of the bits. */ - int nbytes; /* Number of bytes in the output. */ +void +md_number_to_disp (char con[]m /* Return 'nbytes' of chars here. */ + long int value, /* The value of the bits. */ + int nbytes) /* Number of bytes in the output. */ { md_number_to_chars (con, value, nbytes); } -/* Put the bits in an order that a tahoe will understand, despite the ordering - of the native machine. - On Tahoe: first 4 bytes are normal unsigned big endian long, - next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last). - The last byte is broken up with bit 7 as pcrel, - bits 6 & 5 as length, - bit 4 as extern and the last nibble as 'undefined'. */ - -#if comment void -md_ri_to_chars (ri_p, ri) - struct relocation_info *ri_p, ri; +md_number_to_field (char con[], /* Return 'nbytes' of chars here. */ + long int value, /* The value of the bits. */ + int nbytes) /* Number of bytes in the output. */ { - byte the_bytes[sizeof (struct relocation_info)]; - /* The reason I can't just encode these directly into ri_p is that - ri_p may point to ri. */ - - /* 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_symbolnum >> 16) & 0x0ff; - the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff; - the_bytes[6] = ri.r_symbolnum & 0x0ff; - the_bytes[7] = (((ri.r_extern << 4) & 0x10) | ((ri.r_length << 5) & 0x60) | - ((ri.r_pcrel << 7) & 0x80)) & 0xf0; - - bcopy (the_bytes, (char *) ri_p, sizeof (struct relocation_info)); + md_number_to_chars (con, value, nbytes); } -#endif /* comment */ - /* Put the bits in an order that a tahoe will understand, despite the ordering of the native machine. On Tahoe: first 4 bytes are normal unsigned big endian long, @@ -538,10 +490,9 @@ md_ri_to_chars (ri_p, ri) bit 4 as extern and the last nibble as 'undefined'. */ void -tc_aout_fix_to_chars (where, fixP, segment_address_in_file) - char *where; - fixS *fixP; - relax_addressT segment_address_in_file; +tc_aout_fix_to_chars (char *where, + fixS *fixP, + relax_addressT segment_address_in_file) { long r_symbolnum; @@ -569,17 +520,17 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file) | ((!S_IS_DEFINED (fixP->fx_addsy) << 4) & 0x10)); } -/* Relocate byte stuff */ +/* Relocate byte stuff. */ /* This is for broken word. */ -const int md_short_jump_size = 3; +int md_short_jump_size = 3; void -md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - addressT from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; +md_create_short_jump (char *ptr, + addressT from_addr, + addressT to_addr, + fragS *frag, + symbolS *to_symbol) { valueT offset; @@ -588,15 +539,15 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) md_number_to_chars (ptr, offset, 2); } -const int md_long_jump_size = 6; -const int md_reloc_size = 8; /* Size of relocation record */ +int md_long_jump_size = 6; +const int md_reloc_size = 8; /* Size of relocation record. */ void -md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - addressT from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; +md_create_long_jump (char *ptr, + addressT from_addr, + addressT to_addr, + fragS *frag, + symbolS *to_symbol) { valueT offset; @@ -610,10 +561,9 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) Any symbol that is now undefined will not become defined. Return the correct fr_subtype in the frag and the growth beyond fr_fix. */ + int -md_estimate_size_before_relax (fragP, segment_type) - register fragS *fragP; - segT segment_type; /* N_DATA or N_TEXT. */ +md_estimate_size_before_relax (fragS *fragP, segT segment_type) { if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF) { @@ -714,33 +664,27 @@ md_estimate_size_before_relax (fragP, segment_type) return md_relax_table[fragP->fr_subtype].rlx_length; } -/* - * md_convert_frag(); - * - * Called after relax() is finished. - * In: Address of frag. - * fr_type == rs_machine_dependent. - * fr_subtype is what the address relaxed to. - * - * Out: Any fixSs and constants are set up. - * Caller will turn frag into a ".space 0". - */ +/* Called after relax() is finished. + In: Address of frag. + fr_type == rs_machine_dependent. + fr_subtype is what the address relaxed to. + + Out: Any fixSs and constants are set up. + Caller will turn frag into a ".space 0". */ + void -md_convert_frag (headers, seg, fragP) - object_headers *headers; - segT seg; - register fragS *fragP; +md_convert_frag (object_headers *headers, segT seg, fragS *fragP) { - register char *addressP; /* -> _var to change. */ - register char *opcodeP; /* -> opcode char(s) to change. */ - register short int extension = 0; /* Size of relaxed address. - Added to fr_fix: incl. ALL var chars. */ - register symbolS *symbolP; - register long int where; - register long int address_of_var; - /* Where, in file space, is _var of *fragP? */ - register long int target_address; - /* Where, in file space, does addr point? */ + char *addressP; /* -> _var to change. */ + char *opcodeP; /* -> opcode char(s) to change. */ + short int extension = 0; /* Size of relaxed address. + Added to fr_fix: incl. ALL var chars. */ + symbolS *symbolP; + long int where; + long int address_of_var; + /* Where, in file space, is _var of *fragP? */ + long int target_address; + /* Where, in file space, does addr point? */ know (fragP->fr_type == rs_machine_dependent); where = fragP->fr_fix; @@ -750,11 +694,12 @@ md_convert_frag (headers, seg, fragP) know (symbolP); target_address = S_GET_VALUE (symbolP) + fragP->fr_offset; address_of_var = fragP->fr_address + where; + switch (fragP->fr_subtype) { case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE): /* *addressP holds the registers number, plus 0x10, if it's deferred - mode. To set up the right mode, just OR the size of this displacement */ + mode. To set up the right mode, just OR the size of this displacement. */ /* Byte displacement. */ *addressP++ |= TAHOE_PC_OR_BYTE; *addressP = target_address - (address_of_var + 2); @@ -782,7 +727,7 @@ md_convert_frag (headers, seg, fragP) case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD): *opcodeP ^= 0x10; /* Reverse sense of test. */ - *addressP++ = 3; /* Jump over word branch */ + *addressP++ = 3; /* Jump over word branch. */ *addressP++ = TAHOE_BRW; md_number_to_chars (addressP, target_address - (address_of_var + 4), 2); extension = 4; @@ -851,7 +796,7 @@ md_convert_frag (headers, seg, fragP) break; } fragP->fr_fix += extension; -} /* md_convert_frag */ +} /* This is the stuff for md_assemble. */ @@ -860,26 +805,24 @@ md_convert_frag (headers, seg, fragP) #define PC_REG 15 #define BIGGESTREG PC_REG -/* - * Parse the string pointed to by START - * If it represents a valid register, point START to the character after - * the last valid register char, and return the register number (0-15). - * If invalid, leave START alone, return -1. - * The format has to be exact. I don't do things like eat leading zeros - * or the like. - * Note: This doesn't check for the next character in the string making - * this invalid. Ex: R123 would return 12, it's the callers job to check - * what start is point to apon return. - * - * Valid registers are R1-R15, %1-%15, FP (13), SP (14), PC (15) - * Case doesn't matter. - */ +/* Parse the string pointed to by START + If it represents a valid register, point START to the character after + the last valid register char, and return the register number (0-15). + If invalid, leave START alone, return -1. + The format has to be exact. I don't do things like eat leading zeros + or the like. + Note: This doesn't check for the next character in the string making + this invalid. Ex: R123 would return 12, it's the callers job to check + what start is point to apon return. + + Valid registers are R1-R15, %1-%15, FP (13), SP (14), PC (15) + Case doesn't matter. */ + int -tahoe_reg_parse (start) - char **start; /* A pointer to the string to parse. */ +tahoe_reg_parse (char **start) /* A pointer to the string to parse. */ { - register char *regpoint = *start; - register int regnum = -1; + char *regpoint = *start; + int regnum = -1; switch (*regpoint++) { @@ -896,13 +839,11 @@ tahoe_reg_parse (start) /* Its a two digit number. */ regnum = 10 + (*regpoint++ - '0'); if (regnum > BIGGESTREG) - { /* Number too big? */ - regnum = -1; - } + regnum = -1; } } break; - case 'F': /* Is it the FP */ + case 'F': /* Is it the FP. */ case 'f': switch (*regpoint++) { @@ -911,7 +852,7 @@ tahoe_reg_parse (start) regnum = FP_REG; } break; - case 's': /* How about the SP */ + case 's': /* How about the SP. */ case 'S': switch (*regpoint++) { @@ -920,7 +861,7 @@ tahoe_reg_parse (start) regnum = SP_REG; } break; - case 'p': /* OR the PC even */ + case 'p': /* Or the PC even. */ case 'P': switch (*regpoint++) { @@ -932,101 +873,94 @@ tahoe_reg_parse (start) } if (regnum != -1) - { /* No error, so move string pointer */ - *start = regpoint; - } - return regnum; /* Return results */ -} /* tahoe_reg_parse */ + /* No error, so move string pointer. */ + *start = regpoint; + + return regnum; +} -/* - * This chops up an operand and figures out its modes and stuff. - * It's a little touchy about extra characters. - * Optex to start with one extra character so it can be overwritten for - * the backward part of the parsing. - * You can't put a bunch of extra characters in side to - * make the command look cute. ie: * foo ( r1 ) [ r0 ] - * If you like doing a lot of typing, try COBOL! - * Actually, this parser is a little weak all around. It's designed to be - * used with compliers, so I emphisise correct decoding of valid code quickly - * rather that catching every possable error. - * Note: This uses the expression function, so save input_line_pointer before - * calling. - * - * Sperry defines the semantics of address modes (and values) - * by a two-letter code, explained here. - * - * letter 1: access type - * - * a address calculation - no data access, registers forbidden - * b branch displacement - * m read - let go of bus - write back "modify" - * r read - * w write - * v bit field address: like 'a' but registers are OK - * - * letter 2: data type (i.e. width, alignment) - * - * b byte - * w word - * l longword - * q quadword (Even regs < 14 allowed) (if 12, you get a warning) - * - unconditional synthetic jbr operand - * ? simple synthetic reversable branch operand - * ! complex synthetic reversable branch operand - * : complex synthetic non-reversable branch operand - * - * The '-?!:' letter 2's are not for external consumption. They are used - * by GAS for psuedo ops relaxing code. - * - * After parsing topP has: - * - * top_ndx: -1, or the index register. eg 7=[R7] - * top_reg: -1, or register number. eg 7 = R7 or (R7) - * top_mode: The addressing mode byte. This byte, defines which of - * the 11 modes opcode is. - * top_access: Access type wanted for this opperand 'b'branch ' ' - * no-instruction 'amrvw' - * top_width: Operand width expected, one of "bwlq?-:!" - * exp_of_operand: The expression as parsed by expression() - * top_dispsize: Number of bytes in the displacement if we can figure it - * out and it's relavent. - * - * Need syntax checks built. - */ +/* This chops up an operand and figures out its modes and stuff. + It's a little touchy about extra characters. + Optex to start with one extra character so it can be overwritten for + the backward part of the parsing. + You can't put a bunch of extra characters in side to + make the command look cute. ie: * foo ( r1 ) [ r0 ] + If you like doing a lot of typing, try COBOL! + Actually, this parser is a little weak all around. It's designed to be + used with compliers, so I emphasize correct decoding of valid code quickly + rather that catching every possible error. + Note: This uses the expression function, so save input_line_pointer before + calling. + + Sperry defines the semantics of address modes (and values) + by a two-letter code, explained here. + + letter 1: access type + + a address calculation - no data access, registers forbidden + b branch displacement + m read - let go of bus - write back "modify" + r read + w write + v bit field address: like 'a' but registers are OK + + letter 2: data type (i.e. width, alignment) + + b byte + w word + l longword + q quadword (Even regs < 14 allowed) (if 12, you get a warning) + - unconditional synthetic jbr operand + ? simple synthetic reversible branch operand + ! complex synthetic reversible branch operand + : complex synthetic non-reversible branch operand + + The '-?!:' letter 2's are not for external consumption. They are used + by GAS for psuedo ops relaxing code. + + After parsing topP has: + + top_ndx: -1, or the index register. eg 7=[R7] + top_reg: -1, or register number. eg 7 = R7 or (R7) + top_mode: The addressing mode byte. This byte, defines which of + the 11 modes opcode is. + top_access: Access type wanted for this operand 'b'branch ' ' + no-instruction 'amrvw' + top_width: Operand width expected, one of "bwlq?-:!" + exp_of_operand: The expression as parsed by expression() + top_dispsize: Number of bytes in the displacement if we can figure it + out and it's relevant. + + Need syntax checks built. */ void -tip_op (optex, topP) - char *optex; /* The users text input, with one leading character */ - struct top *topP; /* The tahoe instruction with some fields already set: - in: access, width - out: ndx, reg, mode, error, dispsize */ - +tip_op (char *optex, /* The users text input, with one leading character. */ + struct top *topP) /* The tahoe instruction with some fields already set: + in: access, width + out: ndx, reg, mode, error, dispsize. */ { int mode = 0; /* This operand's mode. */ char segfault = *optex; /* To keep the back parsing from freaking. */ char *point = optex + 1; /* Parsing from front to back. */ char *end; /* Parsing from back to front. */ - int reg = -1; /* major register, -1 means absent */ - int imreg = -1; /* Major register in immediate mode */ - int ndx = -1; /* index register number, -1 means absent */ + int reg = -1; /* major register, -1 means absent. */ + int imreg = -1; /* Major register in immediate mode. */ + int ndx = -1; /* index register number, -1 means absent. */ char dec_inc = ' '; /* Is the SP auto-incremented '+' or auto-decremented '-' or neither ' '. */ - int immediate = 0; /* 1 if '$' immediate mode */ - int call_width = 0; /* If the caller casts the displacement */ - int abs_width = 0; /* The width of the absolute displacment */ - int com_width = 0; /* Displacement width required by branch */ - int deferred = 0; /* 1 if '*' deferral is used */ - byte disp_size = 0; /* How big is this operand. 0 == don't know */ - char *op_bad = ""; /* Bad operand error */ - - char *tp, *temp, c; /* Temporary holders */ - - char access = topP->top_access; /* Save on a deref. */ + int immediate = 0; /* 1 if '$' immediate mode. */ + int call_width = 0; /* If the caller casts the displacement. */ + int abs_width = 0; /* The width of the absolute displacement. */ + int com_width = 0; /* Displacement width required by branch. */ + int deferred = 0; /* 1 if '*' deferral is used. */ + byte disp_size = 0; /* How big is this operand. 0 == don't know. */ + char *op_bad = ""; /* Bad operand error. */ + char *tp, *temp, c; /* Temporary holders. */ + char access = topP->top_access;/* Save on a deref. */ char width = topP->top_width; - int really_none = 0; /* Empty expressions evaluate to 0 - but I need to know if it's there or not */ - expressionS *expP; /* -> expression values for this operand */ + but I need to know if it's there or not. */ + expressionS *expP; /* -> expression values for this operand. */ /* Does this command restrict the displacement size. */ if (access == 'b') @@ -1035,23 +969,21 @@ tip_op (optex, topP) (width == 'l' ? 4 : 0))); *optex = '\0'; /* This is kind of a back stop for all - the searches to fail on if needed.*/ + the searches to fail on if needed. */ if (*point == '*') - { /* A dereference? */ + { + /* A dereference? */ deferred = 1; point++; } - /* Force words into a certain mode */ - /* Bitch, Bitch, Bitch! */ - /* - * Using the ^ operator is ambigous. If I have an absolute label - * called 'w' set to, say 2, and I have the expression 'w^1', do I get - * 1, forced to be in word displacement mode, or do I get the value of - * 'w' or'ed with 1 (3 in this case). - * The default is 'w' as an offset, so that's what I use. - * Stick with `, it does the same, and isn't ambig. - */ + /* Force words into a certain mode. */ + /* Using the ^ operator is ambiguous. If I have an absolute label + called 'w' set to, say 2, and I have the expression 'w^1', do I get + 1, forced to be in word displacement mode, or do I get the value of + 'w' or'ed with 1 (3 in this case). + The default is 'w' as an offset, so that's what I use. + Stick with `, it does the same, and isn't ambig. */ if (*point != '\0' && ((point[1] == '^') || (point[1] == '`'))) switch (*point) @@ -1074,26 +1006,24 @@ tip_op (optex, topP) break; } - /* Setting immediate mode */ + /* Setting immediate mode. */ if (*point == '$') { immediate = 1; point++; } - /* - * I've pulled off all the easy stuff off the front, move to the end and - * yank. - */ + /* I've pulled off all the easy stuff off the front, move to the end and + yank. */ for (end = point; *end != '\0'; end++) /* Move to the end. */ ; - if (end != point) /* Null string? */ + if (end != point) /* Null string? */ end--; if (end > point && *end == ' ' && end[-1] != '\'') - end--; /* Hop white space */ + end--; /* Hop white space. */ /* Is this an index reg. */ if ((*end == ']') && (end[-1] != '\'')) @@ -1110,13 +1040,12 @@ tip_op (optex, topP) tp = end + 1; /* tp should point to the start of a reg. */ ndx = tahoe_reg_parse (&tp); if (tp != temp) - { /* Reg. parse error. */ - ndx = -1; - } + /* Reg. parse error. */ + ndx = -1; else - { - end--; /* Found it, move past brace. */ - } + /* Found it, move past brace. */ + end--; + if (ndx == -1) { op_bad = _("Couldn't parse the [index] in this operand."); @@ -1138,7 +1067,7 @@ tip_op (optex, topP) end--; } - /* register in parens? */ + /* Register in parens? */ if ((*end == ')') && (end[-1] != '\'')) { temp = end; @@ -1156,21 +1085,22 @@ tip_op (optex, topP) { /* Not a register, but could be part of the expression. */ reg = -1; - end = temp; /* Rest the pointer back */ + /* Rest the pointer back. */ + end = temp; } else - { - end--; /* Found the reg. move before opening paren. */ - } + /* Found the reg. move before opening paren. */ + end--; } else { op_bad = _("Couldn't find the opening '(' for the deref of this operand."); - end = point; /* Force all the rest of the tests to fail. */ + /* Force all the rest of the tests to fail. */ + end = point; } } - /* Pre decrement? */ + /* Pre decrement? */ if (*end == '-') { if (dec_inc != ' ') @@ -1181,22 +1111,18 @@ tip_op (optex, topP) else { dec_inc = '-'; - /* was: *end--; */ end--; } } - /* - * Everything between point and end is the 'expression', unless it's - * a register name. - */ - + /* Everything between point and end is the 'expression', unless it's + a register name. */ c = end[1]; end[1] = '\0'; tp = point; - imreg = tahoe_reg_parse (&point); /* Get the immediate register - if it is there.*/ + /* Get the immediate register if it is there. */ + imreg = tahoe_reg_parse (&point); if (*point != '\0') { /* If there is junk after point, then the it's not immediate reg. */ @@ -1207,12 +1133,9 @@ tip_op (optex, topP) if (imreg != -1 && reg != -1) op_bad = _("I parsed 2 registers in this operand."); - /* - * Evaluate whats left of the expression to see if it's valid. - * Note again: This assumes that the calling expression has saved - * input_line_pointer. (Nag, nag, nag!) - */ - + /* Evaluate whats left of the expression to see if it's valid. + Note again: This assumes that the calling expression has saved + input_line_pointer. (Nag, nag, nag!). */ if (*op_bad == '\0') { /* Statement has no syntax goofs yet: let's sniff the expression. */ @@ -1223,37 +1146,35 @@ tip_op (optex, topP) { case O_absent: /* No expression. For BSD4.2 compatibility, missing expression is - absolute 0 */ + absolute 0. */ expP->X_op = O_constant; expP->X_add_number = 0; really_none = 1; case O_constant: - /* for SEG_ABSOLUTE, we shouldnt need to set X_op_symbol, + /* For SEG_ABSOLUTE, we shouldn't need to set X_op_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 so. */ expP->X_add_symbol = NULL; expP->X_op_symbol = NULL; - /* How many bytes are needed to express this abs value? */ + /* How many bytes are needed to express this abs value? */ abs_width = - ((((expP->X_add_number & 0xFFFFFF80) == 0) || - ((expP->X_add_number & 0xFFFFFF80) == 0xFFFFFF80)) ? 1 : - (((expP->X_add_number & 0xFFFF8000) == 0) || - ((expP->X_add_number & 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4); + ((((expP->X_add_number & 0xFFFFFF80) == 0) + || ((expP->X_add_number & 0xFFFFFF80) == 0xFFFFFF80)) ? 1 : + (((expP->X_add_number & 0xFFFF8000) == 0) + || ((expP->X_add_number & 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4); case O_symbol: break; default: - /* - * Major bug. We can't handle the case of an operator - * expression in a synthetic opcode variable-length - * instruction. We don't have a frag type that is smart - * enough to relax an operator, and so we just force all - * operators 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. - */ + /* Major bug. We can't handle the case of an operator + expression in a synthetic opcode variable-length + instruction. We don't have a frag type that is smart + enough to relax an operator, and so we just force all + operators 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. */ need_pass_2 = 1; op_bad = _("Can't relocate expression error."); break; @@ -1265,35 +1186,32 @@ tip_op (optex, topP) op_bad = _("Expression is too large for a 32 bits."); break; } + if (*input_line_pointer != '\0') - { - op_bad = _("Junk at end of expression."); - } + op_bad = _("Junk at end of expression."); } end[1] = c; - /* I'm done, so restore optex */ + /* I'm done, so restore optex. */ *optex = segfault; - /* - * At this point in the game, we (in theory) have all the components of - * the operand at least parsed. Now it's time to check for syntax/semantic - * errors, and build the mode. - * This is what I have: - * deferred = 1 if '*' - * call_width = 0,1,2,4 - * abs_width = 0,1,2,4 - * com_width = 0,1,2,4 - * immediate = 1 if '$' - * ndx = -1 or reg num - * dec_inc = '-' or '+' or ' ' - * reg = -1 or reg num - * imreg = -1 or reg num - * topP->exp_of_operand - * really_none - */ - /* Is there a displacement size? */ + /* At this point in the game, we (in theory) have all the components of + the operand at least parsed. Now it's time to check for syntax/semantic + errors, and build the mode. + This is what I have: + deferred = 1 if '*' + call_width = 0,1,2,4 + abs_width = 0,1,2,4 + com_width = 0,1,2,4 + immediate = 1 if '$' + ndx = -1 or reg num + dec_inc = '-' or '+' or ' ' + reg = -1 or reg num + imreg = -1 or reg num + topP->exp_of_operand + really_none. */ + /* Is there a displacement size? */ disp_size = (call_width ? call_width : (com_width ? com_width : abs_width ? abs_width : 0)); @@ -1304,8 +1222,11 @@ tip_op (optex, topP) { /* Rn */ mode = TAHOE_DIRECT_REG; - if (deferred || immediate || (dec_inc != ' ') || - (reg != -1) || !really_none) + if (deferred + || immediate + || (dec_inc != ' ') + || (reg != -1) + || !really_none) op_bad = _("Syntax error in direct register mode."); else if (ndx != -1) op_bad = _("You can't index a register in direct register mode."); @@ -1323,14 +1244,14 @@ tip_op (optex, topP) if (*op_bad == '\0') { - /* No errors, check for warnings */ + /* No errors, check for warnings. */ if (width == 'q' && imreg == 12) as_warn (_("Using reg 14 for quadwords can tromp the FP register.")); reg = imreg; } - /* We know: imm = -1 */ + /* We know: imm = -1. */ } else if (dec_inc == '-') { @@ -1349,7 +1270,7 @@ tip_op (optex, topP) else if (width == 'q') op_bad = _("Auto dec won't work with quadwords."); - /* We know: imm = -1, dec_inc != '-' */ + /* We know: imm = -1, dec_inc != '-'. */ } else if (dec_inc == '+') { @@ -1382,7 +1303,7 @@ tip_op (optex, topP) op_bad = _("You can't have an index in auto inc mode."); } - /* We know: imm = -1, dec_inc == ' ' */ + /* We know: imm = -1, dec_inc == ' '. */ } else if (reg != -1) { @@ -1396,16 +1317,11 @@ tip_op (optex, topP) op_bad = _("Syntax error in register displaced mode."); } else if (really_none) - { - /* (Rn) */ - mode = TAHOE_REG_DEFERRED; - /* if reg = SP then cant be indexed */ - } + /* (Rn) */ + mode = TAHOE_REG_DEFERRED; else - { - /* (Rn) */ - mode = TAHOE_REG_DISP; - } + /* (Rn) */ + mode = TAHOE_REG_DISP; /* We know: imm = -1, dec_inc == ' ', Reg = -1 */ } @@ -1430,64 +1346,51 @@ tip_op (optex, topP) /* ponder the wisdom of a cast because it doesn't do any good. */ } else if (deferred) - { - /* * */ - mode = TAHOE_DISP_REL_DEFERRED; - } + /* * */ + mode = TAHOE_DISP_REL_DEFERRED; else - { - /* */ - mode = TAHOE_DISPLACED_RELATIVE; - } + /* */ + mode = TAHOE_DISPLACED_RELATIVE; } } - /* - * At this point, all the errors we can do have be checked for. - * We can build the 'top'. */ - + /* At this point, all the errors we can do have be checked for. + We can build the 'top'. */ topP->top_ndx = ndx; topP->top_reg = reg; topP->top_mode = mode; topP->top_error = op_bad; topP->top_dispsize = disp_size; -} /* tip_op */ +} -/* - * t i p ( ) - * - * This converts a string into a tahoe instruction. - * The string must be a bare single instruction in tahoe (with BSD4 frobs) - * format. - * It provides at most one fatal error message (which stops the scan) - * some warning messages as it finds them. - * The tahoe instruction is returned in exploded form. - * - * The exploded instruction is returned to a struct tit of your choice. - * #include "tahoe-inst.h" to know what a struct tit is. - * - */ +/* This converts a string into a tahoe instruction. + The string must be a bare single instruction in tahoe (with BSD4 frobs) + format. + It provides at most one fatal error message (which stops the scan) + some warning messages as it finds them. + The tahoe instruction is returned in exploded form. + + The exploded instruction is returned to a struct tit of your choice. + #include "tahoe-inst.h" to know what a struct tit is. */ static void -tip (titP, instring) - struct tit *titP; /* We build an exploded instruction here. */ - char *instring; /* Text of a vax instruction: we modify. */ +tip (struct tit *titP, /* We build an exploded instruction here. */ + char *instring) /* Text of a vax instruction: we modify. */ { - register struct tot_wot *twP = NULL; /* How to bit-encode this opcode. */ - register char *p; /* 1/skip whitespace.2/scan vot_how */ - register char *q; /* */ - register unsigned char count; /* counts number of operands seen */ - register struct top *operandp;/* scan operands in struct tit */ - register char *alloperr = ""; /* error over all operands */ - register char c; /* Remember char, (we clobber it - with '\0' temporarily). */ + struct tot_wot *twP = NULL; /* How to bit-encode this opcode. */ + char *p; /* 1/skip whitespace.2/scan vot_how. */ + char *q; + unsigned char count; /* Counts number of operands seen. */ + struct top *operandp; /* Scan operands in struct tit. */ + char *alloperr = ""; /* Error over all operands. */ + char c; /* Remember char, (we clobber it with '\0' temporarily). */ char *save_input_line_pointer; 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) @@ -1500,13 +1403,13 @@ tip (titP, instring) { 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. - */ + + /* 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. */ twP = (struct tot_wot *) hash_find (op_hash, instring); - *p = c; /* Restore char after op-code. */ + /* Restore char after op-code. */ + *p = c; if (twP == 0) { titP->tit_error = _("Unknown operator"); @@ -1515,53 +1418,53 @@ tip (titP, instring) } else { - /* - * We found a match! So let's 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 tot. - */ - - count = 0; /* no operands seen yet */ - instring = p + (*p != '\0'); /* point past the operation code */ + /* We found a match! So let's pick up as many operands as the + instruction wants, and even gripe if there are too many. + We expect comma to separate each operand. + We let instring track the text, while p tracks a part of the + struct tot. */ + + /* No operands seen yet. */ + count = 0; + /* Point past the operation code. */ + instring = p + (*p != '\0'); /* tip_op() screws with the input_line_pointer, so save it before - I jump in */ + I jump in. */ save_input_line_pointer = input_line_pointer; + for (p = twP->args, operandp = titP->tit_operand; !*alloperr && *p; operandp++, p += 2) { - /* - * Here to parse one operand. Leave instring pointing just - * past any one ',' that marks the end of this operand. - */ + /* Here to parse one operand. Leave instring pointing just + past any one ',' that marks the end of this operand. */ if (!p[1]) as_fatal (_("Compiler bug: ODD number of bytes in arg structure %s."), twP->args); else if (*instring) { for (q = instring; (*q != ',' && *q != '\0'); q++) - { - if (*q == '\'' && q[1] != '\0') /* Jump quoted characters */ - q++; - } + /* Jump quoted characters. */ + if (*q == '\'' && q[1] != '\0') + q++; + c = *q; - /* - * Q points to ',' or '\0' that ends argument. C is that - * character. - */ + /* Q points to ',' or '\0' that ends argument. C is that + character. */ *q = '\0'; operandp->top_access = p[0]; operandp->top_width = p[1]; tip_op (instring - 1, operandp); - *q = c; /* Restore input text. */ + /* Restore input text. */ + *q = c; + if (*(operandp->top_error)) - { - alloperr = operandp->top_error; - } - instring = q + (c ? 1 : 0); /* next operand (if any) */ - count++; /* won another argument, may have an operr */ + alloperr = operandp->top_error; + + /* Next operand (if any). */ + instring = q + (c ? 1 : 0); + /* Won another argument, may have an operr. */ + count++; } else alloperr = _("Not enough operands"); @@ -1571,65 +1474,51 @@ tip (titP, instring) if (!*alloperr) { + /* Skip whitespace. */ if (*instring == ' ') - instring++; /* Skip whitespace. */ + instring ++; + if (*instring) alloperr = _("Too many operands"); } + titP->tit_error = alloperr; } } - titP->tit_opcode = twP->code; /* The op-code. */ + titP->tit_opcode = twP->code; titP->tit_operands = count; -} /* tip */ +} -/* md_assemble() emit frags for 1 instruction */ void -md_assemble (instruction_string) - char *instruction_string; /* A string: assemble 1 instruction. */ +md_assemble (char *instruction_string) { char *p; - register struct top *operandP;/* An operand. Scans all operands. */ - /* char c_save; fixme: remove this line *//* What used to live after an expression. */ - /* struct frag *fragP; fixme: remove this line *//* Fragment of code we just made. */ - /* register struct top *end_operandP; fixme: remove this line *//* -> slot just after last operand - Limit of the for (each operand). */ - register expressionS *expP; /* -> expression values for this operand */ - + struct top *operandP; /* An operand. Scans all operands. */ + 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 symbolS *this_add_symbol; /* +ve (minuend) symbol. */ - - /* tahoe_opcodeT opcode_as_number; fixme: remove this line *//* The opcode as a number. */ + valueT this_add_number; + symbolS *this_add_symbol; /* +ve (minuend) symbol. */ char *opcodeP; /* Where it is in a frag. */ - /* char *opmodeP; fixme: remove this line *//* Where opcode type is, in a frag. */ - - int dispsize; /* From top_dispsize: tahoe_operand_width - (in bytes) */ - int is_undefined; /* 1 if operand expression's - segment not known yet. */ - int pc_rel; /* Is this operand pc relative? */ + int dispsize; /* From top_dispsize: tahoe_operand_width (in bytes). */ + int is_undefined; /* 1 if operand expression's segment not known yet. */ + int pc_rel; /* Is this operand pc relative? */ /* Decode the operand. */ tip (&t, instruction_string); - /* - * Check to see if this operand decode properly. - * Notice that we haven't made any frags yet. - * If it goofed, 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. - */ + /* Check to see if this operand decode properly. + Notice that we haven't made any frags yet. + If it goofed, 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 (*t.tit_error) - { - as_warn (_("Ignoring statement due to \"%s\""), t.tit_error); - } + as_warn (_("Ignoring statement due to \"%s\""), t.tit_error); else { - /* We saw no errors in any operands - try to make frag(s) */ + /* We saw no errors in any operands - try to make frag(s). */ /* Emit op-code. */ /* Remember where it is, in case we want to modify the op-code later. */ opcodeP = frag_more (1); @@ -1643,7 +1532,7 @@ md_assemble (instruction_string) if (operandP->top_ndx >= 0) { /* Indexed addressing byte - Legality of indexed mode already checked: it is OK */ + Legality of indexed mode already checked: it is OK. */ FRAG_APPEND_1_CHAR (0x40 + operandP->top_ndx); } /* if(top_ndx>=0) */ @@ -1651,28 +1540,27 @@ md_assemble (instruction_string) this_add_number = expP->X_add_number; this_add_symbol = expP->X_add_symbol; to_seg = operandP->seg_of_operand; - know (to_seg == SEG_UNKNOWN || \ - to_seg == SEG_ABSOLUTE || \ - to_seg == SEG_DATA || \ - to_seg == SEG_TEXT || \ - to_seg == SEG_BSS); + know (to_seg == SEG_UNKNOWN \ + || to_seg == SEG_ABSOLUTE \ + || to_seg == SEG_DATA \ + || to_seg == SEG_TEXT \ + || to_seg == SEG_BSS); is_undefined = (to_seg == SEG_UNKNOWN); - /* Do we know how big this opperand is? */ + /* Do we know how big this operand is? */ dispsize = operandP->top_dispsize; pc_rel = 0; - /* Deal with the branch possabilities. (Note, this doesn't include - jumps.)*/ + /* Deal with the branch possibilities. (Note, this doesn't include jumps.) */ if (operandP->top_access == 'b') { /* Branches must be expressions. A psuedo branch can also jump to - an absolute address. */ + an absolute address. */ if (to_seg == now_seg || is_undefined) { /* If is_undefined, then it might BECOME now_seg by relax time. */ if (dispsize) { /* I know how big the branch is supposed to be (it's a normal - branch), so I set up the frag, and let GAS do the rest. */ + branch), so I set up the frag, and let GAS do the rest. */ p = frag_more (dispsize); fix_new (frag_now, p - frag_now->fr_literal, this_add_symbol, this_add_number, @@ -1681,16 +1569,15 @@ md_assemble (instruction_string) } else { - /* (to_seg==now_seg || to_seg == SEG_UNKNOWN) && dispsize==0 */ /* If we don't know how big it is, then its a synthetic branch, - so we set up a simple relax state. */ + so we set up a simple relax state. */ switch (operandP->top_width) { case TAHOE_WIDTH_CONDITIONAL_JUMP: /* Simple (conditional) jump. I may have to reverse the - condition of opcodeP, and then jump to my destination. - I set 1 byte aside for the branch off set, and could need 6 - more bytes for the pc_rel jump */ + condition of opcodeP, and then jump to my destination. + I set 1 byte aside for the branch off set, and could need 6 + more bytes for the pc_rel jump. */ frag_var (rs_machine_dependent, 7, 1, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, is_undefined ? STATE_UNDF : STATE_BYTE), @@ -1698,7 +1585,7 @@ md_assemble (instruction_string) break; case TAHOE_WIDTH_ALWAYS_JUMP: /* Simple (unconditional) jump. I may have to convert this to - a word branch, or an absolute jump. */ + a word branch, or an absolute jump. */ frag_var (rs_machine_dependent, 5, 1, ENCODE_RELAX (STATE_ALWAYS_BRANCH, is_undefined ? STATE_UNDF : STATE_BYTE), @@ -1728,24 +1615,24 @@ md_assemble (instruction_string) else { /* to_seg != now_seg && to_seg != seg_unknown (still in branch) - In other words, I'm jumping out of my segment so extend the - branches to jumps, and let GAS fix them. */ + In other words, I'm jumping out of my segment so extend the + branches to jumps, and let GAS fix them. */ /* These are "branches" what will always be branches around a jump - to the correct addresss in real life. - If to_seg is SEG_ABSOLUTE, just encode the branch in, - else let GAS fix the address. */ + to the correct address in real life. + If to_seg is SEG_ABSOLUTE, just encode the branch in, + else let GAS fix the address. */ switch (operandP->top_width) { /* The theory: - For SEG_ABSOLUTE, then mode is ABSOLUTE_ADDR, jump - to that addresss (not pc_rel). - For other segs, address is a long word PC rel jump. */ + For SEG_ABSOLUTE, then mode is ABSOLUTE_ADDR, jump + to that address (not pc_rel). + For other segs, address is a long word PC rel jump. */ case TAHOE_WIDTH_CONDITIONAL_JUMP: /* b */ /* To reverse the condition in a TAHOE branch, - complement bit 4 */ + complement bit 4 */ *opcodeP ^= 0x10; p = frag_more (7); *p++ = 6; @@ -1756,14 +1643,14 @@ md_assemble (instruction_string) fix_new (frag_now, p - frag_now->fr_literal, this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); - /* - * Now (eg) BLEQ 1f - * JMP foo - * 1: - */ + + /* Now (eg) BLEQ 1f + JMP foo + 1: */ break; + case TAHOE_WIDTH_ALWAYS_JUMP: - /* br, just turn it into a jump */ + /* Br, just turn it into a jump. */ *opcodeP = TAHOE_JMP; p = frag_more (5); *p++ = (operandP->top_mode == @@ -1772,8 +1659,9 @@ md_assemble (instruction_string) fix_new (frag_now, p - frag_now->fr_literal, this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); - /* Now (eg) JMP foo */ + /* Now (eg) JMP foo. */ break; + case TAHOE_WIDTH_BIG_REV_JUMP: p = frag_more (8); *opcodeP ^= 0x10; @@ -1786,12 +1674,11 @@ md_assemble (instruction_string) fix_new (frag_now, p - frag_now->fr_literal, this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); - /* - * Now (eg) ACBx 1f - * JMP foo - * 1: - */ + /* Now (eg) ACBx 1f + JMP foo + 1: */ break; + case TAHOE_WIDTH_BIG_NON_REV_JUMP: p = frag_more (10); *p++ = 0; @@ -1805,12 +1692,10 @@ md_assemble (instruction_string) fix_new (frag_now, p - frag_now->fr_literal, this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); - /* - * Now (eg) xOBxxx 1f - * BRB 2f - * 1: JMP @#foo - * 2: - */ + /* Now (eg) xOBxxx 1f + BRB 2f + 1: JMP @#foo + 2: */ break; case 'b': case 'w': @@ -1829,7 +1714,7 @@ md_assemble (instruction_string) switch (operandP->top_mode) { /* Auto-foo access, only works for one reg (SP) - so the only thing needed is the mode. */ + so the only thing needed is the mode. */ case TAHOE_AUTO_DEC: case TAHOE_AUTO_INC: case TAHOE_AUTO_INC_DEFERRED: @@ -1837,14 +1722,14 @@ md_assemble (instruction_string) break; /* Numbered Register only access. Only thing needed is the - mode + Register number */ + mode + Register number. */ case TAHOE_DIRECT_REG: case TAHOE_REG_DEFERRED: FRAG_APPEND_1_CHAR (operandP->top_mode + operandP->top_reg); break; /* An absolute address. It's size is always 5 bytes. - (mode_type + 4 byte address). */ + (mode_type + 4 byte address). */ case TAHOE_ABSOLUTE_ADDR: know ((this_add_symbol == NULL)); p = frag_more (5); @@ -1853,7 +1738,7 @@ md_assemble (instruction_string) break; /* Immediate data. If the size isn't known, then it's an address - + and offset, which is 4 bytes big. */ + + and offset, which is 4 bytes big. */ case TAHOE_IMMEDIATE: if (this_add_symbol != NULL) { @@ -1867,10 +1752,8 @@ md_assemble (instruction_string) { /* It's an integer, and I know it's size. */ if ((unsigned) this_add_number < 0x40) - { - /* Will it fit in a literal? */ - FRAG_APPEND_1_CHAR ((byte) this_add_number); - } + /* Will it fit in a literal? */ + FRAG_APPEND_1_CHAR ((byte) this_add_number); else { p = frag_more (dispsize + 1); @@ -1894,9 +1777,9 @@ md_assemble (instruction_string) break; /* Distance from the PC. If the size isn't known, we have to relax - into it. The difference between this and disp(sp) is that - this offset is pc_rel, and disp(sp) isn't. - Note the drop through code. */ + into it. The difference between this and disp(sp) is that + this offset is pc_rel, and disp(sp) isn't. + Note the drop through code. */ case TAHOE_DISPLACED_RELATIVE: case TAHOE_DISP_REL_DEFERRED: @@ -1904,32 +1787,30 @@ md_assemble (instruction_string) pc_rel = 1; /* Register, plus a displacement mode. Save the register number, - and weather its deffered or not, and relax the size if it isn't - known. */ + and weather its deffered or not, and relax the size if it isn't + known. */ case TAHOE_REG_DISP: case TAHOE_REG_DISP_DEFERRED: - if (operandP->top_mode == TAHOE_DISP_REL_DEFERRED || - operandP->top_mode == TAHOE_REG_DISP_DEFERRED) - operandP->top_reg += 0x10; /* deffered mode is always 0x10 higher - than it's non-deffered sibling. */ + if (operandP->top_mode == TAHOE_DISP_REL_DEFERRED + || operandP->top_mode == TAHOE_REG_DISP_DEFERRED) + /* Deffered mode is always 0x10 higher than it's non-deffered sibling. */ + operandP->top_reg += 0x10; /* Is this a value out of this segment? - The first part of this conditional is a cludge to make gas - produce the same output as 'as' when there is a lable, in - the current segment, displaceing a register. It's strange, - and no one in their right mind would do it, but it's easy - to cludge. */ - if ((dispsize == 0 && !pc_rel) || - (to_seg != now_seg && !is_undefined && to_seg != SEG_ABSOLUTE)) + The first part of this conditional is a cludge to make gas + produce the same output as 'as' when there is a lable, in + the current segment, displacing a register. It's strange, + and no one in their right mind would do it, but it's easy + to cludge. */ + if ((dispsize == 0 && !pc_rel) + || (to_seg != now_seg && !is_undefined && to_seg != SEG_ABSOLUTE)) dispsize = 4; if (dispsize == 0) { - /* - * We have a SEG_UNKNOWN symbol, or the size isn't cast. - * It might turn out to be in the same segment as - * the instruction, permitting relaxation. - */ + /* We have a SEG_UNKNOWN symbol, or the size isn't cast. + 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, is_undefined ? STATE_UNDF : STATE_BYTE), @@ -1961,35 +1842,34 @@ md_assemble (instruction_string) as_fatal (_("Barf, bad mode %x\n"), operandP->top_mode); } } - } /* for(operandP) */ - } /* if(!need_pass_2 && !goofed) */ -} /* tahoe_assemble() */ + } + } +} /* We have no need to default values of symbols. */ symbolS * -md_undefined_symbol (name) - char *name; +md_undefined_symbol (char *name) { return 0; -} /* md_undefined_symbol() */ +} /* Round up a section size to the appropriate boundary. */ + valueT -md_section_align (segment, size) - segT segment; - valueT size; +md_section_align (segT segment, valueT size) { - return ((size + 7) & ~7); /* Round all sects to multiple of 8 */ -} /* md_section_align() */ + /* Round all sects to multiple of 8. */ + return ((size + 7) & ~7); +} /* Exactly what point is a PC-relative offset relative TO? On the sparc, they're relative to the address of the offset, plus its size. This gets us to the following instruction. (??? Is this right? FIXME-SOON) */ + long -md_pcrel_from (fixP) - fixS *fixP; +md_pcrel_from (fixS *fixP) { return (((fixP->fx_type == FX_8 || fixP->fx_type == FX_PCREL8) @@ -2001,13 +1881,12 @@ md_pcrel_from (fixP) || fixP->fx_type == FX_PCREL32) ? 4 : 0))) + fixP->fx_where + fixP->fx_frag->fr_address); -} /* md_pcrel_from() */ +} int -tc_is_pcrel (fixP) - fixS *fixP; +tc_is_pcrel (fixS *fixP) { - /* should never be called */ + /* Should never be called. */ know (0); - return (0); -} /* tc_is_pcrel() */ + return 0; +}