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