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
print_insn_mn10300(memaddr,info)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
disassemble(memaddr,info,insn,size)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 }
769