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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [pdp11-dis.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Print DEC PDP-11 instructions.
2
   Copyright 2001, 2002 Free Software Foundation, Inc.
3
 
4
This file is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
8
 
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
 
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
 
18
#include "sysdep.h"
19
#include "dis-asm.h"
20
#include "opcode/pdp11.h"
21
 
22
#define AFTER_INSTRUCTION       "\t"
23
#define OPERAND_SEPARATOR       ", "
24
 
25
#define JUMP    0x1000  /* flag that this operand is used in a jump */
26
 
27
#define FPRINTF (*info->fprintf_func)
28
#define F       info->stream
29
 
30
/* sign-extend a 16-bit number in an int */
31
#define SIGN_BITS       (8 * sizeof (int) - 16)
32
#define sign_extend(x) (((x) << SIGN_BITS) >> SIGN_BITS)
33
 
34
static int read_word PARAMS ((bfd_vma memaddr, int *word,
35
                              disassemble_info *info));
36
static void print_signed_octal PARAMS ((int n, disassemble_info *info));
37
static void print_reg PARAMS ((int reg, disassemble_info *info));
38
static void print_freg PARAMS ((int freg, disassemble_info *info));
39
static int print_operand PARAMS ((bfd_vma *memaddr, int code,
40
                                  disassemble_info *info));
41
static int print_foperand PARAMS ((bfd_vma *memaddr, int code,
42
                                   disassemble_info *info));
43
int print_insn_pdp11 PARAMS ((bfd_vma memaddr, disassemble_info *info));
44
 
45
static int
46
read_word (memaddr, word, info)
47
     bfd_vma memaddr;
48
     int *word;
49
     disassemble_info *info;
50
{
51
  int status;
52
  bfd_byte x[2];
53
 
54
  status = (*info->read_memory_func) (memaddr, x, 2, info);
55
  if (status != 0)
56
    return -1;
57
 
58
  *word = x[1] << 8 | x[0];
59
  return 0;
60
}
61
 
62
static void
63
print_signed_octal (n, info)
64
     int n;
65
     disassemble_info *info;
66
{
67
  if (n < 0)
68
    FPRINTF (F, "-%o", -n);
69
  else
70
    FPRINTF (F, "%o", n);
71
}
72
 
73
static void
74
print_reg (reg, info)
75
     int reg;
76
     disassemble_info *info;
77
{
78
  /* mask off the addressing mode, if any */
79
  reg &= 7;
80
 
81
  switch (reg)
82
    {
83
    case 0: case 1: case 2: case 3: case 4: case 5:
84
                FPRINTF (F, "r%d", reg); break;
85
    case 6:     FPRINTF (F, "sp"); break;
86
    case 7:     FPRINTF (F, "pc"); break;
87
    default:    /* error */
88
    }
89
}
90
 
91
static void
92
print_freg (freg, info)
93
     int freg;
94
     disassemble_info *info;
95
{
96
  FPRINTF (F, "fr%d", freg);
97
}
98
 
99
static int
100
print_operand (memaddr, code, info)
101
     bfd_vma *memaddr;
102
     int code;
103
     disassemble_info *info;
104
{
105
  int mode = (code >> 3) & 7;
106
  int reg = code & 7;
107
  int disp;
108
 
109
  switch (mode)
110
    {
111
    case 0:
112
      print_reg (reg, info);
113
      break;
114
    case 1:
115
      FPRINTF (F, "(");
116
      print_reg (reg, info);
117
      FPRINTF (F, ")");
118
      break;
119
    case 2:
120
      if (reg == 7)
121
        {
122
          int data;
123
          if (read_word (*memaddr, &data, info) < 0)
124
            return -1;
125
          FPRINTF (F, "$");
126
          print_signed_octal (sign_extend (data), info);
127
          *memaddr += 2;
128
        }
129
      else
130
        {
131
          FPRINTF (F, "(");
132
          print_reg (reg, info);
133
          FPRINTF (F, ")+");
134
        }
135
        break;
136
    case 3:
137
      if (reg == 7)
138
        {
139
          int address;
140
          if (read_word (*memaddr, &address, info) < 0)
141
            return -1;
142
          FPRINTF (F, "*$%o", address);
143
          *memaddr += 2;
144
        }
145
      else
146
        {
147
          FPRINTF (F, "*(");
148
          print_reg (reg, info);
149
          FPRINTF (F, ")+");
150
        }
151
        break;
152
    case 4:
153
      FPRINTF (F, "-(");
154
      print_reg (reg, info);
155
      FPRINTF (F, ")");
156
      break;
157
    case 5:
158
      FPRINTF (F, "*-(");
159
      print_reg (reg, info);
160
      FPRINTF (F, ")");
161
      break;
162
    case 6:
163
    case 7:
164
      if (read_word (*memaddr, &disp, info) < 0)
165
        return -1;
166
      *memaddr += 2;
167
      if (reg == 7)
168
        {
169
          bfd_vma address = *memaddr + sign_extend (disp);
170
          if (mode == 7)
171
            FPRINTF (F, "*");
172
          if (!(code & JUMP))
173
            FPRINTF (F, "$");
174
          (*info->print_address_func) (address, info);
175
        }
176
      else
177
        {
178
          if (mode == 7)
179
            FPRINTF (F, "*");
180
          print_signed_octal (sign_extend (disp), info);
181
          FPRINTF (F, "(");
182
          print_reg (reg, info);
183
          FPRINTF (F, ")");
184
        }
185
      break;
186
    }
187
 
188
  return 0;
189
}
190
 
191
static int
192
print_foperand (memaddr, code, info)
193
     bfd_vma *memaddr;
194
     int code;
195
     disassemble_info *info;
196
{
197
  int mode = (code >> 3) & 7;
198
  int reg = code & 7;
199
 
200
  if (mode == 0)
201
    print_freg (reg, info);
202
  else
203
    return print_operand (memaddr, code, info);
204
 
205
  return 0;
206
}
207
 
208
/* Print the PDP-11 instruction at address MEMADDR in debugged memory,
209
   on INFO->STREAM.  Returns length of the instruction, in bytes.  */
210
 
211
int
212
print_insn_pdp11 (memaddr, info)
213
     bfd_vma memaddr;
214
     disassemble_info *info;
215
{
216
  bfd_vma start_memaddr = memaddr;
217
  int opcode;
218
  int src, dst;
219
  int i;
220
 
221
  info->bytes_per_line = 6;
222
  info->bytes_per_chunk = 2;
223
  info->display_endian = BFD_ENDIAN_LITTLE;
224
 
225
  if (read_word (memaddr, &opcode, info) != 0)
226
    return -1;
227
  memaddr += 2;
228
 
229
  src = (opcode >> 6) & 0x3f;
230
  dst = opcode & 0x3f;
231
 
232
  for (i = 0; i < pdp11_num_opcodes; i++)
233
    {
234
#define OP pdp11_opcodes[i]
235
      if ((opcode & OP.mask) == OP.opcode)
236
        switch (OP.type)
237
          {
238
          case PDP11_OPCODE_NO_OPS:
239
            FPRINTF (F, OP.name);
240
            goto done;
241
          case PDP11_OPCODE_REG:
242
            FPRINTF (F, OP.name);
243
            FPRINTF (F, AFTER_INSTRUCTION);
244
            print_reg (dst, info);
245
            goto done;
246
          case PDP11_OPCODE_OP:
247
            FPRINTF (F, OP.name);
248
            FPRINTF (F, AFTER_INSTRUCTION);
249
            if (strcmp (OP.name, "jmp") == 0)
250
              dst |= JUMP;
251
            if (print_operand (&memaddr, dst, info) < 0)
252
              return -1;
253
            goto done;
254
          case PDP11_OPCODE_FOP:
255
            FPRINTF (F, OP.name);
256
            FPRINTF (F, AFTER_INSTRUCTION);
257
            if (strcmp (OP.name, "jmp") == 0)
258
              dst |= JUMP;
259
            if (print_foperand (&memaddr, dst, info) < 0)
260
              return -1;
261
            goto done;
262
          case PDP11_OPCODE_REG_OP:
263
            FPRINTF (F, OP.name);
264
            FPRINTF (F, AFTER_INSTRUCTION);
265
            print_reg (src, info);
266
            FPRINTF (F, OPERAND_SEPARATOR);
267
            if (strcmp (OP.name, "jsr") == 0)
268
              dst |= JUMP;
269
            if (print_operand (&memaddr, dst, info) < 0)
270
              return -1;
271
            goto done;
272
          case PDP11_OPCODE_REG_OP_REV:
273
            FPRINTF (F, OP.name);
274
            FPRINTF (F, AFTER_INSTRUCTION);
275
            if (print_operand (&memaddr, dst, info) < 0)
276
              return -1;
277
            FPRINTF (F, OPERAND_SEPARATOR);
278
            print_reg (src, info);
279
            goto done;
280
          case PDP11_OPCODE_AC_FOP:
281
            {
282
              int ac = (opcode & 0xe0) >> 6;
283
              FPRINTF (F, OP.name);
284
              FPRINTF (F, AFTER_INSTRUCTION);
285
              print_freg (ac, info);
286
              FPRINTF (F, OPERAND_SEPARATOR);
287
              if (print_foperand (&memaddr, dst, info) < 0)
288
                return -1;
289
              goto done;
290
            }
291
          case PDP11_OPCODE_FOP_AC:
292
            {
293
              int ac = (opcode & 0xe0) >> 6;
294
              FPRINTF (F, OP.name);
295
              FPRINTF (F, AFTER_INSTRUCTION);
296
              if (print_foperand (&memaddr, dst, info) < 0)
297
                return -1;
298
              FPRINTF (F, OPERAND_SEPARATOR);
299
              print_freg (ac, info);
300
              goto done;
301
            }
302
          case PDP11_OPCODE_AC_OP:
303
            {
304
              int ac = (opcode & 0xe0) >> 6;
305
              FPRINTF (F, OP.name);
306
              FPRINTF (F, AFTER_INSTRUCTION);
307
              print_freg (ac, info);
308
              FPRINTF (F, OPERAND_SEPARATOR);
309
              if (print_operand (&memaddr, dst, info) < 0)
310
                return -1;
311
              goto done;
312
            }
313
          case PDP11_OPCODE_OP_AC:
314
            {
315
              int ac = (opcode & 0xe0) >> 6;
316
              FPRINTF (F, OP.name);
317
              FPRINTF (F, AFTER_INSTRUCTION);
318
              if (print_operand (&memaddr, dst, info) < 0)
319
                return -1;
320
              FPRINTF (F, OPERAND_SEPARATOR);
321
              print_freg (ac, info);
322
              goto done;
323
            }
324
          case PDP11_OPCODE_OP_OP:
325
            FPRINTF (F, OP.name);
326
            FPRINTF (F, AFTER_INSTRUCTION);
327
            if (print_operand (&memaddr, src, info) < 0)
328
              return -1;
329
            FPRINTF (F, OPERAND_SEPARATOR);
330
            if (print_operand (&memaddr, dst, info) < 0)
331
              return -1;
332
            goto done;
333
          case PDP11_OPCODE_DISPL:
334
            {
335
              int displ = (opcode & 0xff) << 8;
336
              bfd_vma address = memaddr + (sign_extend (displ) >> 7);
337
              FPRINTF (F, OP.name);
338
              FPRINTF (F, AFTER_INSTRUCTION);
339
              (*info->print_address_func) (address, info);
340
              goto done;
341
            }
342
          case PDP11_OPCODE_REG_DISPL:
343
            {
344
              int displ = (opcode & 0x3f) << 10;
345
              bfd_vma address = memaddr + (sign_extend (displ) >> 9);
346
              FPRINTF (F, OP.name);
347
              FPRINTF (F, AFTER_INSTRUCTION);
348
              print_reg (src, info);
349
              FPRINTF (F, OPERAND_SEPARATOR);
350
              (*info->print_address_func) (address, info);
351
              goto done;
352
            }
353
          case PDP11_OPCODE_IMM8:
354
            {
355
              int code = opcode & 0xff;
356
              FPRINTF (F, OP.name);
357
              FPRINTF (F, AFTER_INSTRUCTION);
358
              FPRINTF (F, "%o", code);
359
              goto done;
360
            }
361
          case PDP11_OPCODE_IMM6:
362
            {
363
              int code = opcode & 0x3f;
364
              FPRINTF (F, OP.name);
365
              FPRINTF (F, AFTER_INSTRUCTION);
366
              FPRINTF (F, "%o", code);
367
              goto done;
368
            }
369
          case PDP11_OPCODE_IMM3:
370
            {
371
              int code = opcode & 7;
372
              FPRINTF (F, OP.name);
373
              FPRINTF (F, AFTER_INSTRUCTION);
374
              FPRINTF (F, "%o", code);
375
              goto done;
376
            }
377
          case PDP11_OPCODE_ILLEGAL:
378
            {
379
              FPRINTF (F, ".word");
380
              FPRINTF (F, AFTER_INSTRUCTION);
381
              FPRINTF (F, "%o", opcode);
382
              goto done;
383
            }
384
          default:
385
            /* TODO: is this a proper way of signalling an error? */
386
            FPRINTF (F, "<internal error: unrecognized instruction type>");
387
            return -1;
388
          }
389
#undef OP
390
    }
391
 done:
392
 
393
  return memaddr - start_memaddr;
394
}

powered by: WebSVN 2.1.0

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