OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [opcodes/] [m88k-dis.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Print instructions for the Motorola 88000, for GDB and GNU Binutils.
2
   Copyright (c) 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1998
3
   Free Software Foundation, Inc.
4
   Contributed by Data General Corporation, November 1989.
5
   Partially derived from an earlier printcmd.c.
6
 
7
This file is part of GDB and the GNU Binutils.
8
 
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13
 
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
 
23
#include "dis-asm.h"
24
#include "opcode/m88k.h"
25
#include "opintl.h"
26
 
27
INSTAB  *hashtable[HASHVAL] = {0};
28
 
29
static int
30
m88kdis PARAMS ((bfd_vma, unsigned long, struct disassemble_info *));
31
 
32
static void
33
printop PARAMS ((struct disassemble_info *, OPSPEC *,
34
                 unsigned long, bfd_vma, int));
35
 
36
static void
37
init_disasm PARAMS ((void));
38
 
39
static void
40
install PARAMS ((INSTAB *instptr));
41
 
42
/*
43
*               Disassemble an M88000 Instruction
44
*
45
*
46
*       This module decodes the instruction at memaddr.
47
*
48
*                       Revision History
49
*
50
*       Revision 1.0    11/08/85        Creation date by Motorola
51
*                       05/11/89        R. Trawick adapted to GDB interface.
52
*                       07/12/93        Ian Lance Taylor updated to
53
*                                       binutils interface.
54
*/
55
 
56
int
57
print_insn_m88k (memaddr, info)
58
     bfd_vma memaddr;
59
     struct disassemble_info *info;
60
{
61
  bfd_byte buffer[4];
62
  int status;
63
 
64
  /* Instruction addresses may have low two bits set. Clear them.       */
65
  memaddr &=~ (bfd_vma) 3;
66
 
67
  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
68
  if (status != 0)
69
    {
70
      (*info->memory_error_func) (status, memaddr, info);
71
      return -1;
72
    }
73
 
74
  return m88kdis (memaddr, bfd_getb32 (buffer), info);
75
}
76
 
77
/*
78
 * disassemble the instruction in 'instruction'.
79
 * 'pc' should be the address of this instruction, it will
80
 *   be used to print the target address if this is a relative jump or call
81
 * the disassembled instruction is written to 'info'.
82
 * The function returns the length of this instruction in bytes.
83
 */
84
 
85
static int
86
m88kdis (pc, instruction, info)
87
     bfd_vma pc;
88
     unsigned long instruction;
89
     struct disassemble_info *info;
90
{
91
  static int ihashtab_initialized = 0;
92
  unsigned int opcode;
93
  INSTAB *entry_ptr;
94
  int opmask;
95
  unsigned int class;
96
 
97
  if (! ihashtab_initialized)
98
    init_disasm ();
99
 
100
  /* create the appropriate mask to isolate the opcode */
101
  opmask = DEFMASK;
102
  class = instruction & DEFMASK;
103
  if ((class >= SFU0) && (class <= SFU7))
104
    {
105
      if (instruction < SFU1)
106
        opmask = CTRLMASK;
107
      else
108
        opmask = SFUMASK;
109
    }
110
  else if (class == RRR)
111
    opmask = RRRMASK;
112
  else if (class == RRI10)
113
    opmask = RRI10MASK;
114
 
115
  /* isolate the opcode */
116
  opcode = instruction & opmask;
117
 
118
  /* search the hash table with the isolated opcode */
119
  for (entry_ptr = hashtable[opcode % HASHVAL];
120
       (entry_ptr != NULL) && (entry_ptr->opcode != opcode);
121
       entry_ptr = entry_ptr->next)
122
    ;
123
 
124
  if (entry_ptr == NULL)
125
    (*info->fprintf_func) (info->stream, "word\t%08x", instruction);
126
  else
127
    {
128
      (*info->fprintf_func) (info->stream, "%s", entry_ptr->mnemonic);
129
      printop (info, &(entry_ptr->op1), instruction, pc, 1);
130
      printop (info, &(entry_ptr->op2), instruction, pc, 0);
131
      printop (info, &(entry_ptr->op3), instruction, pc, 0);
132
    }
133
 
134
  return 4;
135
}
136
 
137
/*
138
*                      Decode an Operand of an Instruction
139
*
140
*                       Functional Description
141
*
142
*       This module formats and writes an operand of an instruction to info
143
*       based on the operand specification.  When the first flag is set this
144
*       is the first operand of an instruction.  Undefined operand types
145
*       cause a <dis error> message.
146
*
147
*                       Parameters
148
*       disassemble_info        where the operand may be printed
149
*       OPSPEC  *opptr          Pointer to an operand specification
150
*       UINT    inst            Instruction from which operand is extracted
151
*       UINT    pc              PC of instruction; used for pc-relative disp.
152
*       int     first           Flag which if nonzero indicates the first
153
*                               operand of an instruction
154
*
155
*                       Output
156
*
157
*       The operand specified is extracted from the instruction and is
158
*       written to buf in the format specified. The operand is preceded
159
*       by a comma if it is not the first operand of an instruction and it
160
*       is not a register indirect form.  Registers are preceded by 'r' and
161
*       hex values by '0x'.
162
*
163
*                       Revision History
164
*
165
*       Revision 1.0    11/08/85        Creation date
166
*/
167
 
168
static void
169
printop (info, opptr, inst, pc, first)
170
     struct disassemble_info *info;
171
     OPSPEC *opptr;
172
     unsigned long inst;
173
     bfd_vma pc;
174
     int first;
175
{
176
  int extracted_field;
177
  char *cond_mask_sym;
178
 
179
  if (opptr->width == 0)
180
    return;
181
 
182
  if (! first)
183
    {
184
      switch (opptr->type)
185
        {
186
        case REGSC:
187
        case CONT:
188
          break;
189
        default:
190
          (*info->fprintf_func) (info->stream, ",");
191
          break;
192
        }
193
    }
194
 
195
  switch (opptr->type)
196
    {
197
    case CRREG:
198
      (*info->fprintf_func) (info->stream, "cr%d",
199
                             UEXT (inst, opptr->offset, opptr->width));
200
      break;
201
 
202
    case FCRREG:
203
      (*info->fprintf_func) (info->stream, "fcr%d",
204
                             UEXT (inst, opptr->offset, opptr->width));
205
      break;
206
 
207
    case REGSC:
208
      (*info->fprintf_func) (info->stream, "[r%d]",
209
                             UEXT (inst, opptr->offset, opptr->width));
210
      break;
211
 
212
    case REG:
213
      (*info->fprintf_func) (info->stream, "r%d",
214
                             UEXT (inst, opptr->offset, opptr->width));
215
      break;
216
 
217
    case XREG:
218
      (*info->fprintf_func) (info->stream, "x%d",
219
                             UEXT (inst, opptr->offset, opptr->width));
220
      break;
221
 
222
    case HEX:
223
      extracted_field = UEXT (inst, opptr->offset, opptr->width);
224
      if (extracted_field == 0)
225
        (*info->fprintf_func) (info->stream, "0");
226
      else
227
        (*info->fprintf_func) (info->stream, "0x%02x", extracted_field);
228
      break;
229
 
230
    case DEC:
231
      extracted_field = UEXT (inst, opptr->offset, opptr->width);
232
      (*info->fprintf_func) (info->stream, "%d", extracted_field);
233
      break;
234
 
235
    case CONDMASK:
236
      extracted_field = UEXT (inst, opptr->offset, opptr->width);
237
      switch (extracted_field & 0x0f)
238
        {
239
        case 0x1: cond_mask_sym = "gt0"; break;
240
        case 0x2: cond_mask_sym = "eq0"; break;
241
        case 0x3: cond_mask_sym = "ge0"; break;
242
        case 0xc: cond_mask_sym = "lt0"; break;
243
        case 0xd: cond_mask_sym = "ne0"; break;
244
        case 0xe: cond_mask_sym = "le0"; break;
245
        default: cond_mask_sym = NULL; break;
246
        }
247
      if (cond_mask_sym != NULL)
248
        (*info->fprintf_func) (info->stream, "%s", cond_mask_sym);
249
      else
250
        (*info->fprintf_func) (info->stream, "%x", extracted_field);
251
      break;
252
 
253
    case PCREL:
254
      (*info->print_address_func)
255
        (pc + (4 * (SEXT (inst, opptr->offset, opptr->width))),
256
         info);
257
      break;
258
 
259
    case CONT:
260
      (*info->fprintf_func) (info->stream, "%d,r%d",
261
                             UEXT (inst, opptr->offset, 5),
262
                             UEXT (inst, (opptr->offset) + 5, 5));
263
      break;
264
 
265
    case BF:
266
      (*info->fprintf_func) (info->stream, "%d<%d>",
267
                              UEXT (inst, (opptr->offset) + 5, 5),
268
                              UEXT (inst, opptr->offset, 5));
269
      break;
270
 
271
    default:
272
      /* xgettext:c-format */
273
      (*info->fprintf_func) (info->stream, _("# <dis error: %08x>"), inst);
274
    }
275
}
276
 
277
/*
278
*                 Initialize the Disassembler Instruction Table
279
*
280
*       Initialize the hash table and instruction table for the disassembler.
281
*       This should be called once before the first call to disasm().
282
*
283
*                       Parameters
284
*
285
*                       Output
286
*
287
*       If the debug option is selected, certain statistics about the hashing
288
*       distribution are written to stdout.
289
*
290
*                       Revision History
291
*
292
*       Revision 1.0    11/08/85        Creation date
293
*/
294
 
295
static void
296
init_disasm ()
297
{
298
   int i, size;
299
 
300
   for (i = 0; i < HASHVAL; i++)
301
     hashtable[i] = NULL;
302
 
303
   size = sizeof (instructions) / sizeof (INSTAB);
304
   for (i = 0; i < size; i++)
305
     install (&instructions[i]);
306
}
307
 
308
/*
309
*       Insert an instruction into the disassembler table by hashing the
310
*       opcode and inserting it into the linked list for that hash value.
311
*
312
*                       Parameters
313
*
314
*       INSTAB *instptr         Pointer to the entry in the instruction table
315
*                               to be installed
316
*
317
*       Revision 1.0    11/08/85        Creation date
318
*                       05/11/89        R. TRAWICK ADAPTED FROM MOTOROLA
319
*/
320
 
321
static void
322
install (instptr)
323
     INSTAB *instptr;
324
{
325
  unsigned int i;
326
 
327
  i = (instptr->opcode) % HASHVAL;
328
  instptr->next = hashtable[i];
329
  hashtable[i] = instptr;
330
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.