diff options
Diffstat (limited to 'opcodes/tic80-dis.c')
-rw-r--r-- | opcodes/tic80-dis.c | 295 |
1 files changed, 111 insertions, 184 deletions
diff --git a/opcodes/tic80-dis.c b/opcodes/tic80-dis.c index a4793b4..09df146 100644 --- a/opcodes/tic80-dis.c +++ b/opcodes/tic80-dis.c @@ -1,19 +1,20 @@ /* Print TI TMS320C80 (MVP) instructions - Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 2000, 2005 Free Software Foundation, Inc. -This file 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 of the License, or -(at your option) any later version. + This file 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 of the License, 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. + 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + 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., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include <stdio.h> @@ -22,20 +23,6 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "dis-asm.h" static int length; - -static void print_operand_bitnum PARAMS ((struct disassemble_info *, long)); -static void print_operand_condition_code PARAMS ((struct disassemble_info *, long)); -static void print_operand_control_register PARAMS ((struct disassemble_info *, long)); -static void print_operand_float PARAMS ((struct disassemble_info *, long)); -static void print_operand_integer PARAMS ((struct disassemble_info *, long)); -static void print_operand PARAMS ((struct disassemble_info *, long, unsigned long, - const struct tic80_operand *, bfd_vma)); -static int print_one_instruction PARAMS ((struct disassemble_info *, bfd_vma, - unsigned long, const struct tic80_opcode *)); -static int print_instruction PARAMS ((struct disassemble_info *, bfd_vma, unsigned long, - const struct tic80_opcode *)); -static int fill_instruction PARAMS ((struct disassemble_info *, bfd_vma, - unsigned long *)); /* Print an integer operand. Try to be somewhat smart about the format by assuming that small positive or negative integers are @@ -44,18 +31,12 @@ static int fill_instruction PARAMS ((struct disassemble_info *, bfd_vma, Larger numbers are probably better printed as hex values. */ static void -print_operand_integer (info, value) - struct disassemble_info *info; - long value; +print_operand_integer (struct disassemble_info *info, long value) { if ((value > 9999 || value < -9999)) - { - (*info->fprintf_func) (info->stream, "%#lx", value); - } + (*info->fprintf_func) (info->stream, "%#lx", value); else - { - (*info->fprintf_func) (info->stream, "%ld", value); - } + (*info->fprintf_func) (info->stream, "%ld", value); } /* FIXME: depends upon sizeof (long) == sizeof (float) and @@ -63,56 +44,40 @@ print_operand_integer (info, value) floating point format. */ static void -print_operand_float (info, value) - struct disassemble_info *info; - long value; +print_operand_float (struct disassemble_info *info, long value) { union { float f; long l; } fval; fval.l = value; (*info->fprintf_func) (info->stream, "%g", fval.f); } - + static void -print_operand_control_register (info, value) - struct disassemble_info *info; - long value; +print_operand_control_register (struct disassemble_info *info, long value) { const char *tmp; tmp = tic80_value_to_symbol (value, TIC80_OPERAND_CR); if (tmp != NULL) - { - (*info->fprintf_func) (info->stream, "%s", tmp); - } + (*info->fprintf_func) (info->stream, "%s", tmp); else - { - (*info->fprintf_func) (info->stream, "%#lx", value); - } + (*info->fprintf_func) (info->stream, "%#lx", value); } - + static void -print_operand_condition_code (info, value) - struct disassemble_info *info; - long value; +print_operand_condition_code (struct disassemble_info *info, long value) { const char *tmp; tmp = tic80_value_to_symbol (value, TIC80_OPERAND_CC); if (tmp != NULL) - { - (*info->fprintf_func) (info->stream, "%s", tmp); - } + (*info->fprintf_func) (info->stream, "%s", tmp); else - { - (*info->fprintf_func) (info->stream, "%ld", value); - } + (*info->fprintf_func) (info->stream, "%ld", value); } - + static void -print_operand_bitnum (info, value) - struct disassemble_info *info; - long value; +print_operand_bitnum (struct disassemble_info *info, long value) { int bitnum; const char *tmp; @@ -120,13 +85,9 @@ print_operand_bitnum (info, value) bitnum = ~value & 0x1F; tmp = tic80_value_to_symbol (bitnum, TIC80_OPERAND_BITNUM); if (tmp != NULL) - { - (*info->fprintf_func) (info->stream, "%s", tmp); - } + (*info->fprintf_func) (info->stream, "%s", tmp); else - { - (*info->fprintf_func) (info->stream, "%ld", bitnum); - } + (*info->fprintf_func) (info->stream, "%ld", bitnum); } /* Print the operand as directed by the flags. */ @@ -136,12 +97,11 @@ print_operand_bitnum (info, value) #define R_SCALED(insn,op) ((((op)->flags & TIC80_OPERAND_SCALED) != 0) && ((insn) & (1 << 11))) static void -print_operand (info, value, insn, operand, memaddr) - struct disassemble_info *info; - long value; - unsigned long insn; - const struct tic80_operand *operand; - bfd_vma memaddr; +print_operand (struct disassemble_info *info, + long value, + unsigned long insn, + const struct tic80_operand *operand, + bfd_vma memaddr) { if ((operand->flags & TIC80_OPERAND_GPR) != 0) { @@ -152,58 +112,81 @@ print_operand (info, value, insn, operand, memaddr) } } else if ((operand->flags & TIC80_OPERAND_FPA) != 0) - { - (*info->fprintf_func) (info->stream, "a%ld", value); - } + (*info->fprintf_func) (info->stream, "a%ld", value); + else if ((operand->flags & TIC80_OPERAND_PCREL) != 0) - { - (*info->print_address_func) (memaddr + 4 * value, info); - } + (*info->print_address_func) (memaddr + 4 * value, info); + else if ((operand->flags & TIC80_OPERAND_BASEREL) != 0) - { - (*info->print_address_func) (value, info); - } + (*info->print_address_func) (value, info); + else if ((operand->flags & TIC80_OPERAND_BITNUM) != 0) - { - print_operand_bitnum (info, value); - } + print_operand_bitnum (info, value); + else if ((operand->flags & TIC80_OPERAND_CC) != 0) - { - print_operand_condition_code (info, value); - } + print_operand_condition_code (info, value); + else if ((operand->flags & TIC80_OPERAND_CR) != 0) - { - print_operand_control_register (info, value); - } + print_operand_control_register (info, value); + else if ((operand->flags & TIC80_OPERAND_FLOAT) != 0) - { - print_operand_float (info, value); - } + print_operand_float (info, value); + else if ((operand->flags & TIC80_OPERAND_BITFIELD)) - { - (*info->fprintf_func) (info->stream, "%#lx", value); - } + (*info->fprintf_func) (info->stream, "%#lx", value); + else - { - print_operand_integer (info, value); - } + print_operand_integer (info, value); /* If this is a scaled operand, then print the modifier. */ - if (R_SCALED (insn, operand)) + (*info->fprintf_func) (info->stream, ":s"); +} + +/* Get the next 32 bit word from the instruction stream and convert it + into internal format in the unsigned long INSN, for which we are + passed the address. Return 0 on success, -1 on error. */ + +static int +fill_instruction (struct disassemble_info *info, + bfd_vma memaddr, + unsigned long *insnp) +{ + bfd_byte buffer[4]; + int status; + + /* Get the bits for the next 32 bit word and put in buffer. */ + status = (*info->read_memory_func) (memaddr + length, buffer, 4, info); + if (status != 0) { - (*info->fprintf_func) (info->stream, ":s"); + (*info->memory_error_func) (status, memaddr, info); + return -1; } + + /* Read was successful, so increment count of bytes read and convert + the bits into internal format. */ + + length += 4; + if (info->endian == BFD_ENDIAN_LITTLE) + *insnp = bfd_getl32 (buffer); + + else if (info->endian == BFD_ENDIAN_BIG) + *insnp = bfd_getb32 (buffer); + + else + /* FIXME: Should probably just default to one or the other. */ + abort (); + + return 0; } - + /* We have chosen an opcode table entry. */ static int -print_one_instruction (info, memaddr, insn, opcode) - struct disassemble_info *info; - bfd_vma memaddr; - unsigned long insn; - const struct tic80_opcode *opcode; +print_one_instruction (struct disassemble_info *info, + bfd_vma memaddr, + unsigned long insn, + const struct tic80_opcode *opcode) { const struct tic80_operand *operand; long value; @@ -219,38 +202,31 @@ print_one_instruction (info, memaddr, insn, opcode) /* Extract the value from the instruction. */ if (operand->extract) - { - value = (*operand->extract) (insn, (int *) NULL); - } + value = (*operand->extract) (insn, NULL); + else if (operand->bits == 32) { status = fill_instruction (info, memaddr, (unsigned long *) &value); if (status == -1) - { - return (status); - } + return status; } else { value = (insn >> operand->shift) & ((1 << operand->bits) - 1); + if ((operand->flags & TIC80_OPERAND_SIGNED) != 0 && (value & (1 << (operand->bits - 1))) != 0) - { - value -= 1 << operand->bits; - } + value -= 1 << operand->bits; } /* If this operand is enclosed in parenthesis, then print the open paren, otherwise just print the regular comma separator, except for the first operand. */ - if ((operand->flags & TIC80_OPERAND_PARENS) == 0) { close_paren = 0; if (opindex != opcode->operands) - { - (*info->fprintf_func) (info->stream, ","); - } + (*info->fprintf_func) (info->stream, ","); } else { @@ -262,13 +238,11 @@ print_one_instruction (info, memaddr, insn, opcode) /* If we printed an open paren before printing this operand, close it now. The flag gets reset on each loop. */ - if (close_paren) - { - (*info->fprintf_func) (info->stream, ")"); - } + (*info->fprintf_func) (info->stream, ")"); } - return (length); + + return length; } /* There are no specific bits that tell us for certain whether a vector @@ -280,11 +254,10 @@ print_one_instruction (info, memaddr, insn, opcode) #define TWO_INSN(insn) ((((insn) & (0x1F << 27)) != 0) && (((insn) & (0x1F << 22)) != 0)) static int -print_instruction (info, memaddr, insn, vec_opcode) - struct disassemble_info *info; - bfd_vma memaddr; - unsigned long insn; - const struct tic80_opcode *vec_opcode; +print_instruction (struct disassemble_info *info, + bfd_vma memaddr, + unsigned long insn, + const struct tic80_opcode *vec_opcode) { const struct tic80_opcode *opcode; const struct tic80_opcode *opcode_end; @@ -300,9 +273,7 @@ print_instruction (info, memaddr, insn, vec_opcode) { if ((insn & opcode->mask) == opcode->opcode && opcode != vec_opcode) - { - break; - } + break; } if (opcode == opcode_end) @@ -323,55 +294,12 @@ print_instruction (info, memaddr, insn, vec_opcode) length = print_instruction (info, memaddr, insn, opcode); } } - return (length); -} -/* Get the next 32 bit word from the instruction stream and convert it - into internal format in the unsigned long INSN, for which we are - passed the address. Return 0 on success, -1 on error. */ - -static int -fill_instruction (info, memaddr, insnp) - struct disassemble_info *info; - bfd_vma memaddr; - unsigned long *insnp; -{ - bfd_byte buffer[4]; - int status; - - /* Get the bits for the next 32 bit word and put in buffer. */ - - status = (*info->read_memory_func) (memaddr + length, buffer, 4, info); - if (status != 0) - { - (*info->memory_error_func) (status, memaddr, info); - return (-1); - } - - /* Read was successful, so increment count of bytes read and convert - the bits into internal format. */ - - length += 4; - if (info->endian == BFD_ENDIAN_LITTLE) - { - *insnp = bfd_getl32 (buffer); - } - else if (info->endian == BFD_ENDIAN_BIG) - { - *insnp = bfd_getb32 (buffer); - } - else - { - /* FIXME: Should probably just default to one or the other. */ - abort (); - } - return (0); + return length; } int -print_insn_tic80 (memaddr, info) - bfd_vma memaddr; - struct disassemble_info *info; +print_insn_tic80 (bfd_vma memaddr, struct disassemble_info *info) { unsigned long insn; int status; @@ -380,8 +308,7 @@ print_insn_tic80 (memaddr, info) info->bytes_per_line = 8; status = fill_instruction (info, memaddr, &insn); if (status != -1) - { - status = print_instruction (info, memaddr, insn, NULL); - } - return (status); + status = print_instruction (info, memaddr, insn, NULL); + + return status; } |