* configure.in (ALL_LINGUAS): Add vi.
[platform/upstream/binutils.git] / opcodes / m10300-dis.c
1 /* Disassemble MN10300 instructions.
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003
3    Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19
20 #include <stdio.h>
21
22 #include "sysdep.h"
23 #include "opcode/mn10300.h"
24 #include "dis-asm.h"
25 #include "opintl.h"
26
27 static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
28                                  unsigned long insn, unsigned int));
29
30 #define HAVE_AM33_2 (info->mach == AM33_2)
31 #define HAVE_AM33 (info->mach == AM33 || HAVE_AM33_2)
32 #define HAVE_AM30 (info->mach == AM30)
33
34 int
35 print_insn_mn10300 (memaddr, info)
36      bfd_vma memaddr;
37      struct disassemble_info *info;
38 {
39   int status;
40   bfd_byte buffer[4];
41   unsigned long insn;
42   unsigned int consume;
43
44   /* First figure out how big the opcode is.  */
45   status = (*info->read_memory_func) (memaddr, buffer, 1, info);
46   if (status != 0)
47     {
48       (*info->memory_error_func) (status, memaddr, info);
49       return -1;
50     }
51   insn = *(unsigned char *) buffer;
52
53   /* These are one byte insns.  */
54   if ((insn & 0xf3) == 0x00
55       || (insn & 0xf0) == 0x10
56       || (insn & 0xfc) == 0x3c
57       || (insn & 0xf3) == 0x41
58       || (insn & 0xf3) == 0x40
59       || (insn & 0xfc) == 0x50
60       || (insn & 0xfc) == 0x54
61       || (insn & 0xf0) == 0x60
62       || (insn & 0xf0) == 0x70
63       || ((insn & 0xf0) == 0x80
64           && (insn & 0x0c) >> 2 != (insn & 0x03))
65       || ((insn & 0xf0) == 0x90
66           && (insn & 0x0c) >> 2 != (insn & 0x03))
67       || ((insn & 0xf0) == 0xa0
68           && (insn & 0x0c) >> 2 != (insn & 0x03))
69       || ((insn & 0xf0) == 0xb0
70           && (insn & 0x0c) >> 2 != (insn & 0x03))
71       || (insn & 0xff) == 0xcb
72       || (insn & 0xfc) == 0xd0
73       || (insn & 0xfc) == 0xd4
74       || (insn & 0xfc) == 0xd8
75       || (insn & 0xf0) == 0xe0
76       || (insn & 0xff) == 0xff)
77     {
78       consume = 1;
79     }
80
81   /* These are two byte insns.  */
82   else if ((insn & 0xf0) == 0x80
83            || (insn & 0xf0) == 0x90
84            || (insn & 0xf0) == 0xa0
85            || (insn & 0xf0) == 0xb0
86            || (insn & 0xfc) == 0x20
87            || (insn & 0xfc) == 0x28
88            || (insn & 0xf3) == 0x43
89            || (insn & 0xf3) == 0x42
90            || (insn & 0xfc) == 0x58
91            || (insn & 0xfc) == 0x5c
92            || ((insn & 0xf0) == 0xc0
93                && (insn & 0xff) != 0xcb
94                && (insn & 0xff) != 0xcc
95                && (insn & 0xff) != 0xcd)
96            || (insn & 0xff) == 0xf0
97            || (insn & 0xff) == 0xf1
98            || (insn & 0xff) == 0xf2
99            || (insn & 0xff) == 0xf3
100            || (insn & 0xff) == 0xf4
101            || (insn & 0xff) == 0xf5
102            || (insn & 0xff) == 0xf6)
103     {
104       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
105       if (status != 0)
106         {
107           (*info->memory_error_func) (status, memaddr, info);
108           return -1;
109         }
110       insn = bfd_getb16 (buffer);
111       consume = 2;
112     }
113
114   /* These are three byte insns.  */
115   else if ((insn & 0xff) == 0xf8
116            || (insn & 0xff) == 0xcc
117            || (insn & 0xff) == 0xf9
118            || (insn & 0xf3) == 0x01
119            || (insn & 0xf3) == 0x02
120            || (insn & 0xf3) == 0x03
121            || (insn & 0xfc) == 0x24
122            || (insn & 0xfc) == 0x2c
123            || (insn & 0xfc) == 0x30
124            || (insn & 0xfc) == 0x34
125            || (insn & 0xfc) == 0x38
126            || (insn & 0xff) == 0xde
127            || (insn & 0xff) == 0xdf
128            || (insn & 0xff) == 0xf9
129            || (insn & 0xff) == 0xcc)
130     {
131       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
132       if (status != 0)
133         {
134           (*info->memory_error_func) (status, memaddr, info);
135           return -1;
136         }
137       insn = bfd_getb16 (buffer);
138       insn <<= 8;
139       status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
140       if (status != 0)
141         {
142           (*info->memory_error_func) (status, memaddr, info);
143           return -1;
144         }
145       insn |= *(unsigned char *) buffer;
146       consume = 3;
147     }
148
149   /* These are four byte insns.  */
150   else if ((insn & 0xff) == 0xfa
151            || (insn & 0xff) == 0xf7
152            || (insn & 0xff) == 0xfb)
153     {
154       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
155       if (status != 0)
156         {
157           (*info->memory_error_func) (status, memaddr, info);
158           return -1;
159         }
160       insn = bfd_getb32 (buffer);
161       consume = 4;
162     }
163
164   /* These are five byte insns.  */
165   else if ((insn & 0xff) == 0xcd
166            || (insn & 0xff) == 0xdc)
167     {
168       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
169       if (status != 0)
170         {
171           (*info->memory_error_func) (status, memaddr, info);
172           return -1;
173         }
174       insn = bfd_getb32 (buffer);
175       consume = 5;
176     }
177
178   /* These are six byte insns.  */
179   else if ((insn & 0xff) == 0xfd
180            || (insn & 0xff) == 0xfc)
181     {
182       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
183       if (status != 0)
184         {
185           (*info->memory_error_func) (status, memaddr, info);
186           return -1;
187         }
188
189       insn = bfd_getb32 (buffer);
190       consume = 6;
191     }
192
193   /* Else its a seven byte insns (in theory).  */
194   else
195     {
196       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
197       if (status != 0)
198         {
199           (*info->memory_error_func) (status, memaddr, info);
200           return -1;
201         }
202
203       insn = bfd_getb32 (buffer);
204       consume = 7;
205       /* Handle the 5-byte extended instruction codes.  */
206       if ((insn & 0xfff80000) == 0xfe800000)
207         consume = 5;
208     }
209
210   disassemble (memaddr, info, insn, consume);
211
212   return consume;
213 }
214
215 static void
216 disassemble (memaddr, info, insn, size)
217      bfd_vma memaddr;
218      struct disassemble_info *info;
219      unsigned long insn;
220      unsigned int size;
221 {
222   struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
223   const struct mn10300_operand *operand;
224   bfd_byte buffer[4];
225   unsigned long extension = 0;
226   int status, match = 0;
227
228   /* Find the opcode.  */
229   while (op->name)
230     {
231       int mysize, extra_shift;
232
233       if (op->format == FMT_S0)
234         mysize = 1;
235       else if (op->format == FMT_S1
236                || op->format == FMT_D0)
237         mysize = 2;
238       else if (op->format == FMT_S2
239                || op->format == FMT_D1)
240         mysize = 3;
241       else if (op->format == FMT_S4)
242         mysize = 5;
243       else if (op->format == FMT_D2)
244         mysize = 4;
245       else if (op->format == FMT_D3)
246         mysize = 5;
247       else if (op->format == FMT_D4)
248         mysize = 6;
249       else if (op->format == FMT_D6)
250         mysize = 3;
251       else if (op->format == FMT_D7 || op->format == FMT_D10)
252         mysize = 4;
253       else if (op->format == FMT_D8)
254         mysize = 6;
255       else if (op->format == FMT_D9)
256         mysize = 7;
257       else
258         mysize = 7;
259
260       if ((op->mask & insn) == op->opcode
261           && size == (unsigned int) mysize
262           && (op->machine == 0
263               || (op->machine == AM33_2 && HAVE_AM33_2)
264               || (op->machine == AM33 && HAVE_AM33)
265               || (op->machine == AM30 && HAVE_AM30)))
266         {
267           const unsigned char *opindex_ptr;
268           unsigned int nocomma;
269           int paren = 0;
270
271           if (op->format == FMT_D1 || op->format == FMT_S1)
272             extra_shift = 8;
273           else if (op->format == FMT_D2 || op->format == FMT_D4
274                    || op->format == FMT_S2 || op->format == FMT_S4
275                    || op->format == FMT_S6 || op->format == FMT_D5)
276             extra_shift = 16;
277           else if (op->format == FMT_D7
278                    || op->format == FMT_D8
279                    || op->format == FMT_D9)
280             extra_shift = 8;
281           else
282             extra_shift = 0;
283
284           if (size == 1 || size == 2)
285             {
286               extension = 0;
287             }
288           else if (size == 3
289                    && (op->format == FMT_D1
290                        || op->opcode == 0xdf0000
291                        || op->opcode == 0xde0000))
292             {
293               extension = 0;
294             }
295           else if (size == 3
296                    && op->format == FMT_D6)
297             {
298               extension = 0;
299             }
300           else if (size == 3)
301             {
302               insn &= 0xff0000;
303               status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
304               if (status != 0)
305                 {
306                   (*info->memory_error_func) (status, memaddr, info);
307                   return;
308                 }
309
310               insn |= bfd_getl16 (buffer);
311               extension = 0;
312             }
313           else if (size == 4
314                    && (op->opcode == 0xfaf80000
315                        || op->opcode == 0xfaf00000
316                        || op->opcode == 0xfaf40000))
317             {
318               extension = 0;
319             }
320           else if (size == 4
321                    && (op->format == FMT_D7
322                        || op->format == FMT_D10))
323             {
324               extension = 0;
325             }
326           else if (size == 4)
327             {
328               insn &= 0xffff0000;
329               status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
330               if (status != 0)
331                 {
332                   (*info->memory_error_func) (status, memaddr, info);
333                   return;
334                 }
335
336               insn |= bfd_getl16 (buffer);
337               extension = 0;
338             }
339           else if (size == 5 && op->opcode == 0xdc000000)
340             {
341               unsigned long temp = 0;
342               status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
343               if (status != 0)
344                 {
345                   (*info->memory_error_func) (status, memaddr, info);
346                   return;
347                 }
348               temp |= bfd_getl32 (buffer);
349
350               insn &= 0xff000000;
351               insn |= (temp & 0xffffff00) >> 8;
352               extension = temp & 0xff;
353             }
354           else if (size == 5 && op->format == FMT_D3)
355             {
356               status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
357               if (status != 0)
358                 {
359                   (*info->memory_error_func) (status, memaddr, info);
360                   return;
361                 }
362               insn &= 0xffff0000;
363               insn |= bfd_getl16 (buffer);
364
365               status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
366               if (status != 0)
367                 {
368                   (*info->memory_error_func) (status, memaddr, info);
369                   return;
370                 }
371               extension = *(unsigned char *) buffer;
372             }
373           else if (size == 5)
374             {
375               unsigned long temp = 0;
376               status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
377               if (status != 0)
378                 {
379                   (*info->memory_error_func) (status, memaddr, info);
380                   return;
381                 }
382               temp |= bfd_getl16 (buffer);
383
384               insn &= 0xff0000ff;
385               insn |= temp << 8;
386
387               status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
388               if (status != 0)
389                 {
390                   (*info->memory_error_func) (status, memaddr, info);
391                   return;
392                 }
393               extension = *(unsigned char *) buffer;
394             }
395           else if (size == 6 && op->format == FMT_D8)
396             {
397               insn &= 0xffffff00;
398               status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
399               if (status != 0)
400                 {
401                   (*info->memory_error_func) (status, memaddr, info);
402                   return;
403                 }
404               insn |= *(unsigned char *) buffer;
405
406               status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
407               if (status != 0)
408                 {
409                   (*info->memory_error_func) (status, memaddr, info);
410                   return;
411                 }
412               extension = bfd_getl16 (buffer);
413             }
414           else if (size == 6)
415             {
416               unsigned long temp = 0;
417               status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
418               if (status != 0)
419                 {
420                   (*info->memory_error_func) (status, memaddr, info);
421                   return;
422                 }
423               temp |= bfd_getl32 (buffer);
424
425               insn &= 0xffff0000;
426               insn |= (temp >> 16) & 0xffff;
427               extension = temp & 0xffff;
428             }
429           else if (size == 7 && op->format == FMT_D9)
430             {
431               insn &= 0xffffff00;
432               status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
433               if (status != 0)
434                 {
435                   (*info->memory_error_func) (status, memaddr, info);
436                   return;
437                 }
438               extension = bfd_getl32 (buffer);
439               insn |= (extension & 0xff000000) >> 24;
440               extension &= 0xffffff;
441             }
442           else if (size == 7 && op->opcode == 0xdd000000)
443             {
444               unsigned long temp = 0;
445               status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
446               if (status != 0)
447                 {
448                   (*info->memory_error_func) (status, memaddr, info);
449                   return;
450                 }
451               temp |= bfd_getl32 (buffer);
452
453               insn &= 0xff000000;
454               insn |= (temp >> 8) & 0xffffff;
455               extension = (temp & 0xff) << 16;
456
457               status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
458               if (status != 0)
459                 {
460                   (*info->memory_error_func) (status, memaddr, info);
461                   return;
462                 }
463               extension |= bfd_getb16 (buffer);
464             }
465           else if (size == 7)
466             {
467               unsigned long temp = 0;
468               status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
469               if (status != 0)
470                 {
471                   (*info->memory_error_func) (status, memaddr, info);
472                   return;
473                 }
474               temp |= bfd_getl32 (buffer);
475
476               insn &= 0xffff0000;
477               insn |= (temp >> 16) & 0xffff;
478               extension = (temp & 0xffff) << 8;
479
480               status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
481               if (status != 0)
482                 {
483                   (*info->memory_error_func) (status, memaddr, info);
484                   return;
485                 }
486               extension |= *(unsigned char *) buffer;
487             }
488
489           match = 1;
490           (*info->fprintf_func) (info->stream, "%s\t", op->name);
491
492           /* Now print the operands.  */
493           for (opindex_ptr = op->operands, nocomma = 1;
494                *opindex_ptr != 0;
495                opindex_ptr++)
496             {
497               unsigned long value;
498
499               operand = &mn10300_operands[*opindex_ptr];
500
501               /* If this operand is a PLUS (autoincrement), then do not emit
502                  a comma before emitting the plus.  */
503               if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
504                 nocomma = 1;
505
506               if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
507                 {
508                   unsigned long temp;
509                   value = insn & ((1 << operand->bits) - 1);
510                   value <<= (32 - operand->bits);
511                   temp = extension >> operand->shift;
512                   temp &= ((1 << (32 - operand->bits)) - 1);
513                   value |= temp;
514                   value = ((value ^ (((unsigned long) 1) << 31))
515                            - (((unsigned long) 1) << 31));
516                 }
517               else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
518                 {
519                   unsigned long temp;
520                   value = insn & ((1 << operand->bits) - 1);
521                   value <<= (24 - operand->bits);
522                   temp = extension >> operand->shift;
523                   temp &= ((1 << (24 - operand->bits)) - 1);
524                   value |= temp;
525                   if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
526                     value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
527                 }
528               else if ((operand->flags & (MN10300_OPERAND_FSREG
529                                           | MN10300_OPERAND_FDREG)))
530                 {
531                   /* See m10300-opc.c just before #define FSM0 for an
532                      explanation of these variables.  Note that
533                      FMT-implied shifts are not taken into account for
534                      FP registers.  */
535                   unsigned long mask_low, mask_high;
536                   int shl_low, shr_high, shl_high;
537
538                   switch (operand->bits)
539                     {
540                     case 5:
541                       /* Handle regular FP registers.  */
542                       if (operand->shift >= 0)
543                         {
544                           /* This is an `m' register.  */
545                           shl_low = operand->shift;
546                           shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
547                         }
548                       else
549                         {
550                           /* This is an `n' register.  */
551                           shl_low = -operand->shift;
552                           shl_high = shl_low / 4;
553                         }
554                       mask_low = 0x0f;
555                       mask_high = 0x10;
556                       shr_high = 4;
557                       break;
558
559                     case 3:
560                       /* Handle accumulators.  */
561                       shl_low = -operand->shift;
562                       shl_high = 0;
563                       mask_low = 0x03;
564                       mask_high = 0x04;
565                       shr_high = 2;
566                       break;
567
568                     default:
569                       abort ();
570                     }
571                   value = ((((insn >> shl_high) << shr_high) & mask_high)
572                            | ((insn >> shl_low) & mask_low));
573                 }
574               else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
575                 {
576                   value = ((extension >> (operand->shift))
577                            & ((1 << operand->bits) - 1));
578                 }
579               else
580                 {
581                   value = ((insn >> (operand->shift))
582                            & ((1 << operand->bits) - 1));
583                 }
584
585               if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
586                   /* These are properly extended by the code above.  */
587                   && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
588                 value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
589                          - (((unsigned long) 1) << (operand->bits - 1)));
590
591               if (!nocomma
592                   && (!paren
593                       || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
594                 (*info->fprintf_func) (info->stream, ",");
595
596               nocomma = 0;
597
598               if ((operand->flags & MN10300_OPERAND_DREG) != 0)
599                 {
600                   value = ((insn >> (operand->shift + extra_shift))
601                            & ((1 << operand->bits) - 1));
602                   (*info->fprintf_func) (info->stream, "d%d", (int) value);
603                 }
604
605               else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
606                 {
607                   value = ((insn >> (operand->shift + extra_shift))
608                            & ((1 << operand->bits) - 1));
609                   (*info->fprintf_func) (info->stream, "a%d", (int) value);
610                 }
611
612               else if ((operand->flags & MN10300_OPERAND_SP) != 0)
613                 (*info->fprintf_func) (info->stream, "sp");
614
615               else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
616                 (*info->fprintf_func) (info->stream, "psw");
617
618               else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
619                 (*info->fprintf_func) (info->stream, "mdr");
620
621               else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
622                 {
623                   value = ((insn >> (operand->shift + extra_shift))
624                            & ((1 << operand->bits) - 1));
625                   if (value < 8)
626                     (*info->fprintf_func) (info->stream, "r%d", (int) value);
627                   else if (value < 12)
628                     (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
629                   else
630                     (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
631                 }
632
633               else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
634                 {
635                   value = ((insn >> (operand->shift + extra_shift))
636                            & ((1 << operand->bits) - 1));
637                   if (value == 0)
638                     (*info->fprintf_func) (info->stream, "sp", value);
639                   else
640                     (*info->fprintf_func) (info->stream, "xr%d", (int) value);
641                 }
642
643               else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
644                 (*info->fprintf_func) (info->stream, "fs%d", (int) value);
645
646               else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
647                 (*info->fprintf_func) (info->stream, "fd%d", (int) value);
648
649               else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
650                 (*info->fprintf_func) (info->stream, "fpcr");
651
652               else if ((operand->flags & MN10300_OPERAND_USP) != 0)
653                 (*info->fprintf_func) (info->stream, "usp");
654
655               else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
656                 (*info->fprintf_func) (info->stream, "ssp");
657
658               else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
659                 (*info->fprintf_func) (info->stream, "msp");
660
661               else if ((operand->flags & MN10300_OPERAND_PC) != 0)
662                 (*info->fprintf_func) (info->stream, "pc");
663
664               else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
665                 (*info->fprintf_func) (info->stream, "epsw");
666
667               else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
668                 (*info->fprintf_func) (info->stream, "+");
669
670               else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
671                 {
672                   if (paren)
673                     (*info->fprintf_func) (info->stream, ")");
674                   else
675                     {
676                       (*info->fprintf_func) (info->stream, "(");
677                       nocomma = 1;
678                     }
679                   paren = !paren;
680                 }
681
682               else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
683                 (*info->print_address_func) ((long) value + memaddr, info);
684
685               else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
686                 (*info->print_address_func) (value, info);
687
688               else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
689                 {
690                   int comma = 0;
691
692                   (*info->fprintf_func) (info->stream, "[");
693                   if (value & 0x80)
694                     {
695                       (*info->fprintf_func) (info->stream, "d2");
696                       comma = 1;
697                     }
698
699                   if (value & 0x40)
700                     {
701                       if (comma)
702                         (*info->fprintf_func) (info->stream, ",");
703                       (*info->fprintf_func) (info->stream, "d3");
704                       comma = 1;
705                     }
706
707                   if (value & 0x20)
708                     {
709                       if (comma)
710                         (*info->fprintf_func) (info->stream, ",");
711                       (*info->fprintf_func) (info->stream, "a2");
712                       comma = 1;
713                     }
714
715                   if (value & 0x10)
716                     {
717                       if (comma)
718                         (*info->fprintf_func) (info->stream, ",");
719                       (*info->fprintf_func) (info->stream, "a3");
720                       comma = 1;
721                     }
722
723                   if (value & 0x08)
724                     {
725                       if (comma)
726                         (*info->fprintf_func) (info->stream, ",");
727                       (*info->fprintf_func) (info->stream, "other");
728                       comma = 1;
729                     }
730
731                   if (value & 0x04)
732                     {
733                       if (comma)
734                         (*info->fprintf_func) (info->stream, ",");
735                       (*info->fprintf_func) (info->stream, "exreg0");
736                       comma = 1;
737                     }
738                   if (value & 0x02)
739                     {
740                       if (comma)
741                         (*info->fprintf_func) (info->stream, ",");
742                       (*info->fprintf_func) (info->stream, "exreg1");
743                       comma = 1;
744                     }
745                   if (value & 0x01)
746                     {
747                       if (comma)
748                         (*info->fprintf_func) (info->stream, ",");
749                       (*info->fprintf_func) (info->stream, "exother");
750                       comma = 1;
751                     }
752                   (*info->fprintf_func) (info->stream, "]");
753                 }
754
755               else
756                 (*info->fprintf_func) (info->stream, "%ld", (long) value);
757             }
758           /* All done. */
759           break;
760         }
761       op++;
762     }
763
764   if (!match)
765     {
766       /* xgettext:c-format */
767       (*info->fprintf_func) (info->stream, _("unknown\t0x%04x"), insn);
768     }
769 }