From: Ken Raeburn Date: Mon, 23 Nov 1992 20:42:33 +0000 (+0000) Subject: Ran "indent", for GNU coding style; some code & comments still need fixup. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=355afbcd8b1a0253180ac565f8e7a18afdfc5977;p=binutils-gdb.git Ran "indent", for GNU coding style; some code & comments still need fixup. Removed some unneeded files. obj-coff.c (obj_coff_endef): Use as_warn, not fprintf. tc-m68k.c (md_assemble): 68000+68881 is okay -- could be emulating. --- diff --git a/gas/config/ChangeLog b/gas/config/ChangeLog index 8c5d3ccae50..f81fe411fe4 100644 --- a/gas/config/ChangeLog +++ b/gas/config/ChangeLog @@ -1,3 +1,10 @@ +Mon Nov 23 11:50:00 1992 Ken Raeburn (raeburn@cygnus.com) + + * obj-coff.c (obj_coff_endef): Use as_warn, not fprintf. + + * tc-m68k.c (md_assemble): Don't complain about 68000 with 68881; + could be doing emulation. + Tue Nov 10 09:50:25 1992 Ian Lance Taylor (ian@cygnus.com) * tc-m68k.c (m68k_reg_parse): If REGISTER_PREFIX isn't defined, diff --git a/gas/config/atof-ieee.c b/gas/config/atof-ieee.c index df98e4cfd1a..a5782c4fce9 100644 --- a/gas/config/atof-ieee.c +++ b/gas/config/atof-ieee.c @@ -1,36 +1,31 @@ /* atof_ieee.c - turn a Flonum into an IEEE floating point number Copyright (C) 1987, 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. */ #include "as.h" -#ifdef USG -#define bzero(s,n) memset(s,0,n) -#define bcopy(from,to,n) memcpy((to),(from),(n)) -#endif - -extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */ +extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */ #ifndef NULL #define NULL (0) #endif -extern char EXP_CHARS[]; +extern const char EXP_CHARS[]; /* Precision in LittleNums. */ #define MAX_PRECISION (6) #define F_PRECISION (2) @@ -41,40 +36,41 @@ extern char EXP_CHARS[]; /* 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, +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, }; @@ -83,58 +79,66 @@ 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); + 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]; } - return(return_value); + } + 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) -int num; +unget_bits (num) + int num; { - if (!littlenums_left) { - ++littlenum_pointer; - ++littlenums_left; - bits_left_in_littlenum = num; - } else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS) { - bits_left_in_littlenum = num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum); - ++littlenum_pointer; - ++littlenums_left; - } else - bits_left_in_littlenum += num; + if (!littlenums_left) + { + ++littlenum_pointer; + ++littlenums_left; + bits_left_in_littlenum = num; + } + else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS) + { + bits_left_in_littlenum = num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum); + ++littlenum_pointer; + ++littlenums_left; + } + else + 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 */ - words[1] = -1; - words[2] = -1; - words[3] = -1; - words[4] = -1; - words[5] = -1; + as_bad ("cannot create floating-point number"); + words[0] = ((unsigned) -1) >> 1; /* Zero the leftmost bit */ + words[1] = -1; + words[2] = -1; + words[3] = -1; + words[4] = -1; + words[5] = -1; } /***********************************************************************\ @@ -149,157 +153,175 @@ LITTLENUM_TYPE *words; 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. */ - 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 + 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. */ + 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. */ - - bzero(bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION); - - switch (what_kind) { - case 'f': - case 'F': - case 's': - case 'S': - precision = F_PRECISION; - exponent_bits = 8; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - precision = D_PRECISION; - exponent_bits = 11; - break; - - case 'x': - case 'X': - case 'e': - case 'E': - 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 + 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. */ + + memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); + + switch (what_kind) + { + case 'f': + case 'F': + case 's': + case 'S': + precision = F_PRECISION; + exponent_bits = 8; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + precision = D_PRECISION; + exponent_bits = 11; + break; + + case 'x': + case 'X': + case 'e': + case 'E': + 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); + generic_floating_point_number = save_gen_flonum; + + return (return_value); } /* Turn generic_floating_point_number into a real float/double/extended */ -int gen_to_words(words, precision, exponent_bits) -LITTLENUM_TYPE *words; -int precision; -long exponent_bits; +int +gen_to_words (words, precision, exponent_bits) + LITTLENUM_TYPE *words; + int precision; + long exponent_bits; { - int return_value = 0; - - long exponent_1; - long exponent_2; - long exponent_3; - long exponent_4; - 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; - else - words[0] = 0x8000; - bzero(&words[1], sizeof(LITTLENUM_TYPE) * (precision - 1)); - return(return_value); + int return_value = 0; + + long exponent_1; + long exponent_2; + long exponent_3; + long exponent_4; + 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; + else + words[0] = 0x8000; + memset (&words[1], '\0', sizeof (LITTLENUM_TYPE) * (precision - 1)); + return (return_value); + } + + /* NaN: Do the right thing */ + if (generic_floating_point_number.sign == 0) + { + if (precision == F_PRECISION) + { + words[0] = 0x7fff; + words[1] = 0xffff; } - - /* NaN: Do the right thing */ - if (generic_floating_point_number.sign == 0) { - if (precision == F_PRECISION) { - words[0] = 0x7fff; - words[1] = 0xffff; - } else { - words[0] = 0x7fff; - words[1] = 0xffff; - words[2] = 0xffff; - words[3] = 0xffff; - } - return return_value; - } else if (generic_floating_point_number.sign == 'P') { - /* +INF: Do the right thing */ - if (precision == F_PRECISION) { - words[0] = 0x7f80; - words[1] = 0; - } else { - words[0] = 0x7ff0; - words[1] = 0; - words[2] = 0; - words[3] = 0; - } - return(return_value); - } else if (generic_floating_point_number.sign == 'N') { - /* Negative INF */ - if (precision == F_PRECISION) { - words[0] = 0xff80; - words[1] = 0x0; - } else { - words[0] = 0xfff0; - words[1] = 0x0; - words[2] = 0x0; - words[3] = 0x0; - } - return(return_value); + else + { + words[0] = 0x7fff; + words[1] = 0xffff; + words[2] = 0xffff; + words[3] = 0xffff; + } + return return_value; + } + else if (generic_floating_point_number.sign == 'P') + { + /* +INF: Do the right thing */ + if (precision == F_PRECISION) + { + words[0] = 0x7f80; + words[1] = 0; + } + else + { + words[0] = 0x7ff0; + words[1] = 0; + words[2] = 0; + words[3] = 0; + } + return (return_value); + } + else if (generic_floating_point_number.sign == 'N') + { + /* Negative INF */ + if (precision == F_PRECISION) + { + words[0] = 0xff80; + words[1] = 0x0; } - /* + else + { + words[0] = 0xfff0; + words[1] = 0x0; + words[2] = 0x0; + words[3] = 0x0; + } + return (return_value); + } + /* * The floating point formats we support have: * Bit 15 is sign bit. * Bits 14:n are excess-whatever exponent. @@ -309,139 +331,163 @@ long exponent_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; - /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.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)) - 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; - - if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits) { - /* Bigger than one littlenum */ - num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits; - *lp++ = word1; - if (num_bits + exponent_bits + 1 >= precision * LITTLENUM_NUMBER_OF_BITS) { - /* Exponent overflow */ - make_invalid_floating_point_number(words); - return(return_value); - } - if (precision == X_PRECISION && exponent_bits == 15) { - *lp++ = 0; - *lp++ = 0; - num_bits -= LITTLENUM_NUMBER_OF_BITS - 1; - } - while (num_bits >= LITTLENUM_NUMBER_OF_BITS) { - num_bits -= LITTLENUM_NUMBER_OF_BITS; - *lp++ = 0; - } - if (num_bits) - *lp++ = next_bits(LITTLENUM_NUMBER_OF_BITS - (num_bits)); - } else { - if (precision == X_PRECISION && exponent_bits == 15) { - *lp++ = word1; - *lp++ = 0; - if (num_bits == LITTLENUM_NUMBER_OF_BITS) { - *lp++ = 0; - *lp++ = next_bits(LITTLENUM_NUMBER_OF_BITS - 1); - } else if (num_bits == LITTLENUM_NUMBER_OF_BITS - 1) - *lp++ = 0; - else - *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)); - *lp++ = word1; - } + 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; + /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.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)) - 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; + + if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits) + { + /* Bigger than one littlenum */ + num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits; + *lp++ = word1; + if (num_bits + exponent_bits + 1 >= precision * LITTLENUM_NUMBER_OF_BITS) + { + /* Exponent overflow */ + make_invalid_floating_point_number (words); + return (return_value); + } + if (precision == X_PRECISION && exponent_bits == 15) + { + *lp++ = 0; + *lp++ = 0; + num_bits -= LITTLENUM_NUMBER_OF_BITS - 1; + } + while (num_bits >= LITTLENUM_NUMBER_OF_BITS) + { + num_bits -= LITTLENUM_NUMBER_OF_BITS; + *lp++ = 0; + } + if (num_bits) + *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits)); + } + else + { + if (precision == X_PRECISION && exponent_bits == 15) + { + *lp++ = word1; + *lp++ = 0; + if (num_bits == LITTLENUM_NUMBER_OF_BITS) + { + *lp++ = 0; + *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - 1); } - while (lp < words + precision) - *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; - --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; - carry >>= LITTLENUM_NUMBER_OF_BITS; - } - } - } else if ((*lp & mask[prec_bits]) != mask[prec_bits]) - lp++; + else if (num_bits == LITTLENUM_NUMBER_OF_BITS - 1) + *lp++ = 0; + else + *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)); + *lp++ = word1; + } + } + while (lp < words + precision) + *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; + --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; + carry >>= LITTLENUM_NUMBER_OF_BITS; + } } - - return return_value; - } else if (exponent_4 & ~ mask [exponent_bits]) { - /* + } + else if ((*lp & mask[prec_bits]) != mask[prec_bits]) + 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. */ - 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); - } - - *lp++ = word1; - - /* X_PRECISION is special: it has 16 bits of zero in the middle, + 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); + } + + *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); - - if (next_bits(1)) { - unsigned long carry; - /* + 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); + + 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 @@ -449,30 +495,32 @@ long exponent_bits; * highest-order bit of the lowest-order word flips. * Is that clear? */ - - /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) + + /* #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))) { - /* We leave return_value alone: admit we read the + 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))) + { + /* We leave return_value alone: admit we read the * number, but return a floating exception * because we can't encode the number. */ - *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1)); - /* make_invalid_floating_point_number (words); */ - /* return return_value; */ - } + *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1)); + /* make_invalid_floating_point_number (words); */ + /* return return_value; */ } - return (return_value); + } + return (return_value); } /* This routine is a real kludge. Someone really should do it better, but @@ -480,47 +528,49 @@ long exponent_bits; (JF) */ void - int_to_gen(x) -long 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?)"); + 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?)"); } #ifdef TEST char * - print_gen(gen) -FLONUM_TYPE *gen; +print_gen (gen) + FLONUM_TYPE *gen; { - FLONUM_TYPE f; - LITTLENUM_TYPE arr[10]; - double dv; - float fv; - static char sbuf[40]; - - if (gen) { - f = generic_floating_point_number; - generic_floating_point_number = *gen; - } - gen_to_words(&arr[0], 4, 11); - bcopy(&arr[0], &dv, sizeof(double)); - sprintf(sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv); - gen_to_words(&arr[0],2,8); - 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; - } - - return(sbuf); + FLONUM_TYPE f; + LITTLENUM_TYPE arr[10]; + double dv; + float fv; + static char sbuf[40]; + + if (gen) + { + f = generic_floating_point_number; + generic_floating_point_number = *gen; + } + gen_to_words (&arr[0], 4, 11); + memcpy (&dv, &arr[0], sizeof (double)); + sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv); + gen_to_words (&arr[0], 2, 8); + memcpy (&fv, &arr[0], sizeof (float)); + sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv); + + if (gen) + { + generic_floating_point_number = f; + } + + return (sbuf); } + #endif /* end of atof-ieee.c */ diff --git a/gas/config/atof-ns32k.c b/gas/config/atof-ns32k.c index 9fde9cb3693..8562b5a6e10 100644 --- a/gas/config/atof-ns32k.c +++ b/gas/config/atof-ns32k.c @@ -21,22 +21,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "as.h" -extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */ +extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */ extern const char EXP_CHARS[]; - /* Precision in LittleNums. */ +/* Precision in LittleNums. */ #define MAX_PRECISION (4) #define F_PRECISION (2) #define D_PRECISION (4) - /* Length in LittleNums of guard bits. */ +/* Length in LittleNums of guard bits. */ #define GUARD (2) int /* Number of chars in flonum type 'letter'. */ atof_sizeof (letter) char letter; { - int return_value; + int return_value; /* * Permitting uppercase letters is probably a bad idea. @@ -60,7 +60,8 @@ atof_sizeof (letter) return (return_value); } -static unsigned long int mask [] = { +static unsigned long int mask[] = +{ 0x00000000, 0x00000001, 0x00000003, @@ -94,48 +95,49 @@ static unsigned long int mask [] = { 0x3fffffff, 0x7fffffff, 0xffffffff - }; +}; static int bits_left_in_littlenum; static int littlenums_left; -static LITTLENUM_TYPE * littlenum_pointer; +static LITTLENUM_TYPE *littlenum_pointer; static int next_bits (number_of_bits) - int number_of_bits; + int number_of_bits; { - int return_value; + int return_value; - if(!littlenums_left) - return 0; + if (!littlenums_left) + return 0; if (number_of_bits >= bits_left_in_littlenum) { - return_value = mask [bits_left_in_littlenum] & *littlenum_pointer; + 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 --; - --littlenums_left; - return_value |= (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits]; - } + if (littlenums_left) + { + bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; + littlenum_pointer--; + --littlenums_left; + 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_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; + LITTLENUM_TYPE *words; { - words[0]= ((unsigned)-1)>>1; /* Zero the leftmost bit */ - words[1]= -1; - words[2]= -1; - words[3]= -1; + words[0] = ((unsigned) -1) >> 1; /* Zero the leftmost bit */ + words[1] = -1; + words[2] = -1; + words[3] = -1; } /***********************************************************************\ @@ -149,77 +151,81 @@ make_invalid_floating_point_number (words) char * /* Return pointer past text consumed. */ atof_ns32k (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. */ + 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 int exponent_bits; - - long int exponent_1; - long int exponent_2; - long int exponent_3; - long int exponent_4; - int exponent_skippage; - LITTLENUM_TYPE word1; - LITTLENUM_TYPE * lp; - - return_value = str; - f.low = bits + MAX_PRECISION; - f.high = NULL; - f.leader = NULL; - f.exponent = NULL; - f.sign = '\0'; - - /* 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': - precision = F_PRECISION; - exponent_bits = 8; - break; - - case 'd': - precision = D_PRECISION; - exponent_bits = 11; - break; - - default: - make_invalid_floating_point_number (words); - return NULL; - } + 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 int exponent_bits; + + long int exponent_1; + long int exponent_2; + long int exponent_3; + long int exponent_4; + int exponent_skippage; + LITTLENUM_TYPE word1; + LITTLENUM_TYPE *lp; + + return_value = str; + f.low = bits + MAX_PRECISION; + f.high = NULL; + f.leader = NULL; + f.exponent = NULL; + f.sign = '\0'; + + /* 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': + precision = F_PRECISION; + exponent_bits = 8; + break; - f.high = f.low + precision - 1 + GUARD; + case 'd': + precision = D_PRECISION; + exponent_bits = 11; + break; - if (atof_generic (& return_value, ".", EXP_CHARS, & f)) { - as_warn("Error converting floating point number (Exponent overflow?)"); - make_invalid_floating_point_number (words); - return NULL; - } + default: + make_invalid_floating_point_number (words); + return NULL; + } - if (f.low > f.leader) { - /* 0.0e0 seen. */ - bzero (words, sizeof(LITTLENUM_TYPE) * precision); - return return_value; - } + f.high = f.low + precision - 1 + GUARD; - if(f.sign!='+' && f.sign!='-') { - make_invalid_floating_point_number(words); - return NULL; - } + if (atof_generic (&return_value, ".", EXP_CHARS, &f)) + { + as_warn ("Error converting floating point number (Exponent overflow?)"); + make_invalid_floating_point_number (words); + return NULL; + } + + if (f.low > f.leader) + { + /* 0.0e0 seen. */ + bzero (words, sizeof (LITTLENUM_TYPE) * precision); + return return_value; + } + + if (f.sign != '+' && f.sign != '-') + { + make_invalid_floating_point_number (words); + return NULL; + } - /* + /* * All vaxen floating_point formats (so far) have: * Bit 15 is sign bit. * Bits 14:n are excess-whatever exponent. @@ -230,51 +236,53 @@ atof_ns32k (str, what_kind, words) * So we need: number of bits of exponent, number of bits of * mantissa. */ - bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; - littlenum_pointer = f.leader; - littlenums_left = 1 + f.leader-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)) - 2); - /* Offset exponent. */ - - if (exponent_4 & ~ mask [exponent_bits]) { - /* + bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; + littlenum_pointer = f.leader; + littlenums_left = 1 + f.leader - 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)) - 2); + /* Offset exponent. */ + + 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. */ - as_warn("Exponent overflow in floating-point number"); - make_invalid_floating_point_number (words); - return return_value; - } - lp = words; + as_warn ("Exponent overflow in floating-point number"); + make_invalid_floating_point_number (words); + return return_value; + } + 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; + /* 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); + /* 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)) { - unsigned long int carry; - /* + if (next_bits (1)) + { + unsigned long int 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 @@ -284,53 +292,56 @@ atof_ns32k (str, what_kind, words) */ -/* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) + /* #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)) ) { - /* We leave return_value alone: admit we read the + 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))) + { + /* 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; - } + make_invalid_floating_point_number (words); + return return_value; } - return (return_value); + } + return (return_value); } /* This is really identical to atof_ns32k except for some details */ -gen_to_words(words,precision,exponent_bits) -LITTLENUM_TYPE *words; -long int exponent_bits; +gen_to_words (words, precision, exponent_bits) + LITTLENUM_TYPE *words; + long int exponent_bits; { - int return_value=0; - - long int exponent_1; - long int exponent_2; - long int exponent_3; - long int exponent_4; - int exponent_skippage; - LITTLENUM_TYPE word1; - LITTLENUM_TYPE * lp; - - if (generic_floating_point_number.low > generic_floating_point_number.leader) { - /* 0.0e0 seen. */ - bzero (words, sizeof(LITTLENUM_TYPE) * precision); - return return_value; - } + int return_value = 0; - /* + long int exponent_1; + long int exponent_2; + long int exponent_3; + long int exponent_4; + int exponent_skippage; + LITTLENUM_TYPE word1; + LITTLENUM_TYPE *lp; + + if (generic_floating_point_number.low > generic_floating_point_number.leader) + { + /* 0.0e0 seen. */ + bzero (words, sizeof (LITTLENUM_TYPE) * precision); + return return_value; + } + + /* * All vaxen floating_point formats (so far) have: * Bit 15 is sign bit. * Bits 14:n are excess-whatever exponent. @@ -341,51 +352,53 @@ long int exponent_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; - /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.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)) - 2); - /* Offset exponent. */ - - if (exponent_4 & ~ mask [exponent_bits]) { - /* + 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; + /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.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)) - 2); + /* Offset exponent. */ + + 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. */ - make_invalid_floating_point_number (words); - return return_value; - } - lp = words; + make_invalid_floating_point_number (words); + return return_value; + } + lp = words; - /* Word 1. Sign, exponent and perhaps high bits. */ - /* Assume 2's complement integers. */ - word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits)) | - ((generic_floating_point_number.sign == '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits); - * lp ++ = word1; + /* Word 1. Sign, exponent and perhaps high bits. */ + /* Assume 2's complement integers. */ + word1 = ((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits)) | + ((generic_floating_point_number.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); + /* 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)) { - unsigned long int carry; - /* + if (next_bits (1)) + { + unsigned long int 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 @@ -395,42 +408,45 @@ long int exponent_bits; */ -/* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) + /* #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)) ) { - /* We leave return_value alone: admit we read the + 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))) + { + /* 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; - } + make_invalid_floating_point_number (words); + return return_value; } - return (return_value); + } + return (return_value); } /* 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) -long x; +void +int_to_gen (x) + long x; { - char buf[20]; - char *bufp; + char buf[20]; + char *bufp; - sprintf(buf,"%ld",x); - bufp= &buf[0]; - if(atof_generic(&bufp,".", EXP_CHARS, &generic_floating_point_number)) - as_warn("Error converting number to floating point (Exponent overflow?)"); + sprintf (buf, "%ld", x); + bufp = &buf[0]; + if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number)) + as_warn ("Error converting number to floating point (Exponent overflow?)"); } diff --git a/gas/config/coff_gnu.h b/gas/config/coff_gnu.h index 7214847894d..a838a5db5d5 100644 --- a/gas/config/coff_gnu.h +++ b/gas/config/coff_gnu.h @@ -1,18 +1,18 @@ /* coff_gnu.h Copyright (C) 1987, 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. */ @@ -30,15 +30,16 @@ /********************** FILE HEADER **********************/ -struct filehdr { - unsigned short f_magic; /* magic number */ - unsigned short f_nscns; /* number of sections */ - long f_timdat; /* time & date stamp */ - long f_symptr; /* file pointer to symtab */ - long f_nsyms; /* number of symtab entries */ - unsigned short f_opthdr; /* sizeof(optional hdr) */ - unsigned short f_flags; /* flags */ -}; +struct filehdr + { + unsigned short f_magic; /* magic number */ + unsigned short f_nscns; /* number of sections */ + long f_timdat; /* time & date stamp */ + long f_symptr; /* file pointer to symtab */ + long f_nsyms; /* number of symtab entries */ + unsigned short f_opthdr; /* sizeof(optional hdr) */ + unsigned short f_flags; /* flags */ + }; /* Bits for f_flags: * F_RELFLG relocation info stripped from file @@ -53,23 +54,23 @@ struct filehdr { #define F_LSYMS (0x0008) #ifdef TC_I960 -#define F_AR32WR (0x0010) /* File has 32 bits per word, least +#define F_AR32WR (0x0010)/* File has 32 bits per word, least significant byte first. */ #else /* TC_I960 */ #define F_AR32WR (0x0100) #endif /* TC_I960 */ -#define F_MINMAL (0x0010) /* ??? */ -#define F_UPDATE (0x0020) /* ??? */ -#define F_SWABD (0x0040) /* ??? */ -#define F_AR16WR (0x0080) /* File has the byte ordering used by +#define F_MINMAL (0x0010)/* ??? */ +#define F_UPDATE (0x0020)/* ??? */ +#define F_SWABD (0x0040)/* ??? */ +#define F_AR16WR (0x0080)/* File has the byte ordering used by the PDP*-11/70 processor. */ -#define F_AR32W (0x0200) /* File has 32 bits per word, most +#define F_AR32W (0x0200)/* File has 32 bits per word, most significant byte first. */ /* * Intel 80960 (I960) processor flags. - * F_I960TYPE == mask for processor type field. + * F_I960TYPE == mask for processor type field. */ #define F_I960TYPE (0xf000) @@ -105,7 +106,7 @@ struct filehdr { # define I386MAGIC 0x14c # define I386BADMAG(x) (((x).f_magic!=I386MAGIC)) #endif /* not TE_I386AIX */ - + #define FILHDR struct filehdr #define FILHSZ sizeof(FILHDR) @@ -113,10 +114,13 @@ struct filehdr { /********************** AOUT "OPTIONAL HEADER" **********************/ -typedef struct { - unsigned long phys_addr; - unsigned long bitarray; -} TAGBITS; +typedef struct + { + unsigned long phys_addr; + unsigned long bitarray; + } + +TAGBITS; /* These appear to be used only by exec(2). I don't know who cares about them in a cross development environment. In any case, this @@ -124,39 +128,42 @@ typedef struct { Apparently, most have these have remained essentially unchanged since v7 days, although a few new ones have been added. xoxorich. */ -#define BAD0MAGIC (0401) /* (?) "lpd (UNIX/RT)" */ -#define BAD1MAGIC (0405) /* (?) overlay */ -#define OMAGIC (0407) /* old impure format. data immediately +#define BAD0MAGIC (0401) /* (?) "lpd (UNIX/RT)" */ +#define BAD1MAGIC (0405) /* (?) overlay */ +#define OMAGIC (0407) /* old impure format. data immediately follows text. both sections are rw. */ -#define NMAGIC (0410) /* split i&d, read-only text */ -#define A_MAGIC3 (0411) /* (?) "separated I&D" */ -#define ZMAGIC (0413) /* like NMAGIC, but demand loaded */ -#define PAGEMAGIC2 (0414) /* (?) like ZMAGIC, but address zero +#define NMAGIC (0410) /* split i&d, read-only text */ +#define A_MAGIC3 (0411) /* (?) "separated I&D" */ +#define ZMAGIC (0413) /* like NMAGIC, but demand loaded */ +#define PAGEMAGIC2 (0414) /* (?) like ZMAGIC, but address zero explicitly unmapped. */ -#define REGMAGIC (0414) /* (?) a PAGEMAGIC2 alias? */ -#define PAGEMAGIC3 (0415) /* (?) like ZMAGIC, but address zero mapped. */ -#define A_MAGIC5 (0437) /* (?) "system overlay, separated I&D" */ +#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 */ -#define SASMAGIC (010000) /* Single Address Space */ -#define MASMAGIC (020000) /* (?) "Multiple (separate I & D) Address Spaces" */ - -typedef struct aouthdr { - short magic; /* type of file */ - short vstamp; /* version stamp */ - unsigned long tsize; /* text size in bytes, padded to FW bdry*/ - unsigned long dsize; /* initialized data " " */ - unsigned long bsize; /* uninitialized data " " */ +#define SASMAGIC (010000)/* Single Address Space */ +#define MASMAGIC (020000)/* (?) "Multiple (separate I & D) Address Spaces" */ + +typedef struct aouthdr + { + short magic; /* type of file */ + short vstamp; /* version stamp */ + unsigned long tsize; /* text size in bytes, padded to FW bdry*/ + unsigned long dsize; /* initialized data " " */ + unsigned long bsize; /* uninitialized data " " */ #if U3B - unsigned long dum1; - unsigned long dum2; /* pad to entry point */ + unsigned long dum1; + unsigned long dum2; /* pad to entry point */ #endif - 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. */ - unsigned long tagentries; /* number of tag entries to + 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. */ + unsigned long tagentries; /* number of tag entries to follow (always zero for i960) */ -} AOUTHDR; + } + +AOUTHDR; /* return a pointer to the tag bits array */ @@ -197,10 +204,10 @@ typedef struct aouthdr { #endif /* TC_I960 */ #ifdef TC_A29K -#define C_GLBLREG 19 /* global register */ -#define C_EXTREG 20 /* external global register */ -#define C_DEFREG 21 /* ext. def. of global register */ -#define C_STARTOF 22 /* as29 $SIZEOF and $STARTOF symbols */ +#define C_GLBLREG 19 /* global register */ +#define C_EXTREG 20 /* external global register */ +#define C_DEFREG 21 /* ext. def. of global register */ +#define C_STARTOF 22 /* as29 $SIZEOF and $STARTOF symbols */ #endif /* TC_A29K */ #define C_BLOCK 100 /* ".bb" or ".eb" */ @@ -222,31 +229,32 @@ typedef struct aouthdr { #define C_DEFINE 110 /* Preprocessor #define */ #define C_PRAGMA 111 /* Advice to compiler or linker */ #define C_SEGMENT 112 /* 80960 segment name */ -#define C_LEAFSTAT 113 /* Static leaf */ +#define C_LEAFSTAT 113 /* Static leaf */ #endif /* TC_I960 */ #ifdef TC_A29K -#define C_SHADOW 107 /* shadow symbol */ +#define C_SHADOW 107 /* shadow symbol */ #endif /* TC_A29K */ /********************** SECTION HEADER **********************/ -struct scnhdr { - char s_name[8]; /* section name */ - long s_paddr; /* physical address, aliased s_nlib */ - long s_vaddr; /* virtual address */ - long s_size; /* section size */ - long s_scnptr; /* file ptr to raw data for section */ - long s_relptr; /* file ptr to relocation */ - long s_lnnoptr; /* file ptr to line numbers */ - unsigned short s_nreloc; /* number of relocation entries */ - unsigned short s_nlnno; /* number of line number entries */ - long s_flags; /* flags */ - +struct scnhdr + { + char s_name[8]; /* section name */ + long s_paddr; /* physical address, aliased s_nlib */ + long s_vaddr; /* virtual address */ + long s_size; /* section size */ + long s_scnptr; /* file ptr to raw data for section */ + long s_relptr; /* file ptr to relocation */ + long s_lnnoptr; /* file ptr to line numbers */ + 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 */ + unsigned long s_align; /* section alignment */ #endif /* TC_I960 */ -}; + }; #define SCNHDR struct scnhdr #define SCNHSZ sizeof(SCNHDR) @@ -254,12 +262,12 @@ struct scnhdr { /* * names of "special" sections */ -#define _TEXT ".text" /* executable code section */ -#define _DATA ".data" /* initialized data */ -#define _BSS ".bss" /* un-initialized data */ -#define _DEBUG ".debug" /* special section used by dbx */ -#define _COMMENT ".comment" /* version info */ -#define _LIB ".lib" /* shared lib info section */ +#define _TEXT ".text" /* executable code section */ +#define _DATA ".data" /* initialized data */ +#define _BSS ".bss" /* un-initialized data */ +#define _DEBUG ".debug" /* special section used by dbx */ +#define _COMMENT ".comment" /* version info */ +#define _LIB ".lib" /* shared lib info section */ #define _TV ".tv" /* @@ -275,25 +283,25 @@ struct scnhdr { * (at least for a29k. Maybe others.) */ -#define STYP_REG (0x0000) /* "regular" section: allocated, relocated, loaded */ -#define STYP_DSECT (0x0001) /* "dummy" section: not allocated, relocated, not loaded */ -#define STYP_NOLOAD (0x0002) /* "noload" section: allocated, relocated, not loaded */ -#define STYP_GROUP (0x0004) /* "grouped" section: formed of input sections */ -#define STYP_PAD (0x0008) /* "padding" section: not allocated, not relocated, loaded */ -#define STYP_COPY (0x0010) /* "copy" section: for decision function used by field update; not allocated, not relocated, +#define STYP_REG (0x0000) /* "regular" section: allocated, relocated, loaded */ +#define STYP_DSECT (0x0001) /* "dummy" section: not allocated, relocated, not loaded */ +#define STYP_NOLOAD (0x0002) /* "noload" section: allocated, relocated, not loaded */ +#define STYP_GROUP (0x0004) /* "grouped" section: formed of input sections */ +#define STYP_PAD (0x0008) /* "padding" section: not allocated, not relocated, loaded */ +#define STYP_COPY (0x0010) /* "copy" section: for decision function used by field update; not allocated, not relocated, loaded; reloc & lineno entries processed normally */ -#define STYP_TEXT (0x0020) /* section contains text only */ -#define S_SHRSEG (0x0020) /* In 3b Update files (output of ogen), sections which appear in SHARED segments of the Pfile +#define STYP_TEXT (0x0020) /* section contains text only */ +#define S_SHRSEG (0x0020) /* In 3b Update files (output of ogen), sections which appear in SHARED segments of the Pfile will have the S_SHRSEG flag set by ogen, to inform dufr that updating 1 copy of the proc. will update all process invocations. */ -#define STYP_DATA (0x0040) /* section contains data only */ -#define STYP_BSS (0x0080) /* section contains bss only */ -#define S_NEWFCN (0x0100) /* In a minimal file or an update file, a new function (as compared with a replaced function) */ -#define STYP_INFO (0x0200) /* comment section : not allocated not relocated, not loaded */ -#define STYP_OVER (0x0400) /* overlay section : relocated not allocated or loaded */ -#define STYP_LIB (0x0800) /* for .lib section : same as INFO */ -#define STYP_MERGE (0x2000) /* merge section -- combines with text, data or bss sections only */ -#define STYP_REVERSE_PAD (0x4000) /* section will be padded with no-op instructions wherever padding is necessary and there is a +#define STYP_DATA (0x0040) /* section contains data only */ +#define STYP_BSS (0x0080) /* section contains bss only */ +#define S_NEWFCN (0x0100) /* In a minimal file or an update file, a new function (as compared with a replaced function) */ +#define STYP_INFO (0x0200) /* comment section : not allocated not relocated, not loaded */ +#define STYP_OVER (0x0400) /* overlay section : relocated not allocated or loaded */ +#define STYP_LIB (0x0800) /* for .lib section : same as INFO */ +#define STYP_MERGE (0x2000) /* merge section -- combines with text, data or bss sections only */ +#define STYP_REVERSE_PAD (0x4000) /* section will be padded with no-op instructions wherever padding is necessary and there is a word of contiguous bytes beginning on a word boundary. */ #ifdef TC_A29K @@ -311,20 +319,23 @@ struct scnhdr { * grouping will have l_lnno = 0 and in place of physical address will be the * symbol table index of the function name. */ -struct lineno { - union { - long l_symndx; /* symbol index of function name, iff l_lnno == 0*/ - long l_paddr; /* (physical) address of line number */ - } l_addr; - unsigned short l_lnno; /* line number */ +struct lineno + { + union + { + long l_symndx; /* symbol index of function name, iff l_lnno == 0*/ + long l_paddr; /* (physical) address of line number */ + } + l_addr; + unsigned short l_lnno; /* line number */ #ifdef TC_I960 - /* not used on a29k */ - char padding[2]; /* force alignment */ + /* not used on a29k */ + char padding[2]; /* force alignment */ #endif /* TC_I960 */ -}; + }; #define LINENO struct lineno -#define LINESZ sizeof(LINENO) +#define LINESZ sizeof(LINENO) /********************** SYMBOLS **********************/ @@ -333,78 +344,83 @@ struct lineno { #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 */ - struct { - long _n_zeroes; /* new == 0 */ - long _n_offset; /* offset into string table */ - } _n_n; - char *_n_nptr[2]; /* allows for overlaying */ - } _n; - long n_value; /* value of symbol */ - short n_scnum; /* section number */ - +struct syment + { + union + { + char _n_name[SYMNMLEN]; /* old COFF version */ + struct + { + long _n_zeroes; /* new == 0 */ + long _n_offset; /* offset into string table */ + } + _n_n; + char *_n_nptr[2]; /* allows for overlaying */ + } + _n; + 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 + /* 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 */ + 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 */ -}; + }; #define SYMENT struct syment -#define SYMESZ sizeof(SYMENT) /* This had better also be sizeof(AUXENT) */ +#define SYMESZ sizeof(SYMENT) /* This had better also be sizeof(AUXENT) */ #define n_name _n._n_name #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: */ - -#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 */ -#define N_DEBUG ((short)-2) /* debugging symbol -- symbol value is meaningless */ -#define N_TV ((short)-3) /* indicates symbol needs preload transfer vector */ -#define P_TV ((short)-4) /* indicates symbol needs transfer vector (postload) */ + +#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 */ +#define N_DEBUG ((short)-2) /* debugging symbol -- symbol value is meaningless */ +#define N_TV ((short)-3) /* indicates symbol needs preload transfer vector */ +#define P_TV ((short)-4) /* indicates symbol needs transfer vector (postload) */ /* * 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_CHAR 2 /* character */ -#define T_SHORT 3 /* short integer */ -#define T_INT 4 /* integer */ -#define T_LONG 5 /* long integer */ -#define T_FLOAT 6 /* floating point */ -#define T_DOUBLE 7 /* double word */ -#define T_STRUCT 8 /* structure */ -#define T_UNION 9 /* union */ -#define T_ENUM 10 /* enumeration */ -#define T_MOE 11 /* member of enumeration */ -#define T_UCHAR 12 /* unsigned character */ -#define T_USHORT 13 /* unsigned short */ -#define T_UINT 14 /* unsigned integer */ -#define T_ULONG 15 /* unsigned long */ +#define T_NULL 0 /* type not assigned */ +#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 */ +#define T_LONG 5 /* long integer */ +#define T_FLOAT 6 /* floating point */ +#define T_DOUBLE 7 /* double word */ +#define T_STRUCT 8 /* structure */ +#define T_UNION 9 /* union */ +#define T_ENUM 10 /* enumeration */ +#define T_MOE 11 /* member of enumeration */ +#define T_UCHAR 12 /* unsigned character */ +#define T_USHORT 13 /* unsigned short */ +#define T_UINT 14 /* unsigned integer */ +#define T_ULONG 15 /* unsigned long */ #ifdef TC_I960 #define T_LNGDBL 16 /* long double */ @@ -442,76 +458,103 @@ struct syment { #define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) -union auxent { - struct { - 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 */ - } 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 */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - 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. */ - union { - char x_fname[FILNMLEN]; - struct { - long x_zeroes; - 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. */ - unsigned short x_tvran[2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - +union auxent + { + struct + { + 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 */ + } + 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 */ + } + x_fcn; + struct + { /* if ISARY, up to 4 dimen. */ + 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. */ + union + { + char x_fname[FILNMLEN]; + struct + { + long x_zeroes; + 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. */ + 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. */ + struct + { + /* 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 */ + 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 */ -}; + }; #define AUXENT union auxent -#define AUXESZ sizeof(AUXENT) /* This had better also be sizeof(SYMENT) */ +#define AUXESZ sizeof(AUXENT) /* This had better also be sizeof(SYMENT) */ #if VAX || I960 # define _ETEXT "_etext" @@ -521,20 +564,21 @@ union auxent { /********************** RELOCATION DIRECTIVES **********************/ -struct reloc { - long r_vaddr; /* Virtual address of reference */ - long r_symndx; /* Index into symbol table */ - unsigned short r_type; /* Relocation type */ +struct reloc + { + long r_vaddr; /* Virtual address of reference */ + long r_symndx; /* Index into symbol table */ + unsigned short r_type; /* Relocation type */ #ifdef TC_I960 - /* not used for a29k */ - char pad[2]; /* Unused */ + /* not used for a29k */ + char pad[2]; /* Unused */ #endif /* TC_I960 */ -}; + }; #define RELOC struct reloc #define RELSZ sizeof(RELOC) -#define R_ABS (0x00) /* reference is absolute */ +#define R_ABS (0x00) /* reference is absolute */ #ifdef TC_I960 #define R_RELLONG (0x11) /* Direct 32-bit relocation */ @@ -567,18 +611,18 @@ struct reloc { * constant fields of the instruction are set to zero. */ -#define R_IREL (0x18) /* instruction relative (jmp/call) */ -#define R_IABS (0x19) /* instruction absolute (jmp/call) */ -#define R_ILOHALF (0x1a) /* instruction low half (const) */ -#define R_IHIHALF (0x1b) /* instruction high half (consth) part 1 */ -#define R_IHCONST (0x1c) /* instruction high half (consth) part 2 +#define R_IREL (0x18) /* instruction relative (jmp/call) */ +#define R_IABS (0x19) /* instruction absolute (jmp/call) */ +#define R_ILOHALF (0x1a) /* instruction low half (const) */ +#define R_IHIHALF (0x1b) /* instruction high half (consth) part 1 */ +#define R_IHCONST (0x1c) /* instruction high half (consth) part 2 constant offset of R_IHIHALF relocation */ -#define R_BYTE (0x1d) /* relocatable byte value */ -#define R_HWORD (0x1e) /* relocatable halfword value */ -#define R_WORD (0x1f) /* relocatable word value */ -#define R_IGLBLRC (0x20) /* instruction global register RC */ -#define R_IGLBLRA (0x21) /* instruction global register RA */ -#define R_IGLBLRB (0x22) /* instruction global register RB */ +#define R_BYTE (0x1d) /* relocatable byte value */ +#define R_HWORD (0x1e) /* relocatable halfword value */ +#define R_WORD (0x1f) /* relocatable word value */ +#define R_IGLBLRC (0x20) /* instruction global register RC */ +#define R_IGLBLRA (0x21) /* instruction global register RA */ +#define R_IGLBLRB (0x22) /* instruction global register RB */ #endif /* TC_A29K */ @@ -592,7 +636,7 @@ struct reloc { /* * X86 generic * 8-bit offset reference in 8-bits - * 8-bit offset reference in 16-bits + * 8-bit offset reference in 16-bits * 12-bit segment reference * auxiliary relocation entry */ @@ -625,7 +669,7 @@ struct reloc { #define R_IND24 015 #define R_IND32 016 -/* +/* * XL generics * 10-bit direct reference * 10-bit "relative" reference @@ -646,34 +690,35 @@ struct reloc { * 32-bit direct reference with bytes swapped */ #define R_DIR32S 012 - + #endif /* TC_I386 */ #if defined(TE_I386AIX) -#define UINFOSIZ 64 /* size of user info buffer */ +#define UINFOSIZ 64 /* size of user info buffer */ typedef char uinfo_t[UINFOSIZ]; -struct env387 { - unsigned short control; - unsigned short r0; - unsigned short status; - unsigned short r1; - unsigned short tag; - unsigned short r2; - unsigned long eip; - unsigned short code_seg; - unsigned short opcode; - unsigned long operand; - unsigned short operand_seg; - unsigned short r3; - unsigned char regs[8][10]; -}; - -#define CD_NAMELEN 16 /* length of most names in this header */ -#define CORHDRSIZ 2048 /* size to which header is padded out */ -#define MAX_CORE_SEGS 32 /* maximum segments in a core dump */ -#define NUM_FREGS 1 /* # of saved FP regs */ +struct env387 + { + unsigned short control; + unsigned short r0; + unsigned short status; + unsigned short r1; + unsigned short tag; + unsigned short r2; + unsigned long eip; + unsigned short code_seg; + unsigned short opcode; + unsigned long operand; + unsigned short operand_seg; + unsigned short r3; + unsigned char regs[8][10]; + }; + +#define CD_NAMELEN 16 /* length of most names in this header */ +#define CORHDRSIZ 2048 /* size to which header is padded out */ +#define MAX_CORE_SEGS 32 /* maximum segments in a core dump */ +#define NUM_FREGS 1 /* # of saved FP regs */ /* * These are defined such that 286 and 386 kernels can produce @@ -698,64 +743,74 @@ struct env387 { #define NUM_REGS 16 #ifndef SPATHLEN -# define SPATHLEN 16 /* sys/param.h */ +# define SPATHLEN 16 /* sys/param.h */ #endif #ifndef NSIG -# define NSIG 63 /* sys/signal.h */ +# define NSIG 63 /* sys/signal.h */ # define SIGSETSZ ((NSIG+31)/32) -typedef struct ksigmask { - unsigned long sigs[SIGSETSZ]; -} ksigmask_t; +typedef struct ksigmask + { + unsigned long sigs[SIGSETSZ]; + } + +ksigmask_t; #endif -struct corehdr { - char cd_magic[4]; /* COR_MAGIC = "core" */ - - /* general information about the dump itself */ - struct dumpseg { /* table of contents for dump */ - long cs_type; /* seg. type; see below */ - long cs_len; /* length (in bytes) of segment */ - long cs_offset; /* offset (in dump) of segment */ - long cs_address; /* address segment had in mem */ - } cd_segs[MAX_CORE_SEGS]; - - /* general information about the process */ - char cd_comm[CD_NAMELEN]; /* command being run */ - char cd_mach[CD_NAMELEN]; /* type of machine it ran on */ - char cd_site[CD_NAMELEN]; /* name of site it ran on */ - long cd_ldtype; /* type of load module running */ - char cd_intsize; /* sizeof(int) */ - char cd_dptrsize; /* sizeof(char *) */ - char cd_tptrsize; /* sizeof(int (*)()) */ - char cd_unused; - - /* user-mode program state */ - long cd_regs[NUM_REGS]; /* user-mode general registers */ - struct env387 cd_fpregs; /* user-mode floating-point state */ - - /* kernel-mode program state */ - int (*cd_sig[NSIG])(); /* disposition of signals */ - ksigmask_t cd_sigmask; /* signals to be blocked */ - ksigmask_t cd_sigpend; /* signals currently pending */ - long cd_cursig; /* signal that caused the dump */ - - long cd_pid; /* process ID of the corpse */ - long cd_ppid; /* parent process ID of corpse */ - short cd_uid; /* process effective user ID */ - short cd_ruid; /* process real user ID */ - short cd_gid; /* process effective group ID */ - short cd_rgid; /* process real group ID */ - - uinfo_t cd_uinfo; /* buffer of user information */ - char cd_locname[32]; /* name of /local */ - char cd_uvers[CD_NAMELEN]; /* user version string */ - unsigned short cd_spath[SPATHLEN]; /* sitepath */ -}; +struct corehdr + { + char cd_magic[4]; /* COR_MAGIC = "core" */ + + /* general information about the dump itself */ + struct dumpseg + { /* table of contents for dump */ + long cs_type; /* seg. type; see below */ + long cs_len; /* length (in bytes) of segment */ + long cs_offset; /* offset (in dump) of segment */ + long cs_address; /* address segment had in mem */ + } + cd_segs[MAX_CORE_SEGS]; + + /* general information about the process */ + char cd_comm[CD_NAMELEN]; /* command being run */ + char cd_mach[CD_NAMELEN]; /* type of machine it ran on */ + char cd_site[CD_NAMELEN]; /* name of site it ran on */ + long cd_ldtype; /* type of load module running */ + char cd_intsize; /* sizeof(int) */ + char cd_dptrsize; /* sizeof(char *) */ + char cd_tptrsize; /* sizeof(int (*)()) */ + char cd_unused; + + /* user-mode program state */ + long cd_regs[NUM_REGS]; /* user-mode general registers */ + struct env387 cd_fpregs; /* user-mode floating-point state */ + + /* kernel-mode program state */ + int (*cd_sig[NSIG]) (); /* disposition of signals */ + ksigmask_t cd_sigmask; /* signals to be blocked */ + ksigmask_t cd_sigpend; /* signals currently pending */ + long cd_cursig; /* signal that caused the dump */ + + long cd_pid; /* process ID of the corpse */ + long cd_ppid; /* parent process ID of corpse */ + short cd_uid; /* process effective user ID */ + short cd_ruid; /* process real user ID */ + short cd_gid; /* process effective group ID */ + short cd_rgid; /* process real group ID */ + + uinfo_t cd_uinfo; /* buffer of user information */ + char cd_locname[32]; /* name of /local */ + char cd_uvers[CD_NAMELEN]; /* user version string */ + unsigned short cd_spath[SPATHLEN]; /* sitepath */ + }; #ifndef NOCHECKS /* this will generate an error if sizeof(struct corehdr) > CORHDRSIZ */ -struct { char xxcdxx[CORHDRSIZ+1-sizeof(struct corehdr)]; }; -#endif /* ! NOCHECKS */ +struct + { + char xxcdxx[CORHDRSIZ + 1 - sizeof (struct corehdr)]; + }; + +#endif /* ! NOCHECKS */ /* * segment types (in cs_type) diff --git a/gas/config/cplus-dem.c b/gas/config/cplus-dem.c index e3819bc098d..a345b0bd285 100644 --- a/gas/config/cplus-dem.c +++ b/gas/config/cplus-dem.c @@ -1,17 +1,17 @@ -/* Demangler for GNU C++ +/* Demangler for GNU C++ Copyright (C) 1989, 1992 Free Software Foundation, Inc. written by James Clark (jjc@jclark.uucp) - + 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; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -20,39 +20,39 @@ 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 a pointer to a malloced string giving a C++ representation 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 #include #include - + #if !defined(sequent) && !defined(NeXT) #include #else -#define memcpy(s1, s2, n) strncpy(s1, s2, n) +#define memcpy(s1, s2, n) strncpy(s1, s2, n) #define memcmp(s1, s2, n) strncmp(s1, s2, n) -#define strchr(s, c) index(s, c) +#define strchr(s, c) index(s, c) #endif #if __STDC__ != 1 @@ -77,68 +77,75 @@ static char **typevec = 0; static int ntypes = 0; static int typevec_size = 0; -static struct { - 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= */ +static struct + { + 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= */ }; /* 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 */ -} string; +typedef struct + { + char *b; /* pointer to start of string */ + char *p; /* pointer after last character */ + char *e; /* pointer after end of allocated space */ + } + +string; #if __STDC__ == 1 -static void string_need (string *s, int n); -static void string_delete (string *s); -static void string_init (string *s); -static void string_clear (string *s); -static int string_empty (string *s); -static void string_append (string *p, const char *s); -static void string_appends (string *p, string *s); -static void string_appendn (string *p, const char *s, int n); -static void string_prepend (string *p, const char *s); +static void string_need (string * s, int n); +static void string_delete (string * s); +static void string_init (string * s); +static void string_clear (string * s); +static int string_empty (string * s); +static void string_append (string * p, const char *s); +static void string_appends (string * p, string * s); +static void string_appendn (string * p, const char *s, int n); +static void string_prepend (string * p, const char *s); #if 0 -static void string_prepends (string *p, string *s); +static void string_prepends (string * p, string * s); #endif -static void string_prependn (string *p, const char *s, int n); +static void string_prependn (string * p, const char *s, int n); static int get_count (const char **type, int *count); -static int do_args (const char **type, string *decl); -static int do_type (const char **type, string *result); -static int do_arg (const char **type, string *result); -static int do_args (const char **type, string *decl); -static void munge_function_name (string *name); +static int do_args (const char **type, string * decl); +static int do_type (const char **type, string * result); +static int do_arg (const char **type, string * result); +static int do_args (const char **type, string * decl); +static void munge_function_name (string * name); #else static void string_need (); static void string_delete (); @@ -160,768 +167,769 @@ 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 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 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; - } + remembered_type = typevec[n]; + type = &remembered_type; } - - 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) + break; + + case 'F': + *type += 1; + if (!string_empty (&decl) && decl.b[0] == '*') { - if (!string_empty (&decl)) - { - string_append (result, " "); - string_appends (result, &decl); - } - string_delete (&decl); - return 1; + string_prepend (&decl, "("); + string_append (&decl, ")"); } - else + 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') { - string_delete (&decl); - string_delete (result); - return 0; + *type += 1; + if (!string_empty (&decl)) + string_prepend (&decl, " "); + string_prepend (&decl, "const"); + break; } + + /* 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) - { - 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; - } - } - - if (**type == 'v') - *type += 1; - else if (**type == 'e') + 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) { - *type += 1; - if (need_comma) - string_append (decl, ","); - string_append (decl, "..."); + 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; } - - string_append (decl, ")"); - return 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; } 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] == '$') + 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++) { - 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; + 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 if (!string_empty (name) && name->p - name->b >= 5 - && memcmp (name->b, "type$", 5) == 0) + } + else + { + for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) { - /* 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; - } + 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 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; +static void +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-ansi.h b/gas/config/ho-ansi.h index 2af034118ee..bd2d9094633 100644 --- a/gas/config/ho-ansi.h +++ b/gas/config/ho-ansi.h @@ -1,18 +1,18 @@ /* ho-ansi.h Host-specific header file for generic ansi environments. Copyright (C) 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. */ diff --git a/gas/config/ho-decstation.h b/gas/config/ho-decstation.h index 1cab4d516e0..e13ea037d86 100644 --- a/gas/config/ho-decstation.h +++ b/gas/config/ho-decstation.h @@ -1,26 +1,26 @@ /* ho-pmax.h Host-specific header file for decstation 3100. Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -extern char *malloc(); -extern int free(); +extern char *malloc (); +extern int free (); #if !defined(__GNUC__) #define know(x) diff --git a/gas/config/ho-generic.h b/gas/config/ho-generic.h index 493cfc69192..b1b0a93315b 100644 --- a/gas/config/ho-generic.h +++ b/gas/config/ho-generic.h @@ -1,18 +1,18 @@ /* 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. */ @@ -25,6 +25,6 @@ #define HAVE_STRERROR -extern int free(); +extern int free (); /* end of ho-generic.h */ diff --git a/gas/config/ho-go32.h b/gas/config/ho-go32.h index d6ac3360034..7ef6862b20d 100644 --- a/gas/config/ho-go32.h +++ b/gas/config/ho-go32.h @@ -19,7 +19,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define HO_I386 1 -extern void free(); -extern void *malloc(); +extern void free (); +extern void *malloc (); /* end of ho-go32.h */ diff --git a/gas/config/ho-hpux.h b/gas/config/ho-hpux.h index d5ff31a8336..ebea9e2d6c9 100644 --- a/gas/config/ho-hpux.h +++ b/gas/config/ho-hpux.h @@ -1,18 +1,18 @@ /* ho-hpux.h -- Header to compile the assembler under HP-UX Copyright (C) 1988, 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. */ diff --git a/gas/config/ho-i386.h b/gas/config/ho-i386.h index 078e3942a0a..c9938177ee6 100644 --- a/gas/config/ho-i386.h +++ b/gas/config/ho-i386.h @@ -1,18 +1,18 @@ /* ho-i386.h i386 specific header file. Copyright (C) 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. */ diff --git a/gas/config/ho-i386aix.h b/gas/config/ho-i386aix.h index d31b51ad57e..d439f74b0f8 100644 --- a/gas/config/ho-i386aix.h +++ b/gas/config/ho-i386aix.h @@ -1,18 +1,18 @@ /* ho-386aix.h AIX PS/2 i386 specific header file. Copyright (C) 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. */ diff --git a/gas/config/ho-rs6000.h b/gas/config/ho-rs6000.h index d53f7220ff7..befb8166d77 100644 --- a/gas/config/ho-rs6000.h +++ b/gas/config/ho-rs6000.h @@ -1,18 +1,18 @@ /* ho-rs6000.h Rs6000 host-specific header file. Copyright (C) 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. */ diff --git a/gas/config/ho-sun386.h b/gas/config/ho-sun386.h index 6c74df47598..bf2831ba7ba 100644 --- a/gas/config/ho-sun386.h +++ b/gas/config/ho-sun386.h @@ -1,5 +1,5 @@ #include -extern int sprintf(); +extern int sprintf (); /* end of ho-sun386.h */ diff --git a/gas/config/ho-sunos.h b/gas/config/ho-sunos.h index 1193b1bf515..15628007265 100644 --- a/gas/config/ho-sunos.h +++ b/gas/config/ho-sunos.h @@ -1,18 +1,18 @@ /* This file is ho-sunos.h Copyright (C) 1987-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. */ @@ -24,7 +24,7 @@ #if !defined(__GNUC__) && (__STDC__ != 1) #include #else -extern int memset(); +extern int memset (); #endif /* #include before when compiling by GCC. */ @@ -37,38 +37,38 @@ extern int memset(); /*extern int abort();*/ /*extern int exit();*/ -extern char *malloc(); -extern char *realloc(); -extern char *strchr(); -extern char *strrchr(); -extern int _filbuf(); -extern int _flsbuf(); -extern int fclose(); -extern int fgetc(); -extern int fprintf(); -extern int fread(); -extern int free(); -extern int perror(); -extern int printf(); -extern int rewind(); -extern int setvbuf(); -extern int sscanf(); -extern int strcmp(); -extern int strlen(); -extern int strncmp(); -extern int time(); -extern int ungetc(); -extern int vfprintf(); -extern int vprintf(); -extern int vsprintf(); -extern long atol(); +extern char *malloc (); +extern char *realloc (); +extern char *strchr (); +extern char *strrchr (); +extern int _filbuf (); +extern int _flsbuf (); +extern int fclose (); +extern int fgetc (); +extern int fprintf (); +extern int fread (); +extern int free (); +extern int perror (); +extern int printf (); +extern int rewind (); +extern int setvbuf (); +extern int sscanf (); +extern int strcmp (); +extern int strlen (); +extern int strncmp (); +extern int time (); +extern int ungetc (); +extern int vfprintf (); +extern int vprintf (); +extern int vsprintf (); +extern long atol (); #ifndef tolower -extern int tolower(); +extern int tolower (); #endif /* tolower */ #ifndef toupper -extern int toupper(); +extern int toupper (); #endif /* toupper */ /* diff --git a/gas/config/ho-sysv.h b/gas/config/ho-sysv.h index 443fe3bf104..d74c0d75bda 100644 --- a/gas/config/ho-sysv.h +++ b/gas/config/ho-sysv.h @@ -1,18 +1,18 @@ /* ho-sysv.h System V specific header file. Copyright (C) 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. */ @@ -21,7 +21,7 @@ #define setbuffer(stream, buf, size) setvbuf((stream), (buf), _IOLBF, (size)) -extern int free(); -extern char *malloc(); +extern int free (); +extern char *malloc (); /* end of ho-sysv.h */ diff --git a/gas/config/ho-vax.h b/gas/config/ho-vax.h index 4e7a5702e8c..1113721f4a0 100644 --- a/gas/config/ho-vax.h +++ b/gas/config/ho-vax.h @@ -1,18 +1,18 @@ /* ho-vax.h Intended for vax ultrix Copyright (C) 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. */ @@ -23,7 +23,7 @@ #define NO_STDARG #endif /* not ansi */ -extern char *malloc(); -extern int free(); +extern char *malloc (); +extern int free (); /* end of ho-vax.h */ diff --git a/gas/config/m88k-opcode.h b/gas/config/m88k-opcode.h index 5f685b90fc8..72823fd44a2 100644 --- a/gas/config/m88k-opcode.h +++ b/gas/config/m88k-opcode.h @@ -47,9 +47,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ struct m88k_opcode { - unsigned int opcode; - char *name; - char *op_spec; + unsigned int opcode; + char *name; + char *op_spec; }; /* and introducing... the Motorola 88100 instruction sets... */ @@ -67,216 +67,216 @@ struct m88k_opcode static struct m88k_opcode m88k_opcodes[] = { - /* Opcode Mnemonic Opspec */ +/* Opcode Mnemonic Opspec */ - _MC88xxx(0xf4007000, "add", "d,1,2") - _MC88xxx(0x70000000, "add", "d,1,I") - _MC88xxx(0xf4007200, "add.ci", "d,1,2") - _MC88xxx(0xf4007300, "add.cio", "d,1,2") - _MC88xxx(0xf4007100, "add.co", "d,1,2") - _MC88xxx(0xf4006000, "addu", "d,1,2") - _MC88xxx(0x60000000, "addu", "d,1,I") - _MC88xxx(0xf4006200, "addu.ci", "d,1,2") - _MC88xxx(0xf4006300, "addu.cio", "d,1,2") - _MC88xxx(0xf4006100, "addu.co", "d,1,2") - _MC88xxx(0xf4004000, "and", "d,1,2") - _MC88xxx(0x40000000, "and", "d,1,I") - _MC88xxx(0xf4004400, "and.c", "d,1,2") - _MC88xxx(0x44000000, "and.u", "d,1,I") - _MC88xxx(0xd0000000, "bb0", "B,1,p") - _MC88xxx(0xd4000000, "bb0.n", "B,1,p") - _MC88xxx(0xd8000000, "bb1", "B,1,p") - _MC88xxx(0xdc000000, "bb1.n", "B,1,p") - _MC88xxx(0xe8000000, "bcnd", "M,1,p") - _MC88xxx(0xec000000, "bcnd.n", "M,1,p") - _MC88xxx(0xc0000000, "br", "P") - _MC88xxx(0xc4000000, "br.n", "P") - _MC88xxx(0xc8000000, "bsr", "P") - _MC88xxx(0xcc000000, "bsr.n", "P") - _MC88xxx(0xf4008000, "clr", "d,1,2") - _MC88xxx(0xf0008000, "clr", "d,1,b") - _MC88xxx(0xf4007c00, "cmp", "d,1,2") - _MC88xxx(0x7c000000, "cmp", "d,1,I") - _MC88xxx(0xf4007800, "div", "d,1,2") - _MC88xxx(0x78000000, "div", "d,1,I") - _MC88xxx(0xf4007800, "divs", "d,1,2") - _MC88xxx(0x78000000, "divs", "d,1,I") - _MC88xxx(0xf4006800, "divu", "d,1,2") - _MC88xxx(0x68000000, "divu", "d,1,I") - _MC88xxx(0xf4009000, "ext", "d,1,2") - _MC88xxx(0xf0009000, "ext", "d,1,b") - _MC88xxx(0xf4009800, "extu", "d,1,2") - _MC88xxx(0xf0009800, "extu", "d,1,b") - _MC88xxx(0x84002800, "fadd.sss", "d,1,2") - _MC88xxx(0x84002880, "fadd.ssd", "d,1,2") - _MC88xxx(0x84002a00, "fadd.sds", "d,1,2") - _MC88xxx(0x84002a80, "fadd.sdd", "d,1,2") - _MC88xxx(0x84002820, "fadd.dss", "d,1,2") - _MC88xxx(0x840028a0, "fadd.dsd", "d,1,2") - _MC88xxx(0x84002a20, "fadd.dds", "d,1,2") - _MC88xxx(0x84002aa0, "fadd.ddd", "d,1,2") - _MC88xxx(0x84003a80, "fcmp.sdd", "d,1,2") - _MC88xxx(0x84003a00, "fcmp.sds", "d,1,2") - _MC88xxx(0x84003880, "fcmp.ssd", "d,1,2") - _MC88xxx(0x84003800, "fcmp.sss", "d,1,2") - _MC88xxx(0x84007000, "fdiv.sss", "d,1,2") - _MC88xxx(0x84007080, "fdiv.ssd", "d,1,2") - _MC88xxx(0x84007200, "fdiv.sds", "d,1,2") - _MC88xxx(0x84007280, "fdiv.sdd", "d,1,2") - _MC88xxx(0x84007020, "fdiv.dss", "d,1,2") - _MC88xxx(0x840070a0, "fdiv.dsd", "d,1,2") - _MC88xxx(0x84007220, "fdiv.dds", "d,1,2") - _MC88xxx(0x840072a0, "fdiv.ddd", "d,1,2") - _MC88xxx(0xf400ec00, "ff0", "d,2") - _MC88xxx(0xf400e800, "ff1", "d,2") - _MC88xxx(0x80004800, "fldcr", "d,f") - _MC88xxx(0x84002020, "flt.ds", "d,2") - _MC88xxx(0x84002000, "flt.ss", "d,2") - _MC88xxx(0x84000000, "fmul.sss", "d,1,2") - _MC88xxx(0x84000080, "fmul.ssd", "d,1,2") - _MC88xxx(0x84000200, "fmul.sds", "d,1,2") - _MC88xxx(0x84000280, "fmul.sdd", "d,1,2") - _MC88xxx(0x84000020, "fmul.dss", "d,1,2") - _MC88xxx(0x840000a0, "fmul.dsd", "d,1,2") - _MC88xxx(0x84000220, "fmul.dds", "d,1,2") - _MC88xxx(0x840002a0, "fmul.ddd", "d,1,2") - _MC88xxx(0x80008800, "fstcr", "3,f") - _MC88xxx(0x84003000, "fsub.sss", "d,1,2") - _MC88xxx(0x84003080, "fsub.ssd", "d,1,2") - _MC88xxx(0x84003200, "fsub.sds", "d,1,2") - _MC88xxx(0x84003280, "fsub.sdd", "d,1,2") - _MC88xxx(0x84003020, "fsub.dss", "d,1,2") - _MC88xxx(0x840030a0, "fsub.dsd", "d,1,2") - _MC88xxx(0x84003220, "fsub.dds", "d,1,2") - _MC88xxx(0x840032a0, "fsub.ddd", "d,1,2") - _MC88xxx(0x8000c800, "fxcr", "d,3,f") - _MC88xxx(0x8400fc01, "illop1", "") - _MC88xxx(0x8400fc02, "illop2", "") - _MC88xxx(0x8400fc03, "illop3", "") - _MC88xxx(0x84004880, "int.sd", "d,2") - _MC88xxx(0x84004800, "int.ss", "d,2") - _MC88xxx(0xf400c000, "jmp", "2") - _MC88xxx(0xf400c400, "jmp.n", "2") - _MC88xxx(0xf400c800, "jsr", "2") - _MC88xxx(0xf400cc00, "jsr.n", "2") - _MC88xxx(0xf4001400, "ld", "d,1,2") - _MC88xxx(0xf4001600, "ld", "d,1[2]") - _MC88xxx(0x14000000, "ld", "d,1,I") - _MC88xxx(0xf4001e00, "ld.b", "d,1[2]") - _MC88xxx(0xf4001c00, "ld.b", "d,1,2") - _MC88xxx(0x1c000000, "ld.b", "d,1,I") - _MC88xxx(0xf4001d00, "ld.b.usr", "d,1,2") - _MC88xxx(0xf4001f00, "ld.b.usr", "d,1[2]") - _MC88xxx(0xf4000e00, "ld.bu", "d,1[2]") - _MC88xxx(0xf4000c00, "ld.bu", "d,1,2") - _MC88xxx(0x0c000000, "ld.bu", "d,1,I") - _MC88xxx(0xf4000d00, "ld.bu.usr", "d,1,2") - _MC88xxx(0xf4000f00, "ld.bu.usr", "d,1[2]") - _MC88xxx(0xf4001200, "ld.d", "d,1[2]") - _MC88xxx(0xf4001000, "ld.d", "d,1,2") - _MC88xxx(0x10000000, "ld.d", "d,1,I") - _MC88xxx(0xf4001100, "ld.d.usr", "d,1,2") - _MC88xxx(0xf4001300, "ld.d.usr", "d,1[2]") - _MC88xxx(0xf4001a00, "ld.h", "d,1[2]") - _MC88xxx(0xf4001800, "ld.h", "d,1,2") - _MC88xxx(0x18000000, "ld.h", "d,1,I") - _MC88xxx(0xf4001900, "ld.h.usr", "d,1,2") - _MC88xxx(0xf4001b00, "ld.h.usr", "d,1[2]") - _MC88xxx(0xf4000a00, "ld.hu", "d,1[2]") - _MC88xxx(0xf4000800, "ld.hu", "d,1,2") - _MC88xxx(0x08000000, "ld.hu", "d,1,I") - _MC88xxx(0xf4000900, "ld.hu.usr", "d,1,2") - _MC88xxx(0xf4000b00, "ld.hu.usr", "d,1[2]") - _MC88xxx(0xf4001500, "ld.usr", "d,1,2") - _MC88xxx(0xf4001700, "ld.usr", "d,1[2]") - _MC88xxx(0xf4003600, "lda", "d,1[2]") - _MC88xxx(0xf4006000, "lda", "?d,1,2") /* Output addu */ - _MC88xxx(0x60000000, "lda", "?d,1,I") /* Output addu */ - _MC88xxx(0xf4006000, "lda.b", "?d,1[2]") /* Output addu */ - _MC88xxx(0xf4006000, "lda.b", "?d,1,2") /* Output addu */ - _MC88xxx(0x60000000, "lda.b", "?d,1,I") /* Output addu */ - _MC88xxx(0xf4003200, "lda.d", "d,1[2]") - _MC88xxx(0xf4006000, "lda.d", "?d,1,2") /* Output addu */ - _MC88xxx(0x60000000, "lda.d", "?d,1,I") /* Output addu */ - _MC88xxx(0xf4003a00, "lda.h", "d,1[2]") - _MC88xxx(0xf4006000, "lda.h", "?d,1,2") /* Output addu */ - _MC88xxx(0x60000000, "lda.h", "?d,1,I") /* Output addu */ - _MC88xxx(0x80004000, "ldcr", "d,c") - _MC88xxx(0xf400a000, "mak", "d,1,2") - _MC88xxx(0xf000a000, "mak", "d,1,b") - _MC88xxx(0x48000000, "mask", "d,1,I") - _MC88xxx(0x4c000000, "mask.u", "d,1,I") - _MC88xxx(0xf4006c00, "mul", "d,1,2") - _MC88xxx(0x6c000000, "mul", "d,1,I") - _MC88xxx(0xf4006c00, "mulu", "d,1,2") /* synonym for mul */ - _MC88xxx(0x6c000000, "mulu", "d,1,I") /* synonym for mul */ - _MC88xxx(0x84005080, "nint.sd", "d,2") - _MC88xxx(0x84005000, "nint.ss", "d,2") - _MC88xxx(0xf4005800, "or", "d,1,2") - _MC88xxx(0x58000000, "or", "d,1,I") - _MC88xxx(0xf4005c00, "or.c", "d,1,2") - _MC88xxx(0x5c000000, "or.u", "d,1,I") - _MC88xxx(0xf000a800, "rot", "d,1,b") - _MC88xxx(0xf400a800, "rot", "d,1,2") - _MC88xxx(0xf400fc00, "rte", "") - _MC88xxx(0xf4008800, "set", "d,1,2") - _MC88xxx(0xf0008800, "set", "d,1,b") - _MC88xxx(0xf4002600, "st", "d,1[2]") - _MC88xxx(0xf4002400, "st", "d,1,2") - _MC88xxx(0x24000000, "st", "d,1,I") - _MC88xxx(0xf4002e00, "st.b", "d,1[2]") - _MC88xxx(0xf4002c00, "st.b", "d,1,2") - _MC88xxx(0x2c000000, "st.b", "d,1,I") - _MC88xxx(0xf4002d00, "st.b.usr", "d,1,2") - _MC88xxx(0xf4002f00, "st.b.usr", "d,1[2]") - _MC88xxx(0xf4002200, "st.d", "d,1[2]") - _MC88xxx(0xf4002000, "st.d", "d,1,2") - _MC88xxx(0x20000000, "st.d", "d,1,I") - _MC88xxx(0xf4002100, "st.d.usr", "d,1,2") - _MC88xxx(0xf4002300, "st.d.usr", "d,1[2]") - _MC88xxx(0xf4002a00, "st.h", "d,1[2]") - _MC88xxx(0xf4002800, "st.h", "d,1,2") - _MC88xxx(0x28000000, "st.h", "d,1,I") - _MC88xxx(0xf4002900, "st.h.usr", "d,1,2") - _MC88xxx(0xf4002b00, "st.h.usr", "d,1[2]") - _MC88xxx(0xf4002500, "st.usr", "d,1,2") - _MC88xxx(0xf4002700, "st.usr", "d,1[2]") - _MC88xxx(0x80008000, "stcr", "3,c") - _MC88xxx(0xf4007400, "sub", "d,1,2") - _MC88xxx(0x74000000, "sub", "d,1,I") - _MC88xxx(0xf4007600, "sub.ci", "d,1,2") - _MC88xxx(0xf4007700, "sub.cio", "d,1,2") - _MC88xxx(0xf4007500, "sub.co", "d,1,2") - _MC88xxx(0xf4006400, "subu", "d,1,2") - _MC88xxx(0x64000000, "subu", "d,1,I") - _MC88xxx(0xf4006600, "subu.ci", "d,1,2") - _MC88xxx(0xf4006700, "subu.cio", "d,1,2") - _MC88xxx(0xf4006500, "subu.co", "d,1,2") - _MC88xxx(0xf000d000, "tb0", "B,1,V") - _MC88xxx(0xf000d800, "tb1", "B,1,V") - _MC88xxx(0xf400f800, "tbnd", "1,2") - _MC88xxx(0xf8000000, "tbnd", "1,I") - _MC88xxx(0xf000e800, "tcnd", "M,1,V") - _MC88xxx(0x84005880, "trnc.sd", "d,2") - _MC88xxx(0x84005800, "trnc.ss", "d,2") - _MC88xxx(0x8000c000, "xcr", "d,1,c") - _MC88xxx(0xf4000600, "xmem", "d,1[2]") - _MC88xxx(0xf4000400, "xmem", "d,1,2") - _MC88100(0x04000000, "xmem", "?d,1,I") - _MC88xxx(0xf4000200, "xmem.bu", "d,1[2]") - _MC88xxx(0xf4000000, "xmem.bu", "d,1,2") - _MC88100(0x00000000, "xmem.bu", "?d,1,I") - _MC88xxx(0xf4000300, "xmem.bu.usr", "d,1[2]") - _MC88xxx(0xf4000100, "xmem.bu.usr", "d,1,2") - _MC88100(0x00000100, "xmem.bu.usr", "?d,1,I") - _MC88xxx(0xf4000700, "xmem.usr", "d,1[2]") - _MC88xxx(0xf4000500, "xmem.usr", "d,1,2") - _MC88100(0x04000100, "xmem.usr", "?d,1,I") - _MC88xxx(0xf4005000, "xor", "d,1,2") - _MC88xxx(0x50000000, "xor", "d,1,I") - _MC88xxx(0xf4005400, "xor.c", "d,1,2") - _MC88xxx(0x54000000, "xor.u", "d,1,I") - _MC88xxx(0x00000000, "", 0) + _MC88xxx (0xf4007000, "add", "d,1,2") + _MC88xxx (0x70000000, "add", "d,1,I") + _MC88xxx (0xf4007200, "add.ci", "d,1,2") + _MC88xxx (0xf4007300, "add.cio", "d,1,2") + _MC88xxx (0xf4007100, "add.co", "d,1,2") + _MC88xxx (0xf4006000, "addu", "d,1,2") + _MC88xxx (0x60000000, "addu", "d,1,I") + _MC88xxx (0xf4006200, "addu.ci", "d,1,2") + _MC88xxx (0xf4006300, "addu.cio", "d,1,2") + _MC88xxx (0xf4006100, "addu.co", "d,1,2") + _MC88xxx (0xf4004000, "and", "d,1,2") + _MC88xxx (0x40000000, "and", "d,1,I") + _MC88xxx (0xf4004400, "and.c", "d,1,2") + _MC88xxx (0x44000000, "and.u", "d,1,I") + _MC88xxx (0xd0000000, "bb0", "B,1,p") + _MC88xxx (0xd4000000, "bb0.n", "B,1,p") + _MC88xxx (0xd8000000, "bb1", "B,1,p") + _MC88xxx (0xdc000000, "bb1.n", "B,1,p") + _MC88xxx (0xe8000000, "bcnd", "M,1,p") + _MC88xxx (0xec000000, "bcnd.n", "M,1,p") + _MC88xxx (0xc0000000, "br", "P") + _MC88xxx (0xc4000000, "br.n", "P") + _MC88xxx (0xc8000000, "bsr", "P") + _MC88xxx (0xcc000000, "bsr.n", "P") + _MC88xxx (0xf4008000, "clr", "d,1,2") + _MC88xxx (0xf0008000, "clr", "d,1,b") + _MC88xxx (0xf4007c00, "cmp", "d,1,2") + _MC88xxx (0x7c000000, "cmp", "d,1,I") + _MC88xxx (0xf4007800, "div", "d,1,2") + _MC88xxx (0x78000000, "div", "d,1,I") + _MC88xxx (0xf4007800, "divs", "d,1,2") + _MC88xxx (0x78000000, "divs", "d,1,I") + _MC88xxx (0xf4006800, "divu", "d,1,2") + _MC88xxx (0x68000000, "divu", "d,1,I") + _MC88xxx (0xf4009000, "ext", "d,1,2") + _MC88xxx (0xf0009000, "ext", "d,1,b") + _MC88xxx (0xf4009800, "extu", "d,1,2") + _MC88xxx (0xf0009800, "extu", "d,1,b") + _MC88xxx (0x84002800, "fadd.sss", "d,1,2") + _MC88xxx (0x84002880, "fadd.ssd", "d,1,2") + _MC88xxx (0x84002a00, "fadd.sds", "d,1,2") + _MC88xxx (0x84002a80, "fadd.sdd", "d,1,2") + _MC88xxx (0x84002820, "fadd.dss", "d,1,2") + _MC88xxx (0x840028a0, "fadd.dsd", "d,1,2") + _MC88xxx (0x84002a20, "fadd.dds", "d,1,2") + _MC88xxx (0x84002aa0, "fadd.ddd", "d,1,2") + _MC88xxx (0x84003a80, "fcmp.sdd", "d,1,2") + _MC88xxx (0x84003a00, "fcmp.sds", "d,1,2") + _MC88xxx (0x84003880, "fcmp.ssd", "d,1,2") + _MC88xxx (0x84003800, "fcmp.sss", "d,1,2") + _MC88xxx (0x84007000, "fdiv.sss", "d,1,2") + _MC88xxx (0x84007080, "fdiv.ssd", "d,1,2") + _MC88xxx (0x84007200, "fdiv.sds", "d,1,2") + _MC88xxx (0x84007280, "fdiv.sdd", "d,1,2") + _MC88xxx (0x84007020, "fdiv.dss", "d,1,2") + _MC88xxx (0x840070a0, "fdiv.dsd", "d,1,2") + _MC88xxx (0x84007220, "fdiv.dds", "d,1,2") + _MC88xxx (0x840072a0, "fdiv.ddd", "d,1,2") + _MC88xxx (0xf400ec00, "ff0", "d,2") + _MC88xxx (0xf400e800, "ff1", "d,2") + _MC88xxx (0x80004800, "fldcr", "d,f") + _MC88xxx (0x84002020, "flt.ds", "d,2") + _MC88xxx (0x84002000, "flt.ss", "d,2") + _MC88xxx (0x84000000, "fmul.sss", "d,1,2") + _MC88xxx (0x84000080, "fmul.ssd", "d,1,2") + _MC88xxx (0x84000200, "fmul.sds", "d,1,2") + _MC88xxx (0x84000280, "fmul.sdd", "d,1,2") + _MC88xxx (0x84000020, "fmul.dss", "d,1,2") + _MC88xxx (0x840000a0, "fmul.dsd", "d,1,2") + _MC88xxx (0x84000220, "fmul.dds", "d,1,2") + _MC88xxx (0x840002a0, "fmul.ddd", "d,1,2") + _MC88xxx (0x80008800, "fstcr", "3,f") + _MC88xxx (0x84003000, "fsub.sss", "d,1,2") + _MC88xxx (0x84003080, "fsub.ssd", "d,1,2") + _MC88xxx (0x84003200, "fsub.sds", "d,1,2") + _MC88xxx (0x84003280, "fsub.sdd", "d,1,2") + _MC88xxx (0x84003020, "fsub.dss", "d,1,2") + _MC88xxx (0x840030a0, "fsub.dsd", "d,1,2") + _MC88xxx (0x84003220, "fsub.dds", "d,1,2") + _MC88xxx (0x840032a0, "fsub.ddd", "d,1,2") + _MC88xxx (0x8000c800, "fxcr", "d,3,f") + _MC88xxx (0x8400fc01, "illop1", "") + _MC88xxx (0x8400fc02, "illop2", "") + _MC88xxx (0x8400fc03, "illop3", "") + _MC88xxx (0x84004880, "int.sd", "d,2") + _MC88xxx (0x84004800, "int.ss", "d,2") + _MC88xxx (0xf400c000, "jmp", "2") + _MC88xxx (0xf400c400, "jmp.n", "2") + _MC88xxx (0xf400c800, "jsr", "2") + _MC88xxx (0xf400cc00, "jsr.n", "2") + _MC88xxx (0xf4001400, "ld", "d,1,2") + _MC88xxx (0xf4001600, "ld", "d,1[2]") + _MC88xxx (0x14000000, "ld", "d,1,I") + _MC88xxx (0xf4001e00, "ld.b", "d,1[2]") + _MC88xxx (0xf4001c00, "ld.b", "d,1,2") + _MC88xxx (0x1c000000, "ld.b", "d,1,I") + _MC88xxx (0xf4001d00, "ld.b.usr", "d,1,2") + _MC88xxx (0xf4001f00, "ld.b.usr", "d,1[2]") + _MC88xxx (0xf4000e00, "ld.bu", "d,1[2]") + _MC88xxx (0xf4000c00, "ld.bu", "d,1,2") + _MC88xxx (0x0c000000, "ld.bu", "d,1,I") + _MC88xxx (0xf4000d00, "ld.bu.usr", "d,1,2") + _MC88xxx (0xf4000f00, "ld.bu.usr", "d,1[2]") + _MC88xxx (0xf4001200, "ld.d", "d,1[2]") + _MC88xxx (0xf4001000, "ld.d", "d,1,2") + _MC88xxx (0x10000000, "ld.d", "d,1,I") + _MC88xxx (0xf4001100, "ld.d.usr", "d,1,2") + _MC88xxx (0xf4001300, "ld.d.usr", "d,1[2]") + _MC88xxx (0xf4001a00, "ld.h", "d,1[2]") + _MC88xxx (0xf4001800, "ld.h", "d,1,2") + _MC88xxx (0x18000000, "ld.h", "d,1,I") + _MC88xxx (0xf4001900, "ld.h.usr", "d,1,2") + _MC88xxx (0xf4001b00, "ld.h.usr", "d,1[2]") + _MC88xxx (0xf4000a00, "ld.hu", "d,1[2]") + _MC88xxx (0xf4000800, "ld.hu", "d,1,2") + _MC88xxx (0x08000000, "ld.hu", "d,1,I") + _MC88xxx (0xf4000900, "ld.hu.usr", "d,1,2") + _MC88xxx (0xf4000b00, "ld.hu.usr", "d,1[2]") + _MC88xxx (0xf4001500, "ld.usr", "d,1,2") + _MC88xxx (0xf4001700, "ld.usr", "d,1[2]") + _MC88xxx (0xf4003600, "lda", "d,1[2]") + _MC88xxx (0xf4006000, "lda", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda", "?d,1,I") /* Output addu */ + _MC88xxx (0xf4006000, "lda.b", "?d,1[2]") /* Output addu */ + _MC88xxx (0xf4006000, "lda.b", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda.b", "?d,1,I") /* Output addu */ + _MC88xxx (0xf4003200, "lda.d", "d,1[2]") + _MC88xxx (0xf4006000, "lda.d", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda.d", "?d,1,I") /* Output addu */ + _MC88xxx (0xf4003a00, "lda.h", "d,1[2]") + _MC88xxx (0xf4006000, "lda.h", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda.h", "?d,1,I") /* Output addu */ + _MC88xxx (0x80004000, "ldcr", "d,c") + _MC88xxx (0xf400a000, "mak", "d,1,2") + _MC88xxx (0xf000a000, "mak", "d,1,b") + _MC88xxx (0x48000000, "mask", "d,1,I") + _MC88xxx (0x4c000000, "mask.u", "d,1,I") + _MC88xxx (0xf4006c00, "mul", "d,1,2") + _MC88xxx (0x6c000000, "mul", "d,1,I") + _MC88xxx (0xf4006c00, "mulu", "d,1,2") /* synonym for mul */ + _MC88xxx (0x6c000000, "mulu", "d,1,I") /* synonym for mul */ + _MC88xxx (0x84005080, "nint.sd", "d,2") + _MC88xxx (0x84005000, "nint.ss", "d,2") + _MC88xxx (0xf4005800, "or", "d,1,2") + _MC88xxx (0x58000000, "or", "d,1,I") + _MC88xxx (0xf4005c00, "or.c", "d,1,2") + _MC88xxx (0x5c000000, "or.u", "d,1,I") + _MC88xxx (0xf000a800, "rot", "d,1,b") + _MC88xxx (0xf400a800, "rot", "d,1,2") + _MC88xxx (0xf400fc00, "rte", "") + _MC88xxx (0xf4008800, "set", "d,1,2") + _MC88xxx (0xf0008800, "set", "d,1,b") + _MC88xxx (0xf4002600, "st", "d,1[2]") + _MC88xxx (0xf4002400, "st", "d,1,2") + _MC88xxx (0x24000000, "st", "d,1,I") + _MC88xxx (0xf4002e00, "st.b", "d,1[2]") + _MC88xxx (0xf4002c00, "st.b", "d,1,2") + _MC88xxx (0x2c000000, "st.b", "d,1,I") + _MC88xxx (0xf4002d00, "st.b.usr", "d,1,2") + _MC88xxx (0xf4002f00, "st.b.usr", "d,1[2]") + _MC88xxx (0xf4002200, "st.d", "d,1[2]") + _MC88xxx (0xf4002000, "st.d", "d,1,2") + _MC88xxx (0x20000000, "st.d", "d,1,I") + _MC88xxx (0xf4002100, "st.d.usr", "d,1,2") + _MC88xxx (0xf4002300, "st.d.usr", "d,1[2]") + _MC88xxx (0xf4002a00, "st.h", "d,1[2]") + _MC88xxx (0xf4002800, "st.h", "d,1,2") + _MC88xxx (0x28000000, "st.h", "d,1,I") + _MC88xxx (0xf4002900, "st.h.usr", "d,1,2") + _MC88xxx (0xf4002b00, "st.h.usr", "d,1[2]") + _MC88xxx (0xf4002500, "st.usr", "d,1,2") + _MC88xxx (0xf4002700, "st.usr", "d,1[2]") + _MC88xxx (0x80008000, "stcr", "3,c") + _MC88xxx (0xf4007400, "sub", "d,1,2") + _MC88xxx (0x74000000, "sub", "d,1,I") + _MC88xxx (0xf4007600, "sub.ci", "d,1,2") + _MC88xxx (0xf4007700, "sub.cio", "d,1,2") + _MC88xxx (0xf4007500, "sub.co", "d,1,2") + _MC88xxx (0xf4006400, "subu", "d,1,2") + _MC88xxx (0x64000000, "subu", "d,1,I") + _MC88xxx (0xf4006600, "subu.ci", "d,1,2") + _MC88xxx (0xf4006700, "subu.cio", "d,1,2") + _MC88xxx (0xf4006500, "subu.co", "d,1,2") + _MC88xxx (0xf000d000, "tb0", "B,1,V") + _MC88xxx (0xf000d800, "tb1", "B,1,V") + _MC88xxx (0xf400f800, "tbnd", "1,2") + _MC88xxx (0xf8000000, "tbnd", "1,I") + _MC88xxx (0xf000e800, "tcnd", "M,1,V") + _MC88xxx (0x84005880, "trnc.sd", "d,2") + _MC88xxx (0x84005800, "trnc.ss", "d,2") + _MC88xxx (0x8000c000, "xcr", "d,1,c") + _MC88xxx (0xf4000600, "xmem", "d,1[2]") + _MC88xxx (0xf4000400, "xmem", "d,1,2") + _MC88100 (0x04000000, "xmem", "?d,1,I") + _MC88xxx (0xf4000200, "xmem.bu", "d,1[2]") + _MC88xxx (0xf4000000, "xmem.bu", "d,1,2") + _MC88100 (0x00000000, "xmem.bu", "?d,1,I") + _MC88xxx (0xf4000300, "xmem.bu.usr", "d,1[2]") + _MC88xxx (0xf4000100, "xmem.bu.usr", "d,1,2") + _MC88100 (0x00000100, "xmem.bu.usr", "?d,1,I") + _MC88xxx (0xf4000700, "xmem.usr", "d,1[2]") + _MC88xxx (0xf4000500, "xmem.usr", "d,1,2") + _MC88100 (0x04000100, "xmem.usr", "?d,1,I") + _MC88xxx (0xf4005000, "xor", "d,1,2") + _MC88xxx (0x50000000, "xor", "d,1,I") + _MC88xxx (0xf4005400, "xor.c", "d,1,2") + _MC88xxx (0x54000000, "xor.u", "d,1,I") + _MC88xxx (0x00000000, "", 0) }; #define NUMOPCODES ((sizeof m88k_opcodes)/(sizeof m88k_opcodes[0])) diff --git a/gas/config/obj-bfd-sunos.c b/gas/config/obj-bfd-sunos.c index 17faf7c7b81..c0d87faa591 100644 --- a/gas/config/obj-bfd-sunos.c +++ b/gas/config/obj-bfd-sunos.c @@ -1,18 +1,18 @@ /* obj-bfd-sunos.c Copyright (C) 1987, 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. */ @@ -20,46 +20,49 @@ #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 */ - }; +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 segT N_TYPE_seg [N_TYPE+2] = { /* N_TYPE == 0x1E = 32-2 */ - SEG_UNKNOWN, /* N_UNDF == 0 */ - SEG_GOOF, - SEG_ABSOLUTE, /* N_ABS == 2 */ - SEG_GOOF, - SEG_TEXT, /* N_TEXT == 4 */ - SEG_GOOF, - SEG_DATA, /* N_DATA == 6 */ - SEG_GOOF, - SEG_BSS, /* N_BSS == 8 */ - 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_REGISTER, /* dummy N_REGISTER for regs = 30 */ - SEG_GOOF, +const segT N_TYPE_seg[N_TYPE + 2] = +{ /* N_TYPE == 0x1E = 32-2 */ + SEG_UNKNOWN, /* N_UNDF == 0 */ + SEG_GOOF, + SEG_ABSOLUTE, /* N_ABS == 2 */ + SEG_GOOF, + SEG_TEXT, /* N_TEXT == 4 */ + SEG_GOOF, + SEG_DATA, /* N_DATA == 6 */ + SEG_GOOF, + SEG_BSS, /* N_BSS == 8 */ + 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_REGISTER, /* dummy N_REGISTER for regs = 30 */ + SEG_GOOF, }; -void obj_symbol_new_hook(symbolP) -symbolS *symbolP; +void +obj_symbol_new_hook (symbolP) + symbolS *symbolP; { - return; -} /* obj_symbol_new_hook() */ + return; +} /* obj_symbol_new_hook() */ /* * Local Variables: diff --git a/gas/config/obj-bfd-sunos.h b/gas/config/obj-bfd-sunos.h index 958d8a9365b..2583d66f73c 100644 --- a/gas/config/obj-bfd-sunos.h +++ b/gas/config/obj-bfd-sunos.h @@ -1,18 +1,18 @@ /* Copyright (C) 1987, 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. */ @@ -56,8 +56,8 @@ typedef void *object_headers; #define S_GET_VALUE(s) ((s)->sy_symbol.value) #define S_IS_DEFINED(s) (!((s)->sy_symbol.flags & BSF_UNDEFINED)) -#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */ -#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */ +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */ +#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */ /* * Local Variables: diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c index 0cca3b0309e..dc7d7374761 100644 --- a/gas/config/obj-bout.c +++ b/gas/config/obj-bout.c @@ -1,18 +1,18 @@ /* b.out object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -20,74 +20,77 @@ #include "as.h" #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 */ - }; - -const segT N_TYPE_seg [N_TYPE+2] = { /* N_TYPE == 0x1E = 32-2 */ - SEG_UNKNOWN, /* N_UNDF == 0 */ - SEG_GOOF, - SEG_ABSOLUTE, /* N_ABS == 2 */ - SEG_GOOF, - SEG_TEXT, /* N_TEXT == 4 */ - SEG_GOOF, - SEG_DATA, /* N_DATA == 6 */ - SEG_GOOF, - SEG_BSS, /* N_BSS == 8 */ - 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_REGISTER, /* dummy N_REGISTER for regs = 30 */ - SEG_GOOF, +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 */ +}; + +const segT N_TYPE_seg[N_TYPE + 2] = +{ /* N_TYPE == 0x1E = 32-2 */ + SEG_UNKNOWN, /* N_UNDF == 0 */ + SEG_GOOF, + SEG_ABSOLUTE, /* N_ABS == 2 */ + SEG_GOOF, + SEG_TEXT, /* N_TEXT == 4 */ + SEG_GOOF, + SEG_DATA, /* N_DATA == 6 */ + SEG_GOOF, + SEG_BSS, /* N_BSS == 8 */ + 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_REGISTER, /* dummy N_REGISTER for regs = 30 */ + SEG_GOOF, }; #if __STDC__ == 1 -static void obj_bout_stab(int what); -static void obj_bout_line(void); -static void obj_bout_desc(void); +static void obj_bout_stab (int what); +static void obj_bout_line (void); +static void obj_bout_desc (void); #else /* not __STDC__ */ -static void obj_bout_desc(); -static void obj_bout_stab(); -static void obj_bout_line(); +static void obj_bout_desc (); +static void obj_bout_stab (); +static void obj_bout_line (); #endif /* not __STDC__ */ -const pseudo_typeS obj_pseudo_table[] = { - /* 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 */ - { "def", s_ignore, 0 }, - { "dim", s_ignore, 0 }, - { "endef", 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 }, - - /* other stuff we don't handle */ - { "ABORT", s_ignore, 0 }, - { "ident", s_ignore, 0 }, - - { NULL} /* end sentinel */ -}; /* obj_pseudo_table */ +const pseudo_typeS obj_pseudo_table[] = +{ +/* 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 */ + {"def", s_ignore, 0}, + {"dim", s_ignore, 0}, + {"endef", 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}, + +/* other stuff we don't handle */ + {"ABORT", s_ignore, 0}, + {"ident", s_ignore, 0}, + + {NULL} /* end sentinel */ +}; /* obj_pseudo_table */ /* Relocation. */ @@ -96,129 +99,141 @@ const pseudo_typeS obj_pseudo_table[] = { * * Crawl along a fixS chain. Emit the segment's relocations. */ -void obj_emit_relocations(where, fixP, segment_address_in_file) -char **where; -fixS *fixP; /* Fixup chain for this segment. */ -relax_addressT segment_address_in_file; +void +obj_emit_relocations (where, fixP, segment_address_in_file) + char **where; + fixS *fixP; /* Fixup chain for this segment. */ + relax_addressT segment_address_in_file; { - for (; fixP; fixP = fixP->fx_next) { - if (fixP->fx_addsy != NULL - || fixP->fx_r_type != NO_RELOC) { - tc_bout_fix_to_chars(*where, fixP, segment_address_in_file); - *where += sizeof(struct relocation_info); - } /* if there's a symbol */ - } /* for each fixup */ - -} /* emit_relocations() */ + for (; fixP; fixP = fixP->fx_next) + { + if (fixP->fx_addsy != NULL + || fixP->fx_r_type != NO_RELOC) + { + tc_bout_fix_to_chars (*where, fixP, segment_address_in_file); + *where += sizeof (struct relocation_info); + } /* if there's a symbol */ + } /* for each fixup */ + +} /* emit_relocations() */ /* Aout file generation & utilities */ /* Convert a lvalue to machine dependent data */ -void obj_header_append(where, headers) -char **where; -object_headers *headers; +void +obj_header_append (where, headers) + 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)); - - headers->header.a_relaxable = linkrelax; + /* 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)); + + headers->header.a_relaxable = linkrelax; #ifdef CROSS_COMPILE - md_number_to_chars(*where, headers->header.a_magic, sizeof(headers->header.a_magic)); - *where += sizeof(headers->header.a_magic); - md_number_to_chars(*where, headers->header.a_text, sizeof(headers->header.a_text)); - *where += sizeof(headers->header.a_text); - md_number_to_chars(*where, headers->header.a_data, sizeof(headers->header.a_data)); - *where += sizeof(headers->header.a_data); - md_number_to_chars(*where, headers->header.a_bss, sizeof(headers->header.a_bss)); - *where += sizeof(headers->header.a_bss); - md_number_to_chars(*where, headers->header.a_syms, sizeof(headers->header.a_syms)); - *where += sizeof(headers->header.a_syms); - md_number_to_chars(*where, headers->header.a_entry, sizeof(headers->header.a_entry)); - *where += sizeof(headers->header.a_entry); - md_number_to_chars(*where, headers->header.a_trsize, sizeof(headers->header.a_trsize)); - *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); - md_number_to_chars(*where, headers->header.a_tload, sizeof(headers->header.a_tload)); - *where += sizeof(headers->header.a_tload); - md_number_to_chars(*where, headers->header.a_dload, sizeof(headers->header.a_dload)); - *where += sizeof(headers->header.a_dload); - md_number_to_chars(*where, headers->header.a_talign, sizeof(headers->header.a_talign)); - *where += sizeof(headers->header.a_talign); - md_number_to_chars(*where, headers->header.a_dalign, sizeof(headers->header.a_dalign)); - *where += sizeof(headers->header.a_dalign); - md_number_to_chars(*where, headers->header.a_balign, sizeof(headers->header.a_balign)); - *where += sizeof(headers->header.a_balign); - md_number_to_chars(*where, headers->header.a_relaxable, sizeof(headers->header.a_relaxable)); - *where += sizeof(headers->header.a_relaxable); + md_number_to_chars (*where, headers->header.a_magic, sizeof (headers->header.a_magic)); + *where += sizeof (headers->header.a_magic); + md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text)); + *where += sizeof (headers->header.a_text); + md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data)); + *where += sizeof (headers->header.a_data); + md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss)); + *where += sizeof (headers->header.a_bss); + md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms)); + *where += sizeof (headers->header.a_syms); + md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry)); + *where += sizeof (headers->header.a_entry); + md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize)); + *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); + md_number_to_chars (*where, headers->header.a_tload, sizeof (headers->header.a_tload)); + *where += sizeof (headers->header.a_tload); + md_number_to_chars (*where, headers->header.a_dload, sizeof (headers->header.a_dload)); + *where += sizeof (headers->header.a_dload); + md_number_to_chars (*where, headers->header.a_talign, sizeof (headers->header.a_talign)); + *where += sizeof (headers->header.a_talign); + md_number_to_chars (*where, headers->header.a_dalign, sizeof (headers->header.a_dalign)); + *where += sizeof (headers->header.a_dalign); + md_number_to_chars (*where, headers->header.a_balign, sizeof (headers->header.a_balign)); + *where += sizeof (headers->header.a_balign); + md_number_to_chars (*where, headers->header.a_relaxable, sizeof (headers->header.a_relaxable)); + *where += sizeof (headers->header.a_relaxable); #else /* ! CROSS_COMPILE */ - append(where, (char *) &headers->header, sizeof(headers->header)); + append (where, (char *) &headers->header, sizeof (headers->header)); #endif /* ! CROSS_COMPILE */ -} /* a_header_append() */ +} /* a_header_append() */ -void obj_symbol_to_chars(where, symbolP) -char **where; -symbolS *symbolP; +void +obj_symbol_to_chars (where, symbolP) + char **where; + 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))); + 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() */ + append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type)); +} /* obj_symbol_to_chars() */ -void obj_emit_symbols(where, symbol_rootP) -char **where; -symbolS *symbol_rootP; +void +obj_emit_symbols (where, symbol_rootP) + char **where; + symbolS *symbol_rootP; { - symbolS * symbolP; - - /* + 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 + 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() */ + 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); -void obj_symbol_new_hook(symbolP) -symbolS *symbolP; + obj_symbol_to_chars (where, symbolP); + S_SET_NAME (symbolP, temp); + } +} /* emit_symbols() */ + +void +obj_symbol_new_hook (symbolP) + symbolS *symbolP; +{ + S_SET_OTHER (symbolP, 0); + S_SET_DESC (symbolP, 0); + return; +} /* obj_symbol_new_hook() */ + +static void +obj_bout_line () { - S_SET_OTHER(symbolP, 0); - S_SET_DESC(symbolP, 0); - return; -} /* obj_symbol_new_hook() */ - -static void obj_bout_line() { - /* Assume delimiter is part of expression. */ - /* BSD4.2 as fails with delightful bug, so we */ - /* are not being incompatible here. */ - new_logical_line ((char *)NULL, (int)(get_absolute_expression ())); - demand_empty_rest_of_line(); -} /* obj_bout_line() */ + /* Assume delimiter is part of expression. */ + /* BSD4.2 as fails with delightful bug, so we */ + /* are not being incompatible here. */ + new_logical_line ((char *) NULL, (int) (get_absolute_expression ())); + demand_empty_rest_of_line (); +} /* obj_bout_line() */ /* * stab() @@ -239,260 +254,294 @@ static void obj_bout_line() { * .stabX directives always make a symbol table entry. It may be junk if * the rest of your .stabX directive is malformed. */ -static void obj_bout_stab(what) -int what; +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; - - /* + 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 ++; - else { - as_bad("I need a comma after symbol's name"); - goof = 1; - } - } else - string = ""; - - /* + goof = 0; /* JF who forgot this?? */ + if (what == 's') + { + string = demand_copy_C_string (&length); + SKIP_WHITESPACE (); + if (*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. */ - if (!goof) { - symbolP = symbol_new(string, - SEG_UNKNOWN, - 0, - (struct frag *)0); - switch (what) { - case 'd': - S_SET_NAME(symbolP,NULL); /* .stabd feature. */ - 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; - 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); - else { - as_bad("I want a comma after the n_other expression"); - goof = 1; - input_line_pointer--; /* Backup over a non-',' char. */ - } + if (!goof) + { + symbolP = symbol_new (string, + SEG_UNKNOWN, + 0, + (struct frag *) 0); + switch (what) + { + case 'd': + S_SET_NAME (symbolP, NULL); /* .stabd feature. */ + 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 (! goof) { - S_SET_DESC(symbolP, get_absolute_expression ()); - if (what == 's' || what == 'n') { - if (* input_line_pointer != ',') { - as_bad("I want a comma after the n_desc expression"); - goof = 1; - } else { - input_line_pointer ++; - } - } + if (get_absolute_expression_and_terminator (&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) && (what=='s' || what=='n')) { - pseudo_set(symbolP); - symbolP->sy_symbol.n_type = saved_type; + } + if (!goof) + { + if (get_absolute_expression_and_terminator (&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. */ } -#ifndef NO_LISTING + } + if (!goof) + { + S_SET_DESC (symbolP, get_absolute_expression ()); + if (what == 's' || what == 'n') { - 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); - } - } + if (*input_line_pointer != ',') + { + as_bad ("I want a comma after the n_desc expression"); + goof = 1; + } + else + { + input_line_pointer++; + } } - -#endif - - if (goof) - ignore_rest_of_line (); - else - demand_empty_rest_of_line (); -} /* obj_bout_stab() */ - -static void obj_bout_desc() { - register char *name; - register char c; - register char *p; - register symbolS * symbolP; - register int temp; - - /* + } + if ((!goof) && (what == 's' || what == 'n')) + { + pseudo_set (symbolP); + 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); + } + } + } + +#endif + + if (goof) + ignore_rest_of_line (); + else + demand_empty_rest_of_line (); +} /* obj_bout_stab() */ + +static void +obj_bout_desc () +{ + register char *name; + register char c; + 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; - * p = c; - SKIP_WHITESPACE(); - if (*input_line_pointer != ',') { - *p = 0; - as_bad("Expected comma after name \"%s\"", name); - *p = c; - ignore_rest_of_line(); - } else { - input_line_pointer ++; - temp = get_absolute_expression (); - *p = 0; - symbolP = symbol_find_or_make(name); - *p = c; - S_SET_DESC(symbolP,temp); - } - demand_empty_rest_of_line(); -} /* obj_bout_desc() */ + name = input_line_pointer; + c = get_symbol_end (); + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + *p = 0; + as_bad ("Expected comma after name \"%s\"", name); + *p = c; + ignore_rest_of_line (); + } + else + { + input_line_pointer++; + temp = get_absolute_expression (); + *p = 0; + symbolP = symbol_find_or_make (name); + *p = c; + S_SET_DESC (symbolP, temp); + } + demand_empty_rest_of_line (); +} /* obj_bout_desc() */ -void obj_read_begin_hook() { - return; -} /* obj_read_begin_hook() */ +void +obj_read_begin_hook () +{ + return; +} /* obj_read_begin_hook() */ -void obj_crawl_symbol_chain(headers) -object_headers *headers; +void +obj_crawl_symbol_chain (headers) + 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 + 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) - || S_IS_DEBUG(symbolP) + + + if (1 + && !S_IS_REGISTER (symbolP) + && (!S_GET_NAME (symbolP) + || S_IS_DEBUG (symbolP) #ifdef TC_I960 - /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */ - || !S_IS_DEFINED(symbolP) - || S_IS_EXTERNAL(symbolP) + /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */ + || !S_IS_DEFINED (symbolP) + || S_IS_EXTERNAL (symbolP) #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 + || (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)) { - /* Ordinary case. */ - symbolP->sy_name_offset = string_byte_count; - string_byte_count += strlen(S_GET_NAME(symbolP)) + 1; - } - else /* .Stabd case. */ - symbolP->sy_name_offset = 0; - 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)); - } /* 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() */ + if (!S_IS_STABD (symbolP)) + { + /* Ordinary case. */ + symbolP->sy_name_offset = string_byte_count; + string_byte_count += strlen (S_GET_NAME (symbolP)) + 1; + } + else /* .Stabd case. */ + symbolP->sy_name_offset = 0; + 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)); + } /* 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() */ /* * Find strings by crawling along symbol table chain. */ -void obj_emit_strings(where) -char **where; +void +obj_emit_strings (where) + char **where; { - symbolS *symbolP; - + 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)); - *where += sizeof(string_byte_count); + /* 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_COMPILE */ - append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count)); + 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() */ + + 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() */ /* * Local Variables: diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h index bb6460c6273..60f28e0661f 100644 --- a/gas/config/obj-bout.h +++ b/gas/config/obj-bout.h @@ -1,18 +1,18 @@ /* b.out object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA @@ -66,7 +66,7 @@ #define OBJ_DEFAULT_OUTPUT_FILE_NAME "b.out" extern const short seg_N_TYPE[]; -extern const segT N_TYPE_seg[]; +extern const segT N_TYPE_seg[]; #define BMAGIC 0415 /* We don't accept the following (see N_BADMAG macro). @@ -86,25 +86,26 @@ extern const segT N_TYPE_seg[]; * 'n' indicates the corresponding segment must begin at an * address that is a multiple of (2**n). */ -struct exec { - /* Standard stuff */ - unsigned long a_magic; /* Identifies this as a b.out file */ - unsigned long a_text; /* Length of text */ - unsigned long a_data; /* Length of data */ - unsigned long a_bss; /* Length of runtime uninitialized data area */ - unsigned long a_syms; /* Length of symbol table */ - 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 */ - unsigned char a_talign; /* Alignment of text segment */ - unsigned char a_dalign; /* Alignment of data segment */ - unsigned char a_balign; /* Alignment of bss segment */ - unsigned char a_relaxable; /* Contains enough info to relax */ -}; +struct exec + { + /* Standard stuff */ + unsigned long a_magic; /* Identifies this as a b.out file */ + unsigned long a_text; /* Length of text */ + unsigned long a_data; /* Length of data */ + unsigned long a_bss; /* Length of runtime uninitialized data area */ + unsigned long a_syms; /* Length of symbol table */ + 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 */ + unsigned char a_talign; /* Alignment of text segment */ + unsigned char a_dalign; /* Alignment of data segment */ + unsigned char a_balign; /* Alignment of bss segment */ + unsigned char a_relaxable; /* Contains enough info to relax */ + }; #define N_BADMAG(x) (((x).a_magic)!=BMAGIC) #define N_TXTOFF(x) ( sizeof(struct exec) ) @@ -116,53 +117,57 @@ struct exec { /* A single entry in the symbol table */ -struct nlist { - union { - char *n_name; - struct nlist *n_next; - long n_strx; /* Index into string table */ - } n_un; - unsigned char n_type; /* See below */ - char n_other; /* Used in i80960 support -- see below */ - short n_desc; - unsigned long n_value; -}; +struct nlist + { + union + { + char *n_name; + struct nlist *n_next; + long n_strx; /* Index into string table */ + } + n_un; + unsigned char n_type; /* See below */ + char n_other; /* Used in i80960 support -- see below */ + short n_desc; + unsigned long n_value; + }; typedef struct nlist obj_symbol_type; /* Legal values of n_type */ -#define N_UNDF 0 /* Undefined symbol */ -#define N_ABS 2 /* Absolute symbol */ -#define N_TEXT 4 /* Text symbol */ -#define N_DATA 6 /* Data symbol */ -#define N_BSS 8 /* BSS symbol */ -#define N_FN 31 /* Filename symbol */ +#define N_UNDF 0 /* Undefined symbol */ +#define N_ABS 2 /* Absolute symbol */ +#define N_TEXT 4 /* Text symbol */ +#define N_DATA 6 /* Data symbol */ +#define N_BSS 8 /* BSS symbol */ +#define N_FN 31 /* Filename symbol */ -#define N_EXT 1 /* External symbol (OR'd in with one of above) */ -#define N_TYPE 036 /* Mask for all the type bits */ -#define N_STAB 0340 /* Mask for all bits used for SDB entries */ +#define N_EXT 1 /* External symbol (OR'd in with one of above) */ +#define N_TYPE 036 /* Mask for all the type bits */ +#define N_STAB 0340 /* Mask for all bits used for SDB entries */ #ifndef CUSTOM_RELOC_FORMAT -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 +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: + 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_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 */ /* @@ -279,17 +284,20 @@ struct relocation_info { #define H_SET_VERSION(h,v) ((h)->header.a_version = (v)) #endif /* EXEC_VERSION */ -/* +/* * Current means for getting the name of a segment. * This will change for infinite-segments support (e.g. COFF). */ #define segment_name(seg) ( seg_name[(int)(seg)] ) extern char *const seg_name[]; -typedef struct { - struct exec header; /* a.out header */ - long string_table_size; /* names + '\0' + sizeof(int) */ -} object_headers; +typedef struct + { + struct exec header; /* a.out header */ + long string_table_size; /* names + '\0' + sizeof(int) */ + } + +object_headers; /* unused hooks. */ #define OBJ_EMIT_LINENO(a, b, c) {;} @@ -297,9 +305,9 @@ typedef struct { #if __STDC__ struct fix; -void tc_aout_fix_to_chars(char *where, struct fix *fixP, relax_addressT segment_address); +void tc_aout_fix_to_chars (char *where, struct fix *fixP, relax_addressT segment_address); #else /* not __STDC__ */ -void tc_aout_fix_to_chars(); +void tc_aout_fix_to_chars (); #endif /* not __STDC__ */ /* diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 82cfcf547ea..881402ae933 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1,18 +1,18 @@ /* coff object file format Copyright (C) 1989, 1990, 1991, 1992 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. */ @@ -21,137 +21,117 @@ #include "obstack.h" -lineno* lineno_rootP; - -const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */ - C_ABS_SECTION, - C_TEXT_SECTION, - C_DATA_SECTION, - C_BSS_SECTION, - C_UNDEF_SECTION, /* SEG_UNKNOWN */ - C_UNDEF_SECTION, /* SEG_ABSENT */ - C_UNDEF_SECTION, /* SEG_PASS1 */ - C_UNDEF_SECTION, /* SEG_GOOF */ - C_UNDEF_SECTION, /* SEG_BIG */ - C_UNDEF_SECTION, /* SEG_DIFFERENCE */ - C_DEBUG_SECTION, /* SEG_DEBUG */ - C_NTV_SECTION, /* SEG_NTV */ - C_PTV_SECTION, /* SEG_PTV */ - C_REGISTER_SECTION, /* SEG_REGISTER */ +lineno *lineno_rootP; + +const short seg_N_TYPE[] = +{ /* in: segT out: N_TYPE bits */ + C_ABS_SECTION, + C_TEXT_SECTION, + C_DATA_SECTION, + C_BSS_SECTION, + C_UNDEF_SECTION, /* SEG_UNKNOWN */ + C_UNDEF_SECTION, /* SEG_ABSENT */ + C_UNDEF_SECTION, /* SEG_PASS1 */ + C_UNDEF_SECTION, /* SEG_GOOF */ + C_UNDEF_SECTION, /* SEG_BIG */ + C_UNDEF_SECTION, /* SEG_DIFFERENCE */ + C_DEBUG_SECTION, /* SEG_DEBUG */ + C_NTV_SECTION, /* SEG_NTV */ + C_PTV_SECTION, /* SEG_PTV */ + C_REGISTER_SECTION, /* SEG_REGISTER */ }; /* Add 4 to the real value to get the index and compensate the negatives */ -const segT N_TYPE_seg [32] = +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 - }; - -#if __STDC__ == 1 - -char *s_get_name(symbolS *s); -static symbolS *tag_find_or_make(char *name); -static symbolS* tag_find(char *name); + 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 +}; + +char *s_get_name PARAMS ((symbolS * s)); +static symbolS *tag_find_or_make PARAMS ((char *name)); +static symbolS *tag_find PARAMS ((char *name)); #ifdef BFD_HEADERS -static void obj_coff_section_header_append(char **where, struct internal_scnhdr *header); +static void obj_coff_section_header_append PARAMS ((char **where, struct internal_scnhdr * header)); #else -static void obj_coff_section_header_append(char **where, SCNHDR *header); +static void obj_coff_section_header_append PARAMS ((char **where, SCNHDR * header)); #endif -static void obj_coff_def(int what); -static void obj_coff_dim(void); -static void obj_coff_endef(void); -static void obj_coff_line(void); -static void obj_coff_ln(void); -static void obj_coff_scl(void); -static void obj_coff_size(void); -static void obj_coff_stab(int what); -static void obj_coff_tag(void); -static void obj_coff_type(void); -static void obj_coff_val(void); -static void tag_init(void); -static void tag_insert(char *name, symbolS *symbolP); - -#else /* not __STDC__ */ - -char *s_get_name(); -static symbolS *tag_find(); -static symbolS *tag_find_or_make(); -static void obj_coff_section_header_append(); -static void obj_coff_def(); -static void obj_coff_dim(); -static void obj_coff_endef(); -static void obj_coff_line(); -static void obj_coff_ln(); -static void obj_coff_scl(); -static void obj_coff_size(); -static void obj_coff_stab(); -static void obj_coff_tag(); -static void obj_coff_type(); -static void obj_coff_val(); -static void tag_init(); -static void tag_insert(); - -#endif /* not __STDC__ */ +static void obj_coff_def PARAMS ((int what)); +static void obj_coff_dim PARAMS ((void)); +static void obj_coff_endef PARAMS ((void)); +static void obj_coff_line PARAMS ((void)); +static void obj_coff_ln PARAMS ((void)); +static void obj_coff_scl PARAMS ((void)); +static void obj_coff_size PARAMS ((void)); +static void obj_coff_stab PARAMS ((int what)); +static void obj_coff_tag PARAMS ((void)); +static void obj_coff_type PARAMS ((void)); +static void obj_coff_val PARAMS ((void)); +static void tag_init PARAMS ((void)); +static void tag_insert PARAMS ((char *name, symbolS * symbolP)); + +int line_base; static struct hash_control *tag_hash; -static symbolS *def_symbol_in_progress = NULL; +static symbolS *def_symbol_in_progress; -const pseudo_typeS obj_pseudo_table[] = { +const pseudo_typeS obj_pseudo_table[] = +{ #ifndef IGNORE_DEBUG - { "def", obj_coff_def, 0 }, - { "dim", obj_coff_dim, 0 }, - { "endef", obj_coff_endef, 0 }, - { "line", obj_coff_line, 0 }, - { "ln", obj_coff_ln, 0 }, - { "scl", obj_coff_scl, 0 }, - { "size", obj_coff_size, 0 }, - { "tag", obj_coff_tag, 0 }, - { "type", obj_coff_type, 0 }, - { "val", obj_coff_val, 0 }, + {"def", obj_coff_def, 0}, + {"dim", obj_coff_dim, 0}, + {"endef", obj_coff_endef, 0}, + {"line", obj_coff_line, 0}, + {"ln", obj_coff_ln, 0}, + {"scl", obj_coff_scl, 0}, + {"size", obj_coff_size, 0}, + {"tag", obj_coff_tag, 0}, + {"type", obj_coff_type, 0}, + {"val", obj_coff_val, 0}, #else - { "def", s_ignore, 0 }, - { "dim", s_ignore, 0 }, - { "endef", 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 }, + {"def", s_ignore, 0}, + {"dim", s_ignore, 0}, + {"endef", 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}, #endif /* ignore debug */ - - { "ident", s_ignore, 0 }, /* we don't yet handle this. */ - - - /* stabs aka a.out aka b.out directives for debug symbols. + + {"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. */ - { "desc", s_ignore, 0 }, /* def */ - /* { "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) */ - { "optim", s_ignore, 0 }, /* For sun386i cc (?) */ - /* other stuff */ - { "ABORT", s_abort, 0 }, - - { NULL} /* end sentinel */ -}; /* obj_pseudo_table */ + {"desc", s_ignore, 0}, /* def */ +/* { "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) */ + {"optim", s_ignore, 0}, /* For sun386i cc (?) */ +/* other stuff */ + {"ABORT", s_abort, 0}, + + {NULL} /* end sentinel */ +}; /* obj_pseudo_table */ /* obj dependant output values */ @@ -166,14 +146,15 @@ SCNHDR text_section_header; #endif /* Relocation. */ -static int reloc_compare(p1, p2) +static int +reloc_compare (p1, p2) #ifdef BFD_HEADERS -struct internal_reloc *p1, *p2; + struct internal_reloc *p1, *p2; #else -RELOC *p1, *p2; + RELOC *p1, *p2; #endif { - return (int)(p1->r_vaddr - p2->r_vaddr); + return (int) (p1->r_vaddr - p2->r_vaddr); } /* @@ -182,78 +163,85 @@ RELOC *p1, *p2; * Crawl along a fixS chain. Emit the segment's relocations. */ -void obj_emit_relocations(where, fixP, segment_address_in_file) -char **where; -fixS *fixP; /* Fixup chain for this segment. */ -relax_addressT segment_address_in_file; +void +obj_emit_relocations (where, fixP, segment_address_in_file) + char **where; + fixS *fixP; /* Fixup chain for this segment. */ + relax_addressT segment_address_in_file; { #ifdef BFD_HEADERS - struct internal_reloc *ri_table; + struct internal_reloc *ri_table; #else - RELOC *ri_table; + RELOC *ri_table; +#endif +#ifdef TC_I960 + char *callj_table; #endif - symbolS *symbolP; - int i, count; - fixS *p; - - for (count = 0, p = fixP; p ; p = p->fx_next) - if (p->fx_addsy) count++; - if (!count) - return; - + symbolS *symbolP; + int i, count; + fixS *p; + + for (count = 0, p = fixP; p; p = p->fx_next) + if (p->fx_addsy) + count++; + if (!count) + return; + #ifdef BFD_HEADERS - ri_table = (struct internal_reloc *) calloc(sizeof(*ri_table),count); + ri_table = (struct internal_reloc *) calloc (sizeof (*ri_table), count); #else - ri_table = (RELOC *) calloc(sizeof(*ri_table),count); + ri_table = (RELOC *) calloc (sizeof (*ri_table), count); #endif - if (!ri_table) - as_fatal ("obj_emit_relocations: Could not malloc relocation table"); - + if (!ri_table) + as_fatal ("obj_emit_relocations: Could not malloc relocation table"); + #ifdef TC_I960 - callj_table = (char *)malloc (sizeof(char)*count); - if (!callj_table) - as_fatal ("obj_emit_relocations: Could not malloc callj table"); + callj_table = (char *) malloc (sizeof (char) * count); + if (!callj_table) + as_fatal ("obj_emit_relocations: Could not malloc callj table"); #endif - - for (i = 0; fixP; fixP = fixP->fx_next) { - if (symbolP = fixP->fx_addsy) { + + for (i = 0; fixP; fixP = fixP->fx_next) + { + if (symbolP = fixP->fx_addsy) + { #if defined(TC_M68K) - ri_table[i].r_type = (fixP->fx_pcrel ? - (fixP->fx_size == 1 ? R_PCRBYTE : - fixP->fx_size == 2 ? R_PCRWORD : - R_PCRLONG): - (fixP->fx_size == 1 ? R_RELBYTE : - fixP->fx_size == 2 ? R_RELWORD : - R_RELLONG)); + ri_table[i].r_type = (fixP->fx_pcrel ? + (fixP->fx_size == 1 ? R_PCRBYTE : + fixP->fx_size == 2 ? R_PCRWORD : + R_PCRLONG) : + (fixP->fx_size == 1 ? R_RELBYTE : + fixP->fx_size == 2 ? R_RELWORD : + R_RELLONG)); #elif defined(TC_I386) - /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly + /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly untested. */ - ri_table[i].r_type = (fixP->fx_pcrel ? - (fixP->fx_size == 1 ? R_PCRBYTE : - fixP->fx_size == 2 ? R_PCRWORD : - R_PCRLONG): - (fixP->fx_size == 1 ? R_OFF8 : - fixP->fx_size == 2 ? R_DIR16 : - R_DIR32)); + ri_table[i].r_type = (fixP->fx_pcrel ? + (fixP->fx_size == 1 ? R_PCRBYTE : + fixP->fx_size == 2 ? R_PCRWORD : + R_PCRLONG) : + (fixP->fx_size == 1 ? R_OFF8 : + fixP->fx_size == 2 ? R_DIR16 : + R_DIR32)); #elif defined(TC_I960) - ri_table[i].r_type = (fixP->fx_pcrel - ? R_IPRMED - : R_RELLONG); - callj_table[i] = fixP->fx_callj ? 1 : 0; + ri_table[i].r_type = (fixP->fx_pcrel + ? R_IPRMED + : R_RELLONG); + callj_table[i] = fixP->fx_callj ? 1 : 0; #elif defined(TC_A29K) - ri_table[i].r_type = tc_coff_fix2rtype(fixP); - + ri_table[i].r_type = tc_coff_fix2rtype (fixP); + #else #error you lose #endif /* TC_M68K || TC_I386 */ - ri_table[i].r_vaddr = (fixP->fx_frag->fr_address - + fixP->fx_where); - /* If symbol associated to relocation entry is a bss symbol + ri_table[i].r_vaddr = (fixP->fx_frag->fr_address + + fixP->fx_where); + /* If symbol associated to relocation entry is a bss symbol or undefined symbol just remember the index of the symbol. Otherwise store the index of the symbol describing the section the symbol belong to. This heuristic speeds up ld. */ - /* Local symbols can generate relocation information. In case + /* Local symbols can generate relocation information. In case of structure return for instance. But they have no symbol number because they won't be emitted in the final object. In the case where they are in the BSS section, this leads @@ -262,484 +250,530 @@ relax_addressT segment_address_in_file; is incorrect. But the SYS V ld complains about this. To avoid this we associate the symbol to the associated section, *even* if it is the BSS section. */ - /* If someone can tell me why the other symbols of the bss + /* If someone can tell me why the other symbols of the bss section are not associated with the .bss section entry, I'd be gratefull. I guess that it has to do with the special nature of the .bss section. Or maybe this is because the bss symbols are declared in the common section and can be resized later. Can it break code some where ? */ - ri_table[i].r_symndx = (S_GET_SEGMENT(symbolP) == SEG_TEXT - ? dot_text_symbol->sy_number - : (S_GET_SEGMENT(symbolP) == SEG_DATA - ? dot_data_symbol->sy_number - : ((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 */ - - i++; - } /* if there's a symbol */ - } /* for each fixP */ - - /* + ri_table[i].r_symndx = (S_GET_SEGMENT (symbolP) == SEG_TEXT + ? dot_text_symbol->sy_number + : (S_GET_SEGMENT (symbolP) == SEG_DATA + ? dot_data_symbol->sy_number + : ((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 */ + + i++; + } /* if there's a symbol */ + } /* for each fixP */ + + /* * AIX ld prefer to have the reloc table with r_vaddr sorted. * But sorting it should not hurt any other ld. */ - qsort (ri_table, count, sizeof(*ri_table), reloc_compare); - - for (i = 0; i < count; i++) - { + qsort (ri_table, count, sizeof (*ri_table), reloc_compare); + + for (i = 0; i < count; i++) + { #ifdef BFD_HEADERS - *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i], *where); + *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], *where); # ifdef TC_A29K - /* The 29k has a special kludge for the high 16 bit reloc. + /* 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 (ri_table[i].r_type == R_IHIHALF) - { - /* now emit the second bit */ - ri_table[i].r_type = R_IHCONST; - ri_table[i].r_symndx = fixP->fx_addnumber; - *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i], - *where); - } -# endif /* TC_A29K */ - + if (ri_table[i].r_type == R_IHIHALF) + { + /* now emit the second bit */ + ri_table[i].r_type = R_IHCONST; + ri_table[i].r_symndx = fixP->fx_addnumber; + *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], + *where); + } +# endif /* TC_A29K */ + #else /* not BFD_HEADERS */ - append(where, (char *) &ri_table[i], RELSZ); + append (where, (char *) &ri_table[i], RELSZ); #endif /* not BFD_HEADERS */ - + #ifdef TC_I960 - if (callj_table[i]) - { - ri_table[i].r_type = R_OPTCALL; + if (callj_table[i]) + { + ri_table[i].r_type = R_OPTCALL; # ifdef BFD_HEADERS - *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i], - *where); + *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], + *where); # else - append(where, (char *) &ri_table[i], (unsigned long)RELSZ); -# endif /* BFD_HEADERS */ - } /* if it's a callj, do it again for the opcode */ + append (where, (char *) &ri_table[i], (unsigned long) RELSZ); +# endif /* BFD_HEADERS */ + } /* if it's a callj, do it again for the opcode */ #endif /* TC_I960 */ - } - - free (ri_table); + } + + free (ri_table); #ifdef TC_I960 - free (callj_table); + free (callj_table); #endif - - return; -} /* obj_emit_relocations() */ + + return; +} /* obj_emit_relocations() */ /* Coff file generation & utilities */ #ifdef BFD_HEADERS -void obj_header_append(where, headers) -char **where; -object_headers *headers; +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 -void obj_header_append(where, headers) -char **where; -object_headers *headers; +void +obj_header_append (where, headers) + char **where; + object_headers *headers; { - tc_headers_hook(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)); - *where += sizeof(headers->filehdr.f_magic); - md_number_to_chars(*where, headers->filehdr.f_nscns, sizeof(headers->filehdr.f_nscns)); - *where += sizeof(headers->filehdr.f_nscns); - md_number_to_chars(*where, headers->filehdr.f_timdat, sizeof(headers->filehdr.f_timdat)); - *where += sizeof(headers->filehdr.f_timdat); - md_number_to_chars(*where, headers->filehdr.f_symptr, sizeof(headers->filehdr.f_symptr)); - *where += sizeof(headers->filehdr.f_symptr); - md_number_to_chars(*where, headers->filehdr.f_nsyms, sizeof(headers->filehdr.f_nsyms)); - *where += sizeof(headers->filehdr.f_nsyms); - md_number_to_chars(*where, headers->filehdr.f_opthdr, sizeof(headers->filehdr.f_opthdr)); - *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); - + /* Eventually swap bytes for cross compilation for file header */ + md_number_to_chars (*where, headers->filehdr.f_magic, sizeof (headers->filehdr.f_magic)); + *where += sizeof (headers->filehdr.f_magic); + md_number_to_chars (*where, headers->filehdr.f_nscns, sizeof (headers->filehdr.f_nscns)); + *where += sizeof (headers->filehdr.f_nscns); + md_number_to_chars (*where, headers->filehdr.f_timdat, sizeof (headers->filehdr.f_timdat)); + *where += sizeof (headers->filehdr.f_timdat); + md_number_to_chars (*where, headers->filehdr.f_symptr, sizeof (headers->filehdr.f_symptr)); + *where += sizeof (headers->filehdr.f_symptr); + md_number_to_chars (*where, headers->filehdr.f_nsyms, sizeof (headers->filehdr.f_nsyms)); + *where += sizeof (headers->filehdr.f_nsyms); + md_number_to_chars (*where, headers->filehdr.f_opthdr, sizeof (headers->filehdr.f_opthdr)); + *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)); - *where += sizeof(headers->aouthdr.magic); - md_number_to_chars(*where, headers->aouthdr.vstamp, sizeof(headers->aouthdr.vstamp)); - *where += sizeof(headers->aouthdr.vstamp); - md_number_to_chars(*where, headers->aouthdr.tsize, sizeof(headers->aouthdr.tsize)); - *where += sizeof(headers->aouthdr.tsize); - md_number_to_chars(*where, headers->aouthdr.dsize, sizeof(headers->aouthdr.dsize)); - *where += sizeof(headers->aouthdr.dsize); - md_number_to_chars(*where, headers->aouthdr.bsize, sizeof(headers->aouthdr.bsize)); - *where += sizeof(headers->aouthdr.bsize); - md_number_to_chars(*where, headers->aouthdr.entry, sizeof(headers->aouthdr.entry)); - *where += sizeof(headers->aouthdr.entry); - md_number_to_chars(*where, headers->aouthdr.text_start, sizeof(headers->aouthdr.text_start)); - *where += sizeof(headers->aouthdr.text_start); - md_number_to_chars(*where, headers->aouthdr.data_start, sizeof(headers->aouthdr.data_start)); - *where += sizeof(headers->aouthdr.data_start); - md_number_to_chars(*where, headers->aouthdr.tagentries, sizeof(headers->aouthdr.tagentries)); - *where += sizeof(headers->aouthdr.tagentries); + /* Eventually swap bytes for cross compilation for a.out header */ + md_number_to_chars (*where, headers->aouthdr.magic, sizeof (headers->aouthdr.magic)); + *where += sizeof (headers->aouthdr.magic); + md_number_to_chars (*where, headers->aouthdr.vstamp, sizeof (headers->aouthdr.vstamp)); + *where += sizeof (headers->aouthdr.vstamp); + md_number_to_chars (*where, headers->aouthdr.tsize, sizeof (headers->aouthdr.tsize)); + *where += sizeof (headers->aouthdr.tsize); + md_number_to_chars (*where, headers->aouthdr.dsize, sizeof (headers->aouthdr.dsize)); + *where += sizeof (headers->aouthdr.dsize); + md_number_to_chars (*where, headers->aouthdr.bsize, sizeof (headers->aouthdr.bsize)); + *where += sizeof (headers->aouthdr.bsize); + md_number_to_chars (*where, headers->aouthdr.entry, sizeof (headers->aouthdr.entry)); + *where += sizeof (headers->aouthdr.entry); + md_number_to_chars (*where, headers->aouthdr.text_start, sizeof (headers->aouthdr.text_start)); + *where += sizeof (headers->aouthdr.text_start); + md_number_to_chars (*where, headers->aouthdr.data_start, sizeof (headers->aouthdr.data_start)); + *where += sizeof (headers->aouthdr.data_start); + 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, FILHSZ); + + append (where, (char *) &headers->filehdr, sizeof (headers->filehdr)); #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER - append(where, (char *) &headers->aouthdr, AOUTHDRSZ); + 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() */ + + /* 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 -void obj_symbol_to_chars(where, symbolP) -char **where; -symbolS *symbolP; +void +obj_symbol_to_chars (where, symbolP) + char **where; + symbolS *symbolP; { #ifdef BFD_HEADERS - 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); - } - *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); - } - + 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); + } + *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); + } + #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); - + 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, 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); + 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, SYMESZ); + 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); - } +#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); + } #endif /* 0 */ #else /* CROSS_COMPILE */ - append(where, (char *) &symbolP->sy_symbol.ost_auxent[i], AUXESZ); + append (where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof (symbolP->sy_symbol.ost_auxent[i])); #endif /* CROSS_COMPILE */ - - }; /* for each aux in use */ -#endif /* BFD_HEADERS */ - return; -} /* obj_symbol_to_chars() */ + + }; /* for each aux in use */ +#endif /* BFD_HEADERS */ + return; +} /* obj_symbol_to_chars() */ #ifdef BFD_HEADERS -static void obj_coff_section_header_append(where, header) -char **where; -struct internal_scnhdr *header; +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) -char **where; -SCNHDR *header; +static void +obj_coff_section_header_append (where, header) + char **where; + SCNHDR *header; { #ifdef CROSS_COMPILE - memcpy(*where, header->s_name, sizeof(header->s_name)); - *where += sizeof(header->s_name); - - md_number_to_chars(*where, header->s_paddr, sizeof(header->s_paddr)); - *where += sizeof(header->s_paddr); - - md_number_to_chars(*where, header->s_vaddr, sizeof(header->s_vaddr)); - *where += sizeof(header->s_vaddr); - - md_number_to_chars(*where, header->s_size, sizeof(header->s_size)); - *where += sizeof(header->s_size); - - md_number_to_chars(*where, header->s_scnptr, sizeof(header->s_scnptr)); - *where += sizeof(header->s_scnptr); - - md_number_to_chars(*where, header->s_relptr, sizeof(header->s_relptr)); - *where += sizeof(header->s_relptr); - - md_number_to_chars(*where, header->s_lnnoptr, sizeof(header->s_lnnoptr)); - *where += sizeof(header->s_lnnoptr); - - md_number_to_chars(*where, header->s_nreloc, sizeof(header->s_nreloc)); - *where += sizeof(header->s_nreloc); - - md_number_to_chars(*where, header->s_nlnno, sizeof(header->s_nlnno)); - *where += sizeof(header->s_nlnno); - - md_number_to_chars(*where, header->s_flags, sizeof(header->s_flags)); - *where += sizeof(header->s_flags); - + memcpy (*where, header->s_name, sizeof (header->s_name)); + *where += sizeof (header->s_name); + + md_number_to_chars (*where, header->s_paddr, sizeof (header->s_paddr)); + *where += sizeof (header->s_paddr); + + md_number_to_chars (*where, header->s_vaddr, sizeof (header->s_vaddr)); + *where += sizeof (header->s_vaddr); + + md_number_to_chars (*where, header->s_size, sizeof (header->s_size)); + *where += sizeof (header->s_size); + + md_number_to_chars (*where, header->s_scnptr, sizeof (header->s_scnptr)); + *where += sizeof (header->s_scnptr); + + md_number_to_chars (*where, header->s_relptr, sizeof (header->s_relptr)); + *where += sizeof (header->s_relptr); + + md_number_to_chars (*where, header->s_lnnoptr, sizeof (header->s_lnnoptr)); + *where += sizeof (header->s_lnnoptr); + + md_number_to_chars (*where, header->s_nreloc, sizeof (header->s_nreloc)); + *where += sizeof (header->s_nreloc); + + md_number_to_chars (*where, header->s_nlnno, sizeof (header->s_nlnno)); + *where += sizeof (header->s_nlnno); + + md_number_to_chars (*where, header->s_flags, sizeof (header->s_flags)); + *where += sizeof (header->s_flags); + #ifdef TC_I960 - md_number_to_chars(*where, header->s_align, sizeof(header->s_align)); - *where += sizeof(header->s_align); + 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, SCNHSZ); - + + append (where, (char *) header, sizeof (*header)); + #endif /* CROSS_COMPILE */ - - return; -} /* obj_coff_section_header_append() */ + + return; +} /* obj_coff_section_header_append() */ #endif -void obj_emit_symbols(where, symbol_rootP) -char **where; -symbolS *symbol_rootP; +void +obj_emit_symbols (where, symbol_rootP) + char **where; + symbolS *symbol_rootP; { - symbolS *symbolP; - /* + 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 + 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 { - memset(symbolP->sy_symbol.ost_entry.n_name, '\0', SYMNMLEN); - strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN); - } - obj_symbol_to_chars(where, symbolP); - S_SET_NAME(symbolP,temp); + 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 + { + memset (symbolP->sy_symbol.ost_entry.n_name, '\0', SYMNMLEN); + strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN); } -} /* obj_emit_symbols() */ + 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. */ -void c_symbol_merge(debug, normal) -symbolS *debug; -symbolS *normal; +void +c_symbol_merge (debug, normal) + symbolS *debug; + 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() */ + 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 symbolS *previous_file_symbol = NULL; -void c_dot_file_symbol(filename) -char *filename; +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 */ - -} /* c_dot_file_symbol() */ + 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); + } + } +#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 */ + +} /* c_dot_file_symbol() */ + /* * Build a 'section static' symbol. */ -char *c_section_symbol(name, value, length, nreloc, nlnno) -char *name; -long value; -long length; -unsigned short nreloc; -unsigned short nlnno; +char * +c_section_symbol (name, value, length, nreloc, nlnno) + char *name; + long value; + 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; -} /* c_section_symbol() */ - -void c_section_header(header, - name, - core_address, - size, - data_ptr, - reloc_ptr, - lineno_ptr, - reloc_number, - lineno_number, - alignment) + 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, + name, + core_address, + size, + data_ptr, + reloc_ptr, + lineno_ptr, + reloc_number, + lineno_number, + alignment) #ifdef BFD_HEADERS -struct internal_scnhdr *header; + struct internal_scnhdr *header; #else -SCNHDR *header; + SCNHDR *header; #endif -char *name; -long core_address; -long size; -long data_ptr; -long reloc_ptr; -long lineno_ptr; -long reloc_number; -long lineno_number; -long alignment; + char *name; + long core_address; + long size; + long data_ptr; + long reloc_ptr; + long lineno_ptr; + long reloc_number; + long lineno_number; + long alignment; { - strncpy(header->s_name, name, 8); - header->s_paddr = header->s_vaddr = core_address; - header->s_scnptr = ((header->s_size = size) != 0) ? data_ptr : 0; - header->s_relptr = reloc_ptr; - header->s_lnnoptr = lineno_ptr; - header->s_nreloc = reloc_number; - header->s_nlnno = lineno_number; - + strncpy (header->s_name, name, 8); + header->s_paddr = header->s_vaddr = core_address; + header->s_scnptr = ((header->s_size = size) != 0) ? data_ptr : 0; + header->s_relptr = reloc_ptr; + 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); + header->s_align = ((name[1] == 'b' || (size > 0)) ? 16 : 0); #else - header->s_align = ((alignment == 0) - ? 0 - : (1 << alignment)); + header->s_align = ((alignment == 0) + ? 0 + : (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' - ? STYP_DATA - : (name[1] == 'b' - ? STYP_BSS - : STYP_INFO))); - return; -} /* c_section_header() */ + + header->s_flags = STYP_REG | (name[1] == 't' + ? STYP_TEXT + : (name[1] == 'd' + ? STYP_DATA + : (name[1] == 'b' + ? STYP_BSS + : STYP_INFO))); + return; +} /* c_section_header() */ /* Line number handling */ @@ -751,176 +785,189 @@ int our_lineno_number = 0; /* we use this to build pointers from .bf's exactly the values that are later assigned in text_lineno_number by write.c. */ -lineno* lineno_lastP = (lineno*)0; +lineno *lineno_lastP = (lineno *) 0; int - c_line_new(paddr, line_number, frag) -long paddr; -unsigned short line_number; -fragS* 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) -char **where; -lineno *line; -char *file_start; +void +obj_emit_lineno (where, line, file_start) + char **where; + lineno *line; + char *file_start; { #ifdef BFD_HEADERS - struct bfd_internal_lineno *line_entry; + struct bfd_internal_lineno *line_entry; #else - LINENO *line_entry; + LINENO *line_entry; #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 + 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. */ - - if (line_entry->l_lnno == 0) { - /* There is a good chance that the symbol pointed to + + 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; */ - 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 */ + /* 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); + *where += bfd_coff_swap_lineno_out (stdoutput, line_entry, *where); #else - /* No matter which member of the union we process, they are + /* No matter which member of the union we process, they are both long. */ #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); - + 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; + **where = '0'; + ++*where; + **where = '0'; + ++*where; #endif /* TC_I960 */ - + #else /* CROSS_COMPILE */ - append(where, (char *) line_entry, LINESZ); + append (where, (char *) line_entry, LINESZ); #endif /* CROSS_COMPILE */ #endif /* BFD_HEADERS */ - } /* for each line number */ - - return ; -} /* obj_emit_lineno() */ + } /* for each line number */ + + return; +} /* obj_emit_lineno() */ -void obj_symbol_new_hook(symbolP) -symbolS *symbolP; +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); - S_SET_DATA_TYPE(symbolP, T_NULL); - S_SET_STORAGE_CLASS(symbolP, 0); - S_SET_NUMBER_AUXILIARY(symbolP, 0); - /* Additional information */ - symbolP->sy_symbol.ost_flags = 0; - /* Auxiliary entries */ - memset((char*) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ); - + char underscore = 0; /* Symbol has leading _ */ + + /* Effective symbol */ + /* Store the pointer in the offset. */ + S_SET_ZEROES (symbolP, 0L); + S_SET_DATA_TYPE (symbolP, T_NULL); + S_SET_STORAGE_CLASS (symbolP, 0); + S_SET_NUMBER_AUXILIARY (symbolP, 0); + /* Additional information */ + symbolP->sy_symbol.ost_flags = 0; + /* Auxiliary entries */ + memset ((char *) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ); + #ifdef STRIP_UNDERSCORE - /* Remove leading underscore at the beginning of the symbol. + /* Remove leading underscore at the beginning of the symbol. * This is to be compatible with the standard librairies. */ - if (*S_GET_NAME(symbolP) == '_') { - underscore = 1; - S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1); - } /* strip underscore */ + if (*S_GET_NAME (symbolP) == '_') + { + underscore = 1; + 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() */ + + 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* stack_init(chunk_size, element_size) -unsigned long chunk_size; -unsigned long element_size; +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) { - free(st); - return (stack*)0; - } - st->pointer = 0; - st->size = chunk_size; - st->chunk_size = chunk_size; - st->element_size = element_size; - return st; -} /* stack_init() */ - -void stack_delete(st) -stack* st; + stack *st; + + if ((st = (stack *) malloc (sizeof (stack))) == (stack *) 0) + return (stack *) 0; + if ((st->data = malloc (chunk_size)) == (char *) 0) + { + free (st); + return (stack *) 0; + } + st->pointer = 0; + st->size = chunk_size; + st->chunk_size = chunk_size; + st->element_size = element_size; + return st; +} /* stack_init() */ + +void +stack_delete (st) + stack *st; { - free(st->data); - free(st); + free (st->data); + free (st); } -char *stack_push(st, element) -stack *st; -char *element; +char * +stack_push (st, element) + stack *st; + char *element; { - if (st->pointer + st->element_size >= st->size) { - st->size += st->chunk_size; - if ((st->data = xrealloc(st->data, st->size)) == (char*)0) - return (char*)0; - } - memcpy(st->data + st->pointer, element, st->element_size); - st->pointer += st->element_size; - return st->data + st->pointer; -} /* stack_push() */ - -char* stack_pop(st) -stack* st; + if (st->pointer + st->element_size >= st->size) + { + st->size += st->chunk_size; + if ((st->data = xrealloc (st->data, st->size)) == (char *) 0) + return (char *) 0; + } + memcpy (st->data + st->pointer, element, st->element_size); + st->pointer += st->element_size; + return st->data + st->pointer; +} /* stack_push() */ + +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; +char * +stack_top (st) + stack *st; { - return st->data + st->pointer - st->element_size; + return st->data + st->pointer - st->element_size; } @@ -928,20 +975,35 @@ stack* st; * Handle .ln directives. */ -static void obj_coff_ln() { - 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(obstack_next_free(&frags) - frag_now->fr_literal, - get_absolute_expression(), - frag_now); - - demand_empty_rest_of_line(); - return; -} /* obj_coff_line() */ +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 (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); + } + } +#endif + + demand_empty_rest_of_line (); + return; +} /* obj_coff_ln() */ /* * def() @@ -962,135 +1024,146 @@ static void obj_coff_ln() { *input_line_pointer == '\t') \ input_line_pointer++; -static void obj_coff_def(what) -int what; +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)); - memset(def_symbol_in_progress, '\0', 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 */ + 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)); + memset (def_symbol_in_progress, '\0', 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); - } /* "long" name */ - - *input_line_pointer = name_end; - - demand_empty_rest_of_line(); - return; -} /* obj_coff_def() */ + /* 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_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_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"); - } /* 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; - } - break; - +static void +obj_coff_endef () +{ + symbolS *symbolP; + /* 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_TEXT); + + if (def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][1] == 'b' + && def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][2] == 'f') + { + if (function_lineoff < 0) + { + as_warn ("`.bf' symbol without preceding function"); + } + SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff; + /* Will need relocating */ + SF_SET_PROCESS (def_symbol_in_progress); + function_lineoff = -1; + } + 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; - } /* switch on storage class */ - - /* Now that we have built a debug symbol, try to + 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 + + /* 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 @@ -1100,851 +1173,1004 @@ 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 + + /* 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 + + 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. This is not mandatory. The linker can handle duplicate symbols correctly. But I 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) + + /* 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 + + 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 appears. Move the existing symbol to the current place. */ - /* If it already is at the end of the symbol list, do nothing */ - 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 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 + /* If it already is at the end of the symbol list, do nothing */ + 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 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() */ - -static void obj_coff_dim() + 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() */ + +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() */ + +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; + } + + + 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 () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".size 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); + SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); + demand_empty_rest_of_line (); + return; +} /* obj_coff_size() */ + +static void +obj_coff_scl () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".scl pseudo-op used outside of .def/.endef ignored."); + 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; +} /* obj_coff_scl() */ + +static void +obj_coff_tag () { - 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() */ - -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() */ - -static void obj_coff_size() { - if (def_symbol_in_progress == NULL) { - as_warn(".size 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); - SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression()); - demand_empty_rest_of_line(); - return; -} /* obj_coff_size() */ - -static void obj_coff_scl() { - if (def_symbol_in_progress == NULL) { - as_warn(".scl pseudo-op used outside of .def/.endef ignored."); - 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; -} /* 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() */ - -static void obj_coff_type() { - if (def_symbol_in_progress == NULL) { - as_warn(".type pseudo-op used outside of .def/.endef ignored."); - 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() */ - -static void obj_coff_val() { - if (def_symbol_in_progress == NULL) { - as_warn(".val pseudo-op used outside of .def/.endef ignored."); - 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 + 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() */ + +static void +obj_coff_type () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".type pseudo-op used outside of .def/.endef ignored."); + 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() */ + +static void +obj_coff_val () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".val pseudo-op used outside of .def/.endef ignored."); + 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. */ - SF_SET_GET_SEGMENT(def_symbol_in_progress); - } - /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */ - *input_line_pointer = name_end; - } else { - S_SET_VALUE(def_symbol_in_progress, get_absolute_expression()); - } /* if symbol based */ - - demand_empty_rest_of_line(); - return; -} /* obj_coff_val() */ + SF_SET_GET_SEGMENT (def_symbol_in_progress); + } + /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */ + *input_line_pointer = name_end; + } + else + { + S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ()); + } /* if symbol based */ + + demand_empty_rest_of_line (); + return; +} /* obj_coff_val() */ /* * Maintain a list of the tagnames of the structres. */ -static void tag_init() { - tag_hash = hash_new(); - return ; -} /* tag_init() */ - -static void tag_insert(name, symbolP) -char *name; -symbolS *symbolP; +static void +tag_init () { - 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); - } - return ; -} /* tag_insert() */ - -static symbolS *tag_find_or_make(name) -char *name; + tag_hash = hash_new (); + return; +} /* tag_init() */ + +static void +tag_insert (name, symbolP) + char *name; + symbolS *symbolP; { - 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; + 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); + } + return; +} /* tag_insert() */ + +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; { #ifdef STRIP_UNDERSCORE - if (*name == '_') name++; + if (*name == '_') + name++; #endif /* STRIP_UNDERSCORE */ - return((symbolS*)hash_find(tag_hash, name)); -} /* tag_find() */ + return ((symbolS *) hash_find (tag_hash, name)); +} /* tag_find() */ -void obj_read_begin_hook() { - /* These had better be the same. Usually 18 bytes. */ +void +obj_read_begin_hook () +{ + /* These had better be the same. Usually 18 bytes. */ #ifndef BFD_HEADERS - know(sizeof(SYMENT) == sizeof(AUXENT)); - know(SYMESZ == AUXESZ); + know (sizeof (SYMENT) == sizeof (AUXENT)); + know (SYMESZ == AUXESZ); #endif - tag_init(); - - return; -} /* obj_read_begin_hook() */ + tag_init (); + + return; +} /* obj_read_begin_hook() */ -void obj_crawl_symbol_chain(headers) -object_headers *headers; +void +obj_crawl_symbol_chain (headers) + object_headers *headers; { - int symbol_number = 0; - lineno *lineP; - symbolS *last_functionP = NULL; - symbolS *last_tagP; - 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_GET_SEGMENT(symbolP) == SEG_UNKNOWN) { - 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 - * . debug entries for functions - * . fake symbols for .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) { - 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 - */ - dot_text_symbol = (symbolS*) - c_section_symbol(".text", - 0, - H_GET_TEXT_SIZE(headers), - 0/*text_relocation_number */, - 0/*text_lineno_number */); - symbol_remove(dot_text_symbol, &symbol_rootP, &symbol_lastP); - symbol_append(dot_text_symbol, previous_file_symbol, - &symbol_rootP, &symbol_lastP); - - 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 */ - symbol_remove(dot_data_symbol, &symbol_rootP, &symbol_lastP); - symbol_append(dot_data_symbol, dot_text_symbol, - &symbol_rootP, &symbol_lastP); - - 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 */ - symbol_remove(dot_bss_symbol, &symbol_rootP, &symbol_lastP); - symbol_append(dot_bss_symbol, dot_data_symbol, - &symbol_rootP, &symbol_lastP); - + int symbol_number = 0; + lineno *lineP; + symbolS *last_functionP = NULL; + symbolS *last_tagP; + 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 ( +#ifndef TE_I386AIX + SF_GET_GET_SEGMENT (symbolP) +#else + SF_GET_GET_SEGMENT (symbolP) + && S_GET_SEGMENT (symbolP) == SEG_UNKNOWN +#endif /* TE_I386AIX */ + ) + { + 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 + * . debug entries for functions + * . fake symbols for .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) + { + 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 + */ + dot_text_symbol = (symbolS *) + c_section_symbol (".text", + 0, + H_GET_TEXT_SIZE (headers), + 0 /*text_relocation_number */ , + 0 /*text_lineno_number */ ); +#ifdef TE_I386AIX + symbol_remove (dot_text_symbol, &symbol_rootP, &symbol_lastP); + symbol_append (dot_text_symbol, previous_file_symbol, + &symbol_rootP, &symbol_lastP); +#endif /* TE_I386AIX */ + + 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 */ +#ifdef TE_I386AIX + symbol_remove (dot_data_symbol, &symbol_rootP, &symbol_lastP); + symbol_append (dot_data_symbol, dot_text_symbol, + &symbol_rootP, &symbol_lastP); +#endif /* TE_I386AIX */ + + 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 */ +#ifdef TE_I386AIX + symbol_remove (dot_bss_symbol, &symbol_rootP, &symbol_lastP); + symbol_append (dot_bss_symbol, dot_data_symbol, + &symbol_rootP, &symbol_lastP); +#endif /* TE_I386AIX */ + #if defined(DEBUG) - verify_symbol_chain(symbol_rootP, symbol_lastP); + 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 - chain, numbers symbols, and does some other guck. - The second traversal is on the temporary chain of - externals and just appends them to the global - chain again, numbering them as we go. The third - traversal patches pointers to symbols (using sym - indexes). The last traversal was once done as - part of the first pass, but that fails when a - 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 - the loop control. + + /* Three traversals of symbol chains here. The + first traversal yanks externals into a temporary + chain, removing the externals from the global + chain, numbers symbols, and does some other guck. + The second traversal is on the temporary chain of + externals and just appends them to the global + chain again, numbering them as we go. The third + traversal patches pointers to symbols (using sym + indexes). The last traversal was once done as + part of the first pass, but that fails when a + 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 + the loop control. + */ + 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_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) + { + if (S_GET_SEGMENT (symbolP) == SEG_TEXT) + { + S_SET_STORAGE_CLASS (symbolP, C_LABEL); + } + else + { + 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. */ + 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. */ + memset (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen, + '\0', 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... */ - 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_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) { - if (S_GET_SEGMENT(symbolP) == SEG_TEXT){ - S_SET_STORAGE_CLASS(symbolP, C_LABEL); - } else { - 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. */ - 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. */ - memset(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen, - '\0', 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 && !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 */ - - 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 */ - - /* 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; - } else { - ; + 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; } - text_lineno_number++; - } /* for each line number */ - - H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number); - - return; -} /* obj_crawl_symbol_chain() */ + } + } + 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 ( +#ifdef TE_I386AIX + S_GET_STORAGE_CLASS (symbolP) == C_EXT && !SF_GET_FUNCTION (symbolP) +#else /* not TE_I386AIX */ + !S_IS_DEFINED (symbolP) && !S_IS_DEBUG (symbolP) && !SF_GET_STATICS (symbolP) +#endif /* not TE_I386AIX */ + ) + { + /* 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 */ + + 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 */ + + /* 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; + } + else + { + ; + } + text_lineno_number++; + } /* for each line number */ + + H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); + + return; +} /* obj_crawl_symbol_chain() */ /* * Find strings by crawling along symbol table chain. */ -void obj_emit_strings(where) -char **where; +void +obj_emit_strings (where) + char **where; { - symbolS *symbolP; - + 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)); - *where += sizeof(string_byte_count); + /* 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_COMPILE */ - append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count)); + 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() */ - -void obj_pre_write_hook(headers) -object_headers *headers; + + 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() */ + +void +obj_pre_write_hook (headers) + 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 + 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. */ - /* Count the number of relocation entries for text and data */ - for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) { - if (fixP->fx_addsy) { - ++text_relocation_number; + /* Count the number of relocation entries for text and data */ + for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) + { + if (fixP->fx_addsy) + { + ++text_relocation_number; #ifdef TC_I960 - /* two relocs per callj under coff. */ - if (fixP->fx_callj) { - ++text_relocation_number; - } /* if callj and not already fixed. */ + /* two relocs per callj under coff. */ + if (fixP->fx_callj) + { + ++text_relocation_number; + } /* if callj and not already fixed. */ #endif /* TC_I960 */ #ifdef TC_A29K - /* Count 2 for a constH */ - if (fixP->fx_r_type == RELOC_CONSTH) { - ++text_relocation_number; - } + /* Count 2 for a constH */ + 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 */ + + } /* 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 */ - headers->relocation_size = text_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 */ + + } /* 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 */ + headers->relocation_size = text_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 */ #ifndef OBJ_COFF_OMIT_TIMESTAMP - H_SET_TIME_STAMP(headers, (long)time((long*)0)); + H_SET_TIME_STAMP (headers, (long) time ((long *) 0)); #else /* OBJ_COFF_OMIT_TIMESTAMP */ - H_SET_TIME_STAMP(headers, 0); + H_SET_TIME_STAMP (headers, 0); #endif /* OBJ_COFF_OMIT_TIMESTAMP */ - H_SET_SYMBOL_TABLE_POINTER(headers, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers)); + 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); - - /* do not added the F_RELFLG for the standard COFF. + /* symbol table size allready set */ + H_SET_SIZEOF_OPTIONAL_HEADER (headers, OBJ_COFF_AOUTHDRSZ); + + /* do not added the F_RELFLG for the standard COFF. * The AIX linker complain on file with relocation info striped flag. */ #ifdef KEEP_RELOC_INFO - H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0) - | BYTE_ORDERING); + H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0) + | BYTE_ORDERING); #else - H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0) - | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG) - | BYTE_ORDERING); -#endif - /* 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, - H_GET_TEXT_SIZE(headers), - H_GET_TEXT_FILE_OFFSET(headers), - (SA_GET_SCN_NRELOC(dot_text_symbol) - ? H_GET_RELOCATION_FILE_OFFSET(headers) - : 0), - (text_lineno_number - ? H_GET_LINENO_FILE_OFFSET(headers) - : 0), - 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), - H_GET_DATA_SIZE(headers), - (H_GET_DATA_SIZE(headers) - ? H_GET_DATA_FILE_OFFSET(headers) - : 0), - (SA_GET_SCN_NRELOC(dot_data_symbol) - ? (H_GET_RELOCATION_FILE_OFFSET(headers) - + text_section_header.s_nreloc * RELSZ) - : 0), - 0, /* No line number information */ - 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), - H_GET_BSS_SIZE(headers), - 0, /* No file offset */ - 0, /* No relocation information */ - 0, /* No line number information */ - 0, /* No relocation information */ - 0, /* No line number information */ - section_alignment[(int) SEG_BSS]); - - return; -} /* obj_pre_write_hook() */ + H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0) + | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG) + | BYTE_ORDERING); +#endif + /* 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, + H_GET_TEXT_SIZE (headers), + H_GET_TEXT_FILE_OFFSET (headers), + (SA_GET_SCN_NRELOC (dot_text_symbol) + ? H_GET_RELOCATION_FILE_OFFSET (headers) + : 0), + (text_lineno_number + ? H_GET_LINENO_FILE_OFFSET (headers) + : 0), + 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), + H_GET_DATA_SIZE (headers), + (H_GET_DATA_SIZE (headers) + ? H_GET_DATA_FILE_OFFSET (headers) + : 0), + (SA_GET_SCN_NRELOC (dot_data_symbol) + ? (H_GET_RELOCATION_FILE_OFFSET (headers) + + text_section_header.s_nreloc * RELSZ) + : 0), + 0, /* No line number information */ + 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), + H_GET_BSS_SIZE (headers), + 0, /* No file offset */ + 0, /* No relocation information */ + 0, /* No line number information */ + 0, /* No relocation information */ + 0, /* No line number information */ + section_alignment[(int) SEG_BSS]); + + return; +} /* obj_pre_write_hook() */ /* This is a copy from aout. All I do is neglect to actually build the symbol. */ -static void obj_coff_stab(what) -int what; +static void +obj_coff_stab (what) + int what; { - char *string; - expressionS e; - int goof = 0; /* TRUE if we have aborted. */ - int length; - 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 { - as_bad("I need a comma after symbol's name"); - goof = 1; - } /* better be a comma */ - } /* skip the string */ - - /* + char *string; + expressionS e; + int goof = 0; /* TRUE if we have aborted. */ + int length; + 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 + { + as_bad ("I need a comma after symbol's name"); + goof = 1; + } /* better be a comma */ + } /* skip the string */ + + /* * Input_line_pointer->after ','. String->symbol name. */ - if (!goof) { - if (get_absolute_expression_and_terminator(&longint) != ',') { - as_bad("I want a comma after the n_type expression"); - goof = 1; - 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"); - goof = 1; - 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"); - goof = 1; - } else { - input_line_pointer++; - } /* on goof */ - } /* not stabd */ - } /* no error */ - - expression(&e); - - if (goof) { - ignore_rest_of_line(); - } else { - demand_empty_rest_of_line(); - } /* on error */ -} /* obj_coff_stab() */ + if (!goof) + { + if (get_absolute_expression_and_terminator (&longint) != ',') + { + as_bad ("I want a comma after the n_type expression"); + goof = 1; + 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"); + goof = 1; + 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"); + goof = 1; + } + else + { + input_line_pointer++; + } /* on goof */ + } /* not stabd */ + } /* no error */ + + expression (&e); + + if (goof) + { + ignore_rest_of_line (); + } + else + { + demand_empty_rest_of_line (); + } /* on error */ +} /* obj_coff_stab() */ #ifdef DEBUG /* for debugging */ -char *s_get_name(s) -symbolS *s; +char * +s_get_name (s) + symbolS *s; { - return((s == NULL) ? "(NULL)" : S_GET_NAME(s)); -} /* s_get_name() */ - -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, - (unsigned long) symbolP, - S_GET_NAME(symbolP), - (long) S_GET_DATA_TYPE(symbolP), - S_GET_STORAGE_CLASS(symbolP), - (int) S_GET_SEGMENT(symbolP)); - } /* traverse symbols */ - - return; -} /* symbol_dump() */ + return ((s == NULL) ? "(NULL)" : S_GET_NAME (s)); +} /* s_get_name() */ + +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, + (unsigned long) symbolP, + S_GET_NAME (symbolP), + (long) S_GET_DATA_TYPE (symbolP), + S_GET_STORAGE_CLASS (symbolP), + (int) S_GET_SEGMENT (symbolP)); + } /* traverse symbols */ + + return; +} /* symbol_dump() */ + #endif /* DEBUG */ diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c index 2af4978d859..69901197790 100644 --- a/gas/config/obj-coffbfd.c +++ b/gas/config/obj-coffbfd.c @@ -28,7 +28,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 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 @@ -45,31 +45,32 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MIN(a,b) ((a) < (b)? (a) : (b)) /* This vector is used to turn an internal segment into a section # - suitable for insertion into a coff symbol table + suitable for insertion into a coff symbol table */ -const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */ - C_ABS_SECTION, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - C_UNDEF_SECTION, /* SEG_UNKNOWN */ - C_UNDEF_SECTION, /* SEG_ABSENT */ - C_UNDEF_SECTION, /* SEG_PASS1 */ - C_UNDEF_SECTION, /* SEG_GOOF */ - C_UNDEF_SECTION, /* SEG_BIG */ - C_UNDEF_SECTION, /* SEG_DIFFERENCE */ - C_DEBUG_SECTION, /* SEG_DEBUG */ - C_NTV_SECTION, /* SEG_NTV */ - C_PTV_SECTION, /* SEG_PTV */ - C_REGISTER_SECTION, /* SEG_REGISTER */ +const short seg_N_TYPE[] = +{ /* in: segT out: N_TYPE bits */ + C_ABS_SECTION, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + C_UNDEF_SECTION, /* SEG_UNKNOWN */ + C_UNDEF_SECTION, /* SEG_ABSENT */ + C_UNDEF_SECTION, /* SEG_PASS1 */ + C_UNDEF_SECTION, /* SEG_GOOF */ + C_UNDEF_SECTION, /* SEG_BIG */ + C_UNDEF_SECTION, /* SEG_DIFFERENCE */ + C_DEBUG_SECTION, /* SEG_DEBUG */ + C_NTV_SECTION, /* SEG_NTV */ + C_PTV_SECTION, /* SEG_PTV */ + C_REGISTER_SECTION, /* SEG_REGISTER */ }; @@ -80,99 +81,100 @@ int function_lineoff = -1; /* Offset in line#s where the last function int had_lineno = 0; int had_reloc = 0; -static symbolS*last_line_symbol; +static symbolS *last_line_symbol; /* 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 + section number into a segment number */ static symbolS *previous_file_symbol = NULL; -void c_symbol_merge(); +void c_symbol_merge (); static int line_base; -symbolS *c_section_symbol(); +symbolS *c_section_symbol (); bfd *abfd; -void EXFUN(bfd_as_write_hook,(struct internal_filehdr *, - bfd *abfd)); +void EXFUN (bfd_as_write_hook, (struct internal_filehdr *, + bfd * abfd)); -static void EXFUN(fixup_segment,(fixS * fixP, - segT this_segment_type)); +static void EXFUN (fixup_segment, (fixS * fixP, + segT this_segment_type)); -static void EXFUN(fixup_mdeps,(fragS *)); +static void EXFUN (fixup_mdeps, (fragS *)); -static void EXFUN(fill_section,(bfd *abfd , - struct internal_filehdr *f, unsigned - long *)); +static void EXFUN (fill_section, (bfd * abfd, + struct internal_filehdr * f, unsigned + long *)); -char *EXFUN(s_get_name,(symbolS *s)); -static symbolS *EXFUN(tag_find_or_make,(char *name)); -static symbolS* EXFUN(tag_find,(char *name)); +char *EXFUN (s_get_name, (symbolS * s)); +static symbolS *EXFUN (tag_find_or_make, (char *name)); +static symbolS *EXFUN (tag_find, (char *name)); static int -EXFUN(c_line_new,( - symbolS *symbol, - long paddr, - unsigned short line_number, - fragS* frag)); - - -static void EXFUN(w_symbols, - (bfd *abfd , - char *where , - symbolS *symbol_rootP)); - - - -static void EXFUN( obj_coff_def,(int what)); -static void EXFUN( obj_coff_lcomm,(void)); -static void EXFUN( obj_coff_dim,(void)); -static void EXFUN( obj_coff_text,(void)); -static void EXFUN( obj_coff_data,(void)); -static void EXFUN( obj_coff_endef,(void)); -static void EXFUN( obj_coff_line,(void)); -static void EXFUN( obj_coff_ln,(void)); -static void EXFUN( obj_coff_scl,(void)); -static void EXFUN( obj_coff_size,(void)); -static void EXFUN( obj_coff_tag,(void)); -static void EXFUN( obj_coff_type,(void)); -static void EXFUN( obj_coff_val,(void)); -void EXFUN( obj_coff_section,(void)); -static void EXFUN( tag_init,(void)); -static void EXFUN( tag_insert,(char *name, symbolS *symbolP)); + EXFUN (c_line_new, ( + symbolS * symbol, + long paddr, + unsigned short line_number, + fragS * frag)); + + +static void EXFUN (w_symbols, + (bfd * abfd, + char *where, + symbolS * symbol_rootP)); + + + +static void EXFUN (obj_coff_def, (int what)); +static void EXFUN (obj_coff_lcomm, (void)); +static void EXFUN (obj_coff_dim, (void)); +static void EXFUN (obj_coff_text, (void)); +static void EXFUN (obj_coff_data, (void)); +static void EXFUN (obj_coff_endef, (void)); +static void EXFUN (obj_coff_line, (void)); +static void EXFUN (obj_coff_ln, (void)); +static void EXFUN (obj_coff_scl, (void)); +static void EXFUN (obj_coff_size, (void)); +static void EXFUN (obj_coff_tag, (void)); +static void EXFUN (obj_coff_type, (void)); +static void EXFUN (obj_coff_val, (void)); +void EXFUN (obj_coff_section, (void)); +static void EXFUN (tag_init, (void)); +static void EXFUN (tag_insert, (char *name, symbolS * symbolP)); static struct hash_control *tag_hash; static symbolS *def_symbol_in_progress = NULL; -const pseudo_typeS obj_pseudo_table[] = { - { "def", obj_coff_def, 0 }, - { "dim", obj_coff_dim, 0 }, - { "endef", obj_coff_endef, 0 }, - { "line", obj_coff_line, 0 }, - { "ln", obj_coff_ln, 0 }, - { "scl", obj_coff_scl, 0 }, - { "size", obj_coff_size, 0 }, - { "tag", obj_coff_tag, 0 }, - { "type", obj_coff_type, 0 }, - { "val", obj_coff_val, 0 }, - { "section", obj_coff_section, 0 }, - { "use", obj_coff_section, 0 }, - { "sect", obj_coff_section, 0 }, - { "text", obj_coff_text, 0 }, - { "data", obj_coff_data, 0 }, - /* we don't yet handle this. */ - { "ident", s_ignore, 0 }, - { "ABORT", s_abort, 0 }, - { "lcomm", obj_coff_lcomm, 0}, - { NULL} /* end sentinel */ -}; /* obj_pseudo_table */ - - - -/* Section stuff +const pseudo_typeS obj_pseudo_table[] = +{ + {"def", obj_coff_def, 0}, + {"dim", obj_coff_dim, 0}, + {"endef", obj_coff_endef, 0}, + {"line", obj_coff_line, 0}, + {"ln", obj_coff_ln, 0}, + {"scl", obj_coff_scl, 0}, + {"size", obj_coff_size, 0}, + {"tag", obj_coff_tag, 0}, + {"type", obj_coff_type, 0}, + {"val", obj_coff_val, 0}, + {"section", obj_coff_section, 0}, + {"use", obj_coff_section, 0}, + {"sect", obj_coff_section, 0}, + {"text", obj_coff_text, 0}, + {"data", obj_coff_data, 0}, +/* we don't yet handle this. */ + {"ident", s_ignore, 0}, + {"ABORT", s_abort, 0}, + {"lcomm", obj_coff_lcomm, 0}, + {NULL} /* end sentinel */ +}; /* 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). @@ -181,7 +183,7 @@ const pseudo_typeS obj_pseudo_table[] = { */ -/* OBS stuff +/* OBS stuff static struct internal_scnhdr bss_section_header; struct internal_scnhdr data_section_header; struct internal_scnhdr text_section_header; @@ -194,99 +196,104 @@ const segT N_TYPE_seg [32] = */ #define N_SEG 32 -typedef struct +typedef struct { - segT seg_t; -int i; -} seg_info_type; + segT seg_t; + int i; +} + +seg_info_type; -seg_info_type seg_info_off_by_4[N_SEG] = +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; + relax_addressT mask; + relax_addressT new_address; - mask = ~ ( (~0) << alignment ); - new_address = (address + mask) & (~ mask); + mask = ~((~0) << alignment); + new_address = (address + mask) & (~mask); return (new_address - address); -} /* relax_align() */ +} /* relax_align() */ -segT -DEFUN(s_get_segment,(x) , -symbolS* x) +segT +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; } /* 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) +static unsigned int +DEFUN (size_section, (abfd, idx), + bfd * abfd AND + unsigned int idx) { unsigned int size = 0; fragS *frag = segment_info[idx].frchainP->frch_root; - while (frag) { - size = frag->fr_address; -#if 0 - if (frag->fr_address != size) { - printf("Out of step\n"); + while (frag) + { + size = frag->fr_address; +#if 0 + if (frag->fr_address != size) + { + printf ("Out of step\n"); size = frag->fr_address; } - switch (frag->fr_type) { + switch (frag->fr_type) + { #ifdef TC_COFF_SIZEMACHDEP - case rs_machine_dependent: - size += TC_COFF_SIZEMACHDEP(frag); - break; + case rs_machine_dependent: + size += TC_COFF_SIZEMACHDEP (frag); + break; #endif case rs_fill: case rs_org: - size += frag->fr_fix; - size += frag->fr_offset * frag->fr_var; + size += frag->fr_fix; + size += frag->fr_offset * frag->fr_var; break; case rs_align: - size += frag->fr_fix; - size += relax_align(size, frag->fr_offset); + size += frag->fr_fix; + size += relax_align (size, frag->fr_offset); } #endif frag = frag->fr_next; @@ -296,253 +303,258 @@ DEFUN(size_section,(abfd, idx), } -static unsigned int DEFUN(count_entries_in_chain,(idx), - unsigned int idx) +static unsigned int +DEFUN (count_entries_in_chain, (idx), + unsigned int idx) { - unsigned int nrelocs; - fixS *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) + /* Count the relocations */ + fixup_ptr = segment_info[idx].fix_root; + nrelocs = 0; + while (fixup_ptr != (fixS *) NULL) { - if (TC_COUNT_RELOC(fixup_ptr)) + if (TC_COUNT_RELOC (fixup_ptr)) { - + #ifdef TC_A29K - if (fixup_ptr->fx_r_type == RELOC_CONSTH) - nrelocs+=2; - else - nrelocs++; -#else + if (fixup_ptr->fx_r_type == RELOC_CONSTH) + nrelocs += 2; + else nrelocs++; +#else + nrelocs++; #endif } - - fixup_ptr = fixup_ptr->fx_next; + + fixup_ptr = fixup_ptr->fx_next; } - return nrelocs; + return nrelocs; } /* output all the relocations for a section */ -void DEFUN(do_relocs_for,(abfd, file_cursor), - bfd *abfd AND - unsigned long *file_cursor) +void +DEFUN (do_relocs_for, (abfd, file_cursor), + bfd * abfd AND + unsigned long *file_cursor) { unsigned int nrelocs; unsigned int idx; unsigned int addr = 0; - 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 = addr; - fixS * fix_ptr = segment_info[idx].fix_root; - nrelocs = count_entries_in_chain(idx); - - if (nrelocs) - had_reloc = 1; - - 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 + 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 = addr; + fixS *fix_ptr = segment_info[idx].fix_root; + nrelocs = count_entries_in_chain (idx); + + if (nrelocs) + had_reloc = 1; + + 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; + while (fix_ptr) + { + symbolS *symbol_ptr; + struct internal_reloc intr; - /* Only output some of the relocations */ - if (TC_COUNT_RELOC(fix_ptr)) - { + /* 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; + 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_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 = fix_ptr->fx_offset; - intr.r_offset = 0; + intr.r_offset = 0; - /* Turn the segment of the symbol into an offset + /* 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; - } + 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; + } + 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. + /* 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++; - } + + 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); - } #ifndef ZERO_BASED_SEGMENTS - /* Supposedly setting segment addresses non-zero causes problems + /* Supposedly setting segment addresses non-zero causes problems for some platforms, although it shouldn't. If you define ZERO_BASED_SEGMENTS, all the segments will be based at 0. Please don't make this the default, since some systems (e.g., SVR3.2) require the segments to be non-zero based. Ian Taylor . */ - addr += segment_info[idx].scnhdr.s_size; + addr += segment_info[idx].scnhdr.s_size; #endif - } + } } /* 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 + 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) +static void +DEFUN (fill_section, (abfd, filehdr, file_cursor), + bfd * abfd AND + struct internal_filehdr *filehdr AND + unsigned long *file_cursor) { unsigned int i; - - 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); - if (s->s_size != 0) - s->s_scnptr = *file_cursor; - else - s->s_scnptr = 0; - - 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; - else if (strcmp(s->s_name,".lit")==0) - s->s_flags = STYP_LIT | STYP_TEXT; - - - while (frag) { - unsigned int fill_size; - switch (frag->fr_type) { - case rs_machine_dependent: - if(frag->fr_fix) - { - memcpy(buffer + frag->fr_address, - frag->fr_literal, - frag->fr_fix); - offset += frag->fr_fix; - } - break; - 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--) + 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); + if (s->s_size != 0) + s->s_scnptr = *file_cursor; + else + s->s_scnptr = 0; + + 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; + else if (strcmp (s->s_name, ".lit") == 0) + s->s_flags = STYP_LIT | STYP_TEXT; + + + while (frag) { - memcpy(buffer + frag->fr_address + off, - frag->fr_literal + frag->fr_fix, - fill_size); - off += fill_size; - offset += fill_size; - + unsigned int fill_size; + switch (frag->fr_type) + { + case rs_machine_dependent: + if (frag->fr_fix) + { + memcpy (buffer + frag->fr_address, + frag->fr_literal, + frag->fr_fix); + offset += frag->fr_fix; + } + + break; + 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; + case rs_broken_word: + break; + default: + abort (); + } + frag = frag->fr_next; } - } - break; - case rs_broken_word: - break; - default: - abort(); - } - frag = frag->fr_next; - } - - bfd_write(buffer, s->s_size,1,abfd); - free(buffer); - - *file_cursor += s->s_size; + bfd_write (buffer, s->s_size, 1, abfd); + free (buffer); - } - } + *file_cursor += s->s_size; + + } + } } @@ -551,170 +563,180 @@ static void DEFUN(fill_section,(abfd, filehdr, file_cursor), /* Coff file generation & utilities */ -static void -DEFUN(coff_header_append,(abfd, filehdr, aouthdr), - bfd *abfd AND - struct internal_filehdr *filehdr AND - struct internal_aouthdr *aouthdr) +static void +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); -#if 0 - filehdr.f_opthdr = bfd_coff_swap_aouthdr_out(abfd, aouthdr, - buffero); + bfd_seek (abfd, 0, 0); +#if 0 + filehdr.f_opthdr = bfd_coff_swap_aouthdr_out (abfd, aouthdr, + buffero); #else filehdr->f_opthdr = 0; #endif - i = bfd_coff_swap_filehdr_out(abfd, filehdr, buffer); + i = bfd_coff_swap_filehdr_out (abfd, filehdr, buffer); - bfd_write(buffer, i ,1, abfd); - bfd_write(buffero, filehdr->f_opthdr, 1, abfd); + 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); + 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; + 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) + /* Turn any symbols with register attributes into abs symbols */ + if (S_GET_SEGMENT (symbolP) == SEG_REGISTER) { - S_SET_SEGMENT(symbolP, SEG_ABSOLUTE); + 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), - where); + /* 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), + where); } - return where; - -} + return where; + +} -void obj_symbol_new_hook(symbolP) -symbolS *symbolP; +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); - S_SET_DATA_TYPE(symbolP, T_NULL); - S_SET_STORAGE_CLASS(symbolP, 0); - S_SET_NUMBER_AUXILIARY(symbolP, 0); - /* Additional information */ - symbolP->sy_symbol.ost_flags = 0; - /* Auxiliary entries */ - bzero((char*)&symbolP->sy_symbol.ost_auxent[0], AUXESZ); + char underscore = 0; /* Symbol has leading _ */ + + /* Effective symbol */ + /* Store the pointer in the offset. */ + S_SET_ZEROES (symbolP, 0L); + S_SET_DATA_TYPE (symbolP, T_NULL); + S_SET_STORAGE_CLASS (symbolP, 0); + S_SET_NUMBER_AUXILIARY (symbolP, 0); + /* Additional information */ + 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. + /* Remove leading underscore at the beginning of the symbol. * This is to be compatible with the standard librairies. */ - if (*S_GET_NAME(symbolP) == '_') { - underscore = 1; - S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1); - } /* strip underscore */ + if (*S_GET_NAME (symbolP) == '_') + { + underscore = 1; + 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); + if (S_IS_STRING (symbolP)) + SF_SET_STRING (symbolP); + if (!underscore && S_IS_LOCAL (symbolP)) + SF_SET_LOCAL (symbolP); - return; -} /* obj_symbol_new_hook() */ + return; +} /* obj_symbol_new_hook() */ - /* stack stuff */ -stack* stack_init(chunk_size, element_size) -unsigned long chunk_size; -unsigned long element_size; +/* stack stuff */ +stack * +stack_init (chunk_size, element_size) + unsigned long chunk_size; + unsigned long element_size; { - stack* st; + stack *st; - if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0) - return (stack*)0; - if ((st->data = malloc(chunk_size)) == (char*)0) { - free(st); - return (stack*)0; - } - st->pointer = 0; - st->size = chunk_size; - st->chunk_size = chunk_size; - st->element_size = element_size; - return st; -} /* stack_init() */ - -void stack_delete(st) -stack* st; + if ((st = (stack *) malloc (sizeof (stack))) == (stack *) 0) + return (stack *) 0; + if ((st->data = malloc (chunk_size)) == (char *) 0) + { + free (st); + return (stack *) 0; + } + st->pointer = 0; + st->size = chunk_size; + st->chunk_size = chunk_size; + st->element_size = element_size; + return st; +} /* stack_init() */ + +void +stack_delete (st) + stack *st; { - free(st->data); - free(st); + free (st->data); + free (st); } -char *stack_push(st, element) -stack *st; -char *element; +char * +stack_push (st, element) + stack *st; + char *element; { - if (st->pointer + st->element_size >= st->size) { - st->size += st->chunk_size; - if ((st->data = xrealloc(st->data, st->size)) == (char*)0) - return (char*)0; - } - memcpy(st->data + st->pointer, element, st->element_size); - st->pointer += st->element_size; - return st->data + st->pointer; -} /* stack_push() */ + if (st->pointer + st->element_size >= st->size) + { + st->size += st->chunk_size; + if ((st->data = xrealloc (st->data, st->size)) == (char *) 0) + return (char *) 0; + } + memcpy (st->data + st->pointer, element, st->element_size); + st->pointer += st->element_size; + return st->data + st->pointer; +} /* stack_push() */ -char* stack_pop(st) -stack* st; +char * +stack_pop (st) + stack *st; { - if ((st->pointer -= st->element_size) < 0) { - st->pointer = 0; - return (char*)0; + if ((st->pointer -= st->element_size) < 0) + { + st->pointer = 0; + return (char *) 0; } - return st->data + st->pointer; + return st->data + st->pointer; } -char* stack_top(st) -stack* st; +char * +stack_top (st) + stack *st; { - return st->data + st->pointer - st->element_size; + return st->data + st->pointer - st->element_size; } @@ -722,32 +744,34 @@ stack* st; * Handle .ln directives. */ -static void obj_coff_ln() +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(); + + 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); + 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(); + demand_empty_rest_of_line (); return; } /* obj_coff_line() */ @@ -770,140 +794,146 @@ static void obj_coff_ln() *input_line_pointer == '\t') \ input_line_pointer++; -static void -DEFUN(obj_coff_def,(what), - int what) +static void +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; - } /* 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 */ + 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); -#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; + 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); +#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; } /* obj_coff_def() */ unsigned int dim_index; -static void -DEFUN_VOID(obj_coff_endef) +static void +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; - } /* 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._n_nptr[1][1] == 'b' - && def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][2] == 'f') { /* .bf */ - if (function_lineoff < 0) { - fprintf(stderr, "`.bf' symbol without preceding function\n"); - } /* missing function symbol */ - SA_GET_SYM_LNNOPTR(last_line_symbol) = function_lineoff; - - SF_SET_PROCESS(last_line_symbol); - function_lineoff = -1; - } - break; + 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._n_nptr[1][1] == 'b' + && def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][2] == 'f') + { /* .bf */ + if (function_lineoff < 0) + { + fprintf (stderr, "`.bf' symbol without preceding function\n"); + } /* missing function symbol */ + SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff; + + SF_SET_PROCESS (last_line_symbol); + function_lineoff = -1; + } + break; #ifdef 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; - } /* switch on storage class */ - - /* Now that we have built a debug symbol, try to + 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; + } /* 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 + /* 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 @@ -914,20 +944,23 @@ DEFUN_VOID(obj_coff_endef) presume the debug symbol is a real function reference. */ - /* FIXME-SOON If for some reason the definition + /* 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) { + 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); + symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); - } else { - /* This symbol already exists, merge the + } + else + { + /* This symbol already exists, merge the newly created symbol into the old one. This is not mandatory. The linker can handle duplicate symbols correctly. But I @@ -935,285 +968,326 @@ DEFUN_VOID(obj_coff_endef) the assembly file defines a lot of symbols. [loic] */ - /* The debug entry (def_symbol_in_progress) + /* 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; + 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 + 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 appears. Move the existing symbol to the current place. */ - /* If it already is at the end of the symbol list, do nothing */ - 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 symbol is a {structure,union} tag, associate symbol to its name. */ + /* If it already is at the end of the symbol list, do nothing */ + 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 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); + 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); + SF_SET_PROCESS (def_symbol_in_progress); - if (symbolP == NULL) { - /* That is, if this is the first + 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 */ + 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) +static void +DEFUN_VOID (obj_coff_dim) { - register int dim_index; + register int dim_index; - if (def_symbol_in_progress == NULL) + if (def_symbol_in_progress == NULL) { - as_warn(".dim pseudo-op used outside of .def/.endef: ignored."); - demand_empty_rest_of_line(); - return; + 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); + S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); - for (dim_index = 0; dim_index < DIMNUM; dim_index++) + for (dim_index = 0; dim_index < DIMNUM; dim_index++) { - SKIP_WHITESPACES(); - SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression()); + SKIP_WHITESPACES (); + SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, get_absolute_expression ()); - switch (*input_line_pointer) + 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; + 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; + demand_empty_rest_of_line (); + return; } /* obj_coff_dim() */ -static void obj_coff_line() +static void +obj_coff_line () { int this_base; - - if (def_symbol_in_progress == NULL) { - obj_coff_ln(); + + 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) + this_base = get_absolute_expression (); + if (this_base > line_base) + { + line_base = this_base; + } + + +#ifndef NO_LISTING { - line_base = this_base; + extern int listing; + if (listing && 0) + { + listing_source_line (line_base); + } } - - -#ifndef NO_LISTING -{ - 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); + S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); + SA_SET_SYM_LNNO (def_symbol_in_progress, line_base); - demand_empty_rest_of_line(); + demand_empty_rest_of_line (); return; } /* obj_coff_line() */ -static void obj_coff_size() { - if (def_symbol_in_progress == NULL) { - as_warn(".size 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); - SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression()); - demand_empty_rest_of_line(); - return; -} /* obj_coff_size() */ - -static void obj_coff_scl() { - if (def_symbol_in_progress == NULL) { - as_warn(".scl pseudo-op used outside of .def/.endef ignored."); - 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; -} /* 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() */ - -static void obj_coff_type() { - if (def_symbol_in_progress == NULL) { - as_warn(".type pseudo-op used outside of .def/.endef ignored."); - 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() */ - -static void obj_coff_val() { - if (def_symbol_in_progress == NULL) { - as_warn(".val pseudo-op used outside of .def/.endef ignored."); - 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 +static void +obj_coff_size () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".size 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); + SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); + demand_empty_rest_of_line (); + return; +} /* obj_coff_size() */ + +static void +obj_coff_scl () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".scl pseudo-op used outside of .def/.endef ignored."); + 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; +} /* 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() */ + +static void +obj_coff_type () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".type pseudo-op used outside of .def/.endef ignored."); + 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() */ + +static void +obj_coff_val () +{ + if (def_symbol_in_progress == NULL) + { + as_warn (".val pseudo-op used outside of .def/.endef ignored."); + 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. */ - SF_SET_GET_SEGMENT(def_symbol_in_progress); - } - /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */ - *input_line_pointer = name_end; - } else { - S_SET_VALUE(def_symbol_in_progress, get_absolute_expression()); - } /* if symbol based */ + SF_SET_GET_SEGMENT (def_symbol_in_progress); + } + /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */ + *input_line_pointer = name_end; + } + else + { + S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ()); + } /* if symbol based */ - demand_empty_rest_of_line(); - return; -} /* obj_coff_val() */ + demand_empty_rest_of_line (); + return; +} /* obj_coff_val() */ /* * Maintain a list of the tagnames of the structres. */ -static void tag_init() { - tag_hash = hash_new(); - return ; -} /* tag_init() */ +static void +tag_init () +{ + tag_hash = hash_new (); + return; +} /* tag_init() */ -static void tag_insert(name, symbolP) -char *name; -symbolS *symbolP; +static void +tag_insert (name, symbolP) + char *name; + symbolS *symbolP; { - register char * error_string; + 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); - } - return ; -} /* tag_insert() */ + if (*(error_string = hash_jam (tag_hash, name, (char *) symbolP))) + { + as_fatal ("Inserting \"%s\" into structure table failed: %s", + name, error_string); + } + return; +} /* tag_insert() */ -static symbolS *tag_find_or_make(name) -char *name; +static symbolS * +tag_find_or_make (name) + char *name; { - symbolS *symbolP; + symbolS *symbolP; - if ((symbolP = tag_find(name)) == NULL) { - symbolP = symbol_new(name, - SEG_UNKNOWN, - 0, - &zero_address_frag); + 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 */ + tag_insert (S_GET_NAME (symbolP), symbolP); + symbol_table_insert (symbolP); + } /* not found */ - return(symbolP); -} /* tag_find_or_make() */ + return (symbolP); +} /* tag_find_or_make() */ -static symbolS *tag_find(name) -char *name; +static symbolS * +tag_find (name) + char *name; { #ifdef STRIP_UNDERSCORE - if (*name == '_') name++; + if (*name == '_') + name++; #endif /* STRIP_UNDERSCORE */ - return((symbolS*)hash_find(tag_hash, name)); -} /* tag_find() */ + return ((symbolS *) hash_find (tag_hash, name)); +} /* tag_find() */ -void obj_read_begin_hook() { - /* These had better be the same. Usually 18 bytes. */ +void +obj_read_begin_hook () +{ + /* These had better be the same. Usually 18 bytes. */ #ifndef BFD_HEADERS - know(sizeof(SYMENT) == sizeof(AUXENT)); - know(SYMESZ == AUXESZ); + know (sizeof (SYMENT) == sizeof (AUXENT)); + know (SYMESZ == AUXESZ); #endif - tag_init(); + tag_init (); - return; -} /* obj_read_begin_hook() */ + return; +} /* obj_read_begin_hook() */ /* This function runs through the symbol table and puts all the externals onto another chain */ @@ -1222,27 +1296,31 @@ void obj_read_begin_hook() { symbolS *symbol_externP = NULL; symbolS *symbol_extern_lastP = NULL; -stack*block_stack; - symbolS *last_functionP = NULL; - symbolS *last_tagP; +stack *block_stack; +symbolS *last_functionP = NULL; +symbolS *last_tagP; -static unsigned int DEFUN_VOID(yank_symbols) +static unsigned int +DEFUN_VOID (yank_symbols) { symbolS *symbolP; - unsigned int symbol_number =0; - + unsigned int symbol_number = 0; + for (symbolP = symbol_rootP; symbolP; - symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) { - if (!SF_GET_DEBUG(symbolP)) { + symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP) + { + if (!SF_GET_DEBUG (symbolP)) + { /* Debug symbols do not need all this rubbish */ - symbolS* real_symbolP; + 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) { + 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 @@ -1250,103 +1328,116 @@ static unsigned int DEFUN_VOID(yank_symbols) 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); + 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); + 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); + 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); + 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) + if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP)) { - S_SET_STORAGE_CLASS(symbolP, C_LABEL); - } - else + S_SET_EXTERNAL (symbolP); + } + else if (S_GET_STORAGE_CLASS (symbolP) == C_NULL) { - S_SET_STORAGE_CLASS(symbolP, C_STAT); + 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 + 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 (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 */ + if (S_GET_NUMBER_AUXILIARY (symbolP) < 1) + { + S_SET_NUMBER_AUXILIARY (symbolP, 1); + } /* make it at least 1 */ - /* Clobber possible stale .dim information. */ + /* Clobber possible stale .dim information. */ #if 0 -/* Iffed out by steve - this fries the lnnoptr info too */ - 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)); + /* Iffed out by steve - this fries the lnnoptr info too */ + 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)); #endif - } - /* The C_FCN doesn't need any additional information. + } + /* 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 + 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 */ + 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 @@ -1360,99 +1451,111 @@ static unsigned int DEFUN_VOID(yank_symbols) endndx will still be 22 instead of 21. */ - if (SF_GET_LOCAL(symbolP)) { + if (SF_GET_LOCAL (symbolP)) + { /* remove C_EFCN and LOCAL (L...) symbols */ /* next pointer remains valid */ - symbol_remove(symbolP, &symbol_rootP, &symbol_lastP); + 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 */ + 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) +static unsigned int +DEFUN_VOID (glue_symbols) { unsigned int symbol_number = 0; - symbolS *symbolP; - for (symbolP = symbol_externP; symbol_externP;) { + 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); + symbol_remove (tmp, &symbol_externP, &symbol_extern_lastP); + symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP); /* and process */ - if (SF_GET_STRING(tmp)) { + 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 */ + 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); + symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp); } /* append the entire extern chain */ return symbol_number; - + } -static unsigned int DEFUN_VOID(tie_tags) +static unsigned int +DEFUN_VOID (tie_tags) { unsigned int symbol_number = 0; - - symbolS*symbolP; + + symbolS *symbolP; for (symbolP = symbol_rootP; symbolP; symbolP = - symbol_next(symbolP)) - { - symbolP->sy_number = symbol_number; + 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); - } + 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); - } + 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) +static void +DEFUN (crawl_symbols, (headers, abfd), + struct internal_filehdr *headers AND + bfd * abfd) { - unsigned int i; + unsigned int i; unsigned int ptr = 0; @@ -1460,25 +1563,27 @@ DEFUN(crawl_symbols,(headers, abfd), /* Initialize the stack used to keep track of the matching .bb .be */ - block_stack = stack_init(512, sizeof(symbolS*)); + block_stack = stack_init (512, sizeof (symbolS *)); /* JF deal with forward references first... */ for (symbolP = symbol_rootP; symbolP; - symbolP = symbol_next(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 (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 */ + 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 */ + 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 @@ -1493,8 +1598,9 @@ DEFUN(crawl_symbols,(headers, abfd), */ if (symbol_rootP == NULL - || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) { - c_dot_file_symbol("fake"); + || 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. */ @@ -1503,26 +1609,26 @@ DEFUN(crawl_symbols,(headers, abfd), */ - for (i = SEG_E0; i < SEG_E9; i++) - { - if (segment_info[i].scnhdr.s_name[0]) + for (i = SEG_E0; i < SEG_E9; i++) { - segment_info[i].dot = - c_section_symbol(segment_info[i].scnhdr.s_name, - i-SEG_E0+1); - + 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(); + headers->f_nsyms = yank_symbols (); /* Take the externals and glue them onto the end.*/ - headers->f_nsyms += glue_symbols(); + headers->f_nsyms += glue_symbols (); - headers->f_nsyms = tie_tags(); - know(symbol_externP == NULL); - know(symbol_extern_lastP == NULL); + headers->f_nsyms = tie_tags (); + know (symbol_externP == NULL); + know (symbol_extern_lastP == NULL); return; } @@ -1531,28 +1637,30 @@ DEFUN(crawl_symbols,(headers, abfd), * Find strings by crawling along symbol table chain. */ -void DEFUN(w_strings,(where), - char *where) +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); + 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; - - } - } + 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; + + } + } } @@ -1560,60 +1668,60 @@ void DEFUN(w_strings,(where), -static void -DEFUN(do_linenos_for,(abfd, file_cursor), - bfd *abfd AND - unsigned long *file_cursor) +static void +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) + for (idx = SEG_E0; idx < SEG_E9; idx++) { - struct lineno_list *line_ptr ; + segment_info_type *s = segment_info + idx; - struct external_lineno *buffer = - (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ); - struct external_lineno *dst= buffer; + if (s->scnhdr.s_nlnno != 0) + { + struct lineno_list *line_ptr; + + struct external_lineno *buffer = + (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ); - /* Run through the table we've built and turn it into its external + 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) - { + 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; - } + 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; + (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; + } } - } } @@ -1621,147 +1729,151 @@ DEFUN(do_linenos_for,(abfd, file_cursor), make all the subsegment frags appear at the end of the list, as if the seg 0 was extra long */ -static void DEFUN_VOID(remove_subsegs) +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; - - while (head && head->frch_seg == i) + unsigned int i; + + 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 = head->frch_root; + prev_frag = head->frch_last; + head = head->frch_next; } - prev_frag->fr_next = 0; + prev_frag->fr_next = 0; } } int machine; int coff_flags; -extern void DEFUN_VOID(write_object_file) +extern void +DEFUN_VOID (write_object_file) { - int i; - struct frchain *frchain_ptr; + int i; + struct frchain *frchain_ptr; - struct internal_filehdr filehdr; - struct internal_aouthdr aouthdr; - unsigned long file_cursor; - bfd *abfd; - unsigned int addr; - abfd = bfd_openw(out_file_name, TARGET_FORMAT); + struct internal_filehdr filehdr; + struct internal_aouthdr aouthdr; + unsigned long file_cursor; + bfd *abfd; + unsigned int addr; + 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, machine); + 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, machine); - 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 + 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); + 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(); - + remove_subsegs (); - for (i = SEG_E0; i < SEG_UNKNOWN; i++) + + for (i = SEG_E0; i < SEG_UNKNOWN; i++) { - relax_segment(segment_info[i].frchainP->frch_root, i); + relax_segment (segment_info[i].frchainP->frch_root, i); } - filehdr.f_nscns = 0; - - /* Find out how big the sections are, and set the addresses. */ - addr = 0; - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - segment_info[i].scnhdr.s_paddr = addr; - segment_info[i].scnhdr.s_vaddr = addr; + filehdr.f_nscns = 0; + + /* Find out how big the sections are, and set the addresses. */ + addr = 0; + for (i = SEG_E0; i < SEG_UNKNOWN; i++) + { + segment_info[i].scnhdr.s_paddr = addr; + segment_info[i].scnhdr.s_vaddr = addr; - if (segment_info[i].scnhdr.s_name[0]) + if (segment_info[i].scnhdr.s_name[0]) { filehdr.f_nscns++; } - + #ifndef ZERO_BASED_SEGMENTS - /* See the comment at the previous ZERO_BASED_SEGMENTS check. */ - if (i == SEG_E2) + /* See the comment at the previous ZERO_BASED_SEGMENTS check. */ + 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. */ addr += segment_info[i].scnhdr.s_size; } - else + else { - addr += size_section(abfd, i); + addr += size_section (abfd, i); } #endif - } + } - /* Turn the gas native symbol table shape into a coff symbol table */ - crawl_symbols(&filehdr, abfd); + /* Turn the gas native symbol table shape into a coff symbol table */ + crawl_symbols (&filehdr, abfd); #if !defined(TC_H8300) && !defined(TC_Z8K) - for (i = SEG_E0; i < SEG_UNKNOWN; i++) + for (i = SEG_E0; i < SEG_UNKNOWN; i++) { - fixup_mdeps(segment_info[i].frchainP->frch_root); - fixup_segment(segment_info[i].fix_root, i); + fixup_mdeps (segment_info[i].frchainP->frch_root); + fixup_segment (segment_info[i].fix_root, i); } #endif - file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns ; + file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns; + + bfd_seek (abfd, file_cursor, 0); - bfd_seek(abfd, file_cursor, 0); + do_relocs_for (abfd, &file_cursor); - do_relocs_for(abfd, &file_cursor); + do_linenos_for (abfd, &file_cursor); - do_linenos_for(abfd, &file_cursor); + /* Plant the data */ - /* Plant the data */ + fill_section (abfd, &filehdr, &file_cursor); - fill_section(abfd,&filehdr, &file_cursor); + filehdr.f_magic = COFF_MAGIC; + filehdr.f_timdat = time (0); + filehdr.f_flags = COFF_FLAGS | coff_flags; - filehdr.f_magic = COFF_MAGIC; - filehdr.f_timdat = time(0); - filehdr.f_flags = COFF_FLAGS | coff_flags; - - if (!had_lineno) + if (!had_lineno) { filehdr.f_flags |= F_LNNO; } - if (!had_reloc) + if (!had_reloc) { filehdr.f_flags |= F_RELFLG; } - + @@ -1770,267 +1882,282 @@ extern void DEFUN_VOID(write_object_file) { - 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); - + 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); + coff_header_append (abfd, &filehdr, &aouthdr); - if (bfd_close_all_done(abfd) == false) - as_fatal ("Can't close %s: %s", out_file_name, - bfd_errmsg (bfd_error)); + if (bfd_close_all_done (abfd) == false) + as_fatal ("Can't close %s: %s", out_file_name, + bfd_errmsg (bfd_error)); } -static void DEFUN(change_to_section,(name, len, exp), - char *name AND - unsigned int len AND - unsigned int exp) +static void +DEFUN (change_to_section, (name, len, exp), + char *name AND + unsigned int len AND + unsigned int exp) { - unsigned int i; + 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) + for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++) { - subseg_new(i, exp); - return; - + 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); + strncpy (segment_info[i].scnhdr.s_name, name, 8); + subseg_new (i, exp); } -void -DEFUN_VOID(obj_coff_section) +void +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(); + /* 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 == ',') + else if (*input_line_pointer == ',') { - - input_line_pointer++; - exp = get_absolute_expression(); + + input_line_pointer++; + exp = get_absolute_expression (); } - else + else { - exp = 0; + exp = 0; } - - change_to_section(section_name, len,exp); -*section_name_end = c; - + + change_to_section (section_name, len, exp); + *section_name_end = c; + } -static void obj_coff_text() +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() +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) -symbolS *debug; -symbolS *normal; +void +c_symbol_merge (debug, normal) + symbolS *debug; + symbolS *normal; { - S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug)); - S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug)); + 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) > 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 */ + 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() */ + /* 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; + 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; had_lineno = 1; - - if (line_number == 0) - { - last_line_symbol = symbol; - 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 (line_number == 0) + { + last_line_symbol = symbol; + new_line->line.l_addr.l_symndx = (long) symbol; + } + else + { + new_line->line.l_addr.l_paddr = paddr; + } - - if (s->lineno_list_head == (struct lineno_list *)NULL) - { - s->lineno_list_head = new_line; - } - else - { - s->lineno_list_tail->next = new_line; - } + 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 ++; + return LINESZ * s->scnhdr.s_nlnno++; } -void c_dot_file_symbol(filename) -char *filename; +void +c_dot_file_symbol (filename) + char *filename; { - symbolS* symbolP; + symbolS *symbolP; - symbolP = symbol_new(".file", - SEG_DEBUG, - 0, - &zero_address_frag); + 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); + 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); - } - + if (listing) + { + listing_source_file (filename); + } + } - -#endif - SF_SET_DEBUG(symbolP); - S_SET_VALUE(symbolP, (long) previous_file_symbol); - previous_file_symbol = symbolP; +#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 */ + /* 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 */ + 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() */ +} /* c_dot_file_symbol() */ /* * Build a 'section static' symbol. */ -symbolS *c_section_symbol(name,idx) -char *name; -int idx; +symbolS * +c_section_symbol (name, idx) + char *name; + int idx; { - symbolS *symbolP; + symbolS *symbolP; - symbolP = symbol_new(name,idx, - 0, - &zero_address_frag); + symbolP = symbol_new (name, idx, + 0, + &zero_address_frag); - S_SET_STORAGE_CLASS(symbolP, C_STAT); - S_SET_NUMBER_AUXILIARY(symbolP, 1); + S_SET_STORAGE_CLASS (symbolP, C_STAT); + S_SET_NUMBER_AUXILIARY (symbolP, 1); - SF_SET_STATICS(symbolP); + SF_SET_STATICS (symbolP); - return symbolP; -} /* c_section_symbol() */ + return symbolP; +} /* c_section_symbol() */ -static void -DEFUN(w_symbols,(abfd, where, symbol_rootP), -bfd *abfd AND -char *where AND -symbolS *symbol_rootP) +static void +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) + 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); - + + 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 + 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; + register char *temp; - tc_coff_symbol_emit_hook(symbolP); + 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); + 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); + } + } /* w_symbols() */ -static void DEFUN_VOID(obj_coff_lcomm) +static void +DEFUN_VOID (obj_coff_lcomm) { char *name; char c; @@ -2042,264 +2169,289 @@ static void DEFUN_VOID(obj_coff_lcomm) name = input_line_pointer; - c = get_symbol_end(); + 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; - } + 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; + } input_line_pointer++; - if ((temp = get_absolute_expression ()) < 0) { - as_warn("lcomm length (%d.) <0! Ignored.", temp); - ignore_rest_of_line(); - return; - } + if ((temp = get_absolute_expression ()) < 0) + { + as_warn ("lcomm length (%d.) <0! Ignored.", temp); + ignore_rest_of_line (); + return; + } *p = 0; { /* Allocate zero static local data in the .data section now instead of the bss section as a symbol with a value */ - char *x; - segT oldseg = now_seg; - int oldsubseg = now_subseg; - - subseg_new(SEG_DATA, 10); - colon(name); - frag_align(2,0); - record_alignment(SEG_DATA, 4); - x = frag_var (rs_fill, 1, 1, (relax_substateT)0, (symbolS *)0, - temp, (char *)0); - * x= 0; - - subseg_new(oldseg, oldsubseg); - } - demand_empty_rest_of_line(); + char *x; + segT oldseg = now_seg; + int oldsubseg = now_subseg; + + subseg_new (SEG_DATA, 10); + colon (name); + frag_align (2, 0); + record_alignment (SEG_DATA, 4); + x = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0, + temp, (char *) 0); + *x = 0; + + subseg_new (oldseg, oldsubseg); + } + demand_empty_rest_of_line (); } -static void DEFUN(fixup_mdeps,(frags), - fragS *frags) +static void +DEFUN (fixup_mdeps, (frags), + fragS * frags) { - while (frags) - { - switch (frags->fr_type) + while (frags) { - case rs_align: - case rs_org: - frags->fr_type = rs_fill; - frags->fr_offset = - (frags->fr_next->fr_address - frags->fr_address - frags->fr_fix); - break; - case rs_machine_dependent: - md_convert_frag(0, frags); - break; - default: - ; + switch (frags->fr_type) + { + case rs_align: + case rs_org: + frags->fr_type = rs_fill; + frags->fr_offset = + (frags->fr_next->fr_address - frags->fr_address - frags->fr_fix); + break; + case rs_machine_dependent: + md_convert_frag (0, frags); + break; + default: + ; + } + frags = frags->fr_next; } - frags = frags->fr_next; - } } + #if 1 -static void DEFUN(fixup_segment,(fixP, this_segment_type), -register fixS * fixP AND -segT this_segment_type) +static void +DEFUN (fixup_segment, (fixP, 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 + 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 (!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); - fixP->fx_subsy = 0; - - /* if sub_symbol is in the same segment that add_symbol + 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); + fixP->fx_subsy = 0; + + /* 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. */ + } + 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 + /* 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); - } 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 sub_symbolP */ - - if (add_symbolP) { - if (add_symbol_segment == this_segment_type && pcrel) { - /* + 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); + } + 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 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', + /* 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: + 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: #ifdef TC_I960 - 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: + 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: #ifdef TC_I960 - if ((int)fixP->fx_bit_fixP == 13) { - /* This is a COBR instruction. They have only a + 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 */ + as_bad ("can't use COBR format with external label"); + fixP->fx_addsy = NULL; /* No relocations please. */ + continue; + } /* COBR */ +#endif /* TC_I960 */ #ifdef TC_I386 - /* 386 COFF uses a peculiar format in + /* 386 COFF uses a peculiar format in which the value of a common symbol is stored in the .text segment (I've checked this on SVR3.2 and SCO 3.2.2) Ian Taylor . */ - add_number += S_GET_VALUE(add_symbolP); + add_number += S_GET_VALUE (add_symbolP); #endif - 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 */ + 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 */ #ifdef WARN_SIGNED_OVERFLOW_WORD - /* Warn if a .word value is too large when treated as + /* Warn if a .word value is too large when treated as a signed number. We already know it is not too negative. This is to catch over-large switches generated by gcc on the 68k. */ - if (! flagseen['J'] - && size == 2 - && add_number > 0x7fff) - as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x", - add_number, fragP->fr_address + where); + if (!flagseen['J'] + && size == 2 + && add_number > 0x7fff) + as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x", + add_number, fragP->fr_address + where); #endif - } /* not a bit fix */ - /* once this fix has been applied, we don't have to output anything + } /* 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 + md_apply_fix (fixP, add_number); + } /* For each fixS in this segment. */ +} /* fixup_segment() */ +#endif diff --git a/gas/config/obj-coffbfd.h b/gas/config/obj-coffbfd.h index ad8b5d44c43..5e9802720d7 100644 --- a/gas/config/obj-coffbfd.h +++ b/gas/config/obj-coffbfd.h @@ -1,18 +1,22 @@ + + + + /* coff object file format Copyright (C) 1989, 1990, 1991, 1992 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. */ @@ -69,32 +73,32 @@ #else help me #endif - + #if 0 - /* Define some processor dependent values according to the processor we are +/* 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 #elif defined(TC_M68K) -#define BYTE_ORDERING F_AR32W /* See filehdr.h for more info. */ +#define BYTE_ORDERING F_AR32W /* See filehdr.h for more info. */ #ifndef FILE_HEADER_MAGIC -#define FILE_HEADER_MAGIC MC68MAGIC /* ... */ +#define FILE_HEADER_MAGIC MC68MAGIC /* ... */ #endif /* FILE_HEADER_MAGIC */ #elif defined(TC_I386) -#define BYTE_ORDERING F_AR32WR /* See filehdr.h for more info. */ +#define BYTE_ORDERING F_AR32WR /* See filehdr.h for more info. */ #ifndef FILE_HEADER_MAGIC -#define FILE_HEADER_MAGIC I386MAGIC /* ... */ +#define FILE_HEADER_MAGIC I386MAGIC /* ... */ #endif /* FILE_HEADER_MAGIC */ #elif defined(TC_I960) -#define BYTE_ORDERING F_AR32WR /* See filehdr.h for more info. */ +#define BYTE_ORDERING F_AR32WR /* See filehdr.h for more info. */ #ifndef FILE_HEADER_MAGIC -#define FILE_HEADER_MAGIC I960ROMAGIC /* ... */ +#define FILE_HEADER_MAGIC I960ROMAGIC /* ... */ #endif /* FILE_HEADER_MAGIC */ #elif defined(TC_A29K) @@ -104,17 +108,17 @@ help me #define FILE_HEADER_MAGIC SIPFBOMAGIC #endif /* FILE_HEADER_MAGIC */ #else -you lose -#endif - + 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 @@ -129,13 +133,15 @@ you lose /* Symbol table entry data type */ -typedef struct +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 */ -} obj_symbol_type; + 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 #define DO_NOT_STRIP 0 @@ -143,7 +149,7 @@ typedef struct #endif /* Symbol table macros and constants */ -/* Possible and usefull section number in symbol table +/* Possible and usefull section number in symbol table * The values of TEXT, DATA and BSS may not be portable. */ @@ -194,7 +200,7 @@ typedef struct /* The zeroes if symbol name is longer than 8 chars */ #define S_GET_ZEROES(s) ((s)->sy_symbol.ost_entry.n_zeroes) /* The value of the symbol */ -#define S_GET_VALUE(s) ((unsigned) ((s)->sy_symbol.ost_entry.n_value)) +#define S_GET_VALUE(s) ((unsigned) ((s)->sy_symbol.ost_entry.n_value)) /* The numeric value of the segment */ #define S_GET_SEGMENT(s) s_get_segment(s) /* The data type */ @@ -280,27 +286,27 @@ typedef struct * differently. */ -#define SF_I960_MASK (0x000001ff) /* Bits 0-8 are used by the i960 port. */ -#define SF_SYSPROC (0x0000003f) /* bits 0-5 are used to store the sysproc number */ -#define SF_IS_SYSPROC (0x00000040) /* bit 6 marks symbols that are sysprocs */ -#define SF_BALNAME (0x00000080) /* bit 7 marks BALNAME symbols */ -#define SF_CALLNAME (0x00000100) /* bit 8 marks CALLNAME symbols */ +#define SF_I960_MASK (0x000001ff) /* Bits 0-8 are used by the i960 port. */ +#define SF_SYSPROC (0x0000003f) /* bits 0-5 are used to store the sysproc number */ +#define SF_IS_SYSPROC (0x00000040) /* bit 6 marks symbols that are sysprocs */ +#define SF_BALNAME (0x00000080) /* bit 7 marks BALNAME symbols */ +#define SF_CALLNAME (0x00000100) /* bit 8 marks CALLNAME symbols */ -#define SF_NORMAL_MASK (0x0000ffff) /* bits 12-15 are general purpose. */ +#define SF_NORMAL_MASK (0x0000ffff) /* bits 12-15 are general purpose. */ -#define SF_STATICS (0x00001000) /* Mark the .text & all symbols */ -#define SF_DEFINED (0x00002000) /* Symbol is defined in this file */ -#define SF_STRING (0x00004000) /* Symbol name length > 8 */ -#define SF_LOCAL (0x00008000) /* Symbol must not be emitted */ +#define SF_STATICS (0x00001000) /* Mark the .text & all symbols */ +#define SF_DEFINED (0x00002000) /* Symbol is defined in this file */ +#define SF_STRING (0x00004000) /* Symbol name length > 8 */ +#define SF_LOCAL (0x00008000) /* Symbol must not be emitted */ -#define SF_DEBUG_MASK (0xffff0000) /* bits 16-31 are debug info */ +#define SF_DEBUG_MASK (0xffff0000) /* bits 16-31 are debug info */ -#define SF_FUNCTION (0x00010000) /* The symbol is a function */ -#define SF_PROCESS (0x00020000) /* Process symbol before write */ -#define SF_TAGGED (0x00040000) /* Is associated with a tag */ -#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. */ +#define SF_FUNCTION (0x00010000) /* The symbol is a function */ +#define SF_PROCESS (0x00020000) /* Process symbol before write */ +#define SF_TAGGED (0x00040000) /* Is associated with a tag */ +#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. */ /* Accessors */ @@ -318,11 +324,11 @@ typedef struct #define SF_GET_TAGGED(s) ((s)->sy_symbol.ost_flags & SF_TAGGED) #define SF_GET_TAG(s) ((s)->sy_symbol.ost_flags & SF_TAG) #define SF_GET_GET_SEGMENT(s) ((s)->sy_symbol.ost_flags & SF_GET_SEGMENT) -#define SF_GET_I960(s) ((s)->sy_symbol.ost_flags & SF_I960_MASK) /* used by i960 */ -#define SF_GET_BALNAME(s) ((s)->sy_symbol.ost_flags & SF_BALNAME) /* used by i960 */ -#define SF_GET_CALLNAME(s) ((s)->sy_symbol.ost_flags & SF_CALLNAME) /* used by i960 */ -#define SF_GET_IS_SYSPROC(s) ((s)->sy_symbol.ost_flags & SF_IS_SYSPROC) /* used by i960 */ -#define SF_GET_SYSPROC(s) ((s)->sy_symbol.ost_flags & SF_SYSPROC) /* used by i960 */ +#define SF_GET_I960(s) ((s)->sy_symbol.ost_flags & SF_I960_MASK) /* used by i960 */ +#define SF_GET_BALNAME(s) ((s)->sy_symbol.ost_flags & SF_BALNAME) /* used by i960 */ +#define SF_GET_CALLNAME(s) ((s)->sy_symbol.ost_flags & SF_CALLNAME) /* used by i960 */ +#define SF_GET_IS_SYSPROC(s) ((s)->sy_symbol.ost_flags & SF_IS_SYSPROC) /* used by i960 */ +#define SF_GET_SYSPROC(s) ((s)->sy_symbol.ost_flags & SF_SYSPROC) /* used by i960 */ /* Modifiers */ #define SF_SET(s,v) ((s)->sy_symbol.ost_flags = (v)) @@ -340,11 +346,11 @@ typedef struct #define SF_SET_TAGGED(s) ((s)->sy_symbol.ost_flags |= SF_TAGGED) #define SF_SET_TAG(s) ((s)->sy_symbol.ost_flags |= SF_TAG) #define SF_SET_GET_SEGMENT(s) ((s)->sy_symbol.ost_flags |= SF_GET_SEGMENT) -#define SF_SET_I960(s,v) ((s)->sy_symbol.ost_flags |= ((v) & SF_I960_MASK)) /* used by i960 */ -#define SF_SET_BALNAME(s) ((s)->sy_symbol.ost_flags |= SF_BALNAME) /* used by i960 */ -#define SF_SET_CALLNAME(s) ((s)->sy_symbol.ost_flags |= SF_CALLNAME) /* used by i960 */ -#define SF_SET_IS_SYSPROC(s) ((s)->sy_symbol.ost_flags |= SF_IS_SYSPROC) /* used by i960 */ -#define SF_SET_SYSPROC(s,v) ((s)->sy_symbol.ost_flags |= ((v) & SF_SYSPROC)) /* used by i960 */ +#define SF_SET_I960(s,v) ((s)->sy_symbol.ost_flags |= ((v) & SF_I960_MASK)) /* used by i960 */ +#define SF_SET_BALNAME(s) ((s)->sy_symbol.ost_flags |= SF_BALNAME) /* used by i960 */ +#define SF_SET_CALLNAME(s) ((s)->sy_symbol.ost_flags |= SF_CALLNAME) /* used by i960 */ +#define SF_SET_IS_SYSPROC(s) ((s)->sy_symbol.ost_flags |= SF_IS_SYSPROC) /* used by i960 */ +#define SF_SET_SYSPROC(s,v) ((s)->sy_symbol.ost_flags |= ((v) & SF_SYSPROC)) /* used by i960 */ /* File header macro and type definition */ @@ -451,79 +457,85 @@ typedef struct /* Segment flipping */ #define segment_name(v) (seg_name[(int) (v)]) -typedef struct { +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; + } + +object_headers; 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 */ -typedef struct { - unsigned long chunk_size; - unsigned long element_size; - unsigned long size; - char* data; - unsigned long pointer; -} stack; +typedef struct + { + unsigned long chunk_size; + unsigned long element_size; + unsigned long size; + char *data; + unsigned long pointer; + } + +stack; + +char *EXFUN (stack_pop, (stack * st)); +char *EXFUN (stack_push, (stack * st, char *element)); +char *EXFUN (stack_top, (stack * st)); +stack *EXFUN (stack_init, (unsigned long chunk_size, unsigned long element_size)); +void EXFUN (c_dot_file_symbol, (char *filename)); +void EXFUN (obj_extra_stuff, (object_headers * headers)); +void EXFUN (stack_delete, (stack * st)); -char *EXFUN(stack_pop,(stack *st)); -char *EXFUN(stack_push,(stack *st, char *element)); -char *EXFUN(stack_top,(stack *st)); -stack *EXFUN(stack_init,(unsigned long chunk_size, unsigned long element_size)); -void EXFUN(c_dot_file_symbol,(char *filename)); -void EXFUN(obj_extra_stuff,(object_headers *headers)); -void EXFUN(stack_delete,(stack *st)); +void EXFUN (c_section_header, ( -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 */ #ifdef TC_I960 #ifndef C_LEAFSTAT -hey! Where is the C_LEAFSTAT definition? i960-coff support is depending on it. +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; diff --git a/gas/config/obj-generic.c b/gas/config/obj-generic.c index a91eff9aac7..2f69ce41960 100644 --- a/gas/config/obj-generic.c +++ b/gas/config/obj-generic.c @@ -1,20 +1,20 @@ /* This file is obj-generic.c and is intended to be a template for - object format specific source files. + object format specific source files. Copyright (C) 1987-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. */ diff --git a/gas/config/obj-generic.h b/gas/config/obj-generic.h index 8dec4bf2af4..6c89aef4567 100644 --- a/gas/config/obj-generic.h +++ b/gas/config/obj-generic.h @@ -1,25 +1,25 @@ /* This file is obj-generic.h Copyright (C) 1987-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 obj-generic.h and is intended to be a template for - * object format specific header files. + * object format specific header files. */ /* define an obj specific macro off which target cpu back ends may key. */ @@ -43,32 +43,35 @@ /* #define SYMBOLS_NEED_PACKPOINTERS */ /* */ -typedef struct { - void *nothing; -} obj_symbol_type; /* should be the format's symbol structure */ +typedef struct + { + void *nothing; + } + +obj_symbol_type; /* should be the format's symbol structure */ typedef void *object_headers; /* symbols have names */ -#define S_GET_NAME(s) ("foo") /* get the name of a symbolP */ +#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) -#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */ +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */ -#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */ +#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */ /* * Local Variables: diff --git a/gas/config/obj-ieee.c b/gas/config/obj-ieee.c index d8a35308353..3e1965c8530 100644 --- a/gas/config/obj-ieee.c +++ b/gas/config/obj-ieee.c @@ -1,26 +1,26 @@ /* obj-format for ieee-695 records. 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. */ -/* +/* created by - + steve chamberlain steve@cygnus.com */ @@ -38,385 +38,443 @@ bfd *abfd; /* 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_align() */ +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_align() */ /* calculate the size of the frag chain and create a bfd section to contain all of it */ -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; +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; } - 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); + 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 */ -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; +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; } + } } /* Count the relocations in a chain */ -static unsigned int DEFUN(count_entries_in_chain,(idx), - unsigned int 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 || +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. - + 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; + 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; } - - /* attatch to the section */ - section->orelocation = reloc_ptr_vector; - section->reloc_count = nrelocs; - section->flags |= SEC_LOAD; - } + } + 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) +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)) + { + 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) { - 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++; + ptr->sy_symbol.sy.flags = BSF_LOCAL; } - symbol_ptr_vec = (asymbol **)malloc((count+1) * sizeof(asymbol *)); - - index = 0; - for (ptr = symbol_rootP; - ptr != (symbolS *)NULL; - ptr = ptr->sy_next) + } + else + { + switch (ptr->sy_symbol.seg) { - symbol_ptr_vec[index] = &(ptr->sy_symbol.sy); - index++; + 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 (); } - symbol_ptr_vec[index] =0; - abfd->outsymbols = symbol_ptr_vec; - abfd->symcount = count; + } + 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 code */ -void DEFUN_VOID(bfd_as_write_hook) +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); + } -S_GET_VALUE(x) -symbolS *x; +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; +S_SET_SEGMENT (x, y) + symbolS *x; + int y; +{ + x->sy_symbol.seg = y; } -S_IS_DEFINED(x) -symbolS *x; +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 (); } -S_IS_EXTERNAL(x) { abort(); } -S_GET_DESC(x) { abort() ; } +S_GET_DESC (x) +{ + abort (); +} + +S_GET_SEGMENT (x) + symbolS *x; +{ + return x->sy_symbol.seg; +} -S_GET_SEGMENT(x) -symbolS *x; -{ return x->sy_symbol.seg; } +S_SET_EXTERNAL (x) + symbolS *x; +{ + x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT; +} -S_SET_EXTERNAL(x) -symbolS *x; +S_SET_NAME (x, y) + symbolS *x; + char *y; { - x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT; + x->sy_symbol.sy.name = y; } -S_SET_NAME(x,y) -symbolS*x; -char *y; { - x->sy_symbol.sy.name = y; } +S_SET_VALUE (s, v) + symbolS *s; + long v; +{ + s->sy_symbol.sy.value = v; +} -S_SET_VALUE(s,v) -symbolS *s; -long v; -{ - s->sy_symbol.sy.value = v; +S_GET_OTHER (x) +{ + abort (); } -S_GET_OTHER(x) { abort() ;} -S_IS_DEBUG(x) { abort(); } +S_IS_DEBUG (x) +{ + abort (); +} -char *segment_name() { abort(); } +char * +segment_name () +{ + abort (); +} -void obj_read_begin_hook() { } +void +obj_read_begin_hook () +{ +} -static void obj_ieee_section(ignore) -int ignore; +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; - - } - } - else break; - } - if (i == SEG_UNKNOWN) { - as_bad("too many sections"); - return; + 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; + + } } - - 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; - + 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; +ok: + subseg_new (i, 0); + while (!is_end_of_line[*p]) + p++; + input_line_pointer = p; + } -void cons(); -void s_ignore(); +void cons (); +void s_ignore (); /* @@ -427,29 +485,30 @@ void s_ignore(); * Caller should have checked need_pass_2 is FALSE because we don't check it. */ -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, - +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, + }; -void obj_symbol_new_hook(symbolP) -symbolS *symbolP; +void +obj_symbol_new_hook (symbolP) + symbolS *symbolP; { - symbolP->sy_symbol.sy.the_bfd = abfd; + symbolP->sy_symbol.sy.the_bfd = abfd; } @@ -457,83 +516,118 @@ 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 +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); + + 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 + 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; + 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; - } - - -#endif - } - - for (i = SEG_E0; i < SEG_UNKNOWN; i++) { - relax_segment(segment_info[i].frag_root, i); + /* 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; } - - /* Now the addresses of the frags are correct within the segment */ - - bfd_as_write_hook(); - bfd_close(abfd); + + +#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); } #endif -H_SET_TEXT_SIZE(a,b) { abort(); } -H_GET_TEXT_SIZE() { abort(); } -H_SET_BSS_SIZE() { abort(); } -H_SET_STRING_SIZE() { abort(); } -H_SET_RELOCATION_SIZE() { abort(); } -H_SET_MAGIC_NUMBER() { abort(); } -H_GET_FILE_SIZE() { abort(); } -H_GET_TEXT_RELOCATION_SIZE() { abort(); } +H_SET_TEXT_SIZE (a, b) +{ + abort (); +} + +H_GET_TEXT_SIZE () +{ + abort (); +} + +H_SET_BSS_SIZE () +{ + abort (); +} + +H_SET_STRING_SIZE () +{ + abort (); +} + +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/obj-ieee.h b/gas/config/obj-ieee.h index 3baa0811826..a5cdbf6bc03 100644 --- a/gas/config/obj-ieee.h +++ b/gas/config/obj-ieee.h @@ -1,19 +1,19 @@ /* This file is obj-ieee.h Copyright (C) 1987-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. */ @@ -22,17 +22,21 @@ #include -typedef struct +typedef struct { -asymbol sy; -int seg; -} obj_symbol_type; + asymbol sy; + int seg; +} + +obj_symbol_type; #define S_GET_NAME(s) (((s)->sy_symbol.sy.name)) -typedef struct { -int x; -} +typedef struct + { + int x; + } + object_headers; #define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 1 diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c index a04cea12392..23d8228533e 100644 --- a/gas/config/tc-a29k.c +++ b/gas/config/tc-a29k.c @@ -1,18 +1,18 @@ /* tc-a29k.c -- Assemble for the AMD 29000. Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -32,7 +32,8 @@ #define machine_ip a29k_ip #define machine_it a29k_it -const relax_typeS md_relax_table[] = { 0 }; +const relax_typeS md_relax_table[] = +{0}; #define IMMEDIATE_BIT 0x01000000 /* Turns RB into Immediate */ #define ABSOLUTE_BIT 0x01000000 /* Turns PC-relative to Absolute */ @@ -42,52 +43,56 @@ const relax_typeS md_relax_table[] = { 0 }; /* handle of the OPCODE hash table */ 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 */ +struct machine_it + { + char *error; + unsigned long opcode; + struct nlist *nlistp; + expressionS exp; + int pcrel; + int reloc_offset; /* Offset of reloc within insn */ + + int reloc; - int reloc; + } -} the_insn; +the_insn; #if __STDC__ == 1 /* static int getExpression(char *str); */ -static void machine_ip(char *str); +static void machine_ip (char *str); /* static void print_insn(struct machine_it *insn); */ -static void s_data1(void); -static void s_use(void); +static void s_data1 (void); +static void s_use (void); #else /* not __STDC__ */ /* static int getExpression(); */ -static void machine_ip(); +static void machine_ip (); /* static void print_insn(); */ -static void s_data1(); -static void s_use(); +static void s_data1 (); +static void s_use (); #endif /* not __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 */ + 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 */ #ifndef OBJ_COFF - /* We can do this right with coff */ - { "use", s_use, 0 }, +/* We can do this right with coff */ + {"use", s_use, 0}, #endif - { "word", cons, 4 }, - { NULL, 0, 0 }, - }; + {"word", cons, 4}, + {NULL, 0, 0}, +}; int md_short_jump_size = 4; int md_long_jump_size = 4; @@ -133,535 +138,580 @@ 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]; /* - * anull bit - causes the branch delay slot instructions to not be executed + * anull bit - causes the branch delay slot instructions to not be executed */ #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 + + 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; + 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; } 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 + /* FIXME-SOON, put something in these syms so they won't be output to the symbol table of the resulting object file. */ - - /* Must be large enough to hold the names of the special registers. */ - char buf[80]; - int i; - - symbol_table_insert(symbol_new(regname, SEG_REGISTER, regnum, &zero_address_frag)); - for (i = 0; regname[i]; i++) - buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i]; - buf[i] = '\0'; - - symbol_table_insert(symbol_new(buf, SEG_REGISTER, regnum, &zero_address_frag)); -} /* insert_sreg() */ + + /* Must be large enough to hold the names of the special registers. */ + char buf[80]; + int i; + + symbol_table_insert (symbol_new (regname, SEG_REGISTER, regnum, &zero_address_frag)); + for (i = 0; regname[i]; i++) + buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i]; + buf[i] = '\0'; + + symbol_table_insert (symbol_new (buf, SEG_REGISTER, regnum, &zero_address_frag)); +} /* insert_sreg() */ /* Install symbol definitions for assorted special registers. See ASM29K Ref page 2-9. */ -void define_some_regs() { +void +define_some_regs () +{ #define SREG 256 - - /* Protected special-purpose register names */ - insert_sreg ("vab", SREG+0); - insert_sreg ("ops", SREG+1); - insert_sreg ("cps", SREG+2); - insert_sreg ("cfg", SREG+3); - insert_sreg ("cha", SREG+4); - insert_sreg ("chd", SREG+5); - insert_sreg ("chc", SREG+6); - insert_sreg ("rbp", SREG+7); - insert_sreg ("tmc", SREG+8); - insert_sreg ("tmr", SREG+9); - insert_sreg ("pc0", SREG+10); - insert_sreg ("pc1", SREG+11); - insert_sreg ("pc2", SREG+12); - insert_sreg ("mmu", SREG+13); - insert_sreg ("lru", SREG+14); - - /* Unprotected special-purpose register names */ - insert_sreg ("ipc", SREG+128); - insert_sreg ("ipa", SREG+129); - insert_sreg ("ipb", SREG+130); - insert_sreg ("q", SREG+131); - insert_sreg ("alu", SREG+132); - insert_sreg ("bp", SREG+133); - insert_sreg ("fc", SREG+134); - insert_sreg ("cr", SREG+135); - insert_sreg ("fpe", SREG+160); - insert_sreg ("inte",SREG+161); - insert_sreg ("fps", SREG+162); - /* "", SREG+163); Reserved */ - insert_sreg ("exop",SREG+164); -} /* define_some_regs() */ + + /* Protected special-purpose register names */ + insert_sreg ("vab", SREG + 0); + insert_sreg ("ops", SREG + 1); + insert_sreg ("cps", SREG + 2); + insert_sreg ("cfg", SREG + 3); + insert_sreg ("cha", SREG + 4); + insert_sreg ("chd", SREG + 5); + insert_sreg ("chc", SREG + 6); + insert_sreg ("rbp", SREG + 7); + insert_sreg ("tmc", SREG + 8); + insert_sreg ("tmr", SREG + 9); + insert_sreg ("pc0", SREG + 10); + insert_sreg ("pc1", SREG + 11); + insert_sreg ("pc2", SREG + 12); + insert_sreg ("mmu", SREG + 13); + insert_sreg ("lru", SREG + 14); + + /* Unprotected special-purpose register names */ + insert_sreg ("ipc", SREG + 128); + insert_sreg ("ipa", SREG + 129); + insert_sreg ("ipb", SREG + 130); + insert_sreg ("q", SREG + 131); + insert_sreg ("alu", SREG + 132); + insert_sreg ("bp", SREG + 133); + insert_sreg ("fc", SREG + 134); + insert_sreg ("cr", SREG + 135); + insert_sreg ("fpe", SREG + 160); + insert_sreg ("inte", SREG + 161); + insert_sreg ("fps", SREG + 162); + /* "", SREG+163); Reserved */ + insert_sreg ("exop", SREG + 164); +} /* 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 + 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 (!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; } - - 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 (); + + /* 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; +void +md_end () +{ + return; } /* Assemble a single instruction. Its label has already been handled by the generic front end. We just parse opcode and operands, and produce the bytes of data and relocation. */ -void md_assemble(str) -char *str; +void +md_assemble (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; - if (seg == SEG_ABSENT) - as_bad("Missing operand"); + if (seg == SEG_ABSENT) + as_bad ("Missing operand"); return new; } -/* Instruction parsing. Takes a string containing the opcode. +/* 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; - memset(&the_insn, '\0', sizeof(the_insn)); - the_insn.reloc = NO_RELOC; - - /* + 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; + memset (&the_insn, '\0', 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 + 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 */ - - /* + 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 + 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); + 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; } - /* Types or values of args don't match. */ - as_bad("Invalid operands"); - return; + } + 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); } + /* 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. @@ -671,296 +721,318 @@ char *str; #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; +void +md_apply_fix (fixP, 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); - - /* + 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 (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; +short +tc_coff_fix2rtype (fixP) + fixS *fixP; { - - switch (fixP->fx_r_type) { - case RELOC_32: return(R_WORD); - case RELOC_8: return(R_BYTE); - case RELOC_CONST: return (R_ILOHALF); - case RELOC_CONSTH: return (R_IHIHALF); - case RELOC_JUMPTARG: return (R_IREL); - default: printf("need %o3\n", fixP->fx_r_type); - abort(); - } /* switch on type */ - - return(0); -} /* tc_coff_fix2rtype() */ + + switch (fixP->fx_r_type) + { + case RELOC_32: + return (R_WORD); + case RELOC_8: + return (R_BYTE); + case RELOC_CONST: + return (R_ILOHALF); + case RELOC_CONSTH: + return (R_IHIHALF); + case RELOC_JUMPTARG: + return (R_IREL); + default: + printf ("need %o3\n", fixP->fx_r_type); + abort (); + } /* 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; -fragS *frag; -symbolS *to_symbol; +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; { - 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; +void +md_convert_frag (headers, fragP) + object_headers *headers; + 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; -long to_addr; -fragS *frag; -symbolS *to_symbol; +void +md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) + char *ptr; + long from_addr; + long to_addr; + fragS *frag; + symbolS *to_symbol; { - as_fatal("sparc_create_long_jump\n"); + as_fatal ("sparc_create_long_jump\n"); } /* should never be called for a29k */ -int md_estimate_size_before_relax(fragP, segtype) -register fragS *fragP; -segT segtype; +int +md_estimate_size_before_relax (fragP, segtype) + register fragS *fragP; + segT segtype; { - as_fatal("sparc_estimate_size_before_relax\n"); - return(0); + as_fatal ("sparc_estimate_size_before_relax\n"); + return (0); } #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 @@ -969,43 +1041,44 @@ struct machine_it *insn; #ifdef OBJ_AOUT -void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) -char *where; -fixS *fixP; -relax_addressT segment_address_in_file; +void +tc_aout_fix_to_chars (where, fixP, segment_address_in_file) + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; { - long r_symbolnum; - - know(fixP->fx_r_type < NO_RELOC); - know(fixP->fx_addsy != NULL); - - md_number_to_chars(where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); - - r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy) - ? S_GET_TYPE(fixP->fx_addsy) - : fixP->fx_addsy->sy_number); - - where[4] = (r_symbolnum >> 16) & 0x0ff; - where[5] = (r_symbolnum >> 8) & 0x0ff; - where[6] = r_symbolnum & 0x0ff; - 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() */ + long r_symbolnum; + + know (fixP->fx_r_type < NO_RELOC); + know (fixP->fx_addsy != NULL); + + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + + where[4] = (r_symbolnum >> 16) & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[6] = r_symbolnum & 0x0ff; + 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); } @@ -1013,82 +1086,85 @@ char ***vecP; don't bother to predefine them unless you actually use one, since there are a lot of them. */ -symbolS *md_undefined_symbol (name) -char *name; +symbolS * +md_undefined_symbol (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 + 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; + 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; +void +md_operand (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 + + 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; - } + 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; +long +md_pcrel_from (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 80a4a1a706e..0cdaf95392f 100644 --- a/gas/config/tc-a29k.h +++ b/gas/config/tc-a29k.h @@ -19,16 +19,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define TC_A29K -#define tc_headers_hook(a) ; /* not used */ -#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 tc_headers_hook(a) ; /* not used */ +#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 ? +/* 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 */ @@ -37,4 +37,3 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define COFF_FLAGS F_AR32W #define reloc_type int - diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index b3201dc55ff..7bd6309f15a 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1,18 +1,18 @@ /* i386.c -- Assemble code for the Intel 80386 Copyright (C) 1989, 1991, 1992 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. */ @@ -27,6 +27,7 @@ #include #include "as.h" +#include "read.h" #include "obstack.h" #include "opcode/i386.h" @@ -34,56 +35,59 @@ /* '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 +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 + 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 + 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 + 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. */ - const seg_entry *seg; /* segment for memory operands (if given) */ - - /* PREFIX holds all the given prefix opcodes (usually null). + const seg_entry *seg; /* segment for memory operands (if given) */ + + /* PREFIX holds all the given prefix opcodes (usually null). PREFIXES is the size of PREFIX. */ - /* richfix: really unsigned? */ - unsigned char prefix[MAX_PREFIXES]; - unsigned int prefixes; - - /* RM and IB are the modrm byte and the base index byte where the addressing + /* richfix: really unsigned? */ + unsigned 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; + + modrm_byte rm; + base_index_byte bi; + } + +i386_insn; /* This array holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful */ @@ -97,7 +101,8 @@ const char comment_chars[] = "#"; #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. */ +const char line_comment_chars[] = "/"; /* removed '#' xoxorich. */ +const char line_separator_chars[] = ""; /* Chars that can be used to separate mant from exp in floating point nums */ const char EXP_CHARS[] = "eE"; @@ -126,7 +131,8 @@ static char digit_chars[256]; /* put here all non-digit non-letter charcters that may occur in an operand */ static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:"; -static char *ordinal_names[] = { "first", "second", "third" }; /* for printfs */ +static char *ordinal_names[] = +{"first", "second", "third"}; /* for printfs */ /* md_assemble() always leaves the strings it's passed unaltered. To effect this we maintain a stack of saved characters that we've smashed @@ -136,9 +142,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]; @@ -168,92 +174,95 @@ static int this_operand; /* current operand we are working on */ #define SIZE_FROM_RELAX_STATE(s) \ ( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) ) -const relax_typeS md_relax_table[] = { - /* +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 + {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: + {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: + {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: + {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: + {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}, - + {0, 0, 3, 0}, + {1, 1, 0, 0}, + }; #if __STDC__ == 1 -static char *output_invalid(int c); -static int fits_in_signed_byte(long num); -static int fits_in_signed_word(long num); -static int fits_in_unsigned_byte(long num); -static int fits_in_unsigned_word(long num); -static int i386_operand(char *operand_string); -static int smallest_imm_type(long num); -static reg_entry *parse_register(char *reg_string); -static unsigned long mode_from_disp_size(unsigned long t); -static unsigned long opcode_suffix_to_type(unsigned long s); -static void s_bss(void); +static char *output_invalid (int c); +static int fits_in_signed_byte (long num); +static int fits_in_signed_word (long num); +static int fits_in_unsigned_byte (long num); +static int fits_in_unsigned_word (long num); +static int i386_operand (char *operand_string); +static int smallest_imm_type (long num); +static reg_entry *parse_register (char *reg_string); +static unsigned long mode_from_disp_size (unsigned long t); +static unsigned long opcode_suffix_to_type (unsigned long s); +static void s_bss (void); #else /* not __STDC__ */ -static char *output_invalid(); -static int fits_in_signed_byte(); -static int fits_in_signed_word(); -static int fits_in_unsigned_byte(); -static int fits_in_unsigned_word(); -static int i386_operand(); -static int smallest_imm_type(); -static reg_entry *parse_register(); -static unsigned long mode_from_disp_size(); -static unsigned long opcode_suffix_to_type(); -static void s_bss(); +static char *output_invalid (); +static int fits_in_signed_byte (); +static int fits_in_signed_word (); +static int fits_in_unsigned_byte (); +static int fits_in_unsigned_word (); +static int i386_operand (); +static int smallest_imm_type (); +static reg_entry *parse_register (); +static unsigned long mode_from_disp_size (); +static unsigned long opcode_suffix_to_type (); +static void s_bss (); #endif /* not __STDC__ */ /* Ignore certain directives generated by gcc. This probably should not be here. */ -void dummy () +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[] = { - { "bss", s_bss, 0 }, - { "align", s_align_bytes, 0 }, - { "ffloat", float_cons, 'f' }, - { "dfloat", float_cons, 'd' }, - { "tfloat", float_cons, 'x' }, - { "value", cons, 2 }, - { 0, 0, 0 } +const pseudo_typeS md_pseudo_table[] = +{ + {"bss", s_bss, 0}, + {"align", s_align_bytes, 0}, + {"ffloat", float_cons, 'f'}, + {"dfloat", float_cons, 'd'}, + {"tfloat", float_cons, 'x'}, + {"value", cons, 2}, + {0, 0, 0} }; /* for interface with expression () */ -extern char * input_line_pointer; +extern char *input_line_pointer; /* obstack for constructing various things in md_begin */ struct obstack o; @@ -264,223 +273,283 @@ static struct hash_control *op_hash = (struct hash_control *) 0; static struct hash_control *reg_hash = (struct hash_control *) 0; /* hash table for prefix lookup */ static struct hash_control *prefix_hash = (struct hash_control *) 0; - -void md_begin () + +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; + 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 + /* 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; - - memset(opcode_chars, '\0', sizeof(opcode_chars)); - memset(operand_chars, '\0', sizeof(operand_chars)); - memset(space_chars, '\0', sizeof(space_chars)); - memset(identifier_chars, '\0', sizeof(identifier_chars)); - memset(digit_chars, '\0', 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; - } - } + 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; + + memset (opcode_chars, '\0', sizeof (opcode_chars)); + memset (operand_chars, '\0', sizeof (operand_chars)); + memset (space_chars, '\0', sizeof (space_chars)); + memset (identifier_chars, '\0', sizeof (identifier_chars)); + memset (digit_chars, '\0', 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. */ - +void +md_end () +{ +} /* not much to do here. */ + #ifdef DEBUG386 /* debugging routines for md_assemble */ /* static void pi (), pte (), pt (), pe (), ps (); */ -static void pi (line, x) -char * line; -i386_insn *x; +static void +pi (line, 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; +static void +pte (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; +static void +pe (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; +static void +ps (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; -} 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, "" } +struct type_name + { + 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, "" } }; -static void pt (t) -unsigned int t; +static void +pt (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 */ @@ -490,196 +559,236 @@ unsigned int t; machine dependent instruction. This funciton is supposed to emit the frags/bytes it assembles to. */ -void md_assemble (line) -char *line; +void +md_assemble (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. */ - memset(&i, '\0', sizeof(i)); - memset(disp_expressions, '\0', sizeof(disp_expressions)); - memset(im_expressions, '\0', 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 + /* Holds temlate once we've found it. */ + register template *t; + + /* Possible templates for current insn */ + templates *current_templates = (templates *) 0; + + /* Initialize globals. */ + memset (&i, '\0', sizeof (i)); + memset (disp_expressions, '\0', sizeof (disp_expressions)); + memset (im_expressions, '\0', 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; + { + 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; } - - /* Lookup insn in hash; try intel & att naming conventions if appropriate; + 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 + 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 */ - } - } - - /* Now we've parsed the opcode into a set of templates, and have the + !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 */ + } + } + + /* 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 + + /* 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)) ) ? @@ -697,910 +806,1105 @@ char *line; ( ((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])) { - 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: + + /* 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!). */ - memcpy(&i.tm, t, sizeof(template)); - t = &i.tm; /* alter new copy of template */ - - /* If there's no opcode suffix we try to invent one based on register + } + 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!). */ + memcpy (&i.tm, t, 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 + 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 + 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 + 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 + + 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 + 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; - } - - /* + + 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 + 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. + 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 + 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; + + /* 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/ + 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) { - /* (%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. + 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) + { + /* (%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. + 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> (,) -- no base register with disp Case 3: (, ) --- 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 + 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) { - 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 + 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) + { + 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 (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 + 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 + 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); + 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. + } + 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, + /* 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. */ - unsigned 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) + 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. */ + unsigned 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 */ - } - + 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; +static int +i386_operand (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 = NULL; - char *displacement_string_end = NULL; - - /* We check for an absolute prefix (differentiating, + 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 = NULL; + char *displacement_string_end = NULL; + + /* 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; + 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 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 + /* Check for segment override, rather than segment register by searching for ':' after %s where = s, c, d, e, f, g. */ - if ((r->reg_type & (SReg2|SReg3)) && op_string[3] == ':') { - switch (r->reg_num) { - case 0: - i.seg = (seg_entry *) &es; break; - case 1: - i.seg = (seg_entry *) &cs; break; - case 2: - i.seg = (seg_entry *) &ss; break; - case 3: - i.seg = (seg_entry *) &ds; break; - case 4: - i.seg = (seg_entry *) &fs; break; - case 5: - i.seg = (seg_entry *) &gs; break; - } - op_string += 4; /* skip % 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; - segT exp_seg = SEG_GOOF; - expressionS *exp; - - if (i.imm_operands == MAX_IMMEDIATE_OPERANDS) { - as_bad("only 1 or 2 immediate operands are allowed"); - return 0; - } + if ((r->reg_type & (SReg2 | SReg3)) && op_string[3] == ':') + { + switch (r->reg_num) + { + case 0: + i.seg = (seg_entry *) & es; + break; + case 1: + i.seg = (seg_entry *) & cs; + break; + case 2: + i.seg = (seg_entry *) & ss; + break; + case 3: + i.seg = (seg_entry *) & ds; + break; + case 4: + i.seg = (seg_entry *) & fs; + break; + case 5: + i.seg = (seg_entry *) & gs; + break; + } + op_string += 4; /* skip % 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; + segT exp_seg = SEG_GOOF; + expressionS *exp; + + 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 + 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; + 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 + 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, + 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 + 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 + 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 (*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; } - - /* 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 = SEG_GOOF; - 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; - } + 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; } - - /* 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; + 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; } - /* - * special case for (%dx) while doing input/output op - */ - if ((i.base_reg && - (i.base_reg->reg_type == (Reg16|InOutPortReg)) && - (i.index_reg == 0))) - return 1; - 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; + 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; } - 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 + { + if (!i.index_reg && *base_string == ',') + { + as_bad ("expecting index register or scale factor after ','; got '%c'", + *(base_string + 1)); + 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 = SEG_GOOF; + 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; + } + /* + * special case for (%dx) while doing input/output op + */ + if ((i.base_reg && + (i.base_reg->reg_type == (Reg16 | InOutPortReg)) && + (i.index_reg == 0))) + return 1; + 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; } - return 1; /* normal return */ + } + 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 */ } /* @@ -1616,44 +1920,46 @@ char *operand_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 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 + 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 --> + 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); + 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; } - return (fragP -> fr_var + fragP -> fr_fix - old_fr_fix); + frag_wane (fragP); + } + return (fragP->fr_var + fragP->fr_fix - old_fr_fix); } /* md_estimate_size_before_relax() */ /* @@ -1668,255 +1974,266 @@ register segT segment; * Caller will turn frag into a ".space 0". */ void - md_convert_frag (headers, fragP) -object_headers *headers; -register fragS * fragP; +md_convert_frag (headers, fragP) + object_headers *headers; + register fragS *fragP; { - register unsigned char *opcode; - unsigned char *where_to_put_displacement = NULL; - unsigned int target_address; - unsigned int opcode_address; - unsigned int extension = 0; - 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): + register unsigned char *opcode; + unsigned char *where_to_put_displacement = NULL; + unsigned int target_address; + unsigned int opcode_address; + unsigned int extension = 0; + 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 ((char *) where_to_put_displacement, - displacement_from_opcode_start - extension, - SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); - fragP -> fr_fix += extension; + /* 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 ((char *) where_to_put_displacement, + displacement_from_opcode_start - extension, + SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); + fragP->fr_fix += extension; } - + int md_short_jump_size = 2; /* size of byte displacement jmp */ -int md_long_jump_size = 5; /* size of dword displacement jmp */ +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; -fragS *frag; -symbolS *to_symbol; +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; { - 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; +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; - - 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) -char **argP; -int *cntP; -char ***vecP; +md_parse_option (argP, cntP, vecP) + char **argP; + int *cntP; + char ***vecP; { - return 1; + return 1; } 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. - + 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) -unsigned char con[]; /* Low order byte 1st. */ -int nbytes; /* Number of bytes in the input. */ +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. */ { - 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 +/* 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 /* comment */ -void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) -char *where; -fixS *fixP; -relax_addressT segment_address_in_file; +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_symbolnum; - - know(fixP->fx_addsy != NULL); - - md_number_to_chars(where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); - - r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy) - ? S_GET_TYPE(fixP->fx_addsy) - : fixP->fx_addsy->sy_number); - - where[6] = (r_symbolnum >> 16) & 0x0ff; - where[5] = (r_symbolnum >> 8) & 0x0ff; - where[4] = r_symbolnum & 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 */ + static unsigned char nbytes_r_length[] = + {42, 0, 1, 42, 2}; + long r_symbolnum; + + know (fixP->fx_addsy != NULL); + + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + + where[6] = (r_symbolnum >> 16) & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[4] = r_symbolnum & 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 /* Turn the string pointed to by litP into a floating point constant of type @@ -1924,75 +2241,82 @@ relax_addressT segment_address_in_file; 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 + 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 */ + 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; +static char * +output_invalid (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 */ +static reg_entry * +parse_register (reg_string) + 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); } @@ -2000,124 +2324,133 @@ char *reg_string; /* reg_string starts *before* REGISTER_PREFIX */ /* 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. +/* Parse an operand that is machine-specific. We just return without modifying the expression if we have nothing to do. */ /* 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; } - /* these were macros, but I don't trust macros that eval their +/* these were macros, but I don't trust macros that eval their arguments more than once. Besides, gcc can static inline them. xoxorich. */ -static unsigned long mode_from_disp_size(t) -unsigned long t; +static unsigned long +mode_from_disp_size (t) + unsigned long t; { - return((t & (Disp8)) - ? 1 - : ((t & (Disp32)) ? 2 : 0)); -} /* mode_from_disp_size() */ + return ((t & (Disp8)) + ? 1 + : ((t & (Disp32)) ? 2 : 0)); +} /* mode_from_disp_size() */ /* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */ -static unsigned long opcode_suffix_to_type(s) -unsigned long s; +static unsigned long +opcode_suffix_to_type (s) + unsigned long s; { - return(s == BYTE_OPCODE_SUFFIX - ? Byte : (s == WORD_OPCODE_SUFFIX - ? Word : DWord)); -} /* opcode_suffix_to_type() */ - -static int fits_in_signed_byte(num) -long num; + return (s == BYTE_OPCODE_SUFFIX + ? Byte : (s == WORD_OPCODE_SUFFIX + ? Word : DWord)); +} /* opcode_suffix_to_type() */ + +static int +fits_in_signed_byte (num) + long num; { - return((num >= -128) && (num <= 127)); -} /* fits_in_signed_byte() */ + return ((num >= -128) && (num <= 127)); +} /* fits_in_signed_byte() */ -static int fits_in_unsigned_byte(num) -long num; +static int +fits_in_unsigned_byte (num) + long num; { - return((num & 0xff) == num); -} /* fits_in_unsigned_byte() */ + return ((num & 0xff) == num); +} /* fits_in_unsigned_byte() */ -static int fits_in_unsigned_word(num) -long num; +static int +fits_in_unsigned_word (num) + long num; { - return((num & 0xffff) == num); -} /* fits_in_unsigned_word() */ + return ((num & 0xffff) == num); +} /* fits_in_unsigned_word() */ -static int fits_in_signed_word(num) -long num; +static int +fits_in_signed_word (num) + long num; { - return((-32768 <= num) && (num <= 32767)); -} /* fits_in_signed_word() */ + return ((-32768 <= num) && (num <= 32767)); +} /* fits_in_signed_word() */ -static int smallest_imm_type(num) -long num; +static int +smallest_imm_type (num) + long num; { - return((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))))); -} /* smallest_imm_type() */ - -static void s_bss() + return ((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))))); +} /* smallest_imm_type() */ + +static void +s_bss () { register int temp; temp = get_absolute_expression (); - subseg_new (SEG_BSS, (subsegT)temp); - demand_empty_rest_of_line(); + subseg_new (SEG_BSS, (subsegT) temp); + demand_empty_rest_of_line (); } - + #ifdef I386COFF -short tc_coff_fix2rtype(fixP) -fixS *fixP; +short +tc_coff_fix2rtype (fixP) + fixS *fixP; { - return (fixP->fx_pcrel ? - (fixP->fx_size == 1 ? R_PCRBYTE : - fixP->fx_size == 2 ? R_PCRWORD : - R_PCRLONG): - (fixP->fx_size == 1 ? R_RELBYTE : - fixP->fx_size == 2 ? R_RELWORD : - R_RELLONG)); + return (fixP->fx_pcrel ? + (fixP->fx_size == 1 ? R_PCRBYTE : + fixP->fx_size == 2 ? R_PCRWORD : + R_PCRLONG) : + (fixP->fx_size == 1 ? R_RELBYTE : + fixP->fx_size == 2 ? R_RELWORD : + R_DIR32)); } @@ -2131,4 +2464,3 @@ fixS *fixP; */ /* end of tc-i386.c */ - diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c index dc8d4c2e35e..b7d13d50836 100644 --- a/gas/config/tc-i960.c +++ b/gas/config/tc-i960.c @@ -1,18 +1,18 @@ /* tc-i960.c - All the i80960-specific stuff Copyright (C) 1989, 1990, 1991, 1992 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. */ @@ -81,6 +81,7 @@ #include #include "as.h" +#include "read.h" #include "obstack.h" @@ -91,52 +92,52 @@ extern struct hash_control *po_hash; extern char *next_object_file_charP; #ifdef OBJ_COFF -int md_reloc_size = sizeof(struct reloc); +int md_reloc_size = sizeof (struct reloc); #else /* OBJ_COFF */ -int md_reloc_size = sizeof(struct relocation_info); +int md_reloc_size = sizeof (struct relocation_info); #endif /* OBJ_COFF */ /*************************** * 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 */ -static void cobr_fmt(); /* Generate COBR instruction */ -static void ctrl_fmt(); /* Generate CTRL instruction */ -static char * emit(); /* Emit (internally) binary */ -static int get_args(); /* Break arguments out of comma-separated list */ -static void get_cdisp(); /* Handle COBR or CTRL displacement */ -static char * get_ispec(); /* Find index specification string */ -static int get_regnum(); /* Translate text to register number */ -static int i_scan(); /* Lexical scan of instruction source */ -static void mem_fmt(); /* Generate MEMA or MEMB instruction */ -static void mema_to_memb(); /* Convert MEMA instruction to MEMB format */ -static segT parse_expr(); /* Parse an expression */ -static int parse_ldconst();/* Parse and replace a 'ldconst' pseudo-op */ -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 */ -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 */ -static int shift_ok(); /* Will a 'shlo' substiture for a 'ldconst'? */ -static void syntax(); /* Give syntax error */ -static int targ_has_sfr(); /* Target chip supports spec-func register? */ -static int targ_has_iclass();/* Target chip supports instruction set? */ -/* static void unlink_sym(); */ /* Remove a symbol from the symbol list */ +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 */ +static void cobr_fmt (); /* Generate COBR instruction */ +static void ctrl_fmt (); /* Generate CTRL instruction */ +static char *emit (); /* Emit (internally) binary */ +static int get_args (); /* Break arguments out of comma-separated list */ +static void get_cdisp (); /* Handle COBR or CTRL displacement */ +static char *get_ispec (); /* Find index specification string */ +static int get_regnum (); /* Translate text to register number */ +static int i_scan (); /* Lexical scan of instruction source */ +static void mem_fmt (); /* Generate MEMA or MEMB instruction */ +static void mema_to_memb (); /* Convert MEMA instruction to MEMB format */ +static segT parse_expr (); /* Parse an expression */ +static int parse_ldconst (); /* Parse and replace a 'ldconst' pseudo-op */ +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 */ +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 */ +static int shift_ok (); /* Will a 'shlo' substiture for a 'ldconst'? */ +static void syntax (); /* Give syntax error */ +static int targ_has_sfr (); /* Target chip supports spec-func register? */ +static int targ_has_iclass (); /* Target chip supports instruction set? */ +/* static void unlink_sym(); *//* Remove a symbol from the symbol list */ /* See md_parse_option() for meanings of these options */ static char norelax; /* True if -norelax switch seen */ -static char instrument_branches; /* True if -b switch seen */ +static char instrument_branches;/* True if -b switch seen */ /* Characters that always start a comment. * If the pre-processor is disabled, these aren't very useful. */ -char comment_chars[] = "#"; +const char comment_chars[] = "#"; /* Characters that only start a comment at the beginning of * a line. If the line seems to have the form '# 123 filename' @@ -149,15 +150,17 @@ char comment_chars[] = "#"; /* Also note that comments started like this one will always work. */ -char line_comment_chars[] = ""; +const char line_comment_chars[] = ""; + +const char line_separator_chars[] = ""; /* Chars that can be used to separate mant from exp in floating point nums */ -char EXP_CHARS[] = "eE"; +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[] = "fFdDtT"; +const char FLT_CHARS[] = "fFdDtT"; /* Table used by base assembler to relax addresses based on varying length @@ -172,11 +175,12 @@ 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. @@ -190,16 +194,17 @@ const relax_typeS #define S_LEAFPROC 1 #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 }, +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 }, + {"word", cons, 4}, + {"quad", big_cons, 16}, - { 0, 0, 0 } + {0, 0, 0} }; /* Macros to extract info from an 'expressionS' structure 'e' */ @@ -207,15 +212,15 @@ const pseudo_typeS md_pseudo_table[] = { #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 */ -#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 */ + + +/* 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 */ #define BE 0x12000000 #define BG 0x11000000 #define BGE 0x13000000 @@ -227,78 +232,136 @@ const pseudo_typeS 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 */ -struct regop { - int mode; /* 0 =>local/global/spec reg; 1=> literal or fp reg */ - int special; /* 0 =>not a sfr; 1=> is a sfr (not valid w/mode=0) */ - int n; /* Register number or literal value */ -}; +struct regop + { + int mode; /* 0 =>local/global/spec reg; 1=> literal or fp reg */ + int special; /* 0 =>not a sfr; 1=> is a sfr (not valid w/mode=0) */ + int n; /* Register number or literal value */ + }; /* Number and assembler mnemonic for all registers that can appear in operands */ -static struct { - char *reg_name; - int reg_num; -} regnames[] = { - { "pfp", 0 }, { "sp", 1 }, { "rip", 2 }, { "r3", 3 }, - { "r4", 4 }, { "r5", 5 }, { "r6", 6 }, { "r7", 7 }, - { "r8", 8 }, { "r9", 9 }, { "r10", 10 }, { "r11", 11 }, - { "r12", 12 }, { "r13", 13 }, { "r14", 14 }, { "r15", 15 }, - { "g0", 16 }, { "g1", 17 }, { "g2", 18 }, { "g3", 19 }, - { "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 }, - { "sf12",44 }, { "sf13",45 }, { "sf14",46 }, { "sf15",47 }, - { "sf16",48 }, { "sf17",49 }, { "sf18",50 }, { "sf19",51 }, - { "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 +static struct + { + char *reg_name; + int reg_num; + } + +regnames[] = +{ + { "pfp", 0 }, + { "sp", 1 }, + { "rip", 2 }, + { "r3", 3 }, + { "r4", 4 }, + { "r5", 5 }, + { "r6", 6 }, + { "r7", 7 }, + { "r8", 8 }, + { "r9", 9 }, + { "r10", 10 }, + { "r11", 11 }, + { "r12", 12 }, + { "r13", 13 }, + { "r14", 14 }, + { "r15", 15 }, + { "g0", 16 }, + { "g1", 17 }, + { "g2", 18 }, + { "g3", 19 }, + { "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 }, + { "sf12", 44 }, + { "sf13", 45 }, + { "sf14", 46 }, + { "sf15", 47 }, + { "sf16", 48 }, + { "sf17", 49 }, + { "sf18", 50 }, + { "sf19", 51 }, + { "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 */ +#define FP0 64 + + { "fp0", 64 }, + { "fp1", 65 }, + { "fp2", 66 }, + { "fp3", 67 }, + + { NULL, 0 }, /* END OF LIST */ }; #define IS_RG_REG(n) ((0 <= (n)) && ((n) < SF0)) @@ -308,26 +371,53 @@ static struct { /* Number and assembler mnemonic for all registers that can appear as 'abase' * (indirect addressing) registers. */ -static struct { - char *areg_name; - int areg_num; -} aregs[] = { - { "(pfp)", 0 }, { "(sp)", 1 }, { "(rip)", 2 }, { "(r3)", 3 }, - { "(r4)", 4 }, { "(r5)", 5 }, { "(r6)", 6 }, { "(r7)", 7 }, - { "(r8)", 8 }, { "(r9)", 9 }, { "(r10)", 10 }, { "(r11)", 11 }, - { "(r12)", 12 }, { "(r13)", 13 }, { "(r14)", 14 }, { "(r15)", 15 }, - { "(g0)", 16 }, { "(g1)", 17 }, { "(g2)", 18 }, { "(g3)", 19 }, - { "(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 */ +static struct + { + char *areg_name; + int areg_num; + } + +aregs[] = +{ + { "(pfp)", 0 }, + { "(sp)", 1 }, + { "(rip)", 2 }, + { "(r3)", 3 }, + { "(r4)", 4 }, + { "(r5)", 5 }, + { "(r6)", 6 }, + { "(r7)", 7 }, + { "(r8)", 8 }, + { "(r9)", 9 }, + { "(r10)", 10 }, + { "(r11)", 11 }, + { "(r12)", 12 }, + { "(r13)", 13 }, + { "(r14)", 14 }, + { "(r15)", 15 }, + { "(g0)", 16 }, + { "(g1)", 17 }, + { "(g2)", 18 }, + { "(g3)", 19 }, + { "(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 */ }; @@ -414,41 +504,46 @@ 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 + 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); - } -} /* md_begin() */ + + 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); + } +} /* md_begin() */ /***************************************************************************** * md_end: One-time final cleanup @@ -457,7 +552,7 @@ void * **************************************************************************** */ void - md_end() +md_end () { } @@ -472,171 +567,188 @@ void * **************************************************************************** */ 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: + char *args[4]; /* Parsed instruction text, containing NO whitespace: * arg[0]->opcode mnemonic * arg[1-3]->operands, with char constants * replaced by decimal numbers */ - int n_ops; /* Number of instruction operands */ - int callx; - struct i960_opcode *oP; - /* Pointer to instruction description */ - int branch_predict; - /* TRUE iff opcode mnemonic included branch-prediction + int n_ops; /* Number of instruction operands */ + int callx; + struct i960_opcode *oP; + /* Pointer to instruction description */ + int branch_predict; + /* TRUE iff opcode mnemonic included branch-prediction * suffix (".f" or ".t") */ - long bp_bits; /* Setting of branch-prediction bit(s) to be OR'd + 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 */ - memset(args, '\0', 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); - if (n_ops == -1){ - return; - } + 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 */ + memset (args, '\0', 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); + if (n_ops == -1) + { + return; } + } - - /* Check for branch-prediction suffix on opcode mnemonic, strip it off */ - n = strlen(args[0]) - 1; - branch_predict = 0; - bp_bits = 0; - if (args[0][n-1] == '.' && (args[0][n] == 't' || args[0][n] == 'f')){ - /* We could check here to see if the target architecture + + /* Check for branch-prediction suffix on opcode mnemonic, strip it off */ + n = strlen (args[0]) - 1; + branch_predict = 0; + bp_bits = 0; + if (args[0][n - 1] == '.' && (args[0][n] == 't' || args[0][n] == 'f')) + { + /* We could check here to see if the target architecture * supports branch prediction, but why bother? The bit * will just be ignored by processors that don't use it. */ - branch_predict = 1; - 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. + branch_predict = 1; + 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. */ - 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: - case CTRL: - ctrl_fmt(args[1], oP->opcode | bp_bits, oP->num_ops); - if (oP->format == FBRA){ - /* Now generate a 'bno' to same arg */ - ctrl_fmt(args[1], BNO | bp_bits, 1); - } - break; - case COBR: - case COJ: - cobr_fmt(args, oP->opcode | bp_bits, oP); - break; - case REG: - if (branch_predict){ - as_warn(bp_error_msg); - } - reg_fmt(args, oP); - break; - case MEM1: - if (args[0][0] == 'c' && args[0][1] == 'a') - { - if (branch_predict) - { - as_warn(bp_error_msg); - } - mem_fmt(args, oP, 1); - break; - } - case MEM2: - case MEM4: - case MEM8: - case MEM12: - case MEM16: - if (branch_predict){ - as_warn(bp_error_msg); - } - mem_fmt(args, oP, 0); - break; - case CALLJ: - if (branch_predict){ - as_warn(bp_error_msg); - } - /* Output opcode & set up "fixup" (relocation); + 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: + case CTRL: + ctrl_fmt (args[1], oP->opcode | bp_bits, oP->num_ops); + if (oP->format == FBRA) + { + /* Now generate a 'bno' to same arg */ + ctrl_fmt (args[1], BNO | bp_bits, 1); + } + break; + case COBR: + case COJ: + cobr_fmt (args, oP->opcode | bp_bits, oP); + break; + case REG: + if (branch_predict) + { + as_warn (bp_error_msg); + } + reg_fmt (args, oP); + break; + case MEM1: + if (args[0][0] == 'c' && args[0][1] == 'a') + { + if (branch_predict) + { + as_warn (bp_error_msg); + } + mem_fmt (args, oP, 1); + break; + } + case MEM2: + case MEM4: + case MEM8: + case MEM12: + case MEM16: + if (branch_predict) + { + as_warn (bp_error_msg); + } + mem_fmt (args, oP, 0); + break; + case CALLJ: + if (branch_predict) + { + as_warn (bp_error_msg); + } + /* Output opcode & set up "fixup" (relocation); * flag relocation as 'callj' type. */ - know(oP->num_ops == 1); - get_cdisp(args[1], "CTRL", oP->opcode, 24, 0, 1); - break; - default: - BAD_CASE(oP->format); - break; - } + know (oP->num_ops == 1); + get_cdisp (args[1], "CTRL", oP->opcode, 24, 0, 1); + break; + default: + BAD_CASE (oP->format); + break; } -} /* md_assemble() */ + } +} /* md_assemble() */ /***************************************************************************** * md_number_to_chars: convert a number to target byte order * **************************************************************************** */ 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 +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() */ + 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() */ /***************************************************************************** * md_chars_to_number: convert from target byte order to host byte order. * **************************************************************************** */ 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]; - } - return retval; + int retval; + + for (retval = 0; n--;) + { + retval <<= 8; + retval |= val[n]; + } + return retval; } @@ -655,58 +767,62 @@ int n; /* Number of bytes in the input */ * things with more files or symbolic links. * **************************************************************************** */ -char * md_atof(type, litP, sizeP) -int type; -char *litP; -int *sizeP; +char * +md_atof (type, litP, sizeP) + int type; + char *litP; + int *sizeP; { - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - 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 + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + 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 */ + + 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 */ } @@ -715,12 +831,12 @@ 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); + md_number_to_chars (buf, val, n); } @@ -729,12 +845,12 @@ int 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); + md_number_to_chars (buf, val, n); } /***************************************************************************** @@ -745,47 +861,51 @@ int 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 + 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 + instr = md_chars_to_number (instrP, 4); + + /* Surprise! -- we stored the number of bits * to be modified rather than a pointer to a structure. */ - numbits = (int)bfixP; - if (numbits == 1){ - /* 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. + numbits = (int) bfixP; + if (numbits == 1) + { + /* 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); - } else { - /* Put bit field into instruction and write back in target + 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); + } + else + { + /* Put bit field into instruction and write back in target * byte order. */ - val &= ~(-1 << (int)numbits); /* Clear unused sign bits */ - instr |= val; - md_number_to_chars(instrP, instr, 4); - } -} /* md_number_to_field() */ + val &= ~(-1 << (int) numbits); /* Clear unused sign bits */ + instr |= val; + md_number_to_chars (instrP, instr, 4); + } +} /* md_number_to_field() */ /***************************************************************************** @@ -828,54 +948,73 @@ bit_fixS *bfixP; /* Description of bit field to be fixed up */ * **************************************************************************** */ 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; }; - static struct tabentry arch_tab[] = { - "KA", ARCH_KA, - "KB", ARCH_KB, - "SA", ARCH_KA, /* Synonym for KA */ - "SB", ARCH_KB, /* Synonym for KB */ - "KC", ARCH_MC, /* Synonym for MC */ - "MC", ARCH_MC, - "CA", ARCH_CA, - NULL, 0 - }; - struct tabentry *tp; - if (!strcmp(*argP,"linkrelax")){ - linkrelax = 1; - flagseen ['L'] = 1; - } else 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 { - architecture = tp->arch; - } - } else { - /* Unknown option */ - (*argP)++; - return 0; + char *p; + struct tabentry + { + char *flag; + int arch; + }; + static struct tabentry arch_tab[] = + { + "KA", ARCH_KA, + "KB", ARCH_KB, + "SA", ARCH_KA, /* Synonym for KA */ + "SB", ARCH_KB, /* Synonym for KB */ + "KC", ARCH_MC, /* Synonym for MC */ + "MC", ARCH_MC, + "CA", ARCH_CA, + NULL, 0 + }; + struct tabentry *tp; + if (!strcmp (*argP, "linkrelax")) + { + linkrelax = 1; + flagseen['L'] = 1; + } + else 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); } - **argP = '\0'; /* Done parsing this switch */ - return 1; + else + { + architecture = tp->arch; + } + } + else + { + /* Unknown option */ + (*argP)++; + return 0; + } + **argP = '\0'; /* Done parsing this switch */ + return 1; } /***************************************************************************** @@ -892,34 +1031,35 @@ char ***vecP; * **************************************************************************** */ void - md_convert_frag(headers, fragP) -object_headers *headers; -fragS * fragP; +md_convert_frag (headers, fragP) + object_headers *headers; + fragS *fragP; { - fixS *fixP; /* Structure describing needed address fix */ - - switch (fragP->fr_subtype){ - case 1: - /* LEAVE SINGLE COBR INSTRUCTION */ - fixP = fix_new(fragP, - fragP->fr_opcode-fragP->fr_literal, - 4, - fragP->fr_symbol, - 0, - fragP->fr_offset, - 1, - 0); - - fixP->fx_bit_fixP = (bit_fixS *) 13; /* size of bit field */ - break; - case 2: - /* REPLACE COBR WITH COMPARE/BRANCH INSTRUCTIONS */ - relax_cobr(fragP); - break; - default: - BAD_CASE(fragP->fr_subtype); - break; - } + fixS *fixP; /* Structure describing needed address fix */ + + switch (fragP->fr_subtype) + { + case 1: + /* LEAVE SINGLE COBR INSTRUCTION */ + fixP = fix_new (fragP, + fragP->fr_opcode - fragP->fr_literal, + 4, + fragP->fr_symbol, + 0, + fragP->fr_offset, + 1, + NO_RELOC); + + fixP->fx_bit_fixP = (bit_fixS *) 13; /* size of bit field */ + break; + case 2: + /* REPLACE COBR WITH COMPARE/BRANCH INSTRUCTIONS */ + relax_cobr (fragP); + break; + default: + BAD_CASE (fragP->fr_subtype); + break; + } } /***************************************************************************** @@ -935,19 +1075,20 @@ fragS * fragP; * **************************************************************************** */ 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 + /* If symbol is undefined in this segment, go to "relaxed" state * (compare and branch instructions instead of cobr) right now. */ - if (S_GET_SEGMENT(fragP->fr_symbol) != segment_type) { - relax_cobr(fragP); - return 4; - } - return 0; -} /* md_estimate_size_before_relax() */ + if (S_GET_SEGMENT (fragP->fr_symbol) != segment_type) + { + relax_cobr (fragP); + return 4; + } + return 0; +} /* md_estimate_size_before_relax() */ /***************************************************************************** @@ -963,47 +1104,50 @@ register segT segment_type; * does do the reordering (Ian Taylor 28 Aug 92). * **************************************************************************** */ -void md_ri_to_chars(where, ri) -char *where; -struct relocation_info *ri; +void +md_ri_to_chars (where, ri) + char *where; + struct relocation_info *ri; { - md_number_to_chars (where, ri->r_address, - sizeof (ri->r_address)); - where[4] = ri->r_index & 0x0ff; - where[5] = (ri->r_index >> 8) & 0x0ff; - where[6] = (ri->r_index >> 16) & 0x0ff; - where[7] = ((ri->r_pcrel << 0) - | (ri->r_length << 1) - | (ri->r_extern << 3) - | (ri->r_bsr << 4) - | (ri->r_disp << 5) - | (ri->r_callj << 6)); -} /* md_ri_to_chars() */ + md_number_to_chars (where, ri->r_address, + sizeof (ri->r_address)); + where[4] = ri->r_index & 0x0ff; + where[5] = (ri->r_index >> 8) & 0x0ff; + where[6] = (ri->r_index >> 16) & 0x0ff; + where[7] = ((ri->r_pcrel << 0) + | (ri->r_length << 1) + | (ri->r_extern << 3) + | (ri->r_bsr << 4) + | (ri->r_disp << 5) + | (ri->r_callj << 6)); +} /* md_ri_to_chars() */ #ifndef WORKING_DOT_WORD int md_short_jump_size = 0; int md_long_jump_size = 0; -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; +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."); + 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."); + as_fatal ("failed sanity check."); } + #endif /************************************************************* @@ -1021,10 +1165,10 @@ symbolS *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 */ + ctrl_fmt (BR_CNT_FUNC, CALL, 1); /* Emit call to "increment" routine */ + emit (0); /* Emit inline counter to be incremented */ } /***************************************************************************** @@ -1034,12 +1178,12 @@ static void * branch-prediction instrumentation. **************************************************************************** */ static char * - brlab_next() +brlab_next () { - static char buf[20]; - - sprintf(buf, "%s%d", BR_LABEL_BASE, br_cnt++); - return buf; + static char buf[20]; + + sprintf (buf, "%s%d", BR_LABEL_BASE, br_cnt++); + return buf; } /***************************************************************************** @@ -1061,37 +1205,39 @@ static char * * .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; ifr_literal, - 4, - symbol_find(buf), - 0, - 0, - 0, - 0); - fixP->fx_im_disp = 2; /* 32-bit displacement fix */ - } + 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); + fixP = fix_new (frag_now, + p - frag_now->fr_literal, + 4, + symbol_find (buf), + 0, + 0, + 0, + NO_RELOC); + fixP->fx_im_disp = 2; /* 32-bit displacement fix */ + } } /***************************************************************************** @@ -1099,65 +1245,72 @@ void * **************************************************************************** */ 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 +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 */ + struct i960_opcode *oP; + /*->description of instruction */ { - long instr; /* 32-bit instruction */ - struct regop regop; /* Description of register operand */ - int n; /* Number of operands */ - int var_frag; /* 1 if varying length code fragment should + long instr; /* 32-bit instruction */ + struct regop regop; /* Description of register operand */ + int n; /* Number of operands */ + int var_frag; /* 1 if varying length code fragment should * 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 + + instr = opcode; + n = oP->num_ops; + + if (n >= 1) + { + /* First operand (if any) of a COBR is always a register * operand. Parse it. */ - parse_regop(®op, arg[1], oP->operand[0]); - instr |= (regop.n << 19) | (regop.mode << 13); - } - if (n >= 2) { - /* Second operand (if any) of a COBR is always a register + parse_regop (®op, arg[1], oP->operand[0]); + instr |= (regop.n << 19) | (regop.mode << 13); + } + if (n >= 2) + { + /* Second operand (if any) of a COBR is always a register * operand. Parse it. */ - parse_regop(®op, arg[2], oP->operand[1]); - instr |= (regop.n << 14) | regop.special; + 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 ()); } - - - if (n < 3){ - emit(instr); - - } else { - if (instrument_branches){ - brcnt_emit(); - colon(brlab_next()); - } - - /* A third operand to a COBR is always a displacement. + + /* 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 * use) set up a variable code fragment; otherwise set up an * address fix. */ - var_frag = !norelax || (oP->format == COJ); /* TRUE or FALSE */ - get_cdisp(arg[3], "COBR", instr, 13, var_frag, 0); - - if (instrument_branches){ - brcnt_emit(); - } + var_frag = !norelax || (oP->format == COJ); /* TRUE or FALSE */ + get_cdisp (arg[3], "COBR", instr, 13, var_frag, 0); + + if (instrument_branches) + { + brcnt_emit (); } -} /* cobr_fmt() */ + } +} /* cobr_fmt() */ /***************************************************************************** @@ -1165,39 +1318,44 @@ struct i960_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 + 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); - - if (instrument){ - brcnt_emit(); - colon(brlab_next()); - } - - /* The operand MUST be an ip-relative displacment. Parse it + + + if (num_ops == 0) + { + emit (opcode); /* Output opcode */ + } + else + { + + instrument = instrument_branches && (opcode != CALL) + && (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(); - } + get_cdisp (targP, "CTRL", opcode, 24, 0, 0); + + if (instrument) + { + brcnt_emit (); } - + } + } @@ -1209,15 +1367,15 @@ int num_ops; /* Number of operands */ * **************************************************************************** */ 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; + 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; } @@ -1238,56 +1396,66 @@ long instr; /* Word to be output, host byte order */ * Number of operands (0,1,2, or 3) or -1 on error. * **************************************************************************** */ -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]. +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 int n; /* Number of operands */ - register char *to; - /* 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. + register int n; /* Number of operands */ + register char *to; + /* 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"); - return -1; - } - *to++ = '\0'; /* Terminate argument */ - args[++n] = to; /* Start next argument */ - p++; - - } else { - *to++ = *p++; - } + to = p; + while (*p != '\0') + { + + if (*p == ' ') + { + p++; + + } + else if (*p == ',') + { + + /* Start of operand */ + if (n == 3) + { + as_bad ("too many operands"); + return -1; + } + *to++ = '\0'; /* Terminate argument */ + args[++n] = to; /* Start next argument */ + p++; + } - *to = '\0'; - return n; + else + { + *to++ = *p++; + } + } + *to = '\0'; + return n; } @@ -1306,70 +1474,74 @@ char *args[]; /* Output arg: pointers to operands placed in args[1-3]. * **************************************************************************** */ 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; +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 */ + 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); - } else { - /* Set up a new fix structure, so address can be updated + 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); + } + else + { + /* Set up a new fix structure, so address can be updated * when all symbol values are known. */ - outP = emit(instr); - fixP = fix_new(frag_now, - outP - frag_now->fr_literal, - 4, - adds(e), - 0, - offs(e), - 1, - 0); - - fixP->fx_callj = callj; - - /* We want to modify a bit field when the address is + outP = emit (instr); + fixP = fix_new (frag_now, + outP - frag_now->fr_literal, + 4, + adds (e), + 0, + offs (e), + 1, + NO_RELOC); + + 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 * the number of bits affected instead of a pointer. */ - 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; + 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; + } } @@ -1384,38 +1556,43 @@ int callj; /* 1 if callj relocation should be done; else 0 */ * **************************************************************************** */ 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 + 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 + 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. */ - *end = '\0'; - if (*(end+1) != '\0'){ - as_bad("garbage after index spec ignored"); - } - } + *end = '\0'; + if (*(end + 1) != '\0') + { + as_bad ("garbage after index spec ignored"); + } } - return start; + } + return start; } /***************************************************************************** @@ -1426,14 +1603,14 @@ char *textP; /*->memory operand from source instruction, no white space */ * **************************************************************************** */ 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; + int *rP; + + rP = (int *) hash_find (reg_hash, regname); + return (rP == NULL) ? -1 : *rP; } @@ -1455,136 +1632,155 @@ char *regname; /* Suspected register name */ * Number of operands (0,1,2, or 3) or -1 on error. * **************************************************************************** */ -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 +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. */ { - - /* Isolate opcode */ - if (*(iP) == ' ') { - iP++; - } /* Skip lead space, if any */ - args[0] = iP; - for (; *iP != ' '; iP++) { - if (*iP == '\0') { - /* There are no operands */ - if (args[0] == iP) { - /* We never moved: there was no opcode either! */ - as_bad("missing opcode"); - return -1; - } - return 0; - } + + /* Isolate opcode */ + if (*(iP) == ' ') + { + iP++; + } /* Skip lead space, if any */ + args[0] = iP; + for (; *iP != ' '; iP++) + { + if (*iP == '\0') + { + /* There are no operands */ + if (args[0] == iP) + { + /* We never moved: there was no opcode either! */ + as_bad ("missing opcode"); + return -1; + } + return 0; } - *iP++ = '\0'; /* Terminate opcode */ - return(get_args(iP, args)); -} /* i_scan() */ + } + *iP++ = '\0'; /* Terminate opcode */ + return (get_args (iP, args)); +} /* i_scan() */ /***************************************************************************** * mem_fmt: generate a MEMA- or MEMB-format instruction * **************************************************************************** */ -static void mem_fmt(args, oP, callx) -char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */ -struct i960_opcode *oP; /* Pointer to description of instruction */ -int callx; /* Is this a callx opcode */ +static void +mem_fmt (args, oP, callx) + char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */ + struct i960_opcode *oP; /* Pointer to description of instruction */ + int callx; /* Is this a callx opcode */ { - int i; /* Loop counter */ - struct regop regop; /* Description of register operand */ - char opdesc; /* Operand descriptor byte */ - memS instr; /* Description of binary to be output */ - char *outP; /* Where the binary was output to */ - expressionS expr; /* Parsed expression */ - fixS *fixP; /*->description of deferred address fixup */ - - memset(&instr, '\0', 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 { - parse_regop(®op, args[i], opdesc); - instr.opcode |= regop.n << 19; - } + int i; /* Loop counter */ + struct regop regop; /* Description of register operand */ + char opdesc; /* Operand descriptor byte */ + memS instr; /* Description of binary to be output */ + char *outP; /* Where the binary was output to */ + expressionS expr; /* Parsed expression */ + fixS *fixP; /*->description of deferred address fixup */ + + memset (&instr, '\0', 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); } - - /* Output opcode */ - outP = emit(instr.opcode); - - if (instr.disp == 0){ - return; + else + { + parse_regop (®op, args[i], opdesc); + instr.opcode |= regop.n << 19; } - - /* 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 */ - } else { - /* 12-bit displacement */ - if (offs(expr) & ~0xfff){ - /* Won't fit in 12 bits: convert already-output - * instruction to MEMB format, output - * displacement. - */ - mema_to_memb(outP); - (void) emit(offs(expr)); - } else { - /* WILL fit in 12 bits: OR into opcode and - * overwrite the binary we already put out - */ - instr.opcode |= offs(expr); - md_number_to_chars(outP, instr.opcode, 4); - } - } - break; - - case SEG_DIFFERENCE: - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - if (instr.disp == 12){ - /* Displacement is dependent on a symbol, whose value - * may change at link time. We HAVE to reserve 32 bits. - * Convert already-output opcode to MEMB format. - */ - mema_to_memb(outP); - } - - /* Output 0 displacement and set up address fixup for when + } + + /* 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 */ + } + else + { + /* 12-bit displacement */ + if (offs (expr) & ~0xfff) + { + /* Won't fit in 12 bits: convert already-output + * instruction to MEMB format, output + * displacement. + */ + mema_to_memb (outP); + (void) emit (offs (expr)); + } + else + { + /* WILL fit in 12 bits: OR into opcode and + * overwrite the binary we already put out + */ + instr.opcode |= offs (expr); + md_number_to_chars (outP, instr.opcode, 4); + } + } + break; + + case SEG_DIFFERENCE: + case SEG_TEXT: + case SEG_DATA: + case SEG_BSS: + case SEG_UNKNOWN: + if (instr.disp == 12) + { + /* Displacement is dependent on a symbol, whose value + * may change at link time. We HAVE to reserve 32 bits. + * Convert already-output opcode to MEMB format. + */ + mema_to_memb (outP); + } + + /* Output 0 displacement and set up address fixup for when * this symbol's value becomes known. */ - outP = emit((long) 0); - fixP = fix_new(frag_now, - outP - frag_now->fr_literal, - 4, - adds(expr), - subs(expr), - offs(expr), - 0, - NO_RELOC); - fixP->fx_im_disp = 2; /* 32-bit displacement fix */ - fixP->fx_bsr = callx; /*SAC LD RELAX HACK */ /* Mark reloc as being in i stream */ - break; - - default: - BAD_CASE(segs(expr)); - break; - } -} /* memfmt() */ + outP = emit ((long) 0); + fixP = fix_new (frag_now, + outP - frag_now->fr_literal, + 4, + adds (expr), + subs (expr), + offs (expr), + 0, + NO_RELOC); + fixP->fx_im_disp = 2; /* 32-bit displacement fix */ + fixP->fx_bsr = callx; /*SAC LD RELAX HACK *//* Mark reloc as being in i stream */ + break; + + default: + BAD_CASE (segs (expr)); + break; + } +} /* memfmt() */ /***************************************************************************** @@ -1597,25 +1793,27 @@ int callx; /* Is this a callx opcode */ * They are distinguished by the setting of the MEMA_ABASE bit. * **************************************************************************** */ -static void mema_to_memb(opcodeP) -char *opcodeP; /* Where to find the opcode, in target byte order */ +static void +mema_to_memb (opcodeP) + 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() */ + 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() */ /***************************************************************************** @@ -1633,41 +1831,46 @@ char *opcodeP; /* Where to find the opcode, in target byte order */ * **************************************************************************** */ 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 */ - seg = SEG_GOOF; - } - symP = expP->X_add_symbol; - if (symP && (hash_find(reg_hash, S_GET_NAME(symP)))) { - /* Register name in an expression */ - seg = SEG_GOOF; - } - - input_line_pointer = save_in; /* Restore global */ + 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 */ + seg = SEG_GOOF; + } + symP = expP->X_add_symbol; + if (symP && (hash_find (reg_hash, S_GET_NAME (symP)))) + { + /* Register name in an expression */ + seg = SEG_GOOF; } - return seg; + + input_line_pointer = save_in; /* Restore global */ + } + return seg; } @@ -1687,32 +1890,33 @@ expressionS *expP; /* Where to put the results of parsing */ * **************************************************************************** */ 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: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - /* We're dependent on one or more symbols -- use "lda" */ - arg[0] = "lda"; - break; - - case SEG_ABSOLUTE: - /* Try the following mappings: + 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: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + /* We're dependent on one or more symbols -- use "lda" */ + arg[0] = "lda"; + break; + + case SEG_ABSOLUTE: + /* Try the following mappings: * ldconst 0, ->mov 0, * ldconst 31, ->mov 31, * ldconst 32, ->addo 1,31, @@ -1724,43 +1928,52 @@ char *arg[]; /* See above */ * anthing else becomes: * lda xxx, */ - 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]; - sprintf(buf, "%d", shift); - arg[1] = buf; - sprintf(buf2, "%d", n >> shift); - arg[2] = buf2; - - } else { - arg[0] = "lda"; - } - break; - - default: - as_bad("invalid constant"); - return -1; - break; + 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"; + } - return (arg[3] == 0) ? 2: 3; + 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]; + sprintf (buf, "%d", shift); + arg[1] = buf; + sprintf (buf2, "%d", n >> shift); + arg[2] = buf2; + + } + else + { + arg[0] = "lda"; + } + break; + + default: + as_bad ("invalid constant"); + return -1; + break; + } + return (arg[3] == 0) ? 2 : 3; } /***************************************************************************** @@ -1795,170 +2008,205 @@ char *arg[]; /* See above */ * **************************************************************************** */ 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 */ - char iprel_flag;/* True if this is an IP-relative operand */ - int regnum; /* Register number */ - int scale; /* Scale factor: 1,2,4,8, or 16. Later converted + char *indexP; /* Pointer to index specification with "[]" removed */ + char *p; /* Temp char pointer */ + char iprel_flag; /* True if this is an IP-relative operand */ + int regnum; /* Register number */ + int scale; /* Scale factor: 1,2,4,8, or 16. Later converted * to internal format (0,1,2,3,4 respectively). */ - int mode; /* MEMB mode bits */ - int *intP; /* Pointer to register number */ - - /* The following table contains the default scale factors for each + 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 * consecutive values, in the order they appear in this table */ - static int def_scale[] = { - 1, /* MEM1 */ - 2, /* MEM2 */ - 4, /* MEM4 */ - 8, /* MEM8 */ - -1, /* MEM12 -- no valid default */ - 16 /* MEM16 */ - }; - - - iprel_flag = mode = 0; - - /* Any index present? */ - indexP = get_ispec(argP); - if (indexP) { - p = strchr(indexP, '*'); - if (p == NULL) { - /* No explicit scale -- use default for this + static int def_scale[] = + { + 1, /* MEM1 */ + 2, /* MEM2 */ + 4, /* MEM4 */ + 8, /* MEM8 */ + -1, /* MEM12 -- no valid default */ + 16 /* MEM16 */ + }; + + + iprel_flag = mode = 0; + + /* Any index present? */ + indexP = get_ispec (argP); + if (indexP) + { + p = strchr (indexP, '*'); + if (p == NULL) + { + /* No explicit scale -- use default for this *instruction type. */ - scale = def_scale[ optype - MEM1 ]; - } else { - *p++ = '\0'; /* Eliminate '*' */ - - /* Now indexP->a '\0'-terminated register name, + 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')){ - scale = *p - '0'; - } else { - 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; - case 2: scale = 1 << 7; break; - case 4: scale = 2 << 7; break; - case 8: scale = 3 << 7; break; - 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 */ + + if (!strcmp (p, "16")) + { + scale = 16; + } + else if (strchr ("1248", *p) && (p[1] == '\0')) + { + scale = *p - '0'; + } + else + { + scale = -1; + } + } + + regnum = get_regnum (indexP); /* Get index reg. # */ + if (!IS_RG_REG (regnum)) + { + as_bad ("invalid index register"); + return; } - - /* Any abase (Register Indirect) specification present? */ - if ((p = strrchr(argP,'(')) != NULL) { - /* "(" is there -- does it start a legal abase spec? + + /* Convert scale to its binary encoding */ + switch (scale) + { + case 1: + scale = 0 << 7; + break; + case 2: + scale = 1 << 7; + break; + case 4: + scale = 2 << 7; + break; + case 8: + scale = 3 << 7; + break; + 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? * (If not it could be part of a displacement expression.) */ - intP = (int *) hash_find(areg_hash, p); - if (intP != NULL){ - /* Got an abase here */ - regnum = *intP; - *p = '\0'; /* discard register spec */ - if (regnum == IPREL){ - /* We have to specialcase ip-rel mode */ - iprel_flag = 1; - } else { - memP->opcode |= regnum << 14; - mode |= A_BIT; - } - } + intP = (int *) hash_find (areg_hash, p); + if (intP != NULL) + { + /* Got an abase here */ + regnum = *intP; + *p = '\0'; /* discard register spec */ + if (regnum == IPREL) + { + /* We have to specialcase ip-rel mode */ + iprel_flag = 1; + } + else + { + memP->opcode |= regnum << 14; + mode |= A_BIT; + } } - - /* Any expression present? */ - memP->e = argP; - if (*argP != '\0'){ - mode |= D_BIT; + } + + /* Any expression present? */ + memP->e = argP; + if (*argP != '\0') + { + mode |= D_BIT; + } + + /* Special-case ip-relative addressing */ + if (iprel_flag) + { + if (mode & I_BIT) + { + syntax (); } - - /* Special-case ip-relative addressing */ - if (iprel_flag){ - if (mode & I_BIT){ - syntax(); - } else { - memP->opcode |= 5 << 10; /* IP-relative mode */ - memP->disp = 32; - } - return; + else + { + memP->opcode |= 5 << 10; /* IP-relative mode */ + memP->disp = 32; } - - /* Handle all other modes */ - switch (mode){ - case D_BIT | A_BIT: - /* Go with MEMA instruction format for now (grow to MEMB later + return; + } + + /* Handle all other modes */ + switch (mode) + { + case D_BIT | A_BIT: + /* Go with MEMA instruction format for now (grow to MEMB later * if 12 bits is not enough for the displacement). * MEMA format has a single mode bit: set it to indicate * that abase is present. */ - memP->opcode |= MEMA_ABASE; - memP->disp = 12; - break; - - case D_BIT: - /* Go with MEMA instruction format for now (grow to MEMB later + 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 + 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), * so we set it "by hand" here. */ - 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; - /*********************** + 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; + /*********************** * Fall into next case * ********************** */ - case D_BIT | A_BIT | I_BIT: - case D_BIT | I_BIT: - /* set MEMB bit in mode, and OR in mode bits */ - memP->opcode |= mode | MEMB_BIT; - memP->disp = 32; - break; - - default: - syntax(); - break; - } + case D_BIT | A_BIT | I_BIT: + case D_BIT | I_BIT: + /* set MEMB bit in mode, and OR in mode bits */ + memP->opcode |= mode | MEMB_BIT; + memP->disp = 32; + break; + + default: + syntax (); + break; + } } /***************************************************************************** @@ -1969,45 +2217,54 @@ int optype; /* MEM1, MEM2, MEM4, MEM8, MEM12, or MEM16 */ * 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. + char *args[4]; /* Pointers operands, with no embedded whitespace. * arg[0] unused. * arg[1-3]->operands */ - 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 ]){ - input_line_pointer++; - } - 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 + 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]) + { + input_line_pointer++; + } + 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. */ - *input_line_pointer++ = eol; + *input_line_pointer++ = eol; } /***************************************************************************** @@ -2017,149 +2274,179 @@ int po_num; /* Pseudo-op number: currently S_LEAFPROC or S_SYSPROC */ * 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){ - if (IS_RG_REG(n)){ - /* global or local register */ - if (!REG_ALIGN(opdesc,n)){ - as_bad("unaligned register"); - } - regopP->n = n; - regopP->mode = 0; - regopP->special = 0; - return; - } else if (IS_FP_REG(n) && FP_OK(opdesc)){ - /* Floating point register, and it's allowed */ - regopP->n = n - FP0; - regopP->mode = 1; - regopP->special = 0; - return; - } else if (IS_SF_REG(n) && SFR_OK(opdesc)){ - /* Special-function register, and it's allowed */ - regopP->n = n - SF0; - regopP->mode = 0; - regopP->special = 1; - if (!targ_has_sfr(regopP->n)){ - as_bad("no such sfr in this architecture"); - } - return; - } - } else if (LIT_OK(opdesc)){ - /* + int n; /* Register number */ + expressionS e; /* Parsed expression */ + + /* See if operand is a register */ + n = get_regnum (optext); + if (n >= 0) + { + if (IS_RG_REG (n)) + { + /* global or local register */ + if (!REG_ALIGN (opdesc, n)) + { + as_bad ("unaligned register"); + } + regopP->n = n; + regopP->mode = 0; + regopP->special = 0; + return; + } + else if (IS_FP_REG (n) && FP_OK (opdesc)) + { + /* Floating point register, and it's allowed */ + regopP->n = n - FP0; + regopP->mode = 1; + regopP->special = 0; + return; + } + else if (IS_SF_REG (n) && SFR_OK (opdesc)) + { + /* Special-function register, and it's allowed */ + regopP->n = n - SF0; + regopP->mode = 0; + regopP->special = 1; + if (!targ_has_sfr (regopP->n)) + { + as_bad ("no such sfr in this architecture"); + } + return; + } + } + else if (LIT_OK (opdesc)) + { + /* * How about a literal? */ - regopP->mode = 1; - regopP->special = 0; - 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 += 2; - } - - if (!strcmp(optext,"0.0") || !strcmp(optext,"0") ){ - regopP->n = 0x10; - return; - } - if (!strcmp(optext,"1.0") || !strcmp(optext,"1") ){ - regopP->n = 0x16; - return; - } - - } else { /* fixed point literal acceptable */ - if ((parse_expr(optext,&e) != SEG_ABSOLUTE) - || (offs(e) < 0) || (offs(e) > 31)){ - as_bad("illegal literal"); - offs(e) = 0; - } - regopP->n = offs(e); - return; - } + regopP->mode = 1; + regopP->special = 0; + 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 += 2; + } + + if (!strcmp (optext, "0.0") || !strcmp (optext, "0")) + { + regopP->n = 0x10; + return; + } + if (!strcmp (optext, "1.0") || !strcmp (optext, "1")) + { + regopP->n = 0x16; + return; + } + } - - /* Nothing worked */ - syntax(); - regopP->mode = 0; /* Register r0 is always a good one */ - regopP->n = 0; - regopP->special = 0; -} /* parse_regop() */ + else + { /* fixed point literal acceptable */ + if ((parse_expr (optext, &e) != SEG_ABSOLUTE) + || (offs (e) < 0) || (offs (e) > 31)) + { + as_bad ("illegal literal"); + offs (e) = 0; + } + regopP->n = offs (e); + return; + } + } + + /* Nothing worked */ + syntax (); + regopP->mode = 0; /* Register r0 is always a good one */ + regopP->n = 0; + regopP->special = 0; +} /* parse_regop() */ /***************************************************************************** * reg_fmt: generate a REG-format instruction * **************************************************************************** */ -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 */ +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 */ { - 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 + 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). */ - regop.n <<= 19; - if (regop.special){ - regop.mode = regop.special; - } - regop.mode <<= 13; - regop.special = 0; - } else { - /* regop.n goes in bit 0, needs no shifting */ - regop.mode <<= 11; - regop.special <<= 5; - } - instr |= regop.n | regop.mode | regop.special; + regop.n <<= 19; + if (regop.special) + { + regop.mode = regop.special; + } + regop.mode <<= 13; + regop.special = 0; + } + else + { + /* regop.n goes in bit 0, needs no shifting */ + regop.mode <<= 11; + regop.special <<= 5; } - - 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 + 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). */ - regop.n <<= 19; - if (regop.special){ - regop.mode = regop.special; - } - regop.mode <<= 13; - regop.special = 0; - } else { - regop.n <<= 14; - regop.mode <<= 12; - regop.special <<= 6; - } - instr |= regop.n | regop.mode | regop.special; + regop.n <<= 19; + if (regop.special) + { + regop.mode = regop.special; + } + regop.mode <<= 13; + regop.special = 0; } - if (n_ops == 3){ - parse_regop(®op, args[3], oP->operand[2]); - if (regop.special){ - regop.mode = regop.special; - } - instr |= (regop.n <<= 19) | (regop.mode <<= 13); + else + { + regop.n <<= 14; + regop.mode <<= 12; + regop.special <<= 6; } - emit(instr); + instr |= regop.n | regop.mode | regop.special; + } + if (n_ops == 3) + { + parse_regop (®op, args[3], oP->operand[2]); + if (regop.special) + { + regop.mode = regop.special; + } + instr |= (regop.n <<= 19) | (regop.mode <<= 13); + } + emit (instr); } @@ -2175,75 +2462,79 @@ struct i960_opcode *oP; /* Pointer to description of instruction */ * 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 +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 */ - 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); - opcode = ((instr >> 24) & 0xff) - 0x30; /* "-0x30" for table index */ - src1 = (instr >> 19) & 0x1f; - m1 = (instr >> 13) & 1; - 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); - 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, - 4, - fragP->fr_symbol, - 0, - fragP->fr_offset, - 1, - 0); - - fixP->fx_bit_fixP = (bit_fixS *) 24; /* Store size of bit field */ - - fragP->fr_fix += 4; - frag_wane(fragP); + int opcode, src1, src2, m1, s2; + /* 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); + opcode = ((instr >> 24) & 0xff) - 0x30; /* "-0x30" for table index */ + src1 = (instr >> 19) & 0x1f; + m1 = (instr >> 13) & 1; + 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); + 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, + 4, + fragP->fr_symbol, + 0, + fragP->fr_offset, + 1, + NO_RELOC); + + fixP->fx_bit_fixP = (bit_fixS *) 24; /* Store size of bit field */ + + fragP->fr_fix += 4; + frag_wane (fragP); } @@ -2267,46 +2558,55 @@ register fragS *fragP; /* fragP->fr_opcode is assumed to point to * passed fixup structure. * **************************************************************************** */ -void reloc_callj(fixP) -fixS *fixP; /* Relocation that can be done at assembly time */ +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'. + 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. + 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 + 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 * relocation as if nothing happened here. */ - md_number_to_chars(where, BAL, 4); - } else if (TC_S_IS_BADPROC(fixP->fx_addsy)) { - as_bad("Looks like a proc, but can't tell what kind.\n"); - } /* switch on proc type */ - - /* else Symbol is neither a sysproc nor a leafproc */ - - return; -} /* reloc_callj() */ + md_number_to_chars (where, BAL, 4); + } + else if (TC_S_IS_BADPROC (fixP->fx_addsy)) + { + as_bad ("Looks like a proc, but can't tell what kind.\n"); + } /* switch on proc type */ + + /* else Symbol is neither a sysproc nor a leafproc */ + + return; +} /* reloc_callj() */ /***************************************************************************** @@ -2324,46 +2624,53 @@ fixS *fixP; /* Relocation that can be done at assembly time */ * list of symbols. * **************************************************************************** */ -static void s_leafproc(n_ops, args) -int n_ops; /* Number of operands */ -char *args[]; /* args[1]->1st operand, args[2]->2nd operand */ +static void +s_leafproc (n_ops, args) + int n_ops; /* Number of operands */ + 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. + 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() */ + 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() */ /* @@ -2378,38 +2685,42 @@ char *args[]; /* args[1]->1st operand, args[2]->2nd operand */ * the symbol. Since that entry is normally 0, we bias 'entrynum' * by adding 1 to it. It must be unbiased before it is used. */ -static void s_sysproc(n_ops, args) -int n_ops; /* Number of operands */ -char *args[]; /* args[1]->1st operand, args[2]->2nd operand */ +static void +s_sysproc (n_ops, args) + int n_ops; /* Number of operands */ + 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) - || (offs(exp) > 31)) { - 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() */ + 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) + || (offs (exp) > 31)) + { + 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() */ /***************************************************************************** @@ -2423,26 +2734,29 @@ 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; - } - return shift; + 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; + } + return shift; } @@ -2450,9 +2764,11 @@ int n; /* The constant of interest */ * syntax: issue syntax error * **************************************************************************** */ -static void syntax() { - as_bad("syntax error"); -} /* syntax() */ +static void +syntax () +{ + as_bad ("syntax error"); +} /* syntax() */ /***************************************************************************** @@ -2462,19 +2778,20 @@ 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: - case ARCH_KB: - case ARCH_MC: - return 0; - case ARCH_CA: - default: - return ((0<=n) && (n<=2)); - } + switch (architecture) + { + case ARCH_KA: + case ARCH_KB: + case ARCH_MC: + return 0; + case ARCH_CA: + default: + return ((0 <= n) && (n <= 2)); + } } @@ -2485,26 +2802,32 @@ int n; /* Number (0-31) of sfr */ * **************************************************************************** */ static - int - targ_has_iclass(ic) -int ic; /* Instruction class; one of: +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){ - case ARCH_KA: return ic & (I_BASE | I_KX); - case ARCH_KB: return ic & (I_BASE | I_KX | I_FP | I_DEC); - case ARCH_MC: return ic & (I_BASE | I_KX | I_FP | I_DEC | I_MIL); - 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)){ - as_warn("architecture of opcode conflicts with that of earlier instruction(s)"); - iclasses_seen &= ~ic; - } - return 1; + iclasses_seen |= ic; + switch (architecture) + { + case ARCH_KA: + return ic & (I_BASE | I_KX); + case ARCH_KB: + return ic & (I_BASE | I_KX | I_FP | I_DEC); + case ARCH_MC: + return ic & (I_BASE | I_KX | I_FP | I_DEC | I_MIL); + 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)) + { + as_warn ("architecture of opcode conflicts with that of earlier instruction(s)"); + iclasses_seen &= ~ic; } + return 1; + } } @@ -2514,162 +2837,189 @@ int ic; /* Instruction class; one of: /* ARGSUSED */ void - md_operand (expressionP) -expressionS *expressionP; +md_operand (expressionP) + expressionS *expressionP; { } /* We have no need to default values of symbols. */ /* ARGSUSED */ -symbolS *md_undefined_symbol(name) -char *name; +symbolS * +md_undefined_symbol (name) + char *name; { - return 0; -} /* md_undefined_symbol() */ + return 0; +} /* md_undefined_symbol() */ /* Exactly what point is a PC-relative offset relative TO? 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; - md_number_to_imm(place, val, fixP->fx_size, fixP); - break; - case 1: - md_number_to_disp(place, - 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); - break; - default: - as_fatal("Internal error in md_apply_fix() in file \"%s\"", __FILE__); - } /* OVE: maybe one ought to put _imm _disp _chars in one md-func */ - } else { - md_number_to_field(place, val, fixP->fx_bit_fixP); - } - - return; -} /* md_apply_fix() */ + 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; + md_number_to_imm (place, val, fixP->fx_size, fixP); + break; + case 1: + md_number_to_disp (place, + 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); + break; + default: + as_fatal ("Internal error in md_apply_fix() in file \"%s\"", __FILE__); + } /* OVE: maybe one ought to put _imm _disp _chars in one md-func */ + } + else + { + md_number_to_field (place, val, fixP->fx_bit_fixP); + } + + return; +} /* md_apply_fix() */ #if defined(OBJ_AOUT) | defined(OBJ_BOUT) -void tc_bout_fix_to_chars(where, fixP, segment_address_in_file) -char *where; -fixS *fixP; -relax_addressT segment_address_in_file; +void +tc_bout_fix_to_chars (where, fixP, segment_address_in_file) + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; { - static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 }; - struct relocation_info ri; - symbolS *symbolP; - - /* JF this is for paranoia */ - memset((char *)&ri, '\0', sizeof(ri)); - symbolP = fixP->fx_addsy; - know(symbolP != 0 || fixP->fx_r_type != NO_RELOC); - ri.r_bsr = fixP->fx_bsr; /*SAC LD RELAX HACK */ - /* These two 'cuz of NS32K */ - ri.r_callj = fixP->fx_callj; - if(fixP->fx_bit_fixP) { - ri.r_length = 1; - } - else { - 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 (fixP->fx_r_type != NO_RELOC) - { - switch (fixP->fx_r_type) - { - case rs_align: - ri.r_index = -2; - ri.r_pcrel = 1; - ri.r_length = fixP->fx_size - 1; - break; - case rs_org: - ri.r_index = -2; - ri.r_pcrel = 0; - break; - case rs_fill: - ri.r_index = -1; - break; - default: - abort (); - } - ri.r_extern = 0; - } - else if (linkrelax || !S_IS_DEFINED(symbolP)) { - ri.r_extern = 1; - ri.r_index = symbolP->sy_number; - } else { - ri.r_extern = 0; - ri.r_index = S_GET_TYPE(symbolP); + static unsigned char nbytes_r_length[] = + {42, 0, 1, 42, 2}; + struct relocation_info ri; + symbolS *symbolP; + + /* JF this is for paranoia */ + memset ((char *) &ri, '\0', sizeof (ri)); + symbolP = fixP->fx_addsy; + know (symbolP != 0 || fixP->fx_r_type != NO_RELOC); + ri.r_bsr = fixP->fx_bsr; /*SAC LD RELAX HACK */ + /* These two 'cuz of NS32K */ + ri.r_callj = fixP->fx_callj; + if (fixP->fx_bit_fixP) + { + ri.r_length = 2; + } + else + { + 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 (fixP->fx_r_type != NO_RELOC) + { + switch (fixP->fx_r_type) + { + case rs_align: + ri.r_index = -2; + ri.r_pcrel = 1; + ri.r_length = fixP->fx_size - 1; + break; + case rs_org: + ri.r_index = -2; + ri.r_pcrel = 0; + break; + case rs_fill: + ri.r_index = -1; + break; + default: + abort (); } - - /* Output the relocation information in machine-dependent form. */ - md_ri_to_chars(where, &ri); - - return; -} /* tc_bout_fix_to_chars() */ + ri.r_extern = 0; + } + else if (linkrelax || !S_IS_DEFINED (symbolP)) + { + ri.r_extern = 1; + ri.r_index = symbolP->sy_number; + } + else + { + ri.r_extern = 0; + ri.r_index = S_GET_TYPE (symbolP); + } + + /* Output the relocation information in machine-dependent form. */ + md_ri_to_chars (where, &ri); + + return; +} /* tc_bout_fix_to_chars() */ #endif /* OBJ_AOUT or OBJ_BOUT */ /* Align an address by rounding it up to the specified boundary. */ -long md_section_align(seg, addr) -segT seg; -long addr; /* Address to be rounded up */ +long +md_section_align (seg, addr) + segT seg; + long addr; /* Address to be rounded up */ { - return((addr + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg])); -} /* md_section_align() */ + return ((addr + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg])); +} /* md_section_align() */ #ifdef OBJ_COFF -void tc_headers_hook(headers) -object_headers *headers; +void +tc_headers_hook (headers) + object_headers *headers; { - /* 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){ - headers->filehdr.f_flags |= F_I960CA; - } else if (iclasses_seen & I_MIL){ - headers->filehdr.f_flags |= F_I960MC; - } else if (iclasses_seen & (I_DEC|I_FP)){ - headers->filehdr.f_flags |= F_I960KB; - } else { - headers->filehdr.f_flags |= F_I960KA; - } /* set arch flag */ - - if (flagseen['R']) { - headers->filehdr.f_magic = I960RWMAGIC; - headers->aouthdr.magic = OMAGIC; - } else { - headers->filehdr.f_magic = I960ROMAGIC; - headers->aouthdr.magic = NMAGIC; - } /* set magic numbers */ - - return; -} /* tc_headers_hook() */ + /* 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) + { + headers->filehdr.f_flags |= F_I960CA; + } + else if (iclasses_seen & I_MIL) + { + headers->filehdr.f_flags |= F_I960MC; + } + else if (iclasses_seen & (I_DEC | I_FP)) + { + headers->filehdr.f_flags |= F_I960KB; + } + else + { + headers->filehdr.f_flags |= F_I960KA; + } /* set arch flag */ + + if (flagseen['R']) + { + headers->filehdr.f_magic = I960RWMAGIC; + headers->aouthdr.magic = OMAGIC; + } + else + { + headers->filehdr.f_magic = I960ROMAGIC; + headers->aouthdr.magic = NMAGIC; + } /* set magic numbers */ + + return; +} /* tc_headers_hook() */ + #endif /* OBJ_COFF */ /* @@ -2691,43 +3041,50 @@ object_headers *headers; * */ -void tc_crawl_symbol_chain(headers) -object_headers *headers; +void +tc_crawl_symbol_chain (headers) + object_headers *headers; { - symbolS *symbolP; - - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { + symbolS *symbolP; + + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + { #ifdef OBJ_COFF - if (TC_S_IS_SYSPROC(symbolP)) { - /* second aux entry already contains the sysproc number */ - S_SET_NUMBER_AUXILIARY(symbolP, 2); - S_SET_STORAGE_CLASS(symbolP, C_SCALL); - S_SET_DATA_TYPE(symbolP, S_GET_DATA_TYPE(symbolP) | (DT_FCN << N_BTSHFT)); - continue; - } /* rewrite sysproc */ + if (TC_S_IS_SYSPROC (symbolP)) + { + /* second aux entry already contains the sysproc number */ + S_SET_NUMBER_AUXILIARY (symbolP, 2); + S_SET_STORAGE_CLASS (symbolP, C_SCALL); + S_SET_DATA_TYPE (symbolP, S_GET_DATA_TYPE (symbolP) | (DT_FCN << N_BTSHFT)); + 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)) { - S_SET_EXTERNAL(symbolP); - S_SET_EXTERNAL(balP); - as_warn("Warning: making leafproc entries %s and %s both global\n", - S_GET_NAME(symbolP), S_GET_NAME(balP)); - } /* externality mismatch */ - } /* if callname */ - } /* walk the symbol chain */ - - return; -} /* tc_crawl_symbol_chain() */ + + 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)) + { + S_SET_EXTERNAL (symbolP); + S_SET_EXTERNAL (balP); + as_warn ("Warning: making leafproc entries %s and %s both global\n", + S_GET_NAME (symbolP), S_GET_NAME (balP)); + } /* externality mismatch */ + } /* if callname */ + } /* walk the symbol chain */ + + return; +} /* tc_crawl_symbol_chain() */ /* * For aout or bout, the bal immediately follows the call. @@ -2736,73 +3093,90 @@ object_headers *headers; * in the second aux entry of the call. */ -void tc_set_bal_of_call(callP, balP) -symbolS *callP; -symbolS *balP; +#undef OBJ_ABOUT +#ifdef OBJ_AOUT +#define OBJ_ABOUT +#endif +#ifdef OBJ_BOUT +#define OBJ_ABOUT +#endif + +void +tc_set_bal_of_call (callP, balP) + symbolS *callP; + symbolS *balP; { - know(TC_S_IS_CALLNAME(callP)); - know(TC_S_IS_BALNAME(balP)); - + know (TC_S_IS_CALLNAME (callP)); + 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' + + callP->sy_symbol.ost_auxent[1].x_bal.x_balntry = (int) balP; + S_SET_NUMBER_AUXILIARY (callP, 2); + +#else /* ! OBJ_COFF */ +#ifdef OBJ_ABOUT + + /* If the 'bal' entry doesn't immediately follow the 'call' * symbol, unlink it from the symbol list and re-insert it. */ - if (symbol_next(callP) != 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 */ - - return; -} /* tc_set_bal_of_call() */ - -char *_tc_get_bal_of_call(callP) -symbolS *callP; + if (symbol_next (callP) != balP) + { + symbol_remove (balP, &symbol_rootP, &symbol_lastP); + symbol_append (balP, callP, &symbol_rootP, &symbol_lastP); + } /* if not in order */ + +#else /* ! OBJ_ABOUT */ + (as yet unwritten.); +#endif /* ! OBJ_ABOUT */ +#endif /* ! OBJ_COFF */ + + return; +} /* tc_set_bal_of_call() */ + +char * +_tc_get_bal_of_call (callP) + symbolS *callP; { - symbolS *retval; - - know(TC_S_IS_CALLNAME(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) - retval = symbol_next(callP); + retval = (symbolS *) (callP->sy_symbol.ost_auxent[1].x_bal.x_balntry); #else - (as yet unwritten.); -#endif /* switch on OBJ_FORMAT */ - - know(TC_S_IS_BALNAME(retval)); - return((char *) retval); -} /* _tc_get_bal_of_call() */ - -void tc_coff_symbol_emit_hook(symbolP) -symbolS *symbolP; +#ifdef OBJ_ABOUT + retval = symbol_next (callP); +#else + (as yet unwritten.); +#endif /* ! OBJ_ABOUT */ +#endif /* ! OBJ_COFF */ + + know (TC_S_IS_BALNAME (retval)); + return ((char *) retval); +} /* _tc_get_bal_of_call() */ + +void +tc_coff_symbol_emit_hook (symbolP) + symbolS *symbolP; { - if (TC_S_IS_CALLNAME(symbolP)) { + if (TC_S_IS_CALLNAME (symbolP)) + { #ifdef OBJ_COFF - symbolS *balP = tc_get_bal_of_call(symbolP); - - /* second aux entry contains the bal entry point */ - /* 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)); - /* fix up the bal symbol */ - S_SET_STORAGE_CLASS(balP, C_LABEL); + symbolS *balP = tc_get_bal_of_call (symbolP); + + /* second aux entry contains the bal entry point */ + /* 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)); + /* fix up the bal symbol */ + S_SET_STORAGE_CLASS (balP, C_LABEL); #endif /* OBJ_COFF */ - } /* only on calls */ - - return; -} /* tc_coff_symbol_emit_hook() */ + } /* only on calls */ + + return; +} /* tc_coff_symbol_emit_hook() */ void i960_handle_align (fragp) diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 775f9306afa..dea873da46e 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -34,7 +34,7 @@ the a.out file. The 2<<16 means that this is a 68020 file instead of an old-style 68000 file */ -long omagic = 2<<16|OMAGIC; /* Magic byte for header file */ +long omagic = 2 << 16 | OMAGIC; /* Magic byte for header file */ #else long omagic = OMAGIC; #endif @@ -141,194 +141,202 @@ static struct obstack robyn; */ -enum operand_type { - IMMED = 1, - DREG, - AREG, - AINDR, - ADEC, - AINC, - AOFF, - AINDX, - APODX, - AMIND, - APRDX, - ABSL, - MSCR, - REGLST, - DINDR -}; - - -struct m68k_exp { - char *e_beg; - char *e_end; - expressionS e_exp; - short e_siz; /* 0== default 1==short/byte 2==word 3==long */ -}; +enum operand_type + { + IMMED = 1, + DREG, + AREG, + AINDR, + ADEC, + AINC, + AOFF, + AINDX, + APODX, + AMIND, + APRDX, + ABSL, + MSCR, + REGLST, + DINDR + }; + + +struct m68k_exp + { + 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, 8-15==addr reg for operands that take both types */ -enum _register { - DATA = 1, /* 1- 8 == data registers 0-7 */ - DATA0 = DATA, - DATA1, - DATA2, - DATA3, - DATA4, - DATA5, - DATA6, - DATA7, - - ADDR, - ADDR0 = ADDR, - ADDR1, - ADDR2, - ADDR3, - ADDR4, - ADDR5, - ADDR6, - ADDR7, - - /* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */ - /* I think. . . */ - - SP = ADDR7, - - FPREG, /* Eight FP registers */ - FP0 = FPREG, - FP1, - FP2, - FP3, - FP4, - FP5, - FP6, - FP7, - COPNUM = (FPREG+8), /* Co-processor #1-#8 */ - COP0 = COPNUM, - COP1, - COP2, - COP3, - COP4, - COP5, - COP6, - COP7, - PC, /* Program counter */ - 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. */ - USP, /* User Stack Pointer */ - ISP, /* Interrupt stack pointer */ - SFC, - DFC, - CACR, - VBR, - CAAR, - MSP, - ITT0, - ITT1, - DTT0, - DTT1, - MMUSR, - TC, - SRP, - URP, - /* end of movec ordering constraints */ - - FPI, - FPS, - FPC, - - DRP, /* 68851 or 68030 MMU regs */ - CRP, - CAL, - VAL, - SCC, - AC, - BAD, - BAD0 = BAD, - BAD1, - BAD2, - BAD3, - BAD4, - BAD5, - BAD6, - BAD7, - BAC, - BAC0 = BAC, - BAC1, - BAC2, - BAC3, - BAC4, - BAC5, - BAC6, - BAC7, - PSR, /* aka MMUSR on 68030 (but not MMUSR on 68040) +enum _register + { + DATA = 1, /* 1- 8 == data registers 0-7 */ + DATA0 = DATA, + DATA1, + DATA2, + DATA3, + DATA4, + DATA5, + DATA6, + DATA7, + + ADDR, + ADDR0 = ADDR, + ADDR1, + ADDR2, + ADDR3, + ADDR4, + ADDR5, + ADDR6, + ADDR7, + + /* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */ + /* I think. . . */ + + SP = ADDR7, + + FPREG, /* Eight FP registers */ + FP0 = FPREG, + FP1, + FP2, + FP3, + FP4, + FP5, + FP6, + FP7, + COPNUM = (FPREG + 8), /* Co-processor #1-#8 */ + COP0 = COPNUM, + COP1, + COP2, + COP3, + COP4, + COP5, + COP6, + COP7, + PC, /* Program counter */ + 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. */ + USP, /* User Stack Pointer */ + ISP, /* Interrupt stack pointer */ + SFC, + DFC, + CACR, + VBR, + CAAR, + MSP, + ITT0, + ITT1, + DTT0, + DTT1, + MMUSR, + TC, + SRP, + URP, + /* end of movec ordering constraints */ + + FPI, + FPS, + FPC, + + DRP, /* 68851 or 68030 MMU regs */ + CRP, + CAL, + VAL, + SCC, + AC, + BAD, + BAD0 = BAD, + BAD1, + BAD2, + BAD3, + BAD4, + BAD5, + BAD6, + BAD7, + BAC, + BAC0 = BAC, + BAC1, + BAC2, + BAC3, + BAC4, + BAC5, + BAC6, + BAC7, + PSR, /* aka MMUSR on 68030 (but not MMUSR on 68040) and ACUSR on 68ec030 */ - PCSR, + PCSR, - IC, /* instruction cache token */ - DC, /* data cache token */ - NC, /* no cache token */ - BC, /* both caches token */ + IC, /* instruction cache token */ + DC, /* data cache token */ + NC, /* no cache token */ + BC, /* both caches token */ - TT0, /* 68030 access control unit regs */ - TT1, -}; + TT0, /* 68030 access control unit regs */ + TT1, + }; /* 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; -}; +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; + }; /* 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??? */ -}; +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??? */ + }; #define cpu_of_arch(x) ((x) & m68000up) #define float_of_arch(x) ((x) & mfloat) #define mmu_of_arch(x) ((x) & mmmu) -static struct m68k_it the_ins; /* the instruction being assembled */ +static struct m68k_it the_ins; /* the instruction being assembled */ /* Macros for adding things to the m68k_it struct */ @@ -378,14 +386,15 @@ static struct m68k_it the_ins; /* the instruction being assembled */ #define offs(exp) ((exp)->e_exp.X_add_number) -struct m68k_incant { - char *m_operands; - unsigned long m_opcode; - short m_opnum; - short m_codenum; - int m_arch; - struct m68k_incant *m_next; -}; +struct m68k_incant + { + char *m_operands; + unsigned long m_opcode; + short m_opnum; + short m_codenum; + int m_arch; + struct m68k_incant *m_next; + }; @@ -395,36 +404,36 @@ struct m68k_incant { #if __STDC__ == 1 -static char *crack_operand(char *str, struct m68k_op *opP); -static int get_num(struct m68k_exp *exp, int ok); -static int get_regs(int i, char *str, struct m68k_op *opP); -static int reverse_16_bits(int in); -static int reverse_8_bits(int in); -static int try_index(char **s, struct m68k_op *opP); -static void install_gen_operand(int mode, int val); -static void install_operand(int mode, int val); -static void s_bss(void); -static void s_data1(void); -static void s_data2(void); -static void s_even(void); -static void s_proc(void); +static char *crack_operand (char *str, struct m68k_op *opP); +static int get_num (struct m68k_exp *exp, int ok); +static int get_regs (int i, char *str, struct m68k_op *opP); +static int reverse_16_bits (int in); +static int reverse_8_bits (int in); +static int try_index (char **s, struct m68k_op *opP); +static void install_gen_operand (int mode, int val); +static void install_operand (int mode, int val); +static void s_bss (void); +static void s_data1 (void); +static void s_data2 (void); +static void s_even (void); +static void s_proc (void); #else /* not __STDC__ */ -static char *crack_operand(); -static int get_num(); -static int get_regs(); -static int reverse_16_bits(); -static int reverse_8_bits(); -static int try_index(); -static void install_gen_operand(); -static void install_operand(); -static void s_bss(); -void s_align_bytes(); -static void s_data1(); -static void s_data2(); -static void s_even(); -static void s_proc(); +static char *crack_operand (); +static int get_num (); +static int get_regs (); +static int reverse_16_bits (); +static int reverse_8_bits (); +static int try_index (); +static void install_gen_operand (); +static void install_operand (); +static void s_bss (); +void s_align_bytes (); +static void s_data1 (); +static void s_data2 (); +static void s_even (); +static void s_proc (); #endif /* not __STDC__ */ @@ -446,43 +455,44 @@ static int current_architecture = 0; 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 */ - { 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(ABRANCH,SHORT)}, - { (32767), (-32768), 2, TAB(ABRANCH,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 }, - - }; + 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 (ABRANCH, SHORT)}, + {(32767), (-32768), 2, TAB (ABRANCH, 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 @@ -495,43 +505,44 @@ const relax_typeS 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 }, +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}, #ifdef TE_SUN3 - { "align", s_align_bytes, 0 }, + {"align", s_align_bytes, 0}, #endif - { 0, 0, 0 } + {0, 0, 0} }; /* The mote pseudo ops are put into the opcode table, since they - don't start with a . they look like opcodes to gas. + don't start with a . they look like opcodes to gas. */ -extern void obj_coff_section(); +extern void obj_coff_section (); const pseudo_typeS mote_pseudo_table[] = { - { "dc.l", cons,4}, - { "dc", cons,2}, - { "dc.w", cons,2}, - { "dc.b", cons,1}, + {"dc.l", cons, 4}, + {"dc", cons, 2}, + {"dc.w", cons, 2}, + {"dc.b", cons, 1}, - { "ds.l", s_space,4}, - { "ds", s_space,2}, - { "ds.w", s_space,2}, - { "ds.b", s_space,1}, + {"ds.l", s_space, 4}, + {"ds", s_space, 2}, + {"ds.w", s_space, 2}, + {"ds.b", s_space, 1}, - { "xdef", s_globl, 0}, - { "align", s_align_ptwo, 0}, + {"xdef", s_globl, 0}, + {"align", s_align_ptwo, 0}, #ifdef M68KCOFF - { "sect", obj_coff_section,0}, - { "section", obj_coff_section,0}, + {"sect", obj_coff_section, 0}, + {"section", obj_coff_section, 0}, #endif 0, }; @@ -550,10 +561,11 @@ const pseudo_typeS mote_pseudo_table[] = extern char *input_line_pointer; -enum { - FAIL = 0, - OK = 1, -}; +enum + { + FAIL = 0, + OK = 1, + }; /* JF these tables here are for speed at the expense of size */ /* You can replace them with the #if 0 versions if you really @@ -579,8 +591,9 @@ static char alt_notend_table[256]; * advance the pointer. */ -enum _register m68k_reg_parse(ccp) -register char **ccp; +enum _register +m68k_reg_parse (ccp) + register char **ccp; { char *start = *ccp; char c; @@ -600,19 +613,19 @@ register char **ccp; return FAIL; c = *p++; - while (isalpha(c) || isdigit(c) || c == '_') + while (isalpha (c) || isdigit (c) || c == '_') { c = *p++; } - * -- p = 0; - symbolP = symbol_find(start); - *p = c; + *--p = 0; + symbolP = symbol_find (start); + *p = c; - if (symbolP && S_GET_SEGMENT(symbolP) == SEG_REGISTER) + if (symbolP && S_GET_SEGMENT (symbolP) == SEG_REGISTER) { *ccp = p; - return S_GET_VALUE(symbolP); + return S_GET_VALUE (symbolP); } return FAIL; @@ -624,69 +637,81 @@ register char **ccp; /* Parse an index specification using Motorola syntax. */ static int -try_moto_index(s,opP) -char **s; -struct m68k_op *opP; +try_moto_index (s, opP) + char **s; + struct m68k_op *opP; { - register int i; - char *ss; - - ss= *s; - /* SKIP_W(); */ - if(*ss==' ') ss++; - i=m68k_reg_parse(&ss); - if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ - opP->error="Invalid index register"; - *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(); - if(mklower(*ss)=='w') opP->isiz=2; - else if(mklower(*ss)=='l') opP->isiz=3; - else { - opP->error="Size spec not .W or .L"; - *s=ss; - return FAIL; - } - SKIP_W(); - if(*ss=='.' || *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; + register int i; + char *ss; + + ss = *s; + /* SKIP_W(); */ + if (*ss == ' ') + ss++; + i = m68k_reg_parse (&ss); + if (!(i >= DATA + 0 && i <= ADDR + 7)) + { /* if i is not DATA or ADDR reg */ + opP->error = "Invalid index register"; + *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 (); + if (mklower (*ss) == 'w') + opP->isiz = 2; + else if (mklower (*ss) == 'l') + opP->isiz = 3; + else + { + opP->error = "Size spec not .W or .L"; + *s = ss; + return FAIL; + } + SKIP_W (); + if (*ss == '.' || *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(); - *s=ss; - return OK; + SKIP_W (); + } + else + opP->imul = 1; + if (*ss != ')') + { + opP->error = "Missing )"; + *s = ss; + return FAIL; + } + SKIP_W (); + *s = ss; + return OK; } /* @@ -706,80 +731,91 @@ struct m68k_op *opP; * */ -static int try_index(s,opP) -char **s; -struct m68k_op *opP; +static int +try_index (s, opP) + char **s; + struct m68k_op *opP; { - register int i; - char *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; - } - SKIP_W(); - switch(*ss) { - case 'w': - case 'W': - opP->isiz=2; - break; - case 'l': - case 'L': - opP->isiz=3; - break; + register int i; + char *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; + } + 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 '1': + case '2': + case '4': + case '8': + if (cpu_of_arch (current_architecture) < m68020) + { + opP->error = "no index scaling in pre-68020's"; + *s = ss; + return FAIL; + } + opP->imul = *ss - '0'; + break; default: - opP->error="Index register size spec not :w or :l"; - *s=ss; - return FAIL; + opP->error = "index multiplier not 1, 2, 4 or 8"; + *s = ss; + return FAIL; } - SKIP_W(); - if(*ss==':') { - SKIP_W(); - switch(*ss) { - case '1': - case '2': - case '4': - case '8': - if (cpu_of_arch(current_architecture) < m68020) { - opP->error="no index scaling in pre-68020's"; - *s=ss; - return FAIL; - } - 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; - } - SKIP_W(); - *s=ss; - return OK; -} /* try_index() */ + SKIP_W (); + } + else + opP->imul = 1; + if (*ss != ')') + { + opP->error = "Missing )"; + *s = ss; + return FAIL; + } + SKIP_W (); + *s = ss; + return OK; +} /* try_index() */ /* Ian Taylor expanded this function to accept both MIT and Motorola syntax. I removed the old comment, since it was wrong. The syntax @@ -789,90 +825,104 @@ struct m68k_op *opP; character. */ int - m68k_ip_op(str,opP) -char *str; -register struct m68k_op *opP; +m68k_ip_op (str, opP) + char *str; + register struct m68k_op *opP; { - char *strend; - long i; - char *parse_index(); - int needp; + char *strend; + long i; + char *parse_index (); + int needp; - if (*str==' ') { - str++; - } /* Find the beginning of the string */ + if (*str == ' ') + { + str++; + } /* Find the beginning of the string */ - if(!*str) { - opP->error="Missing operand"; - return FAIL; - } /* Out of gas */ + if (!*str) + { + opP->error = "Missing operand"; + return FAIL; + } /* Out of gas */ - for(strend = str; *strend; strend++) - ; - --strend; + 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 */ + 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); + i = m68k_reg_parse (&str); - if (i!=FAIL) { - if(*str=='/' || *str=='-') { - /* "Rm-Rn/Ro-Rp" Register list for MOVEM instruction */ - opP->mode=REGLST; - return get_regs(i,str,opP); - } - if(*str=='\0') { - opP->reg=i; - /* "Rn" Register Direct mode */ - 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 != FAIL) + { + if (*str == '/' || *str == '-') + { + /* "Rm-Rn/Ro-Rp" Register list for MOVEM instruction */ + opP->mode = REGLST; + return get_regs (i, str, opP); + } + if (*str == '\0') + { + opP->reg = i; + /* "Rn" Register Direct mode */ + 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 (*str!='@') { - char *stmp; + if (*str != '@') + { + char *stmp; - if ((stmp=strchr(str,'@')) != 0) { - opP->con1=add_exp(str,stmp-1); - if(stmp==strend) { - opP->mode=AINDX; - return(OK); - } + 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 */ + 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); + 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 '@' */ + if (i == FAIL) + { + opP->mode = AMIND; + } + else + { + opP->mode = APODX; + } + return (OK); + } /* if there's an '@' */ #ifndef MIT_SYNTAX_ONLY - /* The operand has no '@'. Try to parse it using + /* The operand has no '@'. Try to parse it using Motorola syntax. */ - /* Logic of the parsing switch(*str): + /* Logic of the parsing switch(*str): case opP->mode = ---- ----------- #anything IMMED 1 @@ -894,255 +944,303 @@ register struct m68k_op *opP; EXP2 means not REG and not '(' and not '-(' */ - if(*str=='(') { - str++; - i=m68k_reg_parse(&str); - if((iADDR+7) - && (iDATA+7 - || *str != ')' || str[1] != '0') - && 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 + if (*str == '(') + { + str++; + i = m68k_reg_parse (&str); + if ((i < ADDR + 0 || i > ADDR + 7) + && (i < DATA + 0 || i > DATA + 7 + || *str != ')' || str[1] != '0') + && 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 or "(Dn)" for cas2. */ - if (i>=DATA+0 && i<=DATA+7) - opP->mode=DINDR; - else - 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_moto_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((iADDR+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_moto_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->mode = ABSL; - opP->con1 = add_exp(str-1,strend); - return OK; - } - } - } + if (i >= DATA + 0 && i <= DATA + 7) + opP->mode = DINDR; + else + 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_moto_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) + { + opP->reg = i; + if (*str == ')') + { + /* "(d,An)" Register Indirect w Displacement */ + opP->mode = AOFF; + return OK; + } + if (*str == ',') + { + str++; + i = try_moto_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->mode = ABSL; + opP->con1 = add_exp (str - 1, strend); + return OK; + } + } + } - if(*str=='-') { - if(str[1]=='(') { - str = str+2; - i=m68k_reg_parse(&str); - if((iADDR+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; - } - opP->error="Bad indirect syntax"; - return FAIL; - } - opP->mode = ABSL; - opP->con1 = add_exp(str-2,strend); - return OK; - } - /* if '-' but not "-(', do nothing */ - } + 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; + } + opP->error = "Bad indirect syntax"; + return FAIL; + } + opP->mode = ABSL; + opP->con1 = add_exp (str - 2, strend); + return OK; + } + /* if '-' but not "-(', do nothing */ + } + + /* whether *str=='-' or not */ + { + /* "EXP2" or "EXP2(REG..." */ + char *stmp; + char *index (); + if (stmp = index (str, '(')) + { + char *ostr = str; - /* whether *str=='-' or not */ + 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 && i != FAIL) + { + /* Can't indirect off non address regs */ + opP->error = "Invalid indirect register"; + return FAIL; + } + if (i != FAIL) + { + opP->reg = i; + if (*str == ')') { - /* "EXP2" or "EXP2(REG..." */ - char *stmp; - char *index(); - if(stmp=index(str,'(')) { - char *ostr=str; - - opP->con1=add_exp(str,stmp-1); - str=stmp+1; - i=m68k_reg_parse(&str); - if((iADDR+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==')') { - /* "d(An)" Register Indirect w Displacement */ - opP->mode=AOFF; - return OK; - } - if(*str==',') { - str++; - i=try_moto_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->mode = ABSL; - opP->con1 = add_exp(ostr,strend); - return OK; - } - } - else { - /* "EXP2" Absolute */ - opP->mode=ABSL; - opP->isiz=0; - if(strend[-1]=='.' || strend[-1]==':') { - /* mode ==foo.[wl] */ - switch(*strend) { - case 'w': - case 'W': - opP->isiz=2; - strend-=2; - break; - case 'l': - case 'L': - opP->isiz=3; - strend-=2; - break; - } - } - opP->con1=add_exp(str,strend); - return OK; - } + /* "d(An)" Register Indirect w Displacement */ + opP->mode = AOFF; + return OK; } - /*NOTREACHED*/ -#else /* defined (MIT_SYNTAX_ONLY) */ - opP->mode=ABSL; - opP->con1=add_exp(str,strend); + if (*str == ',') + { + str++; + i = try_moto_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->mode = ABSL; + opP->con1 = add_exp (ostr, strend); return OK; -#endif /* defined (MIT_SYNTAX_ONLY) */ } + } + else + { + /* "EXP2" Absolute */ + opP->mode = ABSL; + opP->isiz = 0; + if (strend[-1] == '.' || strend[-1] == ':') + { + /* mode ==foo.[wl] */ + switch (*strend) + { + case 'w': + case 'W': + opP->isiz = 2; + strend -= 2; + break; + case 'l': + case 'L': + opP->isiz = 3; + strend -= 2; + break; + } + } + opP->con1 = add_exp (str, strend); + return OK; + } + } + /*NOTREACHED*/ +#else /* defined (MIT_SYNTAX_ONLY) */ + opP->mode = ABSL; + opP->con1 = add_exp (str, strend); + return OK; +#endif /* defined (MIT_SYNTAX_ONLY) */ + } - opP->reg=i; + opP->reg = i; - /* Can't indirect off non address regs, but Dx@ is OK for cas2 */ - if((iADDR+7) && i!=PC && i!=ZPC && i!=FAIL - && (str[1] != '\0' || iDATA+7)) { - opP->error="Invalid indirect register"; - return FAIL; - } - know(*str == '@'); + /* Can't indirect off non address regs, but Dx@ is OK for cas2 */ + if ((i < ADDR + 0 || i > ADDR + 7) && i != PC && i != ZPC && i != FAIL + && (str[1] != '\0' || i < DATA + 0 || i > DATA + 7)) + { + opP->error = "Invalid indirect register"; + return FAIL; + } + know (*str == '@'); - str++; - switch(*str) { - case '\0': - if (iDATA+7) - opP->mode=AINDR; - else - opP->mode=DINDR; - return OK; - case '-': - opP->mode=ADEC; - return OK; - case '+': - opP->mode=AINC; - return OK; - case '(': - str++; - break; - default: - opP->error="Junk after indirect"; - return FAIL; + str++; + switch (*str) + { + case '\0': + if (i < DATA + 0 || i > DATA + 7) + opP->mode = AINDR; + else + opP->mode = DINDR; + return OK; + case '-': + opP->mode = ADEC; + return OK; + case '+': + opP->mode = AINC; + return OK; + case '(': + str++; + 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]==':') { + /* if(str[-3]==':') { int siz; switch(str[-2]) { @@ -1165,155 +1263,191 @@ register struct m68k_op *opP; 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; - } - } + 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 == '@') + { + if (str[1] == '(') + { + needp = 1; + str += 2; } - /* Next thing had better be another @ */ - if (*str == '@') { - if (str[1] == '(') { - needp = 1; - str+=2; - } - else { - needp = 0; - str++; - } + else + { + needp = 0; + str++; } + } - if ((current_architecture & m68020up) == 0) { - return(FAIL); - } /* if target is not a '20 or better */ + if ((current_architecture & m68020up) == 0) + { + return (FAIL); + } /* if target is not a '20 or better */ - if(opP->ireg != FAIL) { - opP->mode = APRDX; + 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); + 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; + if (i == FAIL) + { + char *beg_str; - beg_str = str; + beg_str = str; - for (i = 1; i; ) { - switch(*str++) { - case '\0': - if (needp) - opP->error="Missing )"; - return(FAIL); - break; - case ',': i=0; break; - case '(': i++; break; - case ')': --i; break; - } - } + for (i = 1; i;) + { + switch (*str++) + { + case '\0': + if (needp) + opP->error = "Missing )"; + return (FAIL); + break; + case ',': + i = 0; + break; + case '(': + i++; + break; + case ')': + --i; + break; + } + } - opP->con2=add_exp(beg_str,str-2); + 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 (str[-1] == ',') + { + if (opP->ireg != FAIL) + { + opP->error = "Can't have two index regs"; + return (FAIL); + } - i = try_index(&str, opP); + i = try_index (&str, opP); - if (i == FAIL) { - opP->error = "malformed index reg"; - return(FAIL); - } + 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; - } - } else { - opP->mode = APODX; + opP->mode = APODX; } - - if(*str!='\0') { - opP->error="Junk after indirect"; - return FAIL; + else if (opP->ireg != FAIL) + { + opP->mode = APRDX; + } + else + { + opP->mode = AMIND; } - return(OK); -} /* m68k_ip_op() */ + } + else + { + opP->mode = APODX; + } + + if (*str != '\0') + { + opP->error = "Junk after indirect"; + return FAIL; + } + return (OK); +} /* m68k_ip_op() */ #ifdef M68KCOFF -short tc_coff_fix2rtype(fixP) -fixS *fixP; +short +tc_coff_fix2rtype (fixP) + fixS *fixP; { - return (fixP->fx_pcrel ? - (fixP->fx_size == 1 ? R_PCRBYTE : - fixP->fx_size == 2 ? R_PCRWORD : - R_PCRLONG): - (fixP->fx_size == 1 ? R_RELBYTE : - fixP->fx_size == 2 ? R_RELWORD : - R_RELLONG)); + return (fixP->fx_pcrel ? + (fixP->fx_size == 1 ? R_PCRBYTE : + fixP->fx_size == 2 ? R_PCRWORD : + R_PCRLONG) : + (fixP->fx_size == 1 ? R_RELBYTE : + fixP->fx_size == 2 ? R_RELWORD : + R_RELLONG)); } #endif -#ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */ -main() +#ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */ +main () { - char buf[128]; - struct m68k_op thark; + char buf[128]; + struct m68k_op thark; - for(;;) { - if(!gets(buf)) - break; - memset(&thark, '\0', 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); + for (;;) + { + if (!gets (buf)) + break; + memset (&thark, '\0', 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 +static struct hash_control *op_hash = NULL; /* handle of the OPCODE hash table NULL means any use before m68k_ip_begin() will crash */ - + /* * m 6 8 k _ i p ( ) * @@ -1339,7 +1473,8 @@ 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) +void +m68k_ip (instring) char *instring; { register char *p; @@ -1349,10 +1484,10 @@ void m68k_ip (instring) register int tmpreg = 0, baseo = 0, outro = 0, nextword; char *pdot, *pdotmove; int siz1, siz2; - char c; - int losing; - int opsfound; - char *crack_operand(); + char c; + int losing; + int opsfound; + char *crack_operand (); LITTLENUM_TYPE words[6]; LITTLENUM_TYPE *wordp; unsigned long ok_arch = 0; @@ -1363,652 +1498,705 @@ void m68k_ip (instring) /* Scan up to end of operation-code, which MUST end in end-of-string or exactly 1 space. */ pdot = 0; - for (p = instring; *p != '\0'; p++) { - if (*p == ' ') - break; - if (*p == '.') - pdot = p; - } + for (p = instring; *p != '\0'; p++) + { + if (*p == ' ') + break; + if (*p == '.') + pdot = p; + } - if (p == instring) { - the_ins.error = "No operator"; - the_ins.opcode[0] = NULL; - /* the_ins.numo=1; */ - return; - } + 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. Remove a dot, first, since the opcode tables have none. */ - if (pdot != NULL) { - for (pdotmove=pdot; pdotmovepdot; pdotmove--) - *pdotmove=pdotmove[-1]; - *pdot='.'; - ++p; - } + if (pdot != NULL) + { + for (pdotmove = p; pdotmove > pdot; pdotmove--) + *pdotmove = pdotmove[-1]; + *pdot = '.'; + ++p; + } - if (opcode == NULL) { - the_ins.error = "Unknown operator"; - the_ins.opcode[0] = NULL; - /* the_ins.numo=1; */ - return; - } + 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; + while (*p == ' ') + ++p; - if (opcode->m_operands == 0) { - char *old = input_line_pointer; - *old = '\n'; - input_line_pointer = p; - /* Ahh - it's a motorola style psuedo op */ - mote_pseudo_table[opcode->m_opnum].poc_handler - ( mote_pseudo_table[opcode->m_opnum].poc_val); - input_line_pointer = old; - *old = 0; + if (opcode->m_operands == 0) + { + char *old = input_line_pointer; + *old = '\n'; + input_line_pointer = p; + /* Ahh - it's a motorola style psuedo op */ + mote_pseudo_table[opcode->m_opnum].poc_handler + (mote_pseudo_table[opcode->m_opnum].poc_val); + input_line_pointer = old; + *old = 0; - return; - } + return; + } - for(opP = &the_ins.operands[0]; *p; opP++) { + for (opP = &the_ins.operands[0]; *p; opP++) + { - p = crack_operand(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; + if (opcode->m_operands[0] == 'I') + { + int n; - for(n=opsfound;n>0;--n) - the_ins.operands[n]=the_ins.operands[n-1]; + for (n = opsfound; n > 0; --n) + the_ins.operands[n] = the_ins.operands[n - 1]; - memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0])); - the_ins.operands[0].mode=MSCR; - the_ins.operands[0].reg=COPNUM; /* COP #1 */ - opsfound++; - } + memset ((char *) (&the_ins.operands[0]), '\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, + 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; - ok_arch |= opcode->m_arch; - } - 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: + if (opsfound != opcode->m_opnum + || ((opcode->m_arch & current_architecture) == 0)) + { + ++losing; + ok_arch |= opcode->m_arch; + } + 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 ... + /* 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 '`': - switch (opP->mode) { - case MSCR: case IMMED: case DREG: case AREG: - case AINC: case REGLST: case AINDR: - 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 '3': - if (opP->mode != MSCR || (opP->reg != TT0 && opP->reg != TT1)) - 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->regreg>=COPNUM+7) - losing++; - break; + 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 '`': + switch (opP->mode) + { + case MSCR: + case IMMED: + case DREG: + case AREG: + case AINC: + case REGLST: + case AINDR: + 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 '#': + 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 '3': + if (opP->mode != MSCR || (opP->reg != TT0 && opP->reg != TT1)) + 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 '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; - 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; + t = get_num (opP->con1, 80); + if (!issbyte (t) || isvar (opP->con1)) + 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 'O': - if(opP->mode!=DREG && opP->mode!=IMMED) - losing++; - break; + case 'Q': + if (opP->mode != IMMED) + losing++; + else + { + long t; - 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; + 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 'R': + if (opP->mode != DREG && opP->mode != AREG) + losing++; + break; - case 'r': - if (opP->mode!=AINDR && opP->mode!=DINDR) - losing++; - break; + case 'r': + if (opP->mode != AINDR && opP->mode != DINDR) + 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 == FPI || opP->reg == FPS || opP->reg == FPC)) + losing++; + break; - case 'S': - if(opP->mode!=MSCR || opP->reg!=SR) - losing++; - break; + case 'S': + if (opP->mode != MSCR || opP->reg != SR) + losing++; + break; - case 't': - if (opP->mode != IMMED) - losing++; - else - { - long t = get_num (opP->con1, 80); - if (t < 0 || t > 7 || isvar (opP->con1)) - losing++; - } - break; + case 't': + if (opP->mode != IMMED) + losing++; + else + { + long t = get_num (opP->con1, 80); + if (t < 0 || t > 7 || isvar (opP->con1)) + losing++; + } + break; - case 'U': - if(opP->mode!=MSCR || opP->reg!=USP) - losing++; - break; + case 'U': + if (opP->mode != MSCR || opP->reg != USP) + losing++; + break; - /* JF these are out of order. We could put them + /* 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. Don't forget that you need these operands to use 68030 MMU instructions. */ #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; + /* 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 'Z': - if (opP->reg != PCSR) - 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 '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; - case '_': - if (opP->mode != ABSL) { - ++losing; - } /* not absolute */ - break; + default: + as_fatal ("Internal error: Operand mode %c unknown in line %d of file \"%s\"", + *s, __LINE__, __FILE__); + } /* switch on type of operand */ - default: - as_fatal("Internal error: Operand mode %c unknown in line %d of file \"%s\"", - *s, __LINE__, __FILE__); - } /* switch on type of operand */ + if (losing) + break; + } /* for each operand */ + } /* if immediately wrong */ - if (losing) + if (!losing) + { break; - } /* for each operand */ - } /* if immediately wrong */ + } /* got it. */ - if (!losing) { - break; - } /* got it. */ - - opcode = opcode->m_next; + opcode = opcode->m_next; - if (!opcode) { - if (ok_arch - && !(ok_arch & current_architecture)) + if (!opcode) { - char buf[200], *cp; - int len; - strcpy (buf, "invalid instruction for this architecture; needs "); - cp = buf + strlen (buf); - switch (ok_arch) + if (ok_arch + && !(ok_arch & current_architecture)) { - case mfloat: - strcpy (cp, "fpu (68040 or 68881/68882)"); - break; - case mmmu: - strcpy (cp, "mmu (68030 or 68851)"); - break; - case m68020up: - strcpy (cp, "68020 or higher"); - break; - case m68000up: - strcpy (cp, "68000 or higher"); - break; - case m68010up: - strcpy (cp, "68010 or higher"); - break; - default: - { - int got_one = 0, idx; - const static struct { - int arch; - const char *name; - } archs[] = { - m68000, "68000", - m68010, "68010", - m68020, "68020", - m68030, "68030", - m68040, "68040", - cpu32, "cpu32", - m68881, "68881", - m68851, "68851", - }; - for (idx = 0; idx < sizeof (archs)/sizeof (archs[0]); idx++) + char buf[200], *cp; + int len; + strcpy (buf, "invalid instruction for this architecture; needs "); + cp = buf + strlen (buf); + switch (ok_arch) + { + case mfloat: + strcpy (cp, "fpu (68040 or 68881/68882)"); + break; + case mmmu: + strcpy (cp, "mmu (68030 or 68851)"); + break; + case m68020up: + strcpy (cp, "68020 or higher"); + break; + case m68000up: + strcpy (cp, "68000 or higher"); + break; + case m68010up: + strcpy (cp, "68010 or higher"); + break; + default: { - if (archs[idx].arch & ok_arch) + int got_one = 0, idx; + const static struct + { + int arch; + const char *name; + } + archs[] = + { + m68000, "68000", + m68010, "68010", + m68020, "68020", + m68030, "68030", + m68040, "68040", + cpu32, "cpu32", + m68881, "68881", + m68851, "68851", + }; + for (idx = 0; idx < sizeof (archs) / sizeof (archs[0]); idx++) { - if (got_one) + if (archs[idx].arch & ok_arch) { - strcpy (cp, " or "); + if (got_one) + { + strcpy (cp, " or "); + cp += strlen (cp); + } + got_one = 1; + strcpy (cp, archs[idx].name); cp += strlen (cp); } - got_one = 1; - strcpy (cp, archs[idx].name); - cp += strlen (cp); } } - } + } + len = cp - buf + 1; + cp = malloc (len); + strcpy (cp, buf); + the_ins.error = cp; } - len = cp - buf + 1; - cp = malloc (len); - strcpy (cp, buf); - the_ins.error = cp; - } - else - the_ins.error = "operands mismatch"; - return; - } /* Fell off the end */ + else + the_ins.error = "operands mismatch"; + return; + } /* Fell off the end */ - losing = 0; - } + 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); + 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. + 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 '/': - 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; + switch (s[0]) + { - 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; + case '*': + 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) { - 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: + /* We gotta put out some float */ +#if 0 + 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 */ +#else + if (seg (opP->con1) != SEG_BIG) + { + abort (); + } +#endif + if (offs (opP->con1) > 0) + { + 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 */ + nextword = get_num (opP->con1, 80); + /* Force into index mode. Hope this works */ - /* We do the first bit for 32-bit displacements, + /* 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 @@ -2016,330 +2204,381 @@ void m68k_ip (instring) 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 (!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)); + 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, 0); + } + } + 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; - } else { - addword(0x0170); - add_fix('l',opP->con1,0); - } - } 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, + 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 + /* 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 */ + 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 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; - } + 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); + /* 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; + 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 + 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); + 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 DINDR: + as_bad ("invalid indirect register"); + break; + case MSCR: + default: + as_bad ("unknown/incorrect operand"); + /* abort(); */ + } + install_gen_operand (s[1], tmpreg); break; - } - break; - case DINDR: - as_bad("invalid indirect register"); - 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 + 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 (!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 '+': + 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; + 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 + /* 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 @@ -2347,336 +2586,423 @@ void m68k_ip (instring) 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(ABRANCH,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; - } + 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 (ABRANCH, 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 + /* 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; + 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 '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(baseoADDR+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': /* 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 'D': + install_operand (s[1], opP->reg - DATA); + break; - case 'F': - install_operand(s[1],opP->reg-FPREG); - 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 '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 '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 'k': - tmpreg=get_num(opP->con1,55); - install_operand(s[1],tmpreg&0x7f); - 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 '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 '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(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 '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 'M': - install_operand(s[1],get_num(opP->con1,60)); - 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 'O': - tmpreg= (opP->mode==DREG) - ? 0x20+opP->reg-DATA - : (get_num(opP->con1,40)&0x1F); - install_operand(s[1],tmpreg); - break; + case 'M': + install_operand (s[1], get_num (opP->con1, 60)); + break; - case 'Q': - tmpreg=get_num(opP->con1,10); - if(tmpreg==8) - tmpreg=0; - install_operand(s[1],tmpreg); - break; + case 'O': + tmpreg = (opP->mode == DREG) + ? 0x20 + opP->reg - DATA + : (get_num (opP->con1, 40) & 0x1F); + install_operand (s[1], tmpreg); + break; - case 'R': - case 'r': - /* This depends on the fact that ADDR registers are + case 'Q': + tmpreg = get_num (opP->con1, 10); + if (tmpreg == 8) + tmpreg = 0; + install_operand (s[1], tmpreg); + break; + + case 'R': + 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; + 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': + 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 'S': /* Ignore it */ + break; - case 'T': - install_operand(s[1],get_num(opP->con1,30)); - break; + case 'T': + install_operand (s[1], get_num (opP->con1, 30)); + break; - case 'U': /* Ignore it */ - 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; + 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; + /* 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 '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 'V': + if (opP->reg == VAL) + break; + as_fatal ("failed sanity check."); - case 'W': - switch(opP->reg) { + 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 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 '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; + 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; + 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 '3': - switch (opP->reg) - { - case TT0: - tmpreg = 2; + case '3': + switch (opP->reg) + { + case TT0: + tmpreg = 2; + break; + case TT1: + tmpreg = 3; + break; + default: + as_fatal ("failed sanity check"); + } + install_operand (s[1], tmpreg); + break; + case 't': + tmpreg = get_num (opP->con1, 20); + install_operand (s[1], tmpreg); break; - case TT1: - tmpreg = 3; + case '_': /* used only for move16 absolute 32-bit address */ + tmpreg = get_num (opP->con1, 80); + addword (tmpreg >> 16); + addword (tmpreg & 0xFFFF); break; default: - as_fatal ("failed sanity check"); + as_fatal ("Internal error: Operand type %c unknown in line %d of file \"%s\"", + s[0], __LINE__, __FILE__); } - install_operand (s[1], tmpreg); - break; - case 't': - tmpreg = get_num (opP->con1, 20); - install_operand (s[1], tmpreg); - break; - case '_': /* used only for move16 absolute 32-bit address */ - tmpreg=get_num(opP->con1,80); - addword (tmpreg >> 16); - addword (tmpreg & 0xFFFF); - break; - default: - as_fatal("Internal error: Operand type %c unknown in line %d of file \"%s\"", - s[0], __LINE__, __FILE__); } - } /* By the time whe get here (FINALLY) the_ins contains the complete instruction, ready to be emitted. . . */ -} /* m68k_ip() */ +} /* m68k_ip() */ /* * get_regs := '/' + ? @@ -2694,265 +3020,299 @@ void m68k_ip (instring) * */ -static int get_regs(i,str,opP) -int i; -struct m68k_op *opP; -char *str; +static int +get_regs (i, str, opP) + 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=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=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) { - opP->error="unknown register in register list"; - return FAIL; - } + 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; } - opP->reg=cur_regs; - return OK; -} /* get_regs() */ + } + opP->reg = cur_regs; + return OK; +} /* get_regs() */ -static int reverse_16_bits(in) -int in; +static int +reverse_16_bits (in) + int in; { - int out=0; - int n; + 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; -} /* reverse_16_bits() */ + 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; +} /* reverse_16_bits() */ -static int reverse_8_bits(in) -int in; +static int +reverse_8_bits (in) + int in; { - int out=0; - int n; + int out = 0; + int n; - static int mask[8] = { - 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, - }; + 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() */ + 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; +static void +install_operand (mode, 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 + 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; + 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."); - } -} /* install_operand() */ + 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; +static void +install_gen_operand (mode, 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."); - } -} /* install_gen_operand() */ + 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() */ /* * verify that we have some number of paren pairs, do m68k_ip_op(), and * then deal with the bitfield hack. */ -static char *crack_operand(str,opP) -register char *str; -register struct m68k_op *opP; +static char * +crack_operand (str, opP) + register char *str; + register struct m68k_op *opP; { - register int parens; - register int c; - register char *beg_str; + 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; - return str; - } - *str=c; - if(c=='}') - c= *++str; /* JF bitfield hack */ - if(c) { - c= *++str; - if(!c) - as_bad("Missing operand"); + 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; } - return str; + } + if (!*str && parens) + { /* ERROR */ + opP->error = "Missing )"; + return str; + } + c = *str; + *str = '\0'; + if (m68k_ip_op (beg_str, opP) == FAIL) + { + *str = c; + 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; +notend (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 @@ -2961,130 +3321,141 @@ char *s; */ void -insert_reg(regname, regnum) -char *regname; -int regnum; +insert_reg (regname, regnum) + char *regname; + int regnum; { char buf[100]; int i; - symbol_table_insert(symbol_new(regname, SEG_REGISTER, regnum, &zero_address_frag)); + +#ifdef REGISTER_PREFIX + buf[0] = REGISTER_PREFIX; + strcpy (buf + 1, regname); + regname = buf; +#endif + + symbol_table_insert (symbol_new (regname, SEG_REGISTER, regnum, &zero_address_frag)); for (i = 0; regname[i]; i++) - buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i]; + buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i]; buf[i] = '\0'; - symbol_table_insert(symbol_new(buf, SEG_REGISTER, regnum, &zero_address_frag)); + symbol_table_insert (symbol_new (buf, SEG_REGISTER, regnum, &zero_address_frag)); } -static const struct { -char *name; -int number; -} init_table[] = { - "d0", DATA0, - "d1", DATA1, - "d2", DATA2, - "d3", DATA3, - "d4", DATA4, - "d5", DATA5, - "d6", DATA6, - "d7", DATA7, - "a0", ADDR0, - "a1", ADDR1, - "a2", ADDR2, - "a3", ADDR3, - "a4", ADDR4, - "a5", ADDR5, - "a6", ADDR6, - "fp", ADDR6, - "a7", ADDR7, - "sp", ADDR7, - "fp0", FP0, - "fp1", FP1, - "fp2", FP2, - "fp3", FP3, - "fp4", FP4, - "fp5", FP5, - "fp6", FP6, - "fp7", FP7, - "fpi", FPI, - "fpiar", FPI, - "fpc", FPI, - "fps", FPS, - "fpsr", FPS, - "fpc", FPC, - "fpcr", FPC, - - "cop0", COP0, - "cop1", COP1, - "cop2", COP2, - "cop3", COP3, - "cop4", COP4, - "cop5", COP5, - "cop6", COP6, - "cop7", COP7, - "pc", PC, - "zpc", ZPC, - "sr", SR, - - "ccr", CCR, - "cc", CCR, - - "usp", USP, - "isp", ISP, - "sfc", SFC, - "dfc", DFC, - "cacr", CACR, - "caar", CAAR, - - "vbr", VBR, - - "msp", MSP, - "itt0", ITT0, - "itt1", ITT1, - "dtt0", DTT0, - "dtt1", DTT1, - "mmusr", MMUSR, - "tc", TC, - "srp", SRP, - "urp", URP, - - "ac", AC, - "bc", BC, - "cal", CAL, - "crp", CRP, - "drp", DRP, - "pcsr", PCSR, - "psr", PSR, - "scc", SCC, - "val", VAL, - "bad0", BAD0, - "bad1", BAD1, - "bad2", BAD2, - "bad3", BAD3, - "bad4", BAD4, - "bad5", BAD5, - "bad6", BAD6, - "bad7", BAD7, - "bac0", BAC0, - "bac1", BAC1, - "bac2", BAC2, - "bac3", BAC3, - "bac4", BAC4, - "bac5", BAC5, - "bac6", BAC6, - "bac7", BAC7, - - "ic", IC, - "dc", DC, - "nc", NC, - - "tt0", TT0, - "tt1", TT1, +static const struct + { + char *name; + int number; + } + +init_table[] = +{ + "d0", DATA0, + "d1", DATA1, + "d2", DATA2, + "d3", DATA3, + "d4", DATA4, + "d5", DATA5, + "d6", DATA6, + "d7", DATA7, + "a0", ADDR0, + "a1", ADDR1, + "a2", ADDR2, + "a3", ADDR3, + "a4", ADDR4, + "a5", ADDR5, + "a6", ADDR6, + "fp", ADDR6, + "a7", ADDR7, + "sp", ADDR7, + "fp0", FP0, + "fp1", FP1, + "fp2", FP2, + "fp3", FP3, + "fp4", FP4, + "fp5", FP5, + "fp6", FP6, + "fp7", FP7, + "fpi", FPI, + "fpiar", FPI, + "fpc", FPI, + "fps", FPS, + "fpsr", FPS, + "fpc", FPC, + "fpcr", FPC, + + "cop0", COP0, + "cop1", COP1, + "cop2", COP2, + "cop3", COP3, + "cop4", COP4, + "cop5", COP5, + "cop6", COP6, + "cop7", COP7, + "pc", PC, + "zpc", ZPC, + "sr", SR, + + "ccr", CCR, + "cc", CCR, + + "usp", USP, + "isp", ISP, + "sfc", SFC, + "dfc", DFC, + "cacr", CACR, + "caar", CAAR, + + "vbr", VBR, + + "msp", MSP, + "itt0", ITT0, + "itt1", ITT1, + "dtt0", DTT0, + "dtt1", DTT1, + "mmusr", MMUSR, + "tc", TC, + "srp", SRP, + "urp", URP, + + "ac", AC, + "bc", BC, + "cal", CAL, + "crp", CRP, + "drp", DRP, + "pcsr", PCSR, + "psr", PSR, + "scc", SCC, + "val", VAL, + "bad0", BAD0, + "bad1", BAD1, + "bad2", BAD2, + "bad3", BAD3, + "bad4", BAD4, + "bad5", BAD5, + "bad6", BAD6, + "bad7", BAD7, + "bac0", BAC0, + "bac1", BAC1, + "bac2", BAC2, + "bac3", BAC3, + "bac4", BAC4, + "bac5", BAC5, + "bac6", BAC6, + "bac7", BAC7, + + "ic", IC, + "dc", DC, + "nc", NC, + + "tt0", TT0, + "tt1", TT1, /* 68ec030 versions of same */ - "ac0", TT0, - "ac1", TT1, + "ac0", TT0, + "ac1", TT1, /* 68ec030 access control unit, identical to 030 MMU status reg */ - "acusr", PSR, + "acusr", PSR, 0, @@ -3092,311 +3463,334 @@ int number; void -init_regtable() +init_regtable () { int i; for (i = 0; init_table[i].name; i++) - insert_reg(init_table[i].name, init_table[i].number); + insert_reg (init_table[i].name, init_table[i].number); } static int no_68851, no_68881; 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; - static int done_first_time; - - if (!done_first_time) - { - done_first_time = 1; + char *er; + short *fromP; + char *toP = NULL; + int m, n = 0; + char *to_beg_P; + int shorts_this_frag; + static int done_first_time; + + if (!done_first_time) + { + done_first_time = 1; - if (cpu_of_arch (current_architecture) == 0) - { - int cpu_type; + if (cpu_of_arch (current_architecture) == 0) + { + int cpu_type; #ifndef TARGET_CPU - cpu_type = m68020; + cpu_type = m68020; #else - if (strcmp (TARGET_CPU, "m68000") == 0) - cpu_type = m68000; - else if (strcmp (TARGET_CPU, "m68010") == 0) - cpu_type = m68010; - else if (strcmp (TARGET_CPU, "m68020") == 0 - || strcmp (TARGET_CPU, "m68k") == 0) - cpu_type = m68020; - else if (strcmp (TARGET_CPU, "m68030") == 0) - cpu_type = m68030; - else if (strcmp (TARGET_CPU, "m68040") == 0) - cpu_type = m68040; - else if (strcmp (TARGET_CPU, "cpu32") == 0) - cpu_type = cpu32; - else - cpu_type = m68020; + if (strcmp (TARGET_CPU, "m68000") == 0) + cpu_type = m68000; + else if (strcmp (TARGET_CPU, "m68010") == 0) + cpu_type = m68010; + else if (strcmp (TARGET_CPU, "m68020") == 0 + || strcmp (TARGET_CPU, "m68k") == 0) + cpu_type = m68020; + else if (strcmp (TARGET_CPU, "m68030") == 0) + cpu_type = m68030; + else if (strcmp (TARGET_CPU, "m68040") == 0) + cpu_type = m68040; + else if (strcmp (TARGET_CPU, "cpu32") == 0) + cpu_type = cpu32; + else + cpu_type = m68020; #endif - current_architecture |= cpu_type; - } - if (current_architecture & m68881) - { - if (current_architecture & m68000) - as_bad ("incompatible processors 68000 and 68881/2 specified"); - if (current_architecture & m68010) - as_bad ("incompatible processors 68010 and 68881/2 specified"); - if (current_architecture & m68040) - as_bad ("incompatible processors 68040 and 68881/2 specified"); - } - /* What other incompatibilities ought we to check for? */ - - /* Toss in some default assumptions about coprocessors. */ - if (!no_68881 - && (cpu_of_arch (current_architecture) - /* Can CPU32 have a 68881 coprocessor?? */ - & (m68020 | m68030 | cpu32))) - { - current_architecture |= m68881; - } - if (!no_68851 - && (cpu_of_arch (current_architecture) & m68020up) != 0) - { - current_architecture |= m68851; - } - if (no_68881 && (current_architecture & m68881)) - as_bad ("options for 68881 and no-68881 both given"); - if (no_68851 && (current_architecture & m68851)) - as_bad ("options for 68851 and no-68851 both given"); - done_first_time = 1; - } + current_architecture |= cpu_type; + } +#if 0 /* Could be doing emulation. */ + if (current_architecture & m68881) + { + if (current_architecture & m68000) + as_bad ("incompatible processors 68000 and 68881/2 specified"); + if (current_architecture & m68010) + as_bad ("incompatible processors 68010 and 68881/2 specified"); + if (current_architecture & m68040) + as_bad ("incompatible processors 68040 and 68881/2 specified"); + } +#endif + /* What other incompatibilities could we check for? */ - memset((char *)(&the_ins), '\0', 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; - } + /* Toss in some default assumptions about coprocessors. */ + if (!no_68881 + && (cpu_of_arch (current_architecture) + /* Can CPU32 have a 68881 coprocessor?? */ + & (m68020 | m68030 | cpu32))) + { + current_architecture |= m68881; } - if(er) { - as_bad("%s -- statement `%s' ignored",er,str); - return; + if (!no_68851 + && (cpu_of_arch (current_architecture) & m68020up) != 0) + { + current_architecture |= m68851; } + if (no_68881 && (current_architecture & m68881)) + as_bad ("options for 68881 and no-68881 both given"); + if (no_68851 && (current_architecture & m68851)) + as_bad ("options for 68851 and no-68851 both given"); + done_first_time = 1; + } - 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;mfr_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; + 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); + } - /* There's some frag hacking */ - for(n=0,fromP= &the_ins.opcode[0];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); + 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); - 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++; - } + 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++; + } + 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); } - for(m=0;mfr_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); + /* 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); + } } 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 + /* 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 + 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_bad("Internal Error: Can't hash %s: %s",ins->name,retval); + 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_bad ("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 (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; + 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 #ifdef OPTIONAL_REGISTER_PREFIX - alt_notend_table[OPTIONAL_REGISTER_PREFIX] = 1; + alt_notend_table[OPTIONAL_REGISTER_PREFIX] = 1; #endif #ifndef MIT_SYNTAX_ONLY - /* Insert pseudo ops, these have to go into the opcode table since + /* Insert pseudo ops, these have to go into the opcode table since gas expects pseudo ops to start with a dot */ - { - int n = 0; - while (mote_pseudo_table[n].poc_name) - { - hack=(struct m68k_incant *) - obstack_alloc(&robyn,sizeof(struct m68k_incant)); - hash_insert(op_hash, - mote_pseudo_table[n].poc_name, (char *)hack); - hack->m_operands = 0; - hack->m_opnum = n; - n++; - } - } + { + int n = 0; + while (mote_pseudo_table[n].poc_name) + { + hack = (struct m68k_incant *) + obstack_alloc (&robyn, sizeof (struct m68k_incant)); + hash_insert (op_hash, + mote_pseudo_table[n].poc_name, (char *) hack); + hack->m_operands = 0; + hack->m_opnum = n; + n++; + } + } #endif - init_regtable(); + init_regtable (); } #if 0 @@ -3409,7 +3803,7 @@ void supposed to do any final cleanup for this part of the assembler. */ void - md_end() +md_end () { } @@ -3421,56 +3815,58 @@ void 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; - char *atof_ieee(); + 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; + 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 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; - case 'x': - case 'X': - prec = 6; - break; + case 'x': + case 'X': + prec = 6; + break; - case 'p': - case 'P': - 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 */ + 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 @@ -3481,61 +3877,63 @@ int *sizeP; LITTLENUMS (shorts, here at least) */ 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 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; { #ifdef IBM_COMPILER_SUX - /* This is unnecessary but it convinces the native rs6000 + /* This is unnecessary but it convinces the native rs6000 compiler to generate the code we want. */ - char *buf = fixP->fx_frag->fr_literal; - buf += fixP->fx_where; + char *buf = fixP->fx_frag->fr_literal; + buf += fixP->fx_where; #else /* IBM_COMPILER_SUX */ - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; #endif /* IBM_COMPILER_SUX */ - 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); - } + 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); + } } @@ -3544,364 +3942,411 @@ long val; MAGIC here. .. */ void - md_convert_frag(headers, fragP) -object_headers *headers; -register fragS *fragP; +md_convert_frag (headers, fragP) + object_headers *headers; + register fragS *fragP; { - long disp; - long ext = 0; + long disp; + long ext = 0; - /* Address in object code of the displacement. */ - register int object_address = fragP -> fr_fix + fragP -> fr_address; + /* 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 + /* 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; + 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); */ + /* 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; + /* 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(ABRANCH,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(ABRANCH,SHORT): - know(issword(disp)); - fragP->fr_opcode[1]=0x00; - ext=2; - break; - case TAB(ABRANCH,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 */ + switch (fragP->fr_subtype) + { + case TAB (BCC68000, BYTE): + case TAB (ABRANCH, 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 (ABRANCH, SHORT): + know (issword (disp)); + fragP->fr_opcode[1] = 0x00; + ext = 2; + break; + case TAB (ABRANCH, 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 + /* 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. */ - *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */ - *buffer_address++ = 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; - ext=0; - break; - 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 */ - *buffer_address++ = 0x00; /* branch offset = 4 */ - *buffer_address++ = 0x04; - *buffer_address++ = 0x60; /* put in bra pc+6 */ - *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_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 + *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */ + *buffer_address++ = 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; + ext = 0; + break; + 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 */ + *buffer_address++ = 0x00; /* branch offset = 4 */ + *buffer_address++ = 0x04; + *buffer_address++ = 0x60; /* put in bra pc+6 */ + *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_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, + /* 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; + 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; +{ + 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 (ABRANCH, 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(ABRANCH,SZ_UNDEF) */ -} /* switch on subtype */ + 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) */ - 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 */ + 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) */ - return; -} /* md_convert_frag() */ + 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[0] = 0x4e; /* put in jmp long (0x4ef9) */ + buffer_address[1] = 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) */ -/* 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; -{ - 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(ABRANCH,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; - } + 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, - break; - } /* case TAB(ABRANCH,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[0] = 0x4e; /* put in jmp long (0x4ef9) */ - buffer_address[1] = 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) */ + 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; + } - 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) */ - 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) */ + 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; + default: + break; - } /* switch on subtype looking for SZ_UNDEF's. */ + } /* 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(ABRANCH,BYTE): - /* We can't do a short jump to the next instruction, + /* now that SZ_UNDEF are taken care of, check others */ + switch (fragP->fr_subtype) + { + case TAB (BCC68000, BYTE): + case TAB (ABRANCH, 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; + 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; + break; + default: + break; + } + return fragP->fr_var + fragP->fr_fix - old_fix; } #if defined(OBJ_AOUT) | defined(OBJ_BOUT) @@ -3917,52 +4362,55 @@ segT segment; 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; +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_symbolnum; + static unsigned char nbytes_r_length[] = + {42, 0, 1, 42, 2}; + long r_symbolnum; - know(fixP->fx_addsy != NULL); + know (fixP->fx_addsy != NULL); - md_number_to_chars(where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); - r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy) - ? S_GET_TYPE(fixP->fx_addsy) - : fixP->fx_addsy->sy_number); + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); - 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) | - (((!S_IS_DEFINED(fixP->fx_addsy)) << 4) & 0x10)); + 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) | + (((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10)); - return; -} /* tc_aout_fix_to_chars() */ + return; +} /* tc_aout_fix_to_chars() */ #endif /* OBJ_AOUT or OBJ_BOUT */ @@ -3971,42 +4419,43 @@ 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) -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; + long offset; - offset = to_addr - (from_addr+2); + offset = to_addr - (from_addr + 2); - md_number_to_chars(ptr ,(long)0x6000,2); - md_number_to_chars(ptr+2,(long)offset,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) -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; { - 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 @@ -4025,233 +4474,257 @@ symbolS *to_symbol; */ -static int get_num(exp,ok) -struct m68k_exp *exp; -int ok; +static int +get_num (exp, ok) + struct m68k_exp *exp; + int ok; { #ifdef TEST2 - long l = 0; + 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); + 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; + 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; - } + 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[-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; - exp->e_end-=2; - break; - case 'w': - case 'W': - exp->e_siz=2; - exp->e_end-=2; - break; - case 'l': - case 'L': - exp->e_siz=3; - exp->e_end-=2; - break; - default: - if (exp->e_end[-1] == ':') - as_bad("Unknown size for expression \"%c\"",exp->e_end[0]); - break; - } + exp->e_siz = 0; + if ( /* ok!=80 && */ (exp->e_end[-1] == ':' || 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; + exp->e_end -= 2; + break; + case 'w': + case 'W': + exp->e_siz = 2; + exp->e_end -= 2; + break; + case 'l': + case 'L': + exp->e_siz = 3; + exp->e_end -= 2; + break; + default: + if (exp->e_end[-1] == ':') + as_bad ("Unknown size for expression \"%c\"", exp->e_end[0]); + break; } - 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; + } + 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; - } - 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_BIG: - if (offs (exp) < 0 /* flonum */ - && (ok == 80 /* no bignums */ - || (ok > 10 /* small-int ranges including 0 ok */ - /* If we have a flonum zero, a zero integer should - do as well (e.g., in moveq). */ - && generic_floating_point_number.exponent == 0 - && generic_floating_point_number.low[0] == 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; + 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; + } + 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: - 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; + break; + } + break; + case SEG_BIG: + if (offs (exp) < 0 /* flonum */ + && (ok == 80 /* no bignums */ + || (ok > 10 /* small-int ranges including 0 ok */ + /* If we have a flonum zero, a zero integer should + do as well (e.g., in moveq). */ + && generic_floating_point_number.exponent == 0 + && generic_floating_point_number.low[0] == 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; + default: + 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; + } + 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; } - 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); + } + return offs (exp); #endif -} /* get_num() */ +} /* get_num() */ /* These are the back-ends for the various machine dependent pseudo-ops. */ -void demand_empty_rest_of_line(); /* Hate those extra verbose names */ +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(); -} /* s_data1() */ +static void +s_data1 () +{ + 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(); -} /* s_data2() */ +static void +s_data2 () +{ + subseg_new (SEG_DATA, 2); + demand_empty_rest_of_line (); +} /* s_data2() */ -static void s_bss() +static void +s_bss () { - /* We don't support putting frags in the BSS segment, we fake it + /* We don't support putting frags in the BSS segment, we fake it by marking in_bss, then looking at s_skip for clues */ - subseg_new(SEG_BSS, 0); - demand_empty_rest_of_line(); -} /* s_bss() */ - -static void s_even() { - register int temp; - register long temp_fill; + subseg_new (SEG_BSS, 0); + demand_empty_rest_of_line (); +} /* s_bss() */ - 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(); -} /* s_proc() */ +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 (); +} /* s_even() */ + +static void +s_proc () +{ + demand_empty_rest_of_line (); +} /* s_proc() */ /* s_space is defined in read.c .skip is simply an alias to it. */ @@ -4280,91 +4753,121 @@ static void s_proc() { * of that funny floaty stuff going on. FIXME-later. */ #ifndef MAYBE_FLOAT_TOO -#define MAYBE_FLOAT_TOO /* m68881 */ 0 /* this is handled later */ +#define MAYBE_FLOAT_TOO /* m68881 */ 0 /* this is handled later */ #endif -int md_parse_option(argP,cntP,vecP) -char **argP; -int *cntP; -char ***vecP; +int +md_parse_option (argP, cntP, vecP) + char **argP; + int *cntP; + char ***vecP; { - switch(**argP) { - case 'l': /* -l means keep external to 2 bit offset + switch (**argP) + { + case 'l': /* -l means keep external to 2 bit offset rather than 16 bit one */ - break; + break; - case 'S': /* -S means that jbsr's always turn into jsr's. */ - 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")) { + 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; + current_architecture |= m68010; - } else if (!strcmp(*argP, "68020")) { - current_architecture |= m68020 | MAYBE_FLOAT_TOO; + } + 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, "68030")) + { + current_architecture |= m68030 | MAYBE_FLOAT_TOO; - } else if (!strcmp(*argP, "68040")) { - current_architecture |= m68040 | 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, "68881")) + { + current_architecture |= m68881; - } else if (!strcmp(*argP, "68882")) { - current_architecture |= m68882; + } + else if (!strcmp (*argP, "68882")) + { + current_architecture |= m68882; #endif /* NO_68881 */ - /* Even if we aren't configured to support the processor, + /* Even if we aren't configured to support the processor, it should still be possible to assert that the user doesn't have it... */ - } else if (!strcmp (*argP, "no-68881") - || !strcmp (*argP, "no-68882")) { - no_68881 = 1; + } + else if (!strcmp (*argP, "no-68881") + || !strcmp (*argP, "no-68882")) + { + no_68881 = 1; #ifndef NO_68851 - } else if (!strcmp(*argP,"68851")) { - current_architecture |= m68851; + } + else if (!strcmp (*argP, "68851")) + { + current_architecture |= m68851; #endif /* NO_68851 */ - } else if (!strcmp (*argP, "no-68851")) { - no_68851 = 1; - } else if (!strcmp (*argP, "pu32")) { /* "-mcpu32" */ - current_architecture |= cpu32; - } else { - as_warn("Unknown architecture, \"%s\". option ignored", *argP); - } /* switch on architecture */ - - while(**argP) (*argP)++; + } + else if (!strcmp (*argP, "no-68851")) + { + no_68851 = 1; + } + else if (!strcmp (*argP, "pu32")) + { /* "-mcpu32" */ + current_architecture |= cpu32; + } + else + { + as_warn ("Unknown architecture, \"%s\". option ignored", *argP); + } /* switch on architecture */ - break; + while (**argP) + (*argP)++; - case 'p': - if (!strcmp(*argP,"pic")) { - (*argP) += 3; - break; /* -pic, Position Independent Code */ - } else { - return(0); - } /* pic or not */ + break; - default: - return 0; + case 'p': + if (!strcmp (*argP, "pic")) + { + (*argP) += 3; + break; /* -pic, Position Independent Code */ } - return 1; + else + { + return (0); + } /* pic or not */ + + default: + return 0; + } + return 1; } @@ -4373,64 +4876,70 @@ char ***vecP; /* TEST2: Test md_assemble() */ /* Warning, this routine probably doesn't work anymore */ -main() +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; - memset(&the_ins, '\0', 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;nfx_size + fixP->fx_where + fixP->fx_frag->fr_address); + return (fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address); } -void +void tc_coff_symbol_emit_hook () { } -int -tc_coff_sizemachdep(frag) -fragS *frag; +int +tc_coff_sizemachdep (frag) + fragS *frag; { - switch (frag->fr_subtype & 0x3) - { - case BYTE: return 1; - case SHORT: return 2; - case LONG: return 4; - default: abort(); - } + switch (frag->fr_subtype & 0x3) + { + case BYTE: + return 1; + case SHORT: + return 2; + case LONG: + return 4; + default: + abort (); + } } + /* * Local Variables: * comment-column: 0 @@ -4555,4 +5072,3 @@ fragS *frag; */ /* end of tc-m68k.c */ - diff --git a/gas/config/tc-m88k.c b/gas/config/tc-m88k.c index e560d8e1659..31b7ebb7234 100644 --- a/gas/config/tc-m88k.c +++ b/gas/config/tc-m88k.c @@ -102,18 +102,22 @@ struct field_val_assoc fcr_regs[] = struct field_val_assoc cmpslot[] = { /* Integer Floating point */ - {"nc", 0}, - {"cp", 1}, + {"nc", 0}, + {"cp", 1}, {"eq", 2}, {"ne", 3}, {"gt", 4}, {"le", 5}, {"lt", 6}, {"ge", 7}, - {"hi", 8}, {"ou", 8}, - {"ls", 9}, {"ib", 9}, - {"lo", 10}, {"in", 10}, - {"hs", 11}, {"ob", 11}, + {"hi", 8}, + {"ou", 8}, + {"ls", 9}, + {"ib", 9}, + {"lo", 10}, + {"in", 10}, + {"hs", 11}, + {"ob", 11}, {NULL, 0}, }; @@ -163,8 +167,8 @@ const char EXP_CHARS[] = "eE"; /* or 0H1.234E-12 (see exp chars above) */ const char FLT_CHARS[] = "dDfF"; -extern void float_cons (), cons (), s_globl (), s_line (), - s_space (), s_set (), stringer (), s_lcomm (); +extern void float_cons (), cons (), s_globl (), s_line (), s_space (), + s_set (), stringer (), s_lcomm (); static void s_file (); static void s_bss (); @@ -174,11 +178,11 @@ const pseudo_typeS md_pseudo_table[] = {"dfloat", float_cons, 'd'}, {"ffloat", float_cons, 'f'}, {"global", s_globl, 0}, - {"half", cons, 2 }, + {"half", cons, 2}, {"bss", s_bss, 0}, {"ln", s_line, 0}, {"string", stringer, 0}, - {"word", cons, 4 }, + {"word", cons, 4}, {"zero", s_space, 0}, {0} }; @@ -207,7 +211,7 @@ md_begin () if (retval != NULL && *retval != '\0') as_fatal ("Can't hash instruction '%s':%s", - m88k_opcodes[i].name, retval); + m88k_opcodes[i].name, retval); /* skip to next unique mnemonic or end of list */ @@ -742,7 +746,7 @@ get_bf (param, valp) *param++ = 0; /* Overwrite the '>' */ width = get_absolute_expression (); - xp = get_bf_offset_expression (xp, &offset); + xp = get_bf_offset_expression (xp, &offset); input_line_pointer = save_ptr; if (xp + 1 != param) @@ -867,7 +871,7 @@ get_vec9 (param, valp) return param; } - + #define hexval(z) \ (isdigit (z) ? (z) - '0' : \ islower (z) ? (z) - 'a' + 10 : \ @@ -922,9 +926,9 @@ getval (param, valp) void md_number_to_chars (buf, val, nbytes) -char *buf; -int val; -int nbytes; + char *buf; + int val; + int nbytes; { switch (nbytes) { @@ -944,11 +948,11 @@ int nbytes; void md_number_to_imm (buf, val, nbytes, fixP, seg_type) -unsigned char *buf; -unsigned int val; -int nbytes; -fixS *fixP; -int seg_type; + unsigned char *buf; + unsigned int val; + int nbytes; + fixS *fixP; + int seg_type; { if (seg_type != N_TEXT || fixP->fx_r_type == NO_RELOC) { @@ -1015,9 +1019,9 @@ int seg_type; void md_number_to_disp (buf, val, nbytes) -char *buf; -int val; -int nbytes; + char *buf; + int val; + int nbytes; { as_fatal ("md_number_to_disp not defined"); md_number_to_chars (buf, val, nbytes); @@ -1025,9 +1029,9 @@ int nbytes; void md_number_to_field (buf, val, nbytes) -char *buf; -int val; -int nbytes; + char *buf; + int val; + int nbytes; { as_fatal ("md_number_to_field not defined"); md_number_to_chars (buf, val, nbytes); @@ -1045,11 +1049,11 @@ md_atof (type, litP, sizeP) char *litP; int *sizeP; { - int prec; + int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee (); + char *t; + char *atof_ieee (); switch (type) { @@ -1078,20 +1082,20 @@ md_atof (type, litP, sizeP) break; default: - *sizeP=0; + *sizeP = 0; return "Bad call to MD_ATOF()"; } - t=atof_ieee (input_line_pointer, type, words); + 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--;) + *sizeP = prec * sizeof (LITTLENUM_TYPE); + for (wordP = words; prec--;) { md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); - litP+=sizeof (LITTLENUM_TYPE); + litP += sizeof (LITTLENUM_TYPE); } - return ""; /* Someone should teach Dean about null pointers */ + return ""; /* Someone should teach Dean about null pointers */ } int md_short_jump_size = 4; @@ -1103,7 +1107,10 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) fragS *frag; symbolS *to_symbol; { - ptr[0] = 0xc0; ptr[1] = 0x00; ptr[2] = 0x00; ptr[3] = 0x00; + ptr[0] = 0xc0; + ptr[1] = 0x00; + ptr[2] = 0x00; + ptr[3] = 0x00; fix_new (frag, ptr - frag->fr_literal, 4, @@ -1123,7 +1130,10 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) fragS *frag; symbolS *to_symbol; { - ptr[0] = 0xc0; ptr[1] = 0x00; ptr[2] = 0x00; ptr[3] = 0x00; + ptr[0] = 0xc0; + ptr[1] = 0x00; + ptr[2] = 0x00; + ptr[3] = 0x00; fix_new (frag, ptr - frag->fr_literal, 4, @@ -1142,7 +1152,8 @@ md_estimate_size_before_relax (fragP, segment_type) as_fatal ("Relaxation should never occur"); } -const relax_typeS md_relax_table[] = {0}; +const relax_typeS md_relax_table[] = +{0}; void md_convert_frag (fragP) @@ -1162,104 +1173,114 @@ md_end () */ void emit_relocations (fixP, segment_address_in_file) - fixS *fixP; - relax_addressT segment_address_in_file; + fixS *fixP; + relax_addressT segment_address_in_file; { - struct reloc_info_m88k ri; - symbolS *symbolP; - extern char *next_object_file_charP; + struct reloc_info_m88k ri; + symbolS *symbolP; + extern char *next_object_file_charP; - 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) { - fprintf (stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type); - abort (); + if (fixP->fx_r_type >= NO_RELOC) + { + fprintf (stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type); + abort (); } - 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 = 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; } - 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; } - 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; + else + { + ri.r_addend = fixP->fx_addnumber; } -/* md_ri_to_chars ((char *) &ri, ri); */ - append (&next_object_file_charP, (char *)& ri, sizeof (ri)); + /* md_ri_to_chars ((char *) &ri, ri); */ + append (&next_object_file_charP, (char *) &ri, sizeof (ri)); } } - return; + return; } static void -s_bss() +s_bss () { char *name; char c; char *p; int temp, bss_align = 1; symbolS *symbolP; - extern const char is_end_of_line [256]; + extern const char is_end_of_line[256]; name = input_line_pointer; - c = get_symbol_end(); + c = get_symbol_end (); p = input_line_pointer; *p = c; - SKIP_WHITESPACE(); - if ( * input_line_pointer != ',' ) + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') { - as_warn("Expected comma after name"); - ignore_rest_of_line(); + as_warn ("Expected comma after name"); + ignore_rest_of_line (); return; } - input_line_pointer ++; - if ((temp = get_absolute_expression()) < 0) + input_line_pointer++; + if ((temp = get_absolute_expression ()) < 0) { - as_warn("BSS length (%d.) <0! Ignored.", temp); - ignore_rest_of_line(); + as_warn ("BSS length (%d.) <0! Ignored.", temp); + ignore_rest_of_line (); return; } *p = 0; - symbolP = symbol_find_or_make(name); + symbolP = symbol_find_or_make (name); *p = c; if (*input_line_pointer == ',') { input_line_pointer++; - bss_align = get_absolute_expression(); + bss_align = get_absolute_expression (); while (local_bss_counter % bss_align != 0) local_bss_counter++; } - if (symbolP->sy_other == 0 - && symbolP->sy_desc == 0 - && ((symbolP->sy_type == N_BSS + if (symbolP->sy_other == 0 + && symbolP->sy_desc == 0 + && ((symbolP->sy_type == N_BSS && symbolP->sy_value == local_bss_counter) || ((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0))) { symbolP->sy_value = local_bss_counter; - symbolP->sy_type = N_BSS; - symbolP->sy_frag = & bss_address_frag; + symbolP->sy_type = N_BSS; + symbolP->sy_frag = &bss_address_frag; local_bss_counter += temp; } else { - as_warn( "Ignoring attempt to re-define symbol from %d. to %d.", - symbolP->sy_value, local_bss_counter ); + as_warn ("Ignoring attempt to re-define symbol from %d. to %d.", + symbolP->sy_value, local_bss_counter); } while (!is_end_of_line[*input_line_pointer]) { diff --git a/gas/config/tc-m88k.h b/gas/config/tc-m88k.h index 9e158c83018..8c32449cd8d 100644 --- a/gas/config/tc-m88k.h +++ b/gas/config/tc-m88k.h @@ -1,3 +1,4 @@ + /* m88k.h -- Assembler for the Motorola 88000 Contributed by Devon Bowen of Buffalo University and Torbjorn Granlund of the Swedish Institute of Computer Science. @@ -34,12 +35,12 @@ enum reloc_type struct reloc_info_m88k { - unsigned long int r_address; - unsigned int r_symbolnum: 24; - unsigned int r_extern : 1; - unsigned int r_pad : 3; - enum reloc_type r_type : 4; - long int r_addend; + unsigned long int r_address; + unsigned int r_symbolnum:24; + unsigned int r_extern:1; + unsigned int r_pad:3; + enum reloc_type r_type:4; + long int r_addend; }; #define relocation_info reloc_info_m88k diff --git a/gas/config/tc-ns32k.c b/gas/config/tc-ns32k.c index e34a2041727..db49ef38032 100644 --- a/gas/config/tc-ns32k.c +++ b/gas/config/tc-ns32k.c @@ -1,23 +1,23 @@ /* ns32k.c -- Assemble on the National Semiconductor 32k series Copyright (C) 1987, 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. */ -/*#define SHOW_NUM 1*/ /* uncomment for debugging */ +/*#define SHOW_NUM 1*//* uncomment for debugging */ #include #include @@ -29,14 +29,15 @@ #include "opcode/ns32k.h" #include "as.h" +#include "read.h" #include "obstack.h" /* Macros */ -#define IIF_ENTRIES 13 /* number of entries in iif */ -#define PRIVATE_SIZE 256 /* size of my garbage memory */ +#define IIF_ENTRIES 13 /* number of entries in iif */ +#define PRIVATE_SIZE 256 /* size of my garbage memory */ #define MAX_ARGS 4 -#define DEFAULT -1 /* addr_mode returns this value when plain constant or label is encountered */ +#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; \ @@ -61,37 +62,39 @@ #define LINE_COMMENT_CHARS "#" #endif -char comment_chars[] = "#"; -char line_comment_chars[] = LINE_COMMENT_CHARS; +const char comment_chars[] = "#"; +const char line_comment_chars[] = LINE_COMMENT_CHARS; +const char line_separator_chars[] = ""; #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX) #define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */ #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) +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 index_byte; /* index byte */ + }; typedef struct addr_mode addr_modeS; -char *freeptr,*freeptr_static; /* points at some number of free bytes */ +char *freeptr, *freeptr_static; /* points at some number of free bytes */ struct hash_control *inst_hash_handle; -struct ns32k_opcode *desc; /* pointer at description of instruction */ +struct ns32k_opcode *desc; /* pointer at description of instruction */ addr_modeS addr_modeP; -char EXP_CHARS[] = "eE"; -char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */ +const char EXP_CHARS[] = "eE"; +const char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */ -/* UPPERCASE denotes live names +/* UPPERCASE denotes live names * when an instruction is built, IIF is used as an intermidiate form to store * the actual parts of the instruction. A ns32k machine instruction can * be divided into a couple of sub PARTs. When an instruction is assembled @@ -99,36 +102,41 @@ char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */ * converted to a FRAGment as specified in AS.H */ /* internal structs */ -struct option { - 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; /* length in bytes from the +struct option + { + 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; /* 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 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]; + }; struct int_ins_form iif; expressionS exprP; char *input_line_pointer; -/* description of the PARTs in IIF +/* description of the PARTs in IIF *object[n]: * 0 total length in bytes of entries in iif * 1 opcode @@ -142,7 +150,7 @@ char *input_line_pointer; * 9 imm_b * 10 implied1 * 11 implied2 - * + * * For every entry there is a datalength in bytes. This is stored in size[n]. * 0, the objectlength is not explicitly given by the instruction * and the operand is undefined. This is a case for relaxation. @@ -176,122 +184,122 @@ char *input_line_pointer; * machine dependent/independent parts in a more clean way (said OE) */ -struct option opt1[]= /* restore, exit */ +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 */ +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 */ +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 */ +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 */ +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 */ +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 */ +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 */ +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 */ +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) @@ -303,18 +311,19 @@ struct option *mmureg = mmureg_032; #endif -const pseudo_typeS md_pseudo_table[]={ /* so far empty */ - { 0, 0, 0 } +const pseudo_typeS md_pseudo_table[] = +{ /* so far empty */ + {0, 0, 0} }; #define IND(x,y) (((x)<<2)+(y)) -/* those are index's to relax groups in md_relax_table +/* 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 +#define PCREL 2 /* those are index's to entries in a relax group */ @@ -332,249 +341,308 @@ const pseudo_typeS md_pseudo_table[]={ /* so far empty */ 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 } +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 }; +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}; /* Array used to calculate max size of displacements */ -char disp_size[] = { 4,1,2,0,4 }; +char disp_size[] = +{4, 1, 2, 0, 4}; #if __STDC__ == 1 -static segT evaluate_expr(expressionS *resultP, char *ptr); -static void md_number_to_disp(char *buf, long val, int n); -static void md_number_to_imm(char *buf, long val, int n); +static segT evaluate_expr (expressionS * resultP, char *ptr); +static void md_number_to_disp (char *buf, long val, int n); +static void md_number_to_imm (char *buf, long val, int n); #else /* not __STDC__ */ -static segT evaluate_expr(); -static void md_number_to_disp(); -static void md_number_to_imm(); +static segT evaluate_expr (); +static void md_number_to_disp (); +static void md_number_to_imm (); #endif /* not __STDC__ */ -/* Parses a general operand into an addressingmode struct - +/* 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) - + out: data in addr_mode struct */ -int addr_mode(operand,addr_modeP,recursive_level) -char *operand; -register addr_modeS *addr_modeP; -int recursive_level; +int +addr_mode (operand, addr_modeP, 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 + 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); - } - 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 (jdisp[1]=str+j+2; - addr_modeP->mode=22; - 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); } - break; - default:; + default: + as_warn ("Invalid syntax in PC-relative addressing mode"); + return (0); + } } - 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); - } + 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--; } - case 3: - if (!strncmp(str,"tos",3)) { - addr_modeP->mode=23; /* TopOfStack */ - return (-1); + while (j < strl && i != 0); + if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+')) + { + as_warn ("Invalid syntax in External addressing mode"); + return (0); } - default:; + str[j] = '\000'; /* null terminate disp[0] */ + addr_modeP->disp[1] = str + j + 2; + addr_modeP->mode = 22; + return (-1); + } } - 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 */ - } - } + 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); + } + default:; + } + if (strl > 4) + { + if (str[strl - 1] == ')') + { + if (str[strl - 2] == ')') + { + if (!strncmp (&str[strl - 5], "(fp", 3)) + { + mode = 16; /* Memory Relative */ } - /* 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); - } + 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 */ + } + } + } + /* 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->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 @@ -584,161 +652,204 @@ int recursive_level; 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; +int +get_addr_mode (ptr, 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 + 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 */ + (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; + } } - /* It appears as the sequent compiler wants an absolute when we have a + /* 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*/ - { - 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 (suffixdisp_suffix[i]=suffix; - addr_modeP->am_size+=suffix ? suffix : 4; - } - } - } - } - } 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; - } + 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*/ + { + 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; + } + } + } + } + } + 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; } - 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 */ +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 */ { - 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;j3) 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)<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< 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"); } + } } /* in: instruction line @@ -899,113 +1023,153 @@ char opcode_bit_ptr; Return-value = recursive_level */ /* build iif of one assembly text line */ -int parse(line,recursive_level) -char *line; -int recursive_level; +int +parse (line, 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"); - } - *lineptr=c; - } else { - lineptr=line; + 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"); } - 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 = 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; } + } + 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("Wrong number of operands"); + else + { + as_fatal ("Too many operands passed to instruction"); } - + } } - for (i=0;ioperands) / 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"); + } } - - /* 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); - - /* this call encodes operands to iif format */ - if (argc) { - encode_operand(argc, - argv, - &desc->operands[0], - &suffix[0], - desc->im_size, - desc->opcode_size); + else + { + as_fatal ("Wrong number of operands"); } - return recursive_level; -} + } + 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); + + /* 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; +} + /* 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 @@ -1015,259 +1179,313 @@ int recursive_level; md_? parts according to given instructions Note that iif was invented for the clean ns32k`s architecure. */ -void convert_iif() { - int i; - int j; - fragS *inst_frag; - char *inst_offset; - char **inst_opcode; - char *memP; - segT segment; - int l; - int k; - int rem_size; /* count the remaining bytes of instruction */ - char type; - 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;ifx_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 */ - memset(memP, '\0', 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 +void +convert_iif () +{ + int i; + int j; + fragS *inst_frag; + char *inst_offset; + char **inst_opcode; + char *memP; + segT segment; + int l; + int k; + int rem_size; /* count the remaining bytes of instruction */ + char type; + 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 */ + memset (memP, '\0', 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 */ - memset(memP, '\0', 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"); - } - break; - case 0: /* To bad, the object may be undefined as far as its final + 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 */ + memset (memP, '\0', 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"); + } + 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 + { + 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 + 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 + 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? + (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 && + 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 */ - } - } - break; - default: - as_fatal("Internal logic error in iif.iifP[].type"); - } - size_so_far+=size; - size=0; - } + { + 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 */ + } + } + break; + default: + as_fatal ("Internal logic error in iif.iifP[].type"); + } + size_so_far += size; + size = 0; } + } } -void md_assemble(line) -char *line; +void +md_assemble (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;ptrname,(char*)ptr))) { - as_fatal("Can't hash %s: %s", ptr->name,stat); /*fatal*/ - exit(0); - } +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); } - 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 @@ -1277,222 +1495,277 @@ void 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': - 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_ns32k (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; - } -} /* md_number_to_chars() */ + *buf++ = value; /* Lint wants & MASK_CHAR. */ + value >>= BITS_PER_CHAR; + } +} /* md_number_to_chars() */ /* This is a variant of md_numbers_to_chars. The reason for its' existence 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 - - This must be taken care of and we do it here! + + 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; -{ - switch(n) { - case 1: - if (val < -64 || val > 63) - as_warn("Byte displacement out of range. line number not valid"); - val&=0x7f; +static void +md_number_to_disp (buf, val, 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; #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; -{ - switch(n) { - case 1: +static void +md_number_to_imm (buf, val, n) + char *buf; + long val; + char n; +{ + 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. */ #ifdef comment void - 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) */ +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) */ } + #endif /* comment */ +#ifdef OBJ_AOUT +void +tc_aout_fix_to_chars (where, fixP, segment_address_in_file) + char *where; + struct fix *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_symbolnum; + + know (fixP->fx_addsy != NULL); + + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + + md_number_to_chars (where, + ((long) (r_symbolnum) + | (long) (fixP->fx_pcrel << 24) + | (long) (nbytes_r_length[fixP->fx_size] << 25) + | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27) + | (long) (fixP->fx_bsr << 28) + | (long) (fixP->fx_im_disp << 29)), + 4); + + return; +} /* tc_aout_fix_to_chars() */ + +#endif /* OBJ_AOUT */ + /* 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, - }; -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, - }; +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, +}; +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, +}; #define MASK_BITS 31 /* Insert bitfield described by field_ptr and val at buf This routine is written for modification of the first 4 bytes pointed @@ -1502,139 +1775,154 @@ static unsigned long r_mask[]={ 0x00000000, 0x00000001, 0x00000003, 0x00000007, */ static void - 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 */ +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 */ #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; -#ifdef ENDIAN /* we have a nice ns32k machine with lowbyte at low-physical mem */ - object = *mem_ptr; /* get some bytes */ + 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 */ #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<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. + 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); - break; - - case 2: /* Pointer in a data object */ - md_number_to_chars (buf, val, fixP->fx_size); - break; - } + 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); + break; + + case 2: /* Pointer in a data object */ + md_number_to_chars (buf, val, fixP->fx_size); + break; + } } /* Convert a relaxed displacement to ditto in final output */ void - md_convert_frag(headers, fragP) -object_headers *headers; -register fragS *fragP; +md_convert_frag (headers, fragP) + object_headers *headers; + register fragS *fragP; { - long disp; - long ext = 0; - - /* 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; + long disp; + long ext = 0; + + /* 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; } - if(ext) { - md_number_to_disp(buffer_address,(long)disp,(int)ext); - fragP->fr_fix+=ext; - } } @@ -1643,107 +1931,115 @@ register fragS *fragP; 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; +int +md_estimate_size_before_relax (fragP, 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 + 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; + 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; + 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; -int md_long_jump_size = 5; +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) -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; - 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) -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; { - 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) -char **argP; -int *cntP; -char ***vecP; +md_parse_option (argP, cntP, vecP) + char **argP; + int *cntP; + char ***vecP; { - switch(**argP) { - case 'm': - (*argP)++; - - if(!strcmp(*argP,"32032")) { - cpureg = cpureg_032; - mmureg = mmureg_032; - } else if(!strcmp(*argP, "32532")) { - cpureg = cpureg_532; - mmureg = mmureg_532; - } else - as_warn("Unknown -m option ignored"); - - while(**argP) - (*argP)++; - break; - - default: - return 0; + switch (**argP) + { + case 'm': + (*argP)++; + + if (!strcmp (*argP, "32032")) + { + cpureg = cpureg_032; + mmureg = mmureg_032; + } + else if (!strcmp (*argP, "32532")) + { + cpureg = cpureg_532; + mmureg = mmureg_532; } - return 1; + else + as_warn ("Unknown -m option ignored"); + + while (**argP) + (*argP)++; + break; + + default: + return 0; + } + return 1; } /* @@ -1753,82 +2049,83 @@ char ***vecP; * This struct is used to profile the normal fix. If the bit_fixP is a * 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 */ +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 */ { - 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? */ -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? */ + 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 */ { - fixS *fixP = fix_new(frag, where, size, add_symbol, sub_symbol, - offset, pcrel, NO_RELOC); - - fixP->fx_pcrel_adjust = pcrel_adjust; - fixP->fx_im_disp = im_disp; - fixP->fx_bit_fixP = bit_fixP; - fixP->fx_bsr = bsr; -} /* fix_new_ns32k() */ + fixS *fixP = fix_new (frag, where, size, add_symbol, sub_symbol, + offset, pcrel, NO_RELOC); + + fixP->fx_pcrel_adjust = pcrel_adjust; + fixP->fx_im_disp = im_disp; + fixP->fx_bit_fixP = bit_fixP; + fixP->fx_bsr = bsr; +} /* fix_new_ns32k() */ /* 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. +/* Parse an operand that is machine-specific. We just return without modifying the expression if we have nothing to do. */ /* 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? @@ -1836,21 +2133,16 @@ long 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; -} - -void tc_aout_fix_to_chars(char *where, struct fix *fixP, - relax_addressT segment_address) { - know(0); /* know nothing */ + return res; } /* diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index d7fba8f690f..b5985d316e9 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -1,18 +1,18 @@ /* tc-sparc.c -- Assemble for the SPARC Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -23,54 +23,57 @@ #include #include "as.h" +#include "read.h" /* careful, this file includes data *declarations* */ #include "opcode/sparc.h" -void md_begin(); -void md_end(); -void md_number_to_chars(); -void md_assemble(); -char *md_atof(); -void md_convert_frag(); -void md_create_short_jump(); -void md_create_long_jump(); -int md_estimate_size_before_relax(); -void md_ri_to_chars(); -symbolS *md_undefined_symbol(); -static void sparc_ip(); +void md_begin (); +void md_end (); +void md_number_to_chars (); +void md_assemble (); +char *md_atof (); +void md_convert_frag (); +void md_create_short_jump (); +void md_create_long_jump (); +int md_estimate_size_before_relax (); +void md_ri_to_chars (); +symbolS *md_undefined_symbol (); +static void sparc_ip (); static enum sparc_architecture current_architecture = v6; static int architecture_requested = 0; static int warn_on_bump = 0; -const relax_typeS md_relax_table[] = { - 0 }; +const relax_typeS md_relax_table[] = +{ + 0}; /* handle of the OPCODE hash table */ static struct hash_control *op_hash = NULL; -static void s_seg(), s_proc(), s_data1(), s_reserve(), s_common(); -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 }, +static void s_seg (), s_proc (), s_data1 (), s_reserve (), s_common (); +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}, }; const int md_short_jump_size = 4; const int md_long_jump_size = 4; -const int md_reloc_size = 12; /* Size of relocation record */ +const int md_reloc_size = 12; /* Size of relocation record */ /* This array holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful */ @@ -86,6 +89,8 @@ const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */ work if '/' isn't otherwise defined. */ const char line_comment_chars[] = "#"; +const char line_separator_chars[] = ""; + /* Chars that can be used to separate mant from exp in floating point nums */ const char EXP_CHARS[] = "eE"; @@ -101,27 +106,28 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; static unsigned char octal[256]; #define isoctal(c) octal[c] - static unsigned char toHex[256]; - -struct sparc_it { - char *error; - unsigned long opcode; - struct nlist *nlistp; - expressionS exp; - int pcrel; - enum reloc_type reloc; -} the_insn, set_insn; +static unsigned char toHex[256]; + +struct sparc_it + { + char *error; + unsigned long opcode; + struct nlist *nlistp; + expressionS exp; + int pcrel; + enum reloc_type reloc; + } the_insn, set_insn; #if __STDC__ == 1 #if 0 -static void print_insn(struct sparc_it *insn); +static void print_insn (struct sparc_it *insn); #endif -static int getExpression(char *str); +static int getExpression (char *str); #else /* not __STDC__ */ #if 0 -static void print_insn(); +static void print_insn (); #endif -static int getExpression(); +static int getExpression (); #endif /* not __STDC__ */ static char *expr_end; @@ -140,1268 +146,1443 @@ static int special_case; */ static int max_alignment = 15; -static void s_reserve() { - char *name; - 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; +static void +s_reserve () +{ + char *name; + 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; + + 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."); } - - ++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; - - /* 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; -} /* 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; - } - 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; + + /* 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 */ + + 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); } - if (strncmp(input_line_pointer, "\"bss\"", 5) == 0) { - input_line_pointer += 5; - /* We only support 2 segments -- text and data -- for now, so + } + 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; - } - as_bad("Unknown segment type"); - demand_empty_rest_of_line(); - return; -} /* s_seg() */ + 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; +} /* s_data1() */ -static void s_data1() { - subseg_new(SEG_DATA, 1); - demand_empty_rest_of_line(); - return; -} /* s_data1() */ +static void +s_proc () +{ + extern char is_end_of_line[]; -static void s_proc() { - extern char is_end_of_line[]; - - while (!is_end_of_line[*input_line_pointer]) { - ++input_line_pointer; - } - ++input_line_pointer; - return; -} /* s_proc() */ + while (!is_end_of_line[*input_line_pointer]) + { + ++input_line_pointer; + } + ++input_line_pointer; + return; +} /* s_proc() */ /* start-sanitize-v9 */ #ifndef NO_V9 -struct priv_reg_entry { char *name; int regnum; }; +struct priv_reg_entry + { + char *name; + int regnum; + }; struct priv_reg_entry priv_reg_table[] = { - { "tpc", 0 }, - { "tnpc", 1 }, - { "tstate", 2 }, - { "tt", 3 }, - { "tick", 4 }, - { "tba", 5 }, - { "pstate", 6 }, - { "tl", 7 }, - { "pil", 8 }, - { "cwp", 9 }, - { "cansave", 10 }, - { "canrestore", 11 }, - { "cleanwin", 12 }, - { "otherwin", 13 }, - { "wstate", 14}, - { "fpq", 15}, - { "ver", 31 }, - { "", -1 }, /* end marker */ + {"tpc", 0}, + {"tnpc", 1}, + {"tstate", 2}, + {"tt", 3}, + {"tick", 4}, + {"tba", 5}, + {"pstate", 6}, + {"tl", 7}, + {"pil", 8}, + {"cwp", 9}, + {"cansave", 10}, + {"canrestore", 11}, + {"cleanwin", 12}, + {"otherwin", 13}, + {"wstate", 14}, + {"fpq", 15}, + {"ver", 31}, + {"", -1}, /* end marker */ }; -static int cmp_reg_entry (p, q) +static int +cmp_reg_entry (p, q) struct priv_reg_entry *p, *q; { return strcmp (q->name, p->name); } + #endif /* end-sanitize-v9 */ /* 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)); +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; } - - 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'; - -/* start-sanitize-v9 */ + 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'; + + /* start-sanitize-v9 */ #ifndef NO_V9 - qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]), - sizeof (priv_reg_table[0]), cmp_reg_entry); + qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]), + sizeof (priv_reg_table[0]), cmp_reg_entry); #endif -/* end-sanitize-v9 */ -} /* md_begin() */ + /* end-sanitize-v9 */ +} /* md_begin() */ -void md_end() { - return; -} /* md_end() */ +void +md_end () +{ + return; +} /* md_end() */ -void md_assemble(str) -char *str; +void +md_assemble (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 */ - } - } - - 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); + 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 */ } - 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 + } + + 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); + 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."); - } -} /* md_assemble() */ - -static void sparc_ip(str) -char *str; + 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 *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; - long immediate_max = 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; - memset(&the_insn, '\0', sizeof(the_insn)); - the_insn.reloc = NO_RELOC; - - /* + 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; + long immediate_max = 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; + memset (&the_insn, '\0', 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) { - - /* start-sanitize-v9 */ + for (args = insn->args;; ++args) + { + switch (*args) + { + + /* start-sanitize-v9 */ #ifndef NO_V9 - case 'K': - { - /* Load is 0; Store is 1. + case 'K': + { + /* Load is 0; Store is 1. We compute the mask based on the values we find in S. OK is set set if we see something we don't like. */ - int ok = 1; - int mask = 0; - while (ok == 1) - { - int lo = 0, hi = 0; - if (*s == '#') - { - s += 1; - if (! (lo = (s[0] == 'S'))) - ok = (s[0] == 'L'); - if (! (hi = (s[1] == 'S'))) - ok = (s[1] == 'L'); - mask |= (1 << ((hi<<1) | lo)); - s += 2; - } - else - { - /* Parse a number, somehow. */ - ok = 0; - } - if (s[2] != '|') - break; - } - if (! ok) - { - error_message = "unrecognizable mmask"; - goto error; - } - opcode |= SIMM13(mask); - continue; - } + int ok = 1; + int mask = 0; + while (ok == 1) + { + int lo = 0, hi = 0; + if (*s == '#') + { + s += 1; + if (!(lo = (s[0] == 'S'))) + ok = (s[0] == 'L'); + if (!(hi = (s[1] == 'S'))) + ok = (s[1] == 'L'); + mask |= (1 << ((hi << 1) | lo)); + s += 2; + } + else + { + /* Parse a number, somehow. */ + ok = 0; + } + if (s[2] != '|') + break; + } + if (!ok) + { + error_message = "unrecognizable mmask"; + goto error; + } + opcode |= SIMM13 (mask); + continue; + } + + case '*': + /* Parse a prefetch function. */ + if (*s == '#') + { + int prefetch_fcn = 0; + + s += 1; + if (!strncmp (s, "n_reads", 7)) + prefetch_fcn = 0, s += 7; + else if (!strncmp (s, "one_read", 8)) + prefetch_fcn = 1, s += 8; + else if (!strncmp (s, "n_writes", 8)) + prefetch_fcn = 2, s += 8; + else if (!strncmp (s, "one_write", 9)) + prefetch_fcn = 3, s += 9; + else if (!strncmp (s, "page", 4)) + prefetch_fcn = 4, s += 4; + else + { + error_message = "unrecognizable prefetch fucntion"; + goto error; + } + } + else + { + /* Parse a number, somehow. */ + error_message = "unrecognizable prefetch fucntion"; + goto error; + } + continue; + + case '!': + case '?': + /* Parse a privileged register. */ + if (*s == '%') + { + struct priv_reg_entry *p = priv_reg_table; + int len; + + s += 1; + while (p->name[0] > s[0]) + p++; + while (p->name[0] == s[0]) + { + len = strlen (p->name); + if (strncmp (p->name, s, len) == 0) + break; + p++; + } + if (p->name[0] != s[0]) + { + error_message = "unrecognizable privileged register"; + goto error; + } + if (*args == '?') + opcode |= (p->regnum << 14); + else + opcode |= (p->regnum << 25); + s += len; + continue; + } + else + { + error_message = "unrecognizable privileged register"; + goto error; + } +#endif + /* end-sanitize-v9 */ - case '*': - /* Parse a prefetch function. */ - if (*s == '#') - { - int prefetch_fcn = 0; - - s += 1; - if (! strncmp (s, "n_reads", 7)) - prefetch_fcn = 0, s += 7; - else if (! strncmp (s, "one_read", 8)) - prefetch_fcn = 1, s += 8; - else if (! strncmp (s, "n_writes", 8)) - prefetch_fcn = 2, s += 8; - else if (! strncmp (s, "one_write", 9)) - prefetch_fcn = 3, s += 9; - else if (! strncmp (s, "page", 4)) - prefetch_fcn = 4, s += 4; - else - { - error_message = "unrecognizable prefetch fucntion"; - goto error; - } - } - else - { - /* Parse a number, somehow. */ - error_message = "unrecognizable prefetch fucntion"; - goto error; - } - continue; + case 'M': + case 'm': + if (strncmp (s, "%asr", 4) == 0) + { + s += 4; - case '!': - case '?': - /* Parse a privileged register. */ - if (*s == '%') - { - struct priv_reg_entry *p = priv_reg_table; - int len; - - s += 1; - while (p->name[0] > s[0]) - p++; - while (p->name[0] == s[0]) - { - len = strlen (p->name); - if (strncmp (p->name, s, len) == 0) - break; - p++; - } - if (p->name[0] != s[0]) - { - error_message = "unrecognizable privileged register"; - goto error; - } - if (*args == '?') - opcode |= (p->regnum << 14); - else - opcode |= (p->regnum << 25); - s += len; - continue; - } - else + 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; + immediate_max = 0x03FF; + goto immediate; + + case 'j': + the_insn.reloc = RELOC_10; + immediate_max = 0x01FF; + 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 '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 '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) { - error_message = "unrecognizable privileged register"; goto error; } -#endif - /* end-sanitize-v9 */ - - 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; - immediate_max = 0x03FF; - goto immediate; - - case 'j': - the_insn.reloc = RELOC_10; - immediate_max = 0x01FF; - 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 '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 '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; - } - /* + } + 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; - - 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 */ + 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; + + 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 == 'v' - || *args == 'B' - || *args == 'H') - && (mask & 1)) { - break; - } /* register must be even numbered */ - - if ((*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 == 'v' + || *args == 'B' + || *args == 'H') + && (mask & 1)) + { + break; + } /* register must be even numbered */ + + if ((*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) { - - 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; - immediate_max = 0x0FFF; - - /*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 */ + } /* if not an 'f' register. */ + } /* on error */ + + switch (*args) + { + + 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; + immediate_max = 0x0FFF; + + /*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 == 'u' - && s[2] == 'h' - && s[3] == 'i') { - the_insn.reloc = RELOC_HHI22; - s += 4; - - } else if (c == 'u' - && s[2] == 'l' - && s[3] == 'o') { - the_insn.reloc = RELOC_HLO10; - s += 4; + } + else if (c == 'u' + && s[2] == 'h' + && s[3] == 'i') + { + the_insn.reloc = RELOC_HHI22; + s += 4; + + } + else if (c == 'u' + && 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 + /* 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 + 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; - - /* Check for invalid constant values. Don't + + 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; + + /* Check for invalid constant values. Don't warn if constant was inside %hi or %lo, since these truncate the constant to fit. */ - if (immediate_max != 0 - && the_insn.reloc != RELOC_LO10 - && the_insn.reloc != RELOC_HI22 - /* start-sanitize-v9 */ + if (immediate_max != 0 + && the_insn.reloc != RELOC_LO10 + && the_insn.reloc != RELOC_HI22 + /* start-sanitize-v9 */ #ifndef NO_V9 - && the_insn.reloc != RELOC_HLO10 - && the_insn.reloc != RELOC_HHI22 + && the_insn.reloc != RELOC_HLO10 + && the_insn.reloc != RELOC_HHI22 #endif - /* end-sanitize-v9 */ - && the_insn.exp.X_add_symbol == 0 - && the_insn.exp.X_subtract_symbol == 0 - && the_insn.exp.X_seg == SEG_ABSOLUTE - && (the_insn.exp.X_add_number > immediate_max - || the_insn.exp.X_add_number < ~immediate_max)) - as_bad ("constant value must be between %ld and %ld", - ~immediate_max, immediate_max); - /* Reset to prevent extraneous range check. */ - immediate_max = 0; - - 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; - -/* start-sanitize-v9 */ + /* end-sanitize-v9 */ + && the_insn.exp.X_add_symbol == 0 + && the_insn.exp.X_subtract_symbol == 0 + && the_insn.exp.X_seg == SEG_ABSOLUTE + && (the_insn.exp.X_add_number > immediate_max + || the_insn.exp.X_add_number < ~immediate_max)) + as_bad ("constant value must be between %ld and %ld", + ~immediate_max, immediate_max); + /* Reset to prevent extraneous range check. */ + immediate_max = 0; + + 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; + + /* start-sanitize-v9 */ #ifndef NO_V9 - case 'o': - if (strncmp (s, "%asi", 4) != 0) - break; - s += 4; - continue; - - case 's': - if (strncmp (s, "%fprs", 5) != 0) - break; - s+= 5; - continue; - - case 'E': - if (strncmp (s, "%ccr", 4) != 0) - break; - s+= 4; - continue; + case 'o': + if (strncmp (s, "%asi", 4) != 0) + break; + s += 4; + continue; + + case 's': + if (strncmp (s, "%fprs", 5) != 0) + break; + s += 5; + continue; + + case 'E': + if (strncmp (s, "%ccr", 4) != 0) + break; + s += 4; + continue; #endif /* NO_V9 */ - /* end-sanitize-v9 */ + /* end-sanitize-v9 */ - 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) - && -/* start-sanitize-v9 */ + 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) + && + /* start-sanitize-v9 */ #ifndef NO_V9 - ! ARCHITECTURES_CONFLICT_P (current_architecture, - insn->architecture) + !ARCHITECTURES_CONFLICT_P (current_architecture, + insn->architecture) #else -/* end-sanitize-v9 */ - 1 -/* start-sanitize-v9 */ + /* end-sanitize-v9 */ + 1 + /* start-sanitize-v9 */ #endif -/* end-sanitize-v9 */ - ) { - 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() */ + /* end-sanitize-v9 */ + ) + { + 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 */ -static int getExpression(str) -char *str; + 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 *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 0; -} /* getExpression() */ + 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 0; +} /* getExpression() */ /* 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. @@ -1410,415 +1591,449 @@ char *str; /* Equal to MAX_PRECISION in atof-ieee.c */ #define MAX_LITTLENUMS 6 -char *md_atof(type,litP,sizeP) -char type; -char *litP; -int *sizeP; +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 */ -} /* md_atof() */ + 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 */ +} /* md_atof() */ /* * Write out big-endian. */ -void md_number_to_chars(buf,val,n) -char *buf; -long val; -int n; +void +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; -} /* md_number_to_chars() */ + + 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; +} /* 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; +void +md_apply_fix (fixP, 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) { - - case RELOC_32: - buf[0] = 0; /* val >> 24; */ - buf[1] = 0; /* val >> 16; */ - buf[2] = 0; /* val >> 8; */ - buf[3] = 0; /* val; */ - break; - + 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] = 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_10: - if (((val > 0) && (val & ~0x3ff)) - || ((val < 0) && (~(val - 1) & ~0x3ff))) { - as_bad("relocation overflow."); - } /* on overflow */ - - buf[2] |= (val >> 8) & 0x3; - 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_10: + if (((val > 0) && (val & ~0x3ff)) + || ((val < 0) && (~(val - 1) & ~0x3ff))) + { + as_bad ("relocation overflow."); + } /* on overflow */ + + buf[2] |= (val >> 8) & 0x3; + 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: - if (((val > 0) && (val & ~0x00001fff)) - || ((val < 0) && (~(val - 1) & ~0x00001fff))) { - as_bad("relocation overflow"); - } /* on overflow */ - 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: + if (((val > 0) && (val & ~0x00001fff)) + || ((val < 0) && (~(val - 1) & ~0x00001fff))) + { + as_bad ("relocation overflow"); + } /* on overflow */ + 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; - } -} /* md_apply_fix() */ + + 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; +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("sparc_create_short_jmp\n"); -} /* md_create_short_jump() */ + as_fatal ("sparc_create_short_jmp\n"); +} /* md_create_short_jump() */ /* Translate internal representation of relocation info to target format. - + On sparc: 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 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) +tc_aout_fix_to_chars (where, fixP, segment_address_in_file) char *where; fixS *fixP; relax_addressT segment_address_in_file; { - long r_index; - long r_extern; - long r_addend = 0; - long r_address; - - know(fixP->fx_addsy); - - if (!S_IS_DEFINED(fixP->fx_addsy)) { - 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 += fixP->fx_offset - r_address; - } else { - r_addend = fixP->fx_addnumber; - } - - md_number_to_chars(&where[8], r_addend, 4); - - return; -} /* tc_aout_fix_to_chars() */ + long r_index; + long r_extern; + long r_addend = 0; + long r_address; + + know (fixP->fx_addsy); + + if (!S_IS_DEFINED (fixP->fx_addsy)) + { + 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 += fixP->fx_offset - 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; +void +md_convert_frag (headers, fragP) + object_headers *headers; + register fragS *fragP; { - as_fatal("sparc_convert_frag\n"); -} /* md_convert_frag() */ + 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; +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("sparc_create_long_jump\n"); -} /* md_create_long_jump() */ + 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; +int +md_estimate_size_before_relax (fragP, segtype) + fragS *fragP; + segT segtype; { - as_fatal("sparc_estimate_size_before_relax\n"); - return(1); -} /* md_estimate_size_before_relax() */ + 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; +static void +print_insn (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 = { -\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; -} /* print_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 != 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... */ @@ -1833,49 +2048,61 @@ struct sparc_it *insn; * this machine dependent routine to emit them. */ #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; +void +emit_sparc_reloc (fixP, 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; */ - - memset((char *) &ri, '\0', 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; - } + struct reloc_info_generic ri; + register symbolS *symbolP; + extern char *next_object_file_charP; + /* long add_number; */ + + memset ((char *) &ri, '\0', 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); } - return; -} /* emit_sparc_reloc() */ + + 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 */ @@ -1899,7 +2126,7 @@ relax_addressT segment_address_in_file; * * If an architecture is specified, all instructions must match * that architecture. Any higher level instructions are flagged - * as errors. + * as errors. * * if both an architecture and -bump are specified, the * architecture starts at the specified level, but bumps are @@ -1913,84 +2140,100 @@ relax_addressT segment_address_in_file; /* 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; +int +md_parse_option (argP, cntP, vecP) + char **argP; + int *cntP; + char ***vecP; { - char *p; - const char **arch; - - 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 { - /* Unknown option */ - (*argP)++; - return 0; + char *p; + const char **arch; + + 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; } - **argP = '\0'; /* Done parsing this switch */ - return 1; -} /* md_parse_option() */ + } + 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; +symbolS * +md_undefined_symbol (name) + char *name; { - return 0; -} /* md_undefined_symbol() */ + return 0; +} /* md_undefined_symbol() */ /* Parse an operand that is machine-specific. We just return without modifying the expression if we have nothing to do. */ /* ARGSUSED */ -void md_operand(expressionP) -expressionS *expressionP; +void +md_operand (expressionP) + expressionS *expressionP; { -} /* md_operand() */ +} /* md_operand() */ /* Round up a section size to the appropriate boundary. */ -long md_section_align (segment, size) -segT segment; -long size; +long +md_section_align (segment, size) + segT segment; + long size; { - return (size + 7) & ~7; /* Round all sects to multiple of 8 */ -} /* md_section_align() */ + return (size + 7) & ~7; /* Round all sects to multiple of 8 */ +} /* md_section_align() */ /* 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; +long +md_pcrel_from (fixP) + fixS *fixP; { - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; -} /* md_pcrel_from() */ + 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; +void +tc_aout_pre_write_hook (headers) + object_headers *headers; { - H_SET_VERSION(headers, 1); - return; -} /* tc_aout_pre_write_hook() */ + H_SET_VERSION (headers, 1); + return; +} /* tc_aout_pre_write_hook() */ /* * Local Variables: diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h index 7f450afb325..92b483791f1 100644 --- a/gas/config/tc-sparc.h +++ b/gas/config/tc-sparc.h @@ -1,41 +1,40 @@ /* tc-sparc.h - Macros and type defines for the sparc. Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define TC_SPARC 1 -#define NO_LISTING #define LOCAL_LABELS_FB #ifdef OBJ_BOUT -#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE ((0x103 << 16) | BMAGIC) /* Magic number for header */ +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE ((0x103 << 16) | BMAGIC) /* Magic number for header */ #else #ifdef OBJ_AOUT -#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE ((0x103 << 16) | OMAGIC) /* Magic number for header */ +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE ((0x103 << 16) | OMAGIC) /* Magic number for header */ #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. */ +#define tc_headers_hook(a) {;} /* don't need it. */ +#define tc_crawl_symbol_chain(a) {;} /* don't need it. */ -void tc_aout_pre_write_hook(); +void tc_aout_pre_write_hook (); #define LISTING_HEADER "SPARC GAS " diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index 5faa1441cf2..498b32d4f28 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -1,18 +1,18 @@ -/* vax.c - vax-specific - - Copyright (C) 1987, 1991 Free Software Foundation, Inc. - +/* tc-vax.c - vax-specific - + Copyright (C) 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. */ @@ -24,12 +24,8 @@ #include "as.h" #include "read.h" -#include "flonum.h" #include "vax-inst.h" #include "obstack.h" /* For FRAG_APPEND_1_CHAR macro in "frags.h" */ -#include "frags.h" -#include "expr.h" -#include "symbols.h" /* These chars start a comment anywhere in a source file (except inside another comment */ @@ -39,6 +35,8 @@ const char comment_chars[] = "#"; /* Note that for the VAX the are the same as comment_chars above. */ const char line_comment_chars[] = "#"; +const char line_separator_chars[] = ""; + /* Chars that can be used to separate mant from exp in floating point nums */ const char EXP_CHARS[] = "eE"; @@ -53,10 +51,10 @@ const char FLT_CHARS[] = "dDfFgGhH"; */ 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. */ @@ -81,12 +79,12 @@ 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 where is a simple flag test. length of byte, word, long. VAX opcodes are: (Hex) @@ -104,7 +102,7 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; blssu/bcs 1f Always, you complement 0th bit to reverse condition. Always, 1-byte opcode, then 1-byte displacement. - + 2b. J where cond tests a memory bit. length of byte, word, long. Vax opcodes are: (Hex) @@ -118,7 +116,7 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; bbcci e7 Always, you complement 0th bit to reverse condition. Always, 1-byte opcde, longword-address, byte-address, 1-byte-displacement - + 2c. J where cond tests low-order memory bit length of byte,word,long. Vax opcodes are: (Hex) @@ -126,7 +124,7 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; 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) @@ -134,7 +132,7 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; 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) @@ -150,7 +148,7 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; 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) @@ -160,14 +158,14 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; 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. */ @@ -189,77 +187,31 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) const relax_typeS - md_relax_table[] = -{ -{ - 1, 1, 0, 0 - }, /* error sentinel 0,0 */ -{ - 1, 1, 0, 0 - }, /* unused 0,1 */ -{ - 1, 1, 0, 0 - }, /* unused 0,2 */ -{ - 1, 1, 0, 0 - }, /* unused 0,3 */ -{ - BF + 1, BB + 1, 2, C (1, 1) - }, /* B^"foo" 1,0 */ -{ - WF + 1, WB + 1, 3, C (1, 2) - }, /* W^"foo" 1,1 */ -{ - 0, 0, 5, 0 - }, /* L^"foo" 1,2 */ -{ - 1, 1, 0, 0 - }, /* unused 1,3 */ -{ - BF, BB, 1, C (2, 1) - }, /* b B^"foo" 2,0 */ -{ - WF + 2, WB + 2, 4, C (2, 2) - }, /* br.+? brw X 2,1 */ -{ - 0, 0, 7, 0 - }, /* br.+? jmp X 2,2 */ -{ - 1, 1, 0, 0 - }, /* unused 2,3 */ -{ - BF, BB, 1, C (3, 1) - }, /* brb B^foo 3,0 */ -{ - WF, WB, 2, C (3, 2) - }, /* brw W^foo 3,1 */ -{ - 0, 0, 5, 0 - }, /* Jmp L^foo 3,2 */ -{ - 1, 1, 0, 0 - }, /* unused 3,3 */ -{ - 1, 1, 0, 0 - }, /* unused 4,0 */ -{ - WF, WB, 2, C (4, 2) - }, /* acb_ ^Wfoo 4,1 */ -{ - 0, 0, 10, 0 - }, /* acb_,br,jmp L^foo4,2 */ -{ - 1, 1, 0, 0 - }, /* unused 4,3 */ -{ - BF, BB, 1, C (5, 1) - }, /* Xob___,,foo 5,0 */ -{ - WF + 4, WB + 4, 6, C (5, 2) - }, /* Xob.+2,brb.+3,brw5,1 */ -{ - 0, 0, 9, 0 - }, /* Xob.+2,brb.+6,jmp5,2 */ + md_relax_table[] = +{ + {1, 1, 0, 0}, /* error sentinel 0,0 */ + {1, 1, 0, 0}, /* unused 0,1 */ + {1, 1, 0, 0}, /* unused 0,2 */ + {1, 1, 0, 0}, /* unused 0,3 */ + {BF + 1, BB + 1, 2, C (1, 1)},/* B^"foo" 1,0 */ + {WF + 1, WB + 1, 3, C (1, 2)},/* W^"foo" 1,1 */ + {0, 0, 5, 0}, /* L^"foo" 1,2 */ + {1, 1, 0, 0}, /* unused 1,3 */ + {BF, BB, 1, C (2, 1)}, /* b B^"foo" 2,0 */ + {WF + 2, WB + 2, 4, C (2, 2)},/* br.+? brw X 2,1 */ + {0, 0, 7, 0}, /* br.+? jmp X 2,2 */ + {1, 1, 0, 0}, /* unused 2,3 */ + {BF, BB, 1, C (3, 1)}, /* brb B^foo 3,0 */ + {WF, WB, 2, C (3, 2)}, /* brw W^foo 3,1 */ + {0, 0, 5, 0}, /* Jmp L^foo 3,2 */ + {1, 1, 0, 0}, /* unused 3,3 */ + {1, 1, 0, 0}, /* unused 4,0 */ + {WF, WB, 2, C (4, 2)}, /* acb_ ^Wfoo 4,1 */ + {0, 0, 10, 0}, /* acb_,br,jmp L^foo4,2 */ + {1, 1, 0, 0}, /* unused 4,3 */ + {BF, BB, 1, C (5, 1)}, /* Xob___,,foo 5,0 */ + {WF + 4, WB + 4, 6, C (5, 2)},/* Xob.+2,brb.+3,brw5,1 */ + {0, 0, 9, 0}, /* Xob.+2,brb.+6,jmp5,2 */ }; #undef C @@ -272,11 +224,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) @@ -284,904 +236,932 @@ 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 () + +#if __STDC__ == 1 + +int flonum_gen2vax (char format_letter, FLONUM_TYPE * f, LITTLENUM_TYPE * words); +static void vip_end (void); +static void vip_op_defaults (char *immediate, char *indirect, char *displen); + +#else /* not __STDC__ */ + +int flonum_gen2vax (); +static void vip_end (); +static void vip_op_defaults (); + +#endif /* not __STDC__ */ + +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 (1, "$", "*", "`"))) { - 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. */ +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. */ { - 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. */ +{ + /* We saw no errors in any operands - try to make frag(s) */ + int is_undefined; /* 1 if operand expression's */ + /* segment not known yet. */ + int length_code; + + 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. */ + /* fixme: unused? */ + /* struct frag *fragP; *//* Fragment of code we just made. */ + register int goofed; /* 1: 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 */ + /* richfix: unused? */ + /* 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=1. Notice that we don't make any frags yet. + * Should goofed be 1, 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 */ - { - if (*(operandP->vop_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 */ + 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 = 1; } - 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 = 0; /* 1 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 = 1. */ + 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 = 1; + 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) + int temp = 0; + + 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)); + memcpy (floatP->low, literal_float, 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 = 1; } - 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 */ + return; + } + + + /* 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); + memcpy (opcode_low_byteP, v.vit_opcode, 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); - } /* 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') + /* 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') + { + 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 is_undefined, then it might BECOME now_seg. */ + if (nbytes) + { + p = frag_more (nbytes); + fix_new (frag_now, p - frag_now->fr_literal, nbytes, + this_add_symbol, 0, this_add_number, 1, NO_RELOC); + } + 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) { - p = frag_more (nbytes); - fix_new (frag_now, p - frag_now->fr_literal, nbytes, - this_add_symbol, 0, this_add_number, 1); - } - 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) + 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); + } + else + { + if (operandP->vop_width == VAX_WIDTH_WORD_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); + 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 { - 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); - } - 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 - { - 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 + { + 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 - { /* to_seg != now_seg && to_seg != SEG_UNKNOWN */ - /* - * --- SEG FLOAT MAY APPEAR HERE ---- - */ - if (to_seg == SEG_ABSOLUTE) + } + else + { /* to_seg != now_seg && to_seg != SEG_UNKNOWN */ + /* + * --- 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); - } - else + 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, NO_RELOC); + } + 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) + { + /* 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 { - if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) + if (operandP->vop_width == VAX_WIDTH_WORD_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. */ + 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 { - 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: - */ - } - 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 - { - /* b */ - *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 - { /* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */ - if (nbytes > 0) + else { - /* 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); + /* b */ + *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) + { + /* 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, NO_RELOC); + } + 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) + { + /* 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, NO_RELOC); + /* Now eg JMP foo or JSB foo. */ + } + else { - if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP) + if (operandP->vop_width == VAX_WIDTH_WORD_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. */ + 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, NO_RELOC); + /* + * Now (eg) ACBx 1f + * BRB 2f + * 1: JMP foo + * 2: + */ } - else + else { - 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: - */ - } - 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, NO_RELOC); + /* + * Now (eg) xOBxxx 1f + * BRB 2f + * 1: JMP foo + * 2: + */ } } - 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); - } + } + 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, NO_RELOC); } } } } - 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; - } - } - 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 ("Short literal overflow(%d.), immediate mode assumed.", this_add_number); + 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))) - { /* 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. */ + 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; } - else - { /* {@}{q^}foo{(Rn)} or S^#foo */ - if (operandP->vop_reg == -1 && operandP->vop_short != 's') - { /* "{@}{q^}foo" */ - if (to_seg == now_seg) + } + 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. */ + } + else + { /* {@}{q^}foo{(Rn)} or S^#foo */ + if (operandP->vop_reg == -1 && operandP->vop_short != 's') + { + /* "{@}{q^}foo" */ + 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. */ - } - else + 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 + { + 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, NO_RELOC); + } + } + else + { /* to_seg != now_seg */ + 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 (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); + as_warn ("Length specification ignored. Address mode 9F used"); } } - else - { /* to_seg != now_seg */ - if (this_add_symbol == NULL) + else + { + /* {@}{q^}other_seg */ + know ((length == 0 && operandP->vop_short == ' ') + || (length > 0 && operandP->vop_short != ' ')); + if (is_undefined) { - 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"); - } + /* + * 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 { - /* {@}{q^}other_seg */ - know ((length == 0 && operandP->vop_short == ' ') - ||(length > 0 && operandP->vop_short != ' ')); - if (is_undefined) + if (length == 0) { - /* - * 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 - { - if (length == 0) - { - 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); + 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, NO_RELOC); } } } - else - { /* {@}{q^}foo(Rn) or S^# or I^# or # */ - if (operandP->vop_mode < 0xA) - { /* # or S^# or I^# */ - /* 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) + } + else + { /* {@}{q^}foo(Rn) or S^# or I^# or # */ + if (operandP->vop_mode < 0xA) + { /* # or S^# or I^# */ + /* 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) + { + operandP->vop_short = 's'; + } + if (operandP->vop_short == 's') + { + FRAG_APPEND_1_CHAR (this_add_number); + } + 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) { - operandP->vop_short = 's'; + /* + * 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) + { + memset (p + 5, '\0', nbytes - 4); + } } - if (operandP->vop_short == 's') + else { - FRAG_APPEND_1_CHAR (this_add_number); - } - 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) + if (to_seg == SEG_BIG) { - /* - * 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) + /* + * 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) { - bzero (p + 5, nbytes - 4); + know (nbytes == 1); + p[1] = *lP; } - } - else - { - if (to_seg == SEG_BIG) + else { - /* - * 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; - } - 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 - { - fix_new (frag_now, p + 1 - frag_now->fr_literal, - nbytes, this_add_symbol, 0, - this_add_number, 0); - } } - } - } - else - { /* {@}{q^}foo(Rn) */ - know ((length == 0 && operandP->vop_short == ' ') - ||(length > 0 && operandP->vop_short != ' ')); - if (length == 0) - { - 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; - } - else + else { - length = 4; + fix_new (frag_now, p + 1 - frag_now->fr_literal, + nbytes, this_add_symbol, 0, + this_add_number, 0, NO_RELOC); } } - 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) + } + } + else + { /* {@}{q^}foo(Rn) */ + know ((length == 0 && operandP->vop_short == ' ') + || (length > 0 && operandP->vop_short != ' ')); + if (length == 0) + { + if (to_seg == SEG_ABSOLUTE) { - md_number_to_chars (p + 1, this_add_number, length); + register long test; + + test = this_add_number; + + if (test < 0) + test = ~test; + + length = test & 0xffff8000 ? 4 + : test & 0xffffff80 ? 2 + : 1; } - else + else { - fix_new (frag_now, p + 1 - frag_now->fr_literal, - length, this_add_symbol, 0, - this_add_number, 0); + 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) + { + md_number_to_chars (p + 1, this_add_number, length); + } + else + { + fix_new (frag_now, p + 1 - frag_now->fr_literal, + length, this_add_symbol, 0, + this_add_number, 0, NO_RELOC); + } } - } /* if(single-byte-operand) */ - } - } /* for(operandP) */ - } /* if(!need_pass_2&&!goofed) */ + } + } /* if(single-byte-operand) */ + } + } /* for(operandP) */ } /* vax_assemble() */ /* @@ -1197,113 +1177,113 @@ char *instruction_string; /* A string: assemble 1 instruction. */ * 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, NO_RELOC); + 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, NO_RELOC); + 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, NO_RELOC); + 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, NO_RELOC); + 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, NO_RELOC); + 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() */ /* @@ -1318,163 +1298,203 @@ register segT segment; * Caller will turn frag into a ".space 0". */ void - 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) +md_convert_frag (headers, fragP) + object_headers *headers; + register fragS *fragP; +{ + char *addressP; /* -> _var to change. */ + char *opcodeP; /* -> opcode char(s) to change. */ + short int length_code; /* 2=long 1=word 0=byte */ + short int extension = 0; /* Size of relaxed address. */ + /* Added to fr_fix: incl. ALL var chars. */ + symbolS *symbolP; + long where; + long address_of_var; + /* Where, in file space, is _var of *fragP? */ + long target_address = 0; + /* 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 = 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): - 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; +} /* md_convert_frag() */ /* 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; +#ifdef comment +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; } - + +#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_symbolnum; + + know (fixP->fx_addsy != NULL); + + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + + where[6] = (r_symbolnum >> 16) & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[4] = r_symbolnum & 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() */ + /* * BUGS, GRIPES, APOLOGIA, etc. * @@ -1541,7 +1561,7 @@ struct reloc_info_generic ri; * source file, and changed the makefile. */ -static char *op_hash = NULL; /* handle of the OPCODE hash table */ +static struct hash_control *op_hash = NULL; /* handle of the OPCODE hash table */ /* NULL means any use before vip_begin() */ /* will crash */ @@ -1555,24 +1575,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 _ /* @@ -1624,107 +1644,67 @@ 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 */ @@ -1740,40 +1720,37 @@ You have just broken the encoding below, which assumes the 0x40 M bit means */ 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; /* 1 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 ())) + const struct vot *vP; /* scan votstrs */ + char *retval; /* error text */ + + 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); } @@ -1786,10 +1763,11 @@ char *immediate, *indirect, *displen; * We don't have to do any cleanup ourselves: all of our operand * symbol table is static, and free()ing it is naughty. */ +static void vip_end () { } - + /* * v i p ( ) * @@ -1816,120 +1794,118 @@ 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. */ + + 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; + memset (vitP->vit_opcode, '\0', 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 = (struct vot_wot *) 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; + memset (vitP->vit_opcode, '\0', 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 @@ -1943,7 +1919,7 @@ char answer[100]; /* human types a line of vax assembler here */ char *mybug; /* "" or an internal logic diagnostic */ int mycount; /* number of operands */ struct vop *myvop; /* scan operands from myvit */ -int mysynth; /* TRUE means want synthetic opcodes. */ +int mysynth; /* 1 means want synthetic opcodes. */ char my_immediate[200]; char my_indirect[200]; char my_displen[200]; @@ -1952,75 +1928,75 @@ 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 */ @@ -2071,53 +2047,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,13 +2194,9 @@ char c1, c2, c3; /* c3 == 0 if 2-character reg name */ /* vax registers we need to know */ -/* JF #define SP (14) - /* JF for one big happy file #define PC (15) */ +/* JF #define SP (14) */ +/* JF for one big happy file #define PC (15) */ -/* useful ideas */ -/* #define TRUE (1) */ -/* #define FALSE (0) */ - /* * Because this module is useful for both VMS and UN*X style assemblers * and because of the variety of UN*X assemblers we must recognise @@ -2235,9 +2207,9 @@ char c1, c2, c3; /* c3 == 0 if 2-character reg name */ */ /* 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 ^ */ +#define VIP_IMMEDIATE 01 /* Character is like DEC # */ +#define VIP_INDIRECT 02 /* Char is like DEC @ */ +#define VIP_DISPLEN 04 /* Char is like DEC ^ */ #define IMMEDIATEP(c) (vip_metacharacters [(c)&0xff]&VIP_IMMEDIATE) #define INDIRECTP(c) (vip_metacharacters [(c)&0xff]&VIP_INDIRECT) @@ -2253,25 +2225,26 @@ char c1, c2, c3; /* c3 == 0 if 2-character reg 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 @@ -2283,38 +2256,44 @@ static char vip_metacharacters[256]; #if 0 static #ifdef __GNUC__ - inline + inline #endif - static void - vip_op_1(bit,syms) -int bit; -char *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; \ - } + } #endif +static void 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. */ + char *indirect; + char *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); + + return; } -#endif +#endif + /* * Dec defines the semantics of address modes (and values) * by a two-letter code, explained here. @@ -2359,14 +2338,14 @@ vip_op_defaults (immediate, indirect, displen) /* can be called any time */ * * After parsing we have: * - * at TRUE if leading '@' (or Un*x '*') + * at 1 if leading '@' (or Un*x '*') * len takes one value from " bilsw". eg B^ -> 'b'. - * hash TRUE if leading '#' (or Un*x '$') + * hash 1 if leading '#' (or Un*x '$') * expr_begin, expr_end the expression we did not parse * even though we don't interpret it, we make use * of its presence or absence. * sign -1: -(Rn) 0: absent +1: (Rn)+ - * paren TRUE if () are around register + * paren 1 if () are around register * reg major register number 0:15 -1 means absent * ndx index register number 0:15 -1 means absent * @@ -2374,371 +2353,372 @@ 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 ' '. */ +/* 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; /* 1 if leading '@' ('*') seen */ + char len; /* one of " bilsw" */ + int hash; /* 1 if leading '#' ('$') seen */ + int sign = 0; /* -1, 0 or +1 */ + int paren = 0; /* 1 if () surround register */ + int reg = 0; /* register number, -1:absent */ + int ndx = 0; /* 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 = NULL; /* preserve q in case we backup */ + int mode = 0; /* 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)) + { /* 1 if *p=='@'(or '*' for Un*x) */ + p++; /* at is determined */ + 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)) /* 1 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) /* 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) -{ - sign = 0; /* no ()+ or -() seen yet */ - - if (q > p + 3 && *q == '+' && q[-1] == ')') + /* reverse over whitespace, but don't */ + /* run back over *p */ + if (!*err) { - sign = 1; /* we saw a ")+" */ - q--; /* q points to ')' */ - } - - if (*q == ')' && q > p + 2) - { - paren = TRUE; /* assume we have "(...)" */ - while (q >= p && *q != '(') + 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 = 1; /* assume we have "(...)" */ + while (q >= p && *q != '(') q--; - /* either q

= 0 then we saw (Rn). - */ + /* + * If err == "..." then we lost. Run away. + * Otherwise if reg >= 0 then we saw (Rn). + */ + } + /* + * If err == "..." then we lost. + * Otherwise paren==1 and reg = register in "()". + */ } - /* - * 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 (paren && sign < 1)/* !sign is adequate test */ + else + paren = 0; + /* + * If err == "..." then we lost. + * Otherwise, q points just before "(Rn)", if any. + * If there was a "(...)" then paren==1, and reg is the register. + */ + + /* + * We should only seek '-' of "-(...)" if: + * we saw "(...)" paren == 1 + * 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 (*q == '-') + if (paren && sign < 1)/* !sign is adequate test */ { - sign = -1; - q--; + if (*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. */ + /* 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) - err = "address prohibits #"; - else + else { - if (sign) + if (hash) + err = "address prohibits #"; + else { - if (sign < 0) + if (sign) + { + if (sign < 0) err = "address prohibits -()"; - else + else err = "address prohibits ()+"; - } - else - { - if (paren) - err = "address prohibits ()"; - else + } + else { - if (ndx >= 0) - err = "address prohibits []"; - else + if (paren) + err = "address prohibits ()"; + else { - if (reg >= 0) - err = "address prohibits register"; - else + if (ndx >= 0) + err = "address prohibits []"; + else { - if (len != ' ') - err = "address prohibits displacement length specifier"; - else + if (reg >= 0) + err = "address prohibits register"; + else { - err = " "; /* succeed */ - mode = 0; + if (len != ' ') + err = "address prohibits displacement length specifier"; + else + { + err = " "; /* succeed */ + mode = 0; + } } } } @@ -2747,302 +2727,301 @@ if (!*err) } } } -} #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) - err = "invalid operand of S^#"; - else + /* + * Case of S^#. + * + * in: at 0 + * len 's' definition + * hash 1 demand + * p:q demand not empty + * sign 0 by paren==0 + * paren 0 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 (reg >= 0) + if (!hash || paren || at || ndx >= 0) + err = "invalid operand of S^#"; + else { - /* - * 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) + 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) err = "S^# needs expression"; - else if (access == 'r') - { - err = " "; /* WIN! */ - mode = 0; - } - else + 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

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 = 1; + paren = 0; + } -/* - * Case of (Rn)+, which is slightly different. - * - * in: at - * len ' ' - * hash FALSE - * p:q q

0) -{ - if (len != ' ' || hash || p <= q) - err = "invalid operand of ()+"; - else + /* + * Case of (Rn)+, which is slightly different. + * + * in: at + * len ' ' + * hash 0 + * p:q q

0) { - err = " "; /* win */ - mode = 8 + (at ? 1 : 0); - if (reg == PC) + if (len != ' ' || hash || p <= q) + err = "invalid operand of ()+"; + 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 1 by definition + * p:q + * sign 0 + * paren 0 + * 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 - { - if (reg >= 0) + else { - /* - * 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) + 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') + vopP->vop_nbytes = 4; + + 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 == 0 + */ -/* - * 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) + /* + * Case of Rn. We seperate this one because it has a few special + * errors the remaining modes lack. + * + * in: at optional + * len ' ' + * hash 0 by program logic + * p:q empty + * sign 0 by program logic + * paren 0 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) { - err = " "; /* win */ - mode = 6; /* @Rn */ - } - else if (ndx >= 0) + if (len != ' ') + err = "length not needed"; + 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 == 0 + * paren == 1 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) -{ - err = " "; /* win (always) */ - mode = 10 + (at ? 1 : 0); - switch (len) + /* + * Rest of cases fit into one bunch. + * + * in: at optional + * len ' ' or 'b' or 'w' or 'l' + * hash 0 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) { - case 'l': - mode += 2; - case 'w': - mode += 2; - case ' ': /* assumed B^ until our caller changes it */ - case 'b': - break; + 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; + } } -} -/* - * 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 @@ -3052,7 +3031,7 @@ if (*err == ' ') {@}(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. */ @@ -3085,102 +3064,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 */ @@ -3189,150 +3168,150 @@ mumble (text, value) const int md_short_jump_size = 3; const int md_long_jump_size = 6; -const int md_reloc_size = 8; /* Size of relocation record */ +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 - S_GET_VALUE (to_symbol); + *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, NO_RELOC); } 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; - - case 'h': /* No hashing of mixed-case names */ - break; - - case 'H': /* Show new symbol after hash truncation */ - break; + case '+': /* For g++ */ + break; + + case 'h': /* No hashing of mixed-case names */ + break; + + case 'H': /* Show new symbol after hash truncation */ + 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. +/* Parse an operand that is machine-specific. We just return without modifying the expression if we have nothing to do. */ /* 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; } /* end of tc-vax.c */ diff --git a/gas/config/te-ic960.h b/gas/config/te-ic960.h index 8d326320c2e..aecd42353ff 100644 --- a/gas/config/te-ic960.h +++ b/gas/config/te-ic960.h @@ -1,19 +1,19 @@ /* This file is twe-ic960.h Copyright (C) 1987-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. */