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