X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fns32k-dis.c;h=fe7144ae5054840857025e526bcb5d4a6e9ef82d;hb=90e56b9873239e5c39176bc82c26917a509758d2;hp=808fdd204e3117e1d4352f4f5c5d37ddfd37b000;hpb=fa803dc60f0bf01297674c41d001798e18ade4dc;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/ns32k-dis.c b/opcodes/ns32k-dis.c index 808fdd204e..fe7144ae50 100644 --- a/opcodes/ns32k-dis.c +++ b/opcodes/ns32k-dis.c @@ -1,5 +1,6 @@ /* Print National Semiconductor 32000 instructions. - Copyright 1986, 1988, 1991, 1992, 1994 Free Software Foundation, Inc. + Copyright 1986, 1988, 1991, 1992, 1994, 1998, 2001, 2002 + Free Software Foundation, Inc. This file is part of opcodes library. @@ -15,7 +16,7 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" @@ -25,15 +26,30 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define const #endif #include "opcode/ns32k.h" +#include "opintl.h" static disassemble_info *dis_info; /* * Hacks to get it to compile <= READ THESE AS FIXES NEEDED */ -#define CORE_ADDR unsigned long #define INVALID_FLOAT(val, size) invalid_float((char *)val, size) +static int print_insn_arg + PARAMS ((int, int, int *, char *, bfd_vma, char *, int)); +static int get_displacement PARAMS ((char *, int *)); +static int invalid_float PARAMS ((char *, int)); +static long int read_memory_integer PARAMS ((unsigned char *, int)); +static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *)); +struct ns32k_option; +static void optlist PARAMS ((int, const struct ns32k_option *, char *)); +static void list_search PARAMS ((int, const struct ns32k_option *, char *)); +static int bit_extract PARAMS ((bfd_byte *, int, int)); +static int bit_extract_simple PARAMS ((bfd_byte *, int, int)); +static void bit_copy PARAMS ((char *, int, int, char *)); +static int sign_extend PARAMS ((int, int)); +static void flip_bytes PARAMS ((char *, int)); + static long read_memory_integer(addr, nr) unsigned char *addr; int nr; @@ -98,14 +114,14 @@ fetch_data (info, addr) #define NEXT_IS_ADDR '|' -struct option { +struct ns32k_option { char *pattern; /* the option itself */ unsigned long value; /* binary value of the option */ unsigned long match; /* these bits must match */ }; -static struct option opt_u[]= /* restore, exit */ +static const struct ns32k_option opt_u[]= /* restore, exit */ { { "r0", 0x80, 0x80 }, { "r1", 0x40, 0x40 }, @@ -118,7 +134,7 @@ static struct option opt_u[]= /* restore, exit */ { 0 , 0x00, 0x00 } }; -static struct option opt_U[]= /* save, enter */ +static const struct ns32k_option opt_U[]= /* save, enter */ { { "r0", 0x01, 0x01 }, { "r1", 0x02, 0x02 }, @@ -131,7 +147,7 @@ static struct option opt_U[]= /* save, enter */ { 0 , 0x00, 0x00 } }; -static struct option opt_O[]= /* setcfg */ +static const struct ns32k_option opt_O[]= /* setcfg */ { { "c", 0x8, 0x8 }, { "m", 0x4, 0x4 }, @@ -140,7 +156,7 @@ static struct option opt_O[]= /* setcfg */ { 0 , 0x0, 0x0 } }; -static struct option opt_C[]= /* cinv */ +static const struct ns32k_option opt_C[]= /* cinv */ { { "a", 0x4, 0x4 }, { "i", 0x2, 0x2 }, @@ -148,7 +164,7 @@ static struct option opt_C[]= /* cinv */ { 0 , 0x0, 0x0 } }; -static struct option opt_S[]= /* string inst */ +static const struct ns32k_option opt_S[]= /* string inst */ { { "b", 0x1, 0x1 }, { "u", 0x6, 0x6 }, @@ -156,7 +172,7 @@ static struct option opt_S[]= /* string inst */ { 0 , 0x0, 0x0 } }; -static struct option list_P532[]= /* lpr spr */ +static const struct ns32k_option list_P532[]= /* lpr spr */ { { "us", 0x0, 0xf }, { "dcr", 0x1, 0xf }, @@ -174,7 +190,7 @@ static struct option list_P532[]= /* lpr spr */ { 0 , 0x00, 0xf } }; -static struct option list_M532[]= /* lmr smr */ +static const struct ns32k_option list_M532[]= /* lmr smr */ { { "mcr", 0x9, 0xf }, { "msr", 0xa, 0xf }, @@ -186,7 +202,7 @@ static struct option list_M532[]= /* lmr smr */ { 0 , 0x0, 0xf } }; -static struct option list_P032[]= /* lpr spr */ +static const struct ns32k_option list_P032[]= /* lpr spr */ { { "upsr", 0x0, 0xf }, { "fp", 0x8, 0xf }, @@ -198,7 +214,7 @@ static struct option list_P032[]= /* lpr spr */ { 0 , 0x0, 0xf } }; -static struct option list_M032[]= /* lmr smr */ +static const struct ns32k_option list_M032[]= /* lmr smr */ { { "bpr0", 0x0, 0xf }, { "bpr1", 0x1, 0xf }, @@ -219,9 +235,9 @@ static struct option list_M032[]= /* lmr smr */ */ static void optlist(options, optionP, result) - int options; - struct option *optionP; - char *result; + int options; + const struct ns32k_option *optionP; + char *result; { if (options == 0) { sprintf(result, "[]"); @@ -244,10 +260,11 @@ optlist(options, optionP, result) strcat(result, "]"); } -static list_search(reg_value, optionP, result) - int reg_value; - struct option *optionP; - char *result; +static void +list_search (reg_value, optionP, result) + int reg_value; + const struct ns32k_option *optionP; + char *result; { for (; optionP->pattern; optionP++) { if ((reg_value & optionP->match) == optionP->value) { @@ -270,7 +287,6 @@ bit_extract (buffer, offset, count) int count; { int result; - int mask; int bit; buffer += offset >> 3; @@ -292,6 +308,36 @@ bit_extract (buffer, offset, count) return result; } +/* Like bit extract but the buffer is valid and doen't need to be + * fetched + */ +static int +bit_extract_simple (buffer, offset, count) + bfd_byte *buffer; + int offset; + int count; +{ + int result; + int bit; + + buffer += offset >> 3; + offset &= 7; + bit = 1; + result = 0; + while (count--) + { + if ((*buffer & (1 << offset))) + result |= bit; + if (++offset == 8) + { + offset = 0; + buffer++; + } + bit <<= 1; + } + return result; +} + static void bit_copy (buffer, offset, count, to) char *buffer; @@ -305,7 +351,8 @@ bit_copy (buffer, offset, count, to) } -static sign_extend (value, bits) +static int +sign_extend (value, bits) int value, bits; { value = value & ((1 << bits) - 1); @@ -314,7 +361,8 @@ static sign_extend (value, bits) : value); } -static flip_bytes (ptr, count) +static void +flip_bytes (ptr, count) char *ptr; int count; { @@ -357,11 +405,9 @@ print_insn_ns32k (memaddr, info) bfd_vma memaddr; disassemble_info *info; { - register int i; - register unsigned char *p; - register char *d; + unsigned int i; + const char *d; unsigned short first_word; - int gen, disp; int ioffset; /* bits into instruction */ int aoffset; /* bits into arguments */ char arg_bufs[MAX_ARGS+1][ARG_LEN]; @@ -384,7 +430,8 @@ print_insn_ns32k (memaddr, info) FETCH_DATA(info, buffer + 1); for (i = 0; i < NOPCODES; i++) if (ns32k_opcodes[i].opcode_id_size <= 8 - && ((buffer[0] & ((1 << ns32k_opcodes[i].opcode_id_size) - 1)) + && ((buffer[0] + & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1)) == ns32k_opcodes[i].opcode_seed)) break; if (i == NOPCODES) { @@ -393,7 +440,8 @@ print_insn_ns32k (memaddr, info) first_word = read_memory_integer(buffer, 2); for (i = 0; i < NOPCODES; i++) - if ((first_word & ((1 << ns32k_opcodes[i].opcode_id_size) - 1)) + if ((first_word + & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1)) == ns32k_opcodes[i].opcode_seed) break; @@ -465,14 +513,14 @@ print_insn_ns32k (memaddr, info) } for (argnum = 0; argnum <= maxarg; argnum++) { - CORE_ADDR addr; + bfd_vma addr; char *ch; for (ch = arg_bufs[argnum]; *ch;) { if (*ch == NEXT_IS_ADDR) { ++ch; - addr = atoi (ch); + addr = bfd_scan_vma (ch, NULL, 16); (*dis_info->print_address_func) (addr, dis_info); while (*ch && *ch != NEXT_IS_ADDR) ++ch; @@ -499,18 +547,22 @@ print_insn_ns32k (memaddr, info) of the index byte (it contains garbage if this operand is not a general operand using scaled indexed addressing mode). */ +static int print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset) - char d; + int d; int ioffset, *aoffsetp; char *buffer; - CORE_ADDR addr; + bfd_vma addr; char *result; int index_offset; { - int addr_mode; - float Fvalue; - double Lvalue; + union { + float f; + double d; + int i[2]; + } value; int Ivalue; + int addr_mode; int disp1, disp2; int index; int size; @@ -576,7 +628,7 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset) * aoffsetp by since whatever generated this is broken * anyway! */ - sprintf (result, "$"); + sprintf (result, _("$")); break; case 'B': Ivalue = bit_extract (buffer, *aoffsetp, 8); @@ -586,35 +638,35 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset) break; case 'W': Ivalue = bit_extract (buffer, *aoffsetp, 16); - flip_bytes (&Ivalue, 2); + flip_bytes ((char *) & Ivalue, 2); *aoffsetp += 16; Ivalue = sign_extend (Ivalue, 16); sprintf (result, "$%d", Ivalue); break; case 'D': Ivalue = bit_extract (buffer, *aoffsetp, 32); - flip_bytes (&Ivalue, 4); + flip_bytes ((char *) & Ivalue, 4); *aoffsetp += 32; sprintf (result, "$%d", Ivalue); break; case 'F': - bit_copy (buffer, *aoffsetp, 32, (char *) &Fvalue); - flip_bytes (&Fvalue, 4); + bit_copy (buffer, *aoffsetp, 32, (char *) &value.f); + flip_bytes ((char *) &value.f, 4); *aoffsetp += 32; - if (INVALID_FLOAT (&Fvalue, 4)) - sprintf (result, "<>", *(int *) &Fvalue); + if (INVALID_FLOAT (&value.f, 4)) + sprintf (result, "<>", value.i[0]); else /* assume host has ieee float */ - sprintf (result, "$%g", Fvalue); + sprintf (result, "$%g", value.f); break; case 'L': - bit_copy (buffer, *aoffsetp, 64, (char *) &Lvalue); - flip_bytes (&Lvalue, 8); + bit_copy (buffer, *aoffsetp, 64, (char *) &value.d); + flip_bytes ((char *) &value.d, 8); *aoffsetp += 64; - if (INVALID_FLOAT (&Lvalue, 8)) - sprintf (result, "<>", - *(((int *) &Lvalue) + 1), *(int *) &Lvalue); + if (INVALID_FLOAT (&value.d, 8)) + sprintf (result, "<>", + value.i[1], value.i[0]); else /* assume host has ieee float */ - sprintf (result, "$%g", Lvalue); + sprintf (result, "$%g", value.d); break; } break; @@ -651,7 +703,11 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset) case 0x1b: /* Memory space disp(PC) */ disp1 = get_displacement (buffer, aoffsetp); - sprintf (result, "|%d|", addr + disp1); + *result++ = NEXT_IS_ADDR; + sprintf_vma (result, addr + disp1); + result += strlen (result); + *result++ = NEXT_IS_ADDR; + *result = '\0'; break; case 0x1c: case 0x1d: @@ -662,11 +718,11 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset) print_insn_arg (d, index_offset, aoffsetp, buffer, addr, result, 0); { - static char *ind[] = {"b", "w", "d", "q"}; + static const char *ind = "bwdq"; char *off; off = result + strlen (result); - sprintf (off, "[r%d:%s]", index, + sprintf (off, "[r%d:%c]", index, ind[addr_mode & 3]); } break; @@ -709,9 +765,11 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset) sprintf (result, "%d", (Ivalue / size) + 1); break; case 'p': - sprintf (result, "%c%d%c", NEXT_IS_ADDR, - addr + get_displacement (buffer, aoffsetp), - NEXT_IS_ADDR); + *result++ = NEXT_IS_ADDR; + sprintf_vma (result, addr + get_displacement (buffer, aoffsetp)); + result += strlen (result); + *result++ = NEXT_IS_ADDR; + *result = '\0'; break; case 'i': Ivalue = bit_extract (buffer, *aoffsetp, 8); @@ -767,6 +825,7 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset) return ioffset; } +static int get_displacement (buffer, aoffsetp) char *buffer; int *aoffsetp; @@ -784,13 +843,13 @@ get_displacement (buffer, aoffsetp) break; case 0x80: Ivalue2 = bit_extract (buffer, *aoffsetp, 16); - flip_bytes (&Ivalue2, 2); + flip_bytes ((char *) & Ivalue2, 2); Ivalue = sign_extend (Ivalue2, 14); *aoffsetp += 16; break; case 0xc0: Ivalue = bit_extract (buffer, *aoffsetp, 32); - flip_bytes (&Ivalue, 4); + flip_bytes ((char *) & Ivalue, 4); Ivalue = sign_extend (Ivalue, 30); *aoffsetp += 32; break; @@ -800,21 +859,22 @@ get_displacement (buffer, aoffsetp) #if 1 /* a version that should work on ns32k f's&d's on any machine */ -int invalid_float(p, len) +static int +invalid_float (p, len) register char *p; register int len; { - register val; + register int val; if ( len == 4 ) - val = (bit_extract(p, 23, 8)/*exponent*/ == 0xff - || (bit_extract(p, 23, 8)/*exponent*/ == 0 && - bit_extract(p, 0, 23)/*mantisa*/ != 0)); + val = (bit_extract_simple(p, 23, 8)/*exponent*/ == 0xff + || (bit_extract_simple(p, 23, 8)/*exponent*/ == 0 && + bit_extract_simple(p, 0, 23)/*mantisa*/ != 0)); else if ( len == 8 ) - val = (bit_extract(p, 52, 11)/*exponent*/ == 0x7ff - || (bit_extract(p, 52, 11)/*exponent*/ == 0 - && (bit_extract(p, 0, 32)/*low mantisa*/ != 0 - || bit_extract(p, 32, 20)/*high mantisa*/ != 0))); + val = (bit_extract_simple(p, 52, 11)/*exponent*/ == 0x7ff + || (bit_extract_simple(p, 52, 11)/*exponent*/ == 0 + && (bit_extract_simple(p, 0, 32)/*low mantisa*/ != 0 + || bit_extract_simple(p, 32, 20)/*high mantisa*/ != 0))); else val = 1; return (val); @@ -828,7 +888,8 @@ typedef union { double d; struct { unsigned lm; unsigned m:20, e:11, :1;} sd; } float_type_u; -int invalid_float(p, len) +static int +invalid_float (p, len) register float_type_u *p; register int len; {