ae94271dde5b1795fba71ce7d21cbc6023c1e16d
[platform/upstream/binutils.git] / opcodes / m68hc11-dis.c
1 /* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly
2    Copyright 1999, 2000, 2001, 2002, 2003, 2006
3    Free Software Foundation, Inc.
4    Written by Stephane Carrez (stcarrez@nerim.fr)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20 #include <stdio.h>
21
22 #include "ansidecl.h"
23 #include "opcode/m68hc11.h"
24 #include "dis-asm.h"
25
26 #define PC_REGNUM 3
27
28 static const char *const reg_name[] = {
29   "X", "Y", "SP", "PC"
30 };
31
32 static const char *const reg_src_table[] = {
33   "A", "B", "CCR", "TMP3", "D", "X", "Y", "SP"
34 };
35
36 static const char *const reg_dst_table[] = {
37   "A", "B", "CCR", "TMP2", "D", "X", "Y", "SP"
38 };
39
40 #define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4)
41
42 /* Prototypes for local functions.  */
43 static int read_memory (bfd_vma, bfd_byte *, int, struct disassemble_info *);
44 static int print_indexed_operand (bfd_vma, struct disassemble_info *,
45                                   int*, int, int, bfd_vma);
46 static int print_insn (bfd_vma, struct disassemble_info *, int);
47
48 static int
49 read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
50              struct disassemble_info* info)
51 {
52   int status;
53
54   /* Get first byte.  Only one at a time because we don't know the
55      size of the insn.  */
56   status = (*info->read_memory_func) (memaddr, buffer, size, info);
57   if (status != 0)
58     {
59       (*info->memory_error_func) (status, memaddr, info);
60       return -1;
61     }
62   return 0;
63 }
64
65
66 /* Read the 68HC12 indexed operand byte and print the corresponding mode.
67    Returns the number of bytes read or -1 if failure.  */
68 static int
69 print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info,
70                        int* indirect, int mov_insn, int pc_offset,
71                        bfd_vma endaddr)
72 {
73   bfd_byte buffer[4];
74   int reg;
75   int status;
76   short sval;
77   int pos = 1;
78
79   if (indirect)
80     *indirect = 0;
81
82   status = read_memory (memaddr, &buffer[0], 1, info);
83   if (status != 0)
84     {
85       return status;
86     }
87
88   /* n,r with 5-bits signed constant.  */
89   if ((buffer[0] & 0x20) == 0)
90     {
91       reg = (buffer[0] >> 6) & 3;
92       sval = (buffer[0] & 0x1f);
93       if (sval & 0x10)
94         sval |= 0xfff0;
95       /* 68HC12 requires an adjustment for movb/movw pc relative modes.  */
96       if (reg == PC_REGNUM && info->mach == bfd_mach_m6812 && mov_insn)
97         sval += pc_offset;
98       (*info->fprintf_func) (info->stream, "%d,%s",
99                              (int) sval, reg_name[reg]);
100
101       if (reg == PC_REGNUM)
102         {
103           (* info->fprintf_func) (info->stream, " {");
104           (* info->print_address_func) (endaddr + sval, info);
105           (* info->fprintf_func) (info->stream, "}");
106         }
107     }
108
109   /* Auto pre/post increment/decrement.  */
110   else if ((buffer[0] & 0xc0) != 0xc0)
111     {
112       const char *mode;
113
114       reg = (buffer[0] >> 6) & 3;
115       sval = (buffer[0] & 0x0f);
116       if (sval & 0x8)
117         {
118           sval |= 0xfff0;
119           sval = -sval;
120           mode = "-";
121         }
122       else
123         {
124           sval = sval + 1;
125           mode = "+";
126         }
127       (*info->fprintf_func) (info->stream, "%d,%s%s%s",
128                              (int) sval,
129                              (buffer[0] & 0x10 ? "" : mode),
130                              reg_name[reg], (buffer[0] & 0x10 ? mode : ""));
131     }
132
133   /* [n,r] 16-bits offset indexed indirect.  */
134   else if ((buffer[0] & 0x07) == 3)
135     {
136       if (mov_insn)
137         {
138           (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
139                                  buffer[0] & 0x0ff);
140           return 0;
141         }
142       reg = (buffer[0] >> 3) & 0x03;
143       status = read_memory (memaddr + pos, &buffer[0], 2, info);
144       if (status != 0)
145         {
146           return status;
147         }
148
149       pos += 2;
150       sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
151       (*info->fprintf_func) (info->stream, "[%u,%s]",
152                              sval & 0x0ffff, reg_name[reg]);
153       if (indirect)
154         *indirect = 1;
155     }
156
157   /* n,r with 9 and 16 bit signed constant.  */
158   else if ((buffer[0] & 0x4) == 0)
159     {
160       if (mov_insn)
161         {
162           (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
163                                  buffer[0] & 0x0ff);
164           return 0;
165         }
166       reg = (buffer[0] >> 3) & 0x03;
167       status = read_memory (memaddr + pos,
168                             &buffer[1], (buffer[0] & 0x2 ? 2 : 1), info);
169       if (status != 0)
170         {
171           return status;
172         }
173       if (buffer[0] & 2)
174         {
175           sval = ((buffer[1] << 8) | (buffer[2] & 0x0FF));
176           sval &= 0x0FFFF;
177           pos += 2;
178           endaddr += 2;
179         }
180       else
181         {
182           sval = buffer[1] & 0x00ff;
183           if (buffer[0] & 0x01)
184             sval |= 0xff00;
185           pos++;
186           endaddr++;
187         }
188       (*info->fprintf_func) (info->stream, "%d,%s",
189                              (int) sval, reg_name[reg]);
190       if (reg == PC_REGNUM)
191         {
192           (* info->fprintf_func) (info->stream, " {");
193           (* info->print_address_func) (endaddr + sval, info);
194           (* info->fprintf_func) (info->stream, "}");
195         }
196     }
197   else
198     {
199       reg = (buffer[0] >> 3) & 0x03;
200       switch (buffer[0] & 3)
201         {
202         case 0:
203           (*info->fprintf_func) (info->stream, "A,%s", reg_name[reg]);
204           break;
205         case 1:
206           (*info->fprintf_func) (info->stream, "B,%s", reg_name[reg]);
207           break;
208         case 2:
209           (*info->fprintf_func) (info->stream, "D,%s", reg_name[reg]);
210           break;
211         case 3:
212         default:
213           (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]);
214           if (indirect)
215             *indirect = 1;
216           break;
217         }
218     }
219
220   return pos;
221 }
222
223 /* Disassemble one instruction at address 'memaddr'.  Returns the number
224    of bytes used by that instruction.  */
225 static int
226 print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch)
227 {
228   int status;
229   bfd_byte buffer[4];
230   unsigned char code;
231   long format, pos, i;
232   short sval;
233   const struct m68hc11_opcode *opcode;
234
235   /* Get first byte.  Only one at a time because we don't know the
236      size of the insn.  */
237   status = read_memory (memaddr, buffer, 1, info);
238   if (status != 0)
239     {
240       return status;
241     }
242
243   format = 0;
244   code = buffer[0];
245   pos = 0;
246
247   /* Look for page2,3,4 opcodes.  */
248   if (code == M6811_OPCODE_PAGE2)
249     {
250       pos++;
251       format = M6811_OP_PAGE2;
252     }
253   else if (code == M6811_OPCODE_PAGE3 && arch == cpu6811)
254     {
255       pos++;
256       format = M6811_OP_PAGE3;
257     }
258   else if (code == M6811_OPCODE_PAGE4 && arch == cpu6811)
259     {
260       pos++;
261       format = M6811_OP_PAGE4;
262     }
263
264   /* We are in page2,3,4; get the real opcode.  */
265   if (pos == 1)
266     {
267       status = read_memory (memaddr + pos, &buffer[1], 1, info);
268       if (status != 0)
269         {
270           return status;
271         }
272       code = buffer[1];
273     }
274
275
276   /* Look first for a 68HC12 alias.  All of them are 2-bytes long and
277      in page 1.  There is no operand to print.  We read the second byte
278      only when we have a possible match.  */
279   if ((arch & cpu6812) && format == 0)
280     {
281       int must_read = 1;
282
283       /* Walk the alias table to find a code1+code2 match.  */
284       for (i = 0; i < m68hc12_num_alias; i++)
285         {
286           if (m68hc12_alias[i].code1 == code)
287             {
288               if (must_read)
289                 {
290                   status = read_memory (memaddr + pos + 1,
291                                         &buffer[1], 1, info);
292                   if (status != 0)
293                     break;
294
295                   must_read = 1;
296                 }
297               if (m68hc12_alias[i].code2 == (unsigned char) buffer[1])
298                 {
299                   (*info->fprintf_func) (info->stream, "%s",
300                                          m68hc12_alias[i].name);
301                   return 2;
302                 }
303             }
304         }
305     }
306
307   pos++;
308
309   /* Scan the opcode table until we find the opcode
310      with the corresponding page.  */
311   opcode = m68hc11_opcodes;
312   for (i = 0; i < m68hc11_num_opcodes; i++, opcode++)
313     {
314       int offset;
315       int pc_src_offset;
316       int pc_dst_offset = 0;
317
318       if ((opcode->arch & arch) == 0)
319         continue;
320       if (opcode->opcode != code)
321         continue;
322       if ((opcode->format & OP_PAGE_MASK) != format)
323         continue;
324
325       if (opcode->format & M6812_OP_REG)
326         {
327           int j;
328           int is_jump;
329
330           if (opcode->format & M6811_OP_JUMP_REL)
331             is_jump = 1;
332           else
333             is_jump = 0;
334
335           status = read_memory (memaddr + pos, &buffer[0], 1, info);
336           if (status != 0)
337             {
338               return status;
339             }
340           for (j = 0; i + j < m68hc11_num_opcodes; j++)
341             {
342               if ((opcode[j].arch & arch) == 0)
343                 continue;
344               if (opcode[j].opcode != code)
345                 continue;
346               if (is_jump)
347                 {
348                   if (!(opcode[j].format & M6811_OP_JUMP_REL))
349                     continue;
350
351                   if ((opcode[j].format & M6812_OP_IBCC_MARKER)
352                       && (buffer[0] & 0xc0) != 0x80)
353                     continue;
354                   if ((opcode[j].format & M6812_OP_TBCC_MARKER)
355                       && (buffer[0] & 0xc0) != 0x40)
356                     continue;
357                   if ((opcode[j].format & M6812_OP_DBCC_MARKER)
358                       && (buffer[0] & 0xc0) != 0)
359                     continue;
360                   if ((opcode[j].format & M6812_OP_EQ_MARKER)
361                       && (buffer[0] & 0x20) == 0)
362                     break;
363                   if (!(opcode[j].format & M6812_OP_EQ_MARKER)
364                       && (buffer[0] & 0x20) != 0)
365                     break;
366                   continue;
367                 }
368               if (opcode[j].format & M6812_OP_EXG_MARKER && buffer[0] & 0x80)
369                 break;
370               if ((opcode[j].format & M6812_OP_SEX_MARKER)
371                   && (((buffer[0] & 0x07) >= 3 && (buffer[0] & 7) <= 7))
372                   && ((buffer[0] & 0x0f0) <= 0x20))
373                 break;
374               if (opcode[j].format & M6812_OP_TFR_MARKER
375                   && !(buffer[0] & 0x80))
376                 break;
377             }
378           if (i + j < m68hc11_num_opcodes)
379             opcode = &opcode[j];
380         }
381
382       /* We have found the opcode.  Extract the operand and print it.  */
383       (*info->fprintf_func) (info->stream, "%s", opcode->name);
384
385       format = opcode->format;
386       if (format & (M6811_OP_MASK | M6811_OP_BITMASK
387                     | M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
388         {
389           (*info->fprintf_func) (info->stream, "\t");
390         }
391
392       /* The movb and movw must be handled in a special way...
393          The source constant 'ii' is not always at the same place.
394          This is the same for the destination for the post-indexed byte.
395          The 'offset' is used to do the appropriate correction.
396
397                                    offset          offset
398                               for constant     for destination
399          movb   18 OB ii hh ll       0          0
400                 18 08 xb ii          1          -1
401                 18 0C hh ll hh ll    0          0
402                 18 09 xb hh ll       1          -1
403                 18 0D xb hh ll       0          0
404                 18 0A xb xb          0          0
405
406          movw   18 03 jj kk hh ll    0          0
407                 18 00 xb jj kk       1          -1
408                 18 04 hh ll hh ll    0          0
409                 18 01 xb hh ll       1          -1
410                 18 05 xb hh ll       0          0
411                 18 02 xb xb          0          0
412
413          After the source operand is read, the position 'pos' is incremented
414          this explains the negative offset for destination.
415
416          movb/movw above are the only instructions with this matching
417          format.  */
418       offset = ((format & M6812_OP_IDX_P2)
419                 && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 |
420                               M6811_OP_IND16)));
421
422       /* Operand with one more byte: - immediate, offset,
423          direct-low address.  */
424       if (format &
425           (M6811_OP_IMM8 | M6811_OP_IX | M6811_OP_IY | M6811_OP_DIRECT))
426         {
427           status = read_memory (memaddr + pos + offset, &buffer[0], 1, info);
428           if (status != 0)
429             {
430               return status;
431             }
432
433           pos++;
434
435           /* This movb/movw is special (see above).  */
436           offset = -offset;
437
438           pc_dst_offset = 2;
439           if (format & M6811_OP_IMM8)
440             {
441               (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]);
442               format &= ~M6811_OP_IMM8;
443               /* Set PC destination offset.  */
444               pc_dst_offset = 1;
445             }
446           else if (format & M6811_OP_IX)
447             {
448               /* Offsets are in range 0..255, print them unsigned.  */
449               (*info->fprintf_func) (info->stream, "%u,x", buffer[0] & 0x0FF);
450               format &= ~M6811_OP_IX;
451             }
452           else if (format & M6811_OP_IY)
453             {
454               (*info->fprintf_func) (info->stream, "%u,y", buffer[0] & 0x0FF);
455               format &= ~M6811_OP_IY;
456             }
457           else if (format & M6811_OP_DIRECT)
458             {
459               (*info->fprintf_func) (info->stream, "*");
460               (*info->print_address_func) (buffer[0] & 0x0FF, info);
461               format &= ~M6811_OP_DIRECT;
462             }
463         }
464
465 #define M6812_DST_MOVE  (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)
466 #define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2)
467       /* Analyze the 68HC12 indexed byte.  */
468       if (format & M6812_INDEXED_FLAGS)
469         {
470           int indirect;
471           bfd_vma endaddr;
472
473           endaddr = memaddr + pos + 1;
474           if (format & M6811_OP_IND16)
475             endaddr += 2;
476           pc_src_offset = -1;
477           pc_dst_offset = 1;
478           status = print_indexed_operand (memaddr + pos, info, &indirect,
479                                           (format & M6812_DST_MOVE),
480                                           pc_src_offset, endaddr);
481           if (status < 0)
482             {
483               return status;
484             }
485           pos += status;
486
487           /* The indirect addressing mode of the call instruction does
488              not need the page code.  */
489           if ((format & M6812_OP_PAGE) && indirect)
490             format &= ~M6812_OP_PAGE;
491         }
492
493       /* 68HC12 dbcc/ibcc/tbcc operands.  */
494       if ((format & M6812_OP_REG) && (format & M6811_OP_JUMP_REL))
495         {
496           status = read_memory (memaddr + pos, &buffer[0], 2, info);
497           if (status != 0)
498             {
499               return status;
500             }
501           (*info->fprintf_func) (info->stream, "%s,",
502                                  reg_src_table[buffer[0] & 0x07]);
503           sval = buffer[1] & 0x0ff;
504           if (buffer[0] & 0x10)
505             sval |= 0xff00;
506
507           pos += 2;
508           (*info->print_address_func) (memaddr + pos + sval, info);
509           format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL);
510         }
511       else if (format & (M6812_OP_REG | M6812_OP_REG_2))
512         {
513           status = read_memory (memaddr + pos, &buffer[0], 1, info);
514           if (status != 0)
515             {
516               return status;
517             }
518
519           pos++;
520           (*info->fprintf_func) (info->stream, "%s,%s",
521                                  reg_src_table[(buffer[0] >> 4) & 7],
522                                  reg_dst_table[(buffer[0] & 7)]);
523         }
524
525       if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
526         {
527           int val;
528           bfd_vma addr;
529           unsigned page = 0;
530
531           status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
532           if (status != 0)
533             {
534               return status;
535             }
536           if (format & M6812_OP_IDX_P2)
537             offset = -2;
538           else
539             offset = 0;
540           pos += 2;
541
542           val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
543           val &= 0x0FFFF;
544           addr = val;
545           pc_dst_offset = 2;
546           if (format & M6812_OP_PAGE)
547             {
548               status = read_memory (memaddr + pos + offset, buffer, 1, info);
549               if (status != 0)
550                 return status;
551
552               page = (unsigned) buffer[0];
553               if (addr >= M68HC12_BANK_BASE && addr < 0x0c000)
554                 addr = ((val - M68HC12_BANK_BASE)
555                         | (page << M68HC12_BANK_SHIFT))
556                    + M68HC12_BANK_VIRT;
557             }
558           else if ((arch & cpu6812)
559                    && addr >= M68HC12_BANK_BASE && addr < 0x0c000)
560              {
561                 int cur_page;
562                 bfd_vma vaddr;
563                 
564                 if (memaddr >= M68HC12_BANK_VIRT)
565                    cur_page = ((memaddr - M68HC12_BANK_VIRT)
566                                >> M68HC12_BANK_SHIFT);
567                 else
568                    cur_page = 0;
569
570                 vaddr = ((addr - M68HC12_BANK_BASE)
571                          + (cur_page << M68HC12_BANK_SHIFT))
572                    + M68HC12_BANK_VIRT;
573                 if (!info->symbol_at_address_func (addr, info)
574                     && info->symbol_at_address_func (vaddr, info))
575                    addr = vaddr;
576              }
577           if (format & M6811_OP_IMM16)
578             {
579               format &= ~M6811_OP_IMM16;
580               (*info->fprintf_func) (info->stream, "#");
581             }
582           else
583             format &= ~M6811_OP_IND16;
584
585           (*info->print_address_func) (addr, info);
586           if (format & M6812_OP_PAGE)
587             {
588               (* info->fprintf_func) (info->stream, " {");
589               (* info->print_address_func) (val, info);
590               (* info->fprintf_func) (info->stream, ", %d}", page);
591               format &= ~M6812_OP_PAGE;
592               pos += 1;
593             }
594         }
595
596       if (format & M6812_OP_IDX_P2)
597         {
598           (*info->fprintf_func) (info->stream, ", ");
599           status = print_indexed_operand (memaddr + pos + offset, info,
600                                           0, 1, pc_dst_offset,
601                                           memaddr + pos + offset + 1);
602           if (status < 0)
603             return status;
604           pos += status;
605         }
606
607       if (format & M6812_OP_IND16_P2)
608         {
609           int val;
610
611           (*info->fprintf_func) (info->stream, ", ");
612
613           status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
614           if (status != 0)
615             {
616               return status;
617             }
618           pos += 2;
619
620           val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
621           val &= 0x0FFFF;
622           (*info->print_address_func) (val, info);
623         }
624
625       /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately
626          and in that order.  The brset/brclr insn have a bitmask and then
627          a relative branch offset.  */
628       if (format & M6811_OP_BITMASK)
629         {
630           status = read_memory (memaddr + pos, &buffer[0], 1, info);
631           if (status != 0)
632             {
633               return status;
634             }
635           pos++;
636           (*info->fprintf_func) (info->stream, " #$%02x%s",
637                                  buffer[0] & 0x0FF,
638                                  (format & M6811_OP_JUMP_REL ? " " : ""));
639           format &= ~M6811_OP_BITMASK;
640         }
641       if (format & M6811_OP_JUMP_REL)
642         {
643           int val;
644
645           status = read_memory (memaddr + pos, &buffer[0], 1, info);
646           if (status != 0)
647             {
648               return status;
649             }
650
651           pos++;
652           val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0];
653           (*info->print_address_func) (memaddr + pos + val, info);
654           format &= ~M6811_OP_JUMP_REL;
655         }
656       else if (format & M6812_OP_JUMP_REL16)
657         {
658           int val;
659
660           status = read_memory (memaddr + pos, &buffer[0], 2, info);
661           if (status != 0)
662             {
663               return status;
664             }
665
666           pos += 2;
667           val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
668           if (val & 0x8000)
669             val |= 0xffff0000;
670
671           (*info->print_address_func) (memaddr + pos + val, info);
672           format &= ~M6812_OP_JUMP_REL16;
673         }
674
675       if (format & M6812_OP_PAGE)
676         {
677           int val;
678
679           status = read_memory (memaddr + pos + offset, &buffer[0], 1, info);
680           if (status != 0)
681             {
682               return status;
683             }
684           pos += 1;
685
686           val = buffer[0] & 0x0ff;
687           (*info->fprintf_func) (info->stream, ", %d", val);
688         }
689       
690 #ifdef DEBUG
691       /* Consistency check.  'format' must be 0, so that we have handled
692          all formats; and the computed size of the insn must match the
693          opcode table content.  */
694       if (format & ~(M6811_OP_PAGE4 | M6811_OP_PAGE3 | M6811_OP_PAGE2))
695         {
696           (*info->fprintf_func) (info->stream, "; Error, format: %lx", format);
697         }
698       if (pos != opcode->size)
699         {
700           (*info->fprintf_func) (info->stream, "; Error, size: %ld expect %d",
701                                  pos, opcode->size);
702         }
703 #endif
704       return pos;
705     }
706
707   /* Opcode not recognized.  */
708   if (format == M6811_OP_PAGE2 && arch & cpu6812
709       && ((code >= 0x30 && code <= 0x39) || (code >= 0x40)))
710     (*info->fprintf_func) (info->stream, "trap\t#%d", code & 0x0ff);
711
712   else if (format == M6811_OP_PAGE2)
713     (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
714                            M6811_OPCODE_PAGE2, code);
715   else if (format == M6811_OP_PAGE3)
716     (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
717                            M6811_OPCODE_PAGE3, code);
718   else if (format == M6811_OP_PAGE4)
719     (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
720                            M6811_OPCODE_PAGE4, code);
721   else
722     (*info->fprintf_func) (info->stream, ".byte\t0x%02x", code);
723
724   return pos;
725 }
726
727 /* Disassemble one instruction at address 'memaddr'.  Returns the number
728    of bytes used by that instruction.  */
729 int
730 print_insn_m68hc11 (bfd_vma memaddr, struct disassemble_info* info)
731 {
732   return print_insn (memaddr, info, cpu6811);
733 }
734
735 int
736 print_insn_m68hc12 (bfd_vma memaddr, struct disassemble_info* info)
737 {
738   return print_insn (memaddr, info, cpu6812);
739 }