Ignore:
Timestamp:
Aug 16, 2003, 6:59:22 PM (22 years ago)
Author:
bird
Message:

binutils v2.14 - offical sources.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GNU/src/binutils/opcodes/z8k-dis.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.1.1.2
    r608 r609  
    11/* Disassemble z8000 code.
    2    Copyright 1992, 1993, 1998, 2000
     2   Copyright 1992, 1993, 1998, 2000, 2001, 2002
    33   Free Software Foundation, Inc.
    44
    5 This file is part of GNU Binutils.
    6 
    7 This program is free software; you can redistribute it and/or modify
    8 it under the terms of the GNU General Public License as published by
    9 the Free Software Foundation; either version 2 of the License, or
    10 (at your option) any later version.
    11 
    12 This program is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with this program; if not, write to the Free Software
    19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
     5   This file is part of GNU Binutils.
     6
     7   This program is free software; you can redistribute it and/or modify
     8   it under the terms of the GNU General Public License as published by
     9   the Free Software Foundation; either version 2 of the License, or
     10   (at your option) any later version.
     11
     12   This program is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15   GNU General Public License for more details.
     16
     17   You should have received a copy of the GNU General Public License
     18   along with this program; if not, write to the Free Software
     19   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
     20   USA.  */
    2021
    2122#include "sysdep.h"
     
    5556instr_data_s;
    5657
     58static int fetch_data PARAMS ((struct disassemble_info *, int));
     59
     60
    5761/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
    5862   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
    5963   on error.  */
    6064#define FETCH_DATA(info, nibble) \
    61   ((nibble) < ((instr_data_s *)(info->private_data))->max_fetched \
     65  ((nibble) < ((instr_data_s *) (info->private_data))->max_fetched \
    6266   ? 1 : fetch_data ((info), (nibble)))
    6367
     
    109113
    110114static char *codes[16] =
    111 {
    112   "f",
    113   "lt",
    114   "le",
    115   "ule",
    116   "ov/pe",
    117   "mi",
    118   "eq",
    119   "c/ult",
    120   "t",
    121   "ge",
    122   "gt",
    123   "ugt",
    124   "nov/po",
    125   "pl",
    126   "ne",
    127   "nc/uge"
    128 };
    129 
     115  {
     116    "f",
     117    "lt",
     118    "le",
     119    "ule",
     120    "ov/pe",
     121    "mi",
     122    "eq",
     123    "c/ult",
     124    "t",
     125    "ge",
     126    "gt",
     127    "ugt",
     128    "nov/po",
     129    "pl",
     130    "ne",
     131    "nc/uge"
     132  };
     133
     134static char *ctrl_names[8] =
     135  {
     136    "<invld>",
     137    "flags",
     138    "fcw",
     139    "refresh",
     140    "psapseg",
     141    "psapoff",
     142    "nspseg",
     143    "nspoff"
     144  };
     145
     146static int seg_length;
     147static int print_insn_z8k PARAMS ((bfd_vma, disassemble_info *, int));
    130148int z8k_lookup_instr PARAMS ((unsigned char *, disassemble_info *));
    131149static void output_instr
    132150  PARAMS ((instr_data_s *, unsigned long, disassemble_info *));
    133151static void unpack_instr PARAMS ((instr_data_s *, int, disassemble_info *));
    134 static void unparse_instr PARAMS ((instr_data_s *));
     152static void unparse_instr PARAMS ((instr_data_s *, int));
    135153
    136154static int
     
    149167    return -1;
    150168
     169  info->bytes_per_chunk = 2;
     170  info->bytes_per_line = 6;
     171  info->display_endian = BFD_ENDIAN_BIG;
     172
    151173  instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info);
    152174  if (instr_data.tabl_index > 0)
    153175    {
    154176      unpack_instr (&instr_data, is_segmented, info);
    155       unparse_instr (&instr_data);
     177      unparse_instr (&instr_data, is_segmented);
    156178      output_instr (&instr_data, addr, info);
    157       return z8k_table[instr_data.tabl_index].length;
     179      return z8k_table[instr_data.tabl_index].length + seg_length;
    158180    }
    159181  else
     
    190212  int nibl_index, tabl_index;
    191213  int nibl_matched;
     214  int need_fetch = 0;
    192215  unsigned short instr_nibl;
    193216  unsigned short tabl_datum, datum_class, datum_value;
     
    195218  nibl_matched = 0;
    196219  tabl_index = 0;
     220  FETCH_DATA (info, 4);
    197221  while (!nibl_matched && z8k_table[tabl_index].name)
    198222    {
     
    203227        {
    204228          if ((nibl_index % 4) == 0)
    205             /* Fetch one word at a time.  */
    206             FETCH_DATA (info, nibl_index + 4);
     229            {
     230              /* Fetch data only if it isn't already there.  */
     231              if (nibl_index >= 4 || (nibl_index < 4 && need_fetch))
     232                FETCH_DATA (info, nibl_index + 4);   /* Fetch one word at a time.  */
     233              if (nibl_index < 4)
     234                need_fetch = 0;
     235              else
     236                need_fetch = 1;
     237            }
    207238          instr_nibl = nibbles[nibl_index];
    208239
     
    217248                nibl_matched = 0;
    218249              break;
     250            case CLASS_IGNORE:
     251              break;
    219252            case CLASS_00II:
    220253              if (!((~instr_nibl) & 0x4))
     
    255288            }
    256289        }
     290
    257291      if (nibl_matched)
    258         {
    259           return tabl_index;
    260         }
     292        return tabl_index;
    261293
    262294      tabl_index++;
    263295    }
    264296  return -1;
    265 
    266297}
    267298
     
    269300output_instr (instr_data, addr, info)
    270301     instr_data_s *instr_data;
    271      unsigned long addr;
     302     unsigned long addr ATTRIBUTE_UNUSED;
    272303     disassemble_info *info;
    273304{
    274   int loop, loop_limit;
    275   char tmp_str[20];
     305  int num_bytes;
    276306  char out_str[100];
    277307
    278   strcpy (out_str, "\t");
    279 
    280   loop_limit = z8k_table[instr_data->tabl_index].length * 2;
    281   FETCH_DATA (info, loop_limit);
    282   for (loop = 0; loop < loop_limit; loop++)
    283     {
    284       sprintf (tmp_str, "%x", instr_data->nibbles[loop]);
    285       strcat (out_str, tmp_str);
    286     }
    287 
    288   while (loop++ < 8)
    289     {
    290       strcat (out_str, " ");
    291     }
     308  out_str[0] = 0;
     309
     310  num_bytes = (z8k_table[instr_data->tabl_index].length + seg_length) * 2;
     311  FETCH_DATA (info, num_bytes);
    292312
    293313  strcat (out_str, instr_data->instr_asmsrc);
     
    305325  unsigned short instr_nibl, instr_byte, instr_word;
    306326  long instr_long;
    307   unsigned short tabl_datum, datum_class, datum_value;
     327  unsigned int tabl_datum, datum_class;
     328  unsigned short datum_value;
    308329
    309330  nibl_count = 0;
    310331  loop = 0;
     332  seg_length = 0;
     333
    311334  while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0)
    312335    {
    313336      FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4));
    314337      instr_nibl = instr_data->nibbles[nibl_count];
    315       instr_byte = instr_data->bytes[nibl_count];
    316       instr_word = instr_data->words[nibl_count];
     338      instr_byte = instr_data->bytes[nibl_count & ~1];
     339      instr_word = instr_data->words[nibl_count & ~3];
    317340
    318341      tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop];
     
    322345      switch (datum_class)
    323346        {
    324         case CLASS_X:
    325           instr_data->address = instr_nibl;
    326           break;
    327         case CLASS_BA:
    328           instr_data->displacement = instr_nibl;
    329           break;
    330         case CLASS_BX:
    331           instr_data->arg_reg[datum_value] = instr_nibl;
    332           break;
    333347        case CLASS_DISP:
    334348          switch (datum_value)
    335349            {
    336350            case ARG_DISP16:
    337               instr_data->displacement = instr_word;
     351              instr_data->displacement = instr_data->insn_start + 4
     352                + (signed short) (instr_word & 0xffff);
    338353              nibl_count += 3;
    339354              break;
    340355            case ARG_DISP12:
    341               instr_data->displacement = instr_word & 0x0fff;
     356              if (instr_word & 0x800)
     357                /* Negative 12 bit displacement.  */
     358                instr_data->displacement = instr_data->insn_start + 2
     359                  - (signed short) ((instr_word & 0xfff) | 0xf000) * 2;
     360              else
     361                instr_data->displacement = instr_data->insn_start + 2
     362                  - (instr_word & 0x0fff) * 2;
     363
    342364              nibl_count += 2;
    343365              break;
     
    352374              instr_data->immediate = instr_nibl;
    353375              break;
     376            case ARG_NIM4:
     377              instr_data->immediate = (- instr_nibl) & 0xf;
     378              break;
    354379            case ARG_NIM8:
    355               instr_data->immediate = (-instr_byte);
     380              instr_data->immediate = (- instr_byte) & 0xff;
    356381              nibl_count += 1;
    357382              break;
     
    393418          instr_data->cond_code = instr_nibl;
    394419          break;
    395         case CLASS_CTRL:
    396           instr_data->ctrl_code = instr_nibl;
    397           break;
    398         case CLASS_DA:
    399420        case CLASS_ADDRESS:
    400421          if (is_segmented)
     
    405426                  instr_long = (instr_data->words[nibl_count] << 16)
    406427                    | (instr_data->words[nibl_count + 4]);
    407                   instr_data->address = ((instr_word & 0x7f00) << 8) +
    408                     (instr_long & 0xffff);
     428                  instr_data->address = ((instr_word & 0x7f00) << 16)
     429                    + (instr_long & 0xffff);
    409430                  nibl_count += 7;
     431                  seg_length = 2;
    410432                }
    411433              else
    412434                {
    413                   instr_data->address = ((instr_word & 0x7f00) << 8) +
    414                     (instr_word & 0x00ff);
     435                  instr_data->address = ((instr_word & 0x7f00) << 16)
     436                    + (instr_word & 0x00ff);
    415437                  nibl_count += 3;
    416438                }
     
    423445          break;
    424446        case CLASS_0CCC:
    425           instr_data->cond_code = instr_nibl & 0x7;
    426           break;
    427447        case CLASS_1CCC:
    428           instr_data->cond_code = instr_nibl & 0x7;
     448          instr_data->ctrl_code = instr_nibl & 0x7;
    429449          break;
    430450        case CLASS_0DISP7:
    431           instr_data->displacement = instr_byte & 0x7f;
     451          instr_data->displacement =
     452            instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
    432453          nibl_count += 1;
    433454          break;
    434455        case CLASS_1DISP7:
    435           instr_data->displacement = instr_byte & 0x7f;
     456          instr_data->displacement =
     457            instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
    436458          nibl_count += 1;
    437459          break;
     
    442464          instr_data->interrupts = instr_nibl & 0x3;
    443465          break;
     466        case CLASS_IGNORE:
    444467        case CLASS_BIT:
    445           /* Do nothing.  */
    446           break;
    447         case CLASS_IR:
    448           instr_data->arg_reg[datum_value] = instr_nibl;
     468          instr_data->ctrl_code = instr_nibl & 0x7;
    449469          break;
    450470        case CLASS_FLAGS:
     
    454474          instr_data->arg_reg[datum_value] = instr_nibl;
    455475          break;
    456         case CLASS_REG_BYTE:
    457           instr_data->arg_reg[datum_value] = instr_nibl;
    458           break;
    459         case CLASS_REG_WORD:
    460           instr_data->arg_reg[datum_value] = instr_nibl;
    461           break;
    462         case CLASS_REG_QUAD:
    463           instr_data->arg_reg[datum_value] = instr_nibl;
    464           break;
    465         case CLASS_REG_LONG:
    466           instr_data->arg_reg[datum_value] = instr_nibl;
    467           break;
    468476        case CLASS_REGN0:
    469477          instr_data->arg_reg[datum_value] = instr_nibl;
    470478          break;
     479        case CLASS_DISP8:
     480          instr_data->displacement =
     481            instr_data->insn_start + 2 + (signed char) instr_byte * 2;
     482          nibl_count += 1;
     483          break;
     484        case CLASS_BIT_1OR2:
     485          instr_data->immediate = ((instr_nibl >> 1) & 0x1) + 1;
     486          nibl_count += 1;
     487          break;
    471488        default:
     489          abort ();
    472490          break;
    473491        }
     
    478496}
    479497
     498static char *intr_names[] = {
     499  "all",    /* 0 */
     500  "vi",     /* 1 */
     501  "nvi",    /* 2 */
     502  "none"    /* 3 */
     503};
     504
    480505static void
    481 unparse_instr (instr_data)
     506unparse_instr (instr_data, is_segmented)
    482507     instr_data_s *instr_data;
    483 {
    484   unsigned short tabl_datum, datum_class, datum_value;
     508     int is_segmented;
     509{
     510  unsigned short datum_value;
     511  unsigned int tabl_datum, datum_class;
    485512  int loop, loop_limit;
    486513  char out_str[80], tmp_str[25];
    487514
    488   sprintf (out_str, "\t%s\t", z8k_table[instr_data->tabl_index].name);
     515  sprintf (out_str, "%s\t", z8k_table[instr_data->tabl_index].name);
    489516
    490517  loop_limit = z8k_table[instr_data->tabl_index].noperands;
     
    501528        {
    502529        case CLASS_X:
    503           sprintf (tmp_str, "0x%0lx(R%ld)", instr_data->address,
    504                    instr_data->arg_reg[datum_value]);
     530          sprintf (tmp_str, "0x%0lx(r%ld)", instr_data->address,
     531                   instr_data->arg_reg[datum_value]);
    505532          strcat (out_str, tmp_str);
    506533          break;
    507534        case CLASS_BA:
    508           sprintf (tmp_str, "r%ld(#%lx)", instr_data->arg_reg[datum_value],
    509                    instr_data->immediate);
     535          if (is_segmented)
     536            sprintf (tmp_str, "rr%ld(#0x%lx)", instr_data->arg_reg[datum_value],
     537                     instr_data->immediate);
     538          else
     539            sprintf (tmp_str, "r%ld(#0x%lx)", instr_data->arg_reg[datum_value],
     540                     instr_data->immediate);
    510541          strcat (out_str, tmp_str);
    511542          break;
    512543        case CLASS_BX:
    513           sprintf (tmp_str, "r%ld(R%ld)", instr_data->arg_reg[datum_value],
    514                    instr_data->arg_reg[ARG_RX]);
     544          if (is_segmented)
     545            sprintf (tmp_str, "rr%ld(r%ld)", instr_data->arg_reg[datum_value],
     546                     instr_data->arg_reg[ARG_RX]);
     547          else
     548            sprintf (tmp_str, "r%ld(r%ld)", instr_data->arg_reg[datum_value],
     549                     instr_data->arg_reg[ARG_RX]);
    515550          strcat (out_str, tmp_str);
    516551          break;
    517552        case CLASS_DISP:
    518           sprintf (tmp_str, "#0x%0lx", instr_data->displacement);
     553          sprintf (tmp_str, "0x%0lx", instr_data->displacement);
    519554          strcat (out_str, tmp_str);
    520555          break;
    521556        case CLASS_IMM:
     557          if (datum_value == ARG_IMM2)  /* True with EI/DI instructions only.  */
     558            {
     559              sprintf (tmp_str, "%s", intr_names[instr_data->interrupts]);
     560              strcat (out_str, tmp_str);
     561              break;
     562            }
    522563          sprintf (tmp_str, "#0x%0lx", instr_data->immediate);
    523564          strcat (out_str, tmp_str);
     
    528569          break;
    529570        case CLASS_CTRL:
    530           sprintf (tmp_str, "0x%0lx", instr_data->ctrl_code);
     571          sprintf (tmp_str, "%s", ctrl_names[instr_data->ctrl_code]);
    531572          strcat (out_str, tmp_str);
    532573          break;
    533574        case CLASS_DA:
    534575        case CLASS_ADDRESS:
    535           sprintf (tmp_str, "#0x%0lx", instr_data->address);
     576          sprintf (tmp_str, "0x%0lx", instr_data->address);
    536577          strcat (out_str, tmp_str);
    537578          break;
    538579        case CLASS_IR:
    539           sprintf (tmp_str, "@R%ld", instr_data->arg_reg[datum_value]);
     580          if (is_segmented)
     581            sprintf (tmp_str, "@rr%ld", instr_data->arg_reg[datum_value]);
     582          else
     583            sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]);
    540584          strcat (out_str, tmp_str);
    541585          break;
     
    546590        case CLASS_REG_BYTE:
    547591          if (instr_data->arg_reg[datum_value] >= 0x8)
    548             {
    549               sprintf (tmp_str, "rl%ld",
    550                        instr_data->arg_reg[datum_value] - 0x8);
    551             }
     592            sprintf (tmp_str, "rl%ld",
     593                     instr_data->arg_reg[datum_value] - 0x8);
    552594          else
    553             {
    554               sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]);
    555             }
     595            sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]);
    556596          strcat (out_str, tmp_str);
    557597          break;
     
    568608          strcat (out_str, tmp_str);
    569609          break;
     610        case CLASS_PR:
     611          if (is_segmented)
     612            sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
     613          else
     614            sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
     615          strcat (out_str, tmp_str);
     616          break;
    570617        default:
     618          abort ();
    571619          break;
    572620        }
Note: See TracChangeset for help on using the changeset viewer.