2003-06-03 Michael Snyder <msnyder@redhat.com>
[binutils-gdb.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7 This file is part of libopcodes.
8
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
13
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23 #include "sysdep.h"
24 #include "dis-asm.h"
25 #define DEFINE_TABLE
26 #include "arm-opc.h"
27 #include "coff/internal.h"
28 #include "libcoff.h"
29 #include "opintl.h"
30
31 /* FIXME: This shouldn't be done here. */
32 #include "elf-bfd.h"
33 #include "elf/internal.h"
34 #include "elf/arm.h"
35
36 #ifndef streq
37 #define streq(a,b) (strcmp ((a), (b)) == 0)
38 #endif
39
40 #ifndef strneq
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
42 #endif
43
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
46 #endif
47
48 static char * arm_conditional[] =
49 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
50 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
51
52 typedef struct
53 {
54 const char * name;
55 const char * description;
56 const char * reg_names[16];
57 }
58 arm_regname;
59
60 static arm_regname regnames[] =
61 {
62 { "raw" , "Select raw register names",
63 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
64 { "gcc", "Select register names used by GCC",
65 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
66 { "std", "Select register names used in ARM's ISA documentation",
67 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
68 { "apcs", "Select register names used in the APCS",
69 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
70 { "atpcs", "Select register names used in the ATPCS",
71 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
72 { "special-atpcs", "Select special register names used in the ATPCS",
73 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
74 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
75 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
76 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
77 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
78 };
79
80 static char * iwmmxt_wwnames[] =
81 {"b", "h", "w", "d"};
82
83 static char * iwmmxt_wwssnames[] =
84 {"b", "bus", "b", "bss",
85 "h", "hus", "h", "hss",
86 "w", "wus", "w", "wss",
87 "d", "dus", "d", "dss"
88 };
89
90 /* Default to GCC register name set. */
91 static unsigned int regname_selected = 1;
92
93 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
94 #define arm_regnames regnames[regname_selected].reg_names
95
96 static bfd_boolean force_thumb = FALSE;
97
98 static char * arm_fp_const[] =
99 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
100
101 static char * arm_shift[] =
102 {"lsl", "lsr", "asr", "ror"};
103 \f
104 /* Forward declarations. */
105 static void arm_decode_shift
106 PARAMS ((long, fprintf_ftype, void *));
107 static int print_insn_arm
108 PARAMS ((bfd_vma, struct disassemble_info *, long));
109 static int print_insn_thumb
110 PARAMS ((bfd_vma, struct disassemble_info *, long));
111 static void parse_disassembler_options
112 PARAMS ((char *));
113 static int print_insn
114 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
115 static int set_iwmmxt_regnames
116 PARAMS ((void));
117
118 int get_arm_regname_num_options
119 PARAMS ((void));
120 int set_arm_regname_option
121 PARAMS ((int));
122 int get_arm_regnames
123 PARAMS ((int, const char **, const char **, const char ***));
124 \f
125 /* Functions. */
126 int
127 get_arm_regname_num_options ()
128 {
129 return NUM_ARM_REGNAMES;
130 }
131
132 int
133 set_arm_regname_option (option)
134 int option;
135 {
136 int old = regname_selected;
137 regname_selected = option;
138 return old;
139 }
140
141 int
142 get_arm_regnames (option, setname, setdescription, register_names)
143 int option;
144 const char **setname;
145 const char **setdescription;
146 const char ***register_names;
147 {
148 *setname = regnames[option].name;
149 *setdescription = regnames[option].description;
150 *register_names = regnames[option].reg_names;
151 return 16;
152 }
153
154 static void
155 arm_decode_shift (given, func, stream)
156 long given;
157 fprintf_ftype func;
158 void * stream;
159 {
160 func (stream, "%s", arm_regnames[given & 0xf]);
161
162 if ((given & 0xff0) != 0)
163 {
164 if ((given & 0x10) == 0)
165 {
166 int amount = (given & 0xf80) >> 7;
167 int shift = (given & 0x60) >> 5;
168
169 if (amount == 0)
170 {
171 if (shift == 3)
172 {
173 func (stream, ", rrx");
174 return;
175 }
176
177 amount = 32;
178 }
179
180 func (stream, ", %s #%d", arm_shift[shift], amount);
181 }
182 else
183 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
184 arm_regnames[(given & 0xf00) >> 8]);
185 }
186 }
187
188 static int
189 set_iwmmxt_regnames ()
190 {
191 const char * setname;
192 const char * setdesc;
193 const char ** regnames;
194 int iwmmxt_regnames = 0;
195 int num_regnames = get_arm_regname_num_options ();
196
197 get_arm_regnames (iwmmxt_regnames, &setname,
198 &setdesc, &regnames);
199 while ((strcmp ("iwmmxt_regnames", setname))
200 && (iwmmxt_regnames < num_regnames))
201 get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
202
203 return iwmmxt_regnames;
204 }
205
206 /* Print one instruction from PC on INFO->STREAM.
207 Return the size of the instruction (always 4 on ARM). */
208
209 static int
210 print_insn_arm (pc, info, given)
211 bfd_vma pc;
212 struct disassemble_info *info;
213 long given;
214 {
215 const struct arm_opcode *insn;
216 void *stream = info->stream;
217 fprintf_ftype func = info->fprintf_func;
218 static int iwmmxt_regnames = 0;
219
220 for (insn = arm_opcodes; insn->assembler; insn++)
221 {
222 if (insn->value == FIRST_IWMMXT_INSN
223 && info->mach != bfd_mach_arm_XScale
224 && info->mach != bfd_mach_arm_iWMMXt)
225 insn = insn + IWMMXT_INSN_COUNT;
226
227 if ((given & insn->mask) == insn->value)
228 {
229 char * c;
230
231 for (c = insn->assembler; *c; c++)
232 {
233 if (*c == '%')
234 {
235 switch (*++c)
236 {
237 case '%':
238 func (stream, "%%");
239 break;
240
241 case 'a':
242 if (((given & 0x000f0000) == 0x000f0000)
243 && ((given & 0x02000000) == 0))
244 {
245 int offset = given & 0xfff;
246
247 func (stream, "[pc");
248
249 if (given & 0x01000000)
250 {
251 if ((given & 0x00800000) == 0)
252 offset = - offset;
253
254 /* Pre-indexed. */
255 func (stream, ", #%d]", offset);
256
257 offset += pc + 8;
258
259 /* Cope with the possibility of write-back
260 being used. Probably a very dangerous thing
261 for the programmer to do, but who are we to
262 argue ? */
263 if (given & 0x00200000)
264 func (stream, "!");
265 }
266 else
267 {
268 /* Post indexed. */
269 func (stream, "], #%d", offset);
270
271 /* ie ignore the offset. */
272 offset = pc + 8;
273 }
274
275 func (stream, "\t; ");
276 info->print_address_func (offset, info);
277 }
278 else
279 {
280 func (stream, "[%s",
281 arm_regnames[(given >> 16) & 0xf]);
282 if ((given & 0x01000000) != 0)
283 {
284 if ((given & 0x02000000) == 0)
285 {
286 int offset = given & 0xfff;
287 if (offset)
288 func (stream, ", %s#%d",
289 (((given & 0x00800000) == 0)
290 ? "-" : ""), offset);
291 }
292 else
293 {
294 func (stream, ", %s",
295 (((given & 0x00800000) == 0)
296 ? "-" : ""));
297 arm_decode_shift (given, func, stream);
298 }
299
300 func (stream, "]%s",
301 ((given & 0x00200000) != 0) ? "!" : "");
302 }
303 else
304 {
305 if ((given & 0x02000000) == 0)
306 {
307 int offset = given & 0xfff;
308 if (offset)
309 func (stream, "], %s#%d",
310 (((given & 0x00800000) == 0)
311 ? "-" : ""), offset);
312 else
313 func (stream, "]");
314 }
315 else
316 {
317 func (stream, "], %s",
318 (((given & 0x00800000) == 0)
319 ? "-" : ""));
320 arm_decode_shift (given, func, stream);
321 }
322 }
323 }
324 break;
325
326 case 's':
327 if ((given & 0x004f0000) == 0x004f0000)
328 {
329 /* PC relative with immediate offset. */
330 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
331
332 if ((given & 0x00800000) == 0)
333 offset = -offset;
334
335 func (stream, "[pc, #%d]\t; ", offset);
336
337 (*info->print_address_func)
338 (offset + pc + 8, info);
339 }
340 else
341 {
342 func (stream, "[%s",
343 arm_regnames[(given >> 16) & 0xf]);
344 if ((given & 0x01000000) != 0)
345 {
346 /* Pre-indexed. */
347 if ((given & 0x00400000) == 0x00400000)
348 {
349 /* Immediate. */
350 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
351 if (offset)
352 func (stream, ", %s#%d",
353 (((given & 0x00800000) == 0)
354 ? "-" : ""), offset);
355 }
356 else
357 {
358 /* Register. */
359 func (stream, ", %s%s",
360 (((given & 0x00800000) == 0)
361 ? "-" : ""),
362 arm_regnames[given & 0xf]);
363 }
364
365 func (stream, "]%s",
366 ((given & 0x00200000) != 0) ? "!" : "");
367 }
368 else
369 {
370 /* Post-indexed. */
371 if ((given & 0x00400000) == 0x00400000)
372 {
373 /* Immediate. */
374 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
375 if (offset)
376 func (stream, "], %s#%d",
377 (((given & 0x00800000) == 0)
378 ? "-" : ""), offset);
379 else
380 func (stream, "]");
381 }
382 else
383 {
384 /* Register. */
385 func (stream, "], %s%s",
386 (((given & 0x00800000) == 0)
387 ? "-" : ""),
388 arm_regnames[given & 0xf]);
389 }
390 }
391 }
392 break;
393
394 case 'b':
395 (*info->print_address_func)
396 (BDISP (given) * 4 + pc + 8, info);
397 break;
398
399 case 'c':
400 func (stream, "%s",
401 arm_conditional [(given >> 28) & 0xf]);
402 break;
403
404 case 'm':
405 {
406 int started = 0;
407 int reg;
408
409 func (stream, "{");
410 for (reg = 0; reg < 16; reg++)
411 if ((given & (1 << reg)) != 0)
412 {
413 if (started)
414 func (stream, ", ");
415 started = 1;
416 func (stream, "%s", arm_regnames[reg]);
417 }
418 func (stream, "}");
419 }
420 break;
421
422 case 'o':
423 if ((given & 0x02000000) != 0)
424 {
425 int rotate = (given & 0xf00) >> 7;
426 int immed = (given & 0xff);
427 immed = (((immed << (32 - rotate))
428 | (immed >> rotate)) & 0xffffffff);
429 func (stream, "#%d\t; 0x%x", immed, immed);
430 }
431 else
432 arm_decode_shift (given, func, stream);
433 break;
434
435 case 'p':
436 if ((given & 0x0000f000) == 0x0000f000)
437 func (stream, "p");
438 break;
439
440 case 't':
441 if ((given & 0x01200000) == 0x00200000)
442 func (stream, "t");
443 break;
444
445 case 'A':
446 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
447 if ((given & 0x01000000) != 0)
448 {
449 int offset = given & 0xff;
450 if (offset)
451 func (stream, ", %s#%d]%s",
452 ((given & 0x00800000) == 0 ? "-" : ""),
453 offset * 4,
454 ((given & 0x00200000) != 0 ? "!" : ""));
455 else
456 func (stream, "]");
457 }
458 else
459 {
460 int offset = given & 0xff;
461 if (offset)
462 func (stream, "], %s#%d",
463 ((given & 0x00800000) == 0 ? "-" : ""),
464 offset * 4);
465 else
466 func (stream, "]");
467 }
468 break;
469
470 case 'B':
471 /* Print ARM V5 BLX(1) address: pc+25 bits. */
472 {
473 bfd_vma address;
474 bfd_vma offset = 0;
475
476 if (given & 0x00800000)
477 /* Is signed, hi bits should be ones. */
478 offset = (-1) ^ 0x00ffffff;
479
480 /* Offset is (SignExtend(offset field)<<2). */
481 offset += given & 0x00ffffff;
482 offset <<= 2;
483 address = offset + pc + 8;
484
485 if (given & 0x01000000)
486 /* H bit allows addressing to 2-byte boundaries. */
487 address += 2;
488
489 info->print_address_func (address, info);
490 }
491 break;
492
493 case 'I':
494 /* Print a Cirrus/DSP shift immediate. */
495 /* Immediates are 7bit signed ints with bits 0..3 in
496 bits 0..3 of opcode and bits 4..6 in bits 5..7
497 of opcode. */
498 {
499 int imm;
500
501 imm = (given & 0xf) | ((given & 0xe0) >> 1);
502
503 /* Is ``imm'' a negative number? */
504 if (imm & 0x40)
505 imm |= (-1 << 7);
506
507 func (stream, "%d", imm);
508 }
509
510 break;
511
512 case 'C':
513 func (stream, "_");
514 if (given & 0x80000)
515 func (stream, "f");
516 if (given & 0x40000)
517 func (stream, "s");
518 if (given & 0x20000)
519 func (stream, "x");
520 if (given & 0x10000)
521 func (stream, "c");
522 break;
523
524 case 'F':
525 switch (given & 0x00408000)
526 {
527 case 0:
528 func (stream, "4");
529 break;
530 case 0x8000:
531 func (stream, "1");
532 break;
533 case 0x00400000:
534 func (stream, "2");
535 break;
536 default:
537 func (stream, "3");
538 }
539 break;
540
541 case 'P':
542 switch (given & 0x00080080)
543 {
544 case 0:
545 func (stream, "s");
546 break;
547 case 0x80:
548 func (stream, "d");
549 break;
550 case 0x00080000:
551 func (stream, "e");
552 break;
553 default:
554 func (stream, _("<illegal precision>"));
555 break;
556 }
557 break;
558 case 'Q':
559 switch (given & 0x00408000)
560 {
561 case 0:
562 func (stream, "s");
563 break;
564 case 0x8000:
565 func (stream, "d");
566 break;
567 case 0x00400000:
568 func (stream, "e");
569 break;
570 default:
571 func (stream, "p");
572 break;
573 }
574 break;
575 case 'R':
576 switch (given & 0x60)
577 {
578 case 0:
579 break;
580 case 0x20:
581 func (stream, "p");
582 break;
583 case 0x40:
584 func (stream, "m");
585 break;
586 default:
587 func (stream, "z");
588 break;
589 }
590 break;
591
592 case '0': case '1': case '2': case '3': case '4':
593 case '5': case '6': case '7': case '8': case '9':
594 {
595 int bitstart = *c++ - '0';
596 int bitend = 0;
597 while (*c >= '0' && *c <= '9')
598 bitstart = (bitstart * 10) + *c++ - '0';
599
600 switch (*c)
601 {
602 case '-':
603 c++;
604
605 while (*c >= '0' && *c <= '9')
606 bitend = (bitend * 10) + *c++ - '0';
607
608 if (!bitend)
609 abort ();
610
611 switch (*c)
612 {
613 case 'r':
614 {
615 long reg;
616
617 reg = given >> bitstart;
618 reg &= (2 << (bitend - bitstart)) - 1;
619
620 func (stream, "%s", arm_regnames[reg]);
621 }
622 break;
623 case 'd':
624 {
625 long reg;
626
627 reg = given >> bitstart;
628 reg &= (2 << (bitend - bitstart)) - 1;
629
630 func (stream, "%d", reg);
631 }
632 break;
633 case 'x':
634 {
635 long reg;
636
637 reg = given >> bitstart;
638 reg &= (2 << (bitend - bitstart)) - 1;
639
640 func (stream, "0x%08x", reg);
641
642 /* Some SWI instructions have special
643 meanings. */
644 if ((given & 0x0fffffff) == 0x0FF00000)
645 func (stream, "\t; IMB");
646 else if ((given & 0x0fffffff) == 0x0FF00001)
647 func (stream, "\t; IMBRange");
648 }
649 break;
650 case 'X':
651 {
652 long reg;
653
654 reg = given >> bitstart;
655 reg &= (2 << (bitend - bitstart)) - 1;
656
657 func (stream, "%01x", reg & 0xf);
658 }
659 break;
660 case 'f':
661 {
662 long reg;
663
664 reg = given >> bitstart;
665 reg &= (2 << (bitend - bitstart)) - 1;
666
667 if (reg > 7)
668 func (stream, "#%s",
669 arm_fp_const[reg & 7]);
670 else
671 func (stream, "f%d", reg);
672 }
673 break;
674
675 case 'w':
676 {
677 long reg;
678
679 if (bitstart != bitend)
680 {
681 reg = given >> bitstart;
682 reg &= (2 << (bitend - bitstart)) - 1;
683 if (bitend - bitstart == 1)
684 func (stream, "%s", iwmmxt_wwnames[reg]);
685 else
686 func (stream, "%s", iwmmxt_wwssnames[reg]);
687 }
688 else
689 {
690 reg = (((given >> 8) & 0x1) |
691 ((given >> 22) & 0x1));
692 func (stream, "%s", iwmmxt_wwnames[reg]);
693 }
694 }
695 break;
696
697 case 'g':
698 {
699 long reg;
700 int current_regnames;
701
702 if (! iwmmxt_regnames)
703 iwmmxt_regnames = set_iwmmxt_regnames ();
704 current_regnames = set_arm_regname_option
705 (iwmmxt_regnames);
706
707 reg = given >> bitstart;
708 reg &= (2 << (bitend - bitstart)) - 1;
709 func (stream, "%s", arm_regnames[reg]);
710 set_arm_regname_option (current_regnames);
711 }
712 break;
713
714 case 'G':
715 {
716 long reg;
717 int current_regnames;
718
719 if (! iwmmxt_regnames)
720 iwmmxt_regnames = set_iwmmxt_regnames ();
721 current_regnames = set_arm_regname_option
722 (iwmmxt_regnames + 1);
723
724 reg = given >> bitstart;
725 reg &= (2 << (bitend - bitstart)) - 1;
726 func (stream, "%s", arm_regnames[reg]);
727 set_arm_regname_option (current_regnames);
728 }
729 break;
730
731 default:
732 abort ();
733 }
734 break;
735
736 case 'y':
737 case 'z':
738 {
739 int single = *c == 'y';
740 int regno;
741
742 switch (bitstart)
743 {
744 case 4: /* Sm pair */
745 func (stream, "{");
746 /* Fall through. */
747 case 0: /* Sm, Dm */
748 regno = given & 0x0000000f;
749 if (single)
750 {
751 regno <<= 1;
752 regno += (given >> 5) & 1;
753 }
754 break;
755
756 case 1: /* Sd, Dd */
757 regno = (given >> 12) & 0x0000000f;
758 if (single)
759 {
760 regno <<= 1;
761 regno += (given >> 22) & 1;
762 }
763 break;
764
765 case 2: /* Sn, Dn */
766 regno = (given >> 16) & 0x0000000f;
767 if (single)
768 {
769 regno <<= 1;
770 regno += (given >> 7) & 1;
771 }
772 break;
773
774 case 3: /* List */
775 func (stream, "{");
776 regno = (given >> 12) & 0x0000000f;
777 if (single)
778 {
779 regno <<= 1;
780 regno += (given >> 22) & 1;
781 }
782 break;
783
784
785 default:
786 abort ();
787 }
788
789 func (stream, "%c%d", single ? 's' : 'd', regno);
790
791 if (bitstart == 3)
792 {
793 int count = given & 0xff;
794
795 if (single == 0)
796 count >>= 1;
797
798 if (--count)
799 {
800 func (stream, "-%c%d",
801 single ? 's' : 'd',
802 regno + count);
803 }
804
805 func (stream, "}");
806 }
807 else if (bitstart == 4)
808 func (stream, ", %c%d}", single ? 's' : 'd',
809 regno + 1);
810
811 break;
812 }
813
814 case '`':
815 c++;
816 if ((given & (1 << bitstart)) == 0)
817 func (stream, "%c", *c);
818 break;
819 case '\'':
820 c++;
821 if ((given & (1 << bitstart)) != 0)
822 func (stream, "%c", *c);
823 break;
824 case '?':
825 ++c;
826 if ((given & (1 << bitstart)) != 0)
827 func (stream, "%c", *c++);
828 else
829 func (stream, "%c", *++c);
830 break;
831 default:
832 abort ();
833 }
834 break;
835
836 case 'L':
837 switch (given & 0x00400100)
838 {
839 case 0x00000000: func (stream, "b"); break;
840 case 0x00400000: func (stream, "h"); break;
841 case 0x00000100: func (stream, "w"); break;
842 case 0x00400100: func (stream, "d"); break;
843 default:
844 break;
845 }
846 break;
847
848 case 'Z':
849 {
850 int value;
851 /* given (20, 23) | given (0, 3) */
852 value = ((given >> 16) & 0xf0) | (given & 0xf);
853 func (stream, "%d", value);
854 }
855 break;
856
857 case 'l':
858 /* This is like the 'A' operator, except that if
859 the width field "M" is zero, then the offset is
860 *not* multiplied by four. */
861 {
862 int offset = given & 0xff;
863 int multiplier = (given & 0x00000100) ? 4 : 1;
864
865 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
866
867 if (offset)
868 {
869 if ((given & 0x01000000) != 0)
870 func (stream, ", %s#%d]%s",
871 ((given & 0x00800000) == 0 ? "-" : ""),
872 offset * multiplier,
873 ((given & 0x00200000) != 0 ? "!" : ""));
874 else
875 func (stream, "], %s#%d",
876 ((given & 0x00800000) == 0 ? "-" : ""),
877 offset * multiplier);
878 }
879 else
880 func (stream, "]");
881 }
882 break;
883
884 default:
885 abort ();
886 }
887 }
888 }
889 else
890 func (stream, "%c", *c);
891 }
892 return 4;
893 }
894 }
895 abort ();
896 }
897
898 /* Print one instruction from PC on INFO->STREAM.
899 Return the size of the instruction. */
900
901 static int
902 print_insn_thumb (pc, info, given)
903 bfd_vma pc;
904 struct disassemble_info *info;
905 long given;
906 {
907 const struct thumb_opcode *insn;
908 void *stream = info->stream;
909 fprintf_ftype func = info->fprintf_func;
910
911 for (insn = thumb_opcodes; insn->assembler; insn++)
912 {
913 if ((given & insn->mask) == insn->value)
914 {
915 char * c = insn->assembler;
916
917 /* Special processing for Thumb 2 instruction BL sequence: */
918 if (!*c) /* Check for empty (not NULL) assembler string. */
919 {
920 long offset;
921
922 info->bytes_per_chunk = 4;
923 info->bytes_per_line = 4;
924
925 offset = BDISP23 (given);
926 offset = offset * 2 + pc + 4;
927
928 if ((given & 0x10000000) == 0)
929 {
930 func (stream, "blx\t");
931 offset &= 0xfffffffc;
932 }
933 else
934 func (stream, "bl\t");
935
936 info->print_address_func (offset, info);
937 return 4;
938 }
939 else
940 {
941 info->bytes_per_chunk = 2;
942 info->bytes_per_line = 4;
943
944 given &= 0xffff;
945
946 for (; *c; c++)
947 {
948 if (*c == '%')
949 {
950 int domaskpc = 0;
951 int domasklr = 0;
952
953 switch (*++c)
954 {
955 case '%':
956 func (stream, "%%");
957 break;
958
959 case 'S':
960 {
961 long reg;
962
963 reg = (given >> 3) & 0x7;
964 if (given & (1 << 6))
965 reg += 8;
966
967 func (stream, "%s", arm_regnames[reg]);
968 }
969 break;
970
971 case 'D':
972 {
973 long reg;
974
975 reg = given & 0x7;
976 if (given & (1 << 7))
977 reg += 8;
978
979 func (stream, "%s", arm_regnames[reg]);
980 }
981 break;
982
983 case 'T':
984 func (stream, "%s",
985 arm_conditional [(given >> 8) & 0xf]);
986 break;
987
988 case 'N':
989 if (given & (1 << 8))
990 domasklr = 1;
991 /* Fall through. */
992 case 'O':
993 if (*c == 'O' && (given & (1 << 8)))
994 domaskpc = 1;
995 /* Fall through. */
996 case 'M':
997 {
998 int started = 0;
999 int reg;
1000
1001 func (stream, "{");
1002
1003 /* It would be nice if we could spot
1004 ranges, and generate the rS-rE format: */
1005 for (reg = 0; (reg < 8); reg++)
1006 if ((given & (1 << reg)) != 0)
1007 {
1008 if (started)
1009 func (stream, ", ");
1010 started = 1;
1011 func (stream, "%s", arm_regnames[reg]);
1012 }
1013
1014 if (domasklr)
1015 {
1016 if (started)
1017 func (stream, ", ");
1018 started = 1;
1019 func (stream, arm_regnames[14] /* "lr" */);
1020 }
1021
1022 if (domaskpc)
1023 {
1024 if (started)
1025 func (stream, ", ");
1026 func (stream, arm_regnames[15] /* "pc" */);
1027 }
1028
1029 func (stream, "}");
1030 }
1031 break;
1032
1033
1034 case '0': case '1': case '2': case '3': case '4':
1035 case '5': case '6': case '7': case '8': case '9':
1036 {
1037 int bitstart = *c++ - '0';
1038 int bitend = 0;
1039
1040 while (*c >= '0' && *c <= '9')
1041 bitstart = (bitstart * 10) + *c++ - '0';
1042
1043 switch (*c)
1044 {
1045 case '-':
1046 {
1047 long reg;
1048
1049 c++;
1050 while (*c >= '0' && *c <= '9')
1051 bitend = (bitend * 10) + *c++ - '0';
1052 if (!bitend)
1053 abort ();
1054 reg = given >> bitstart;
1055 reg &= (2 << (bitend - bitstart)) - 1;
1056 switch (*c)
1057 {
1058 case 'r':
1059 func (stream, "%s", arm_regnames[reg]);
1060 break;
1061
1062 case 'd':
1063 func (stream, "%d", reg);
1064 break;
1065
1066 case 'H':
1067 func (stream, "%d", reg << 1);
1068 break;
1069
1070 case 'W':
1071 func (stream, "%d", reg << 2);
1072 break;
1073
1074 case 'a':
1075 /* PC-relative address -- the bottom two
1076 bits of the address are dropped
1077 before the calculation. */
1078 info->print_address_func
1079 (((pc + 4) & ~3) + (reg << 2), info);
1080 break;
1081
1082 case 'x':
1083 func (stream, "0x%04x", reg);
1084 break;
1085
1086 case 'I':
1087 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1088 func (stream, "%d", reg);
1089 break;
1090
1091 case 'B':
1092 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1093 (*info->print_address_func)
1094 (reg * 2 + pc + 4, info);
1095 break;
1096
1097 default:
1098 abort ();
1099 }
1100 }
1101 break;
1102
1103 case '\'':
1104 c++;
1105 if ((given & (1 << bitstart)) != 0)
1106 func (stream, "%c", *c);
1107 break;
1108
1109 case '?':
1110 ++c;
1111 if ((given & (1 << bitstart)) != 0)
1112 func (stream, "%c", *c++);
1113 else
1114 func (stream, "%c", *++c);
1115 break;
1116
1117 default:
1118 abort ();
1119 }
1120 }
1121 break;
1122
1123 default:
1124 abort ();
1125 }
1126 }
1127 else
1128 func (stream, "%c", *c);
1129 }
1130 }
1131 return 2;
1132 }
1133 }
1134
1135 /* No match. */
1136 abort ();
1137 }
1138
1139 /* Parse an individual disassembler option. */
1140
1141 void
1142 parse_arm_disassembler_option (option)
1143 char * option;
1144 {
1145 if (option == NULL)
1146 return;
1147
1148 if (strneq (option, "reg-names-", 10))
1149 {
1150 int i;
1151
1152 option += 10;
1153
1154 for (i = NUM_ARM_REGNAMES; i--;)
1155 if (streq (option, regnames[i].name))
1156 {
1157 regname_selected = i;
1158 break;
1159 }
1160
1161 if (i < 0)
1162 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1163 }
1164 else if (streq (option, "force-thumb"))
1165 force_thumb = 1;
1166 else if (streq (option, "no-force-thumb"))
1167 force_thumb = 0;
1168 else
1169 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1170
1171 return;
1172 }
1173
1174 /* Parse the string of disassembler options, spliting it at whitespaces. */
1175
1176 static void
1177 parse_disassembler_options (options)
1178 char * options;
1179 {
1180 char * space;
1181
1182 if (options == NULL)
1183 return;
1184
1185 do
1186 {
1187 space = strchr (options, ' ');
1188
1189 if (space)
1190 {
1191 * space = '\0';
1192 parse_arm_disassembler_option (options);
1193 * space = ' ';
1194 options = space + 1;
1195 }
1196 else
1197 parse_arm_disassembler_option (options);
1198 }
1199 while (space);
1200 }
1201
1202 /* NOTE: There are no checks in these routines that
1203 the relevant number of data bytes exist. */
1204
1205 static int
1206 print_insn (pc, info, little)
1207 bfd_vma pc;
1208 struct disassemble_info * info;
1209 bfd_boolean little;
1210 {
1211 unsigned char b[4];
1212 long given;
1213 int status;
1214 int is_thumb;
1215
1216 if (info->disassembler_options)
1217 {
1218 parse_disassembler_options (info->disassembler_options);
1219
1220 /* To avoid repeated parsing of these options, we remove them here. */
1221 info->disassembler_options = NULL;
1222 }
1223
1224 is_thumb = force_thumb;
1225
1226 if (!is_thumb && info->symbols != NULL)
1227 {
1228 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1229 {
1230 coff_symbol_type * cs;
1231
1232 cs = coffsymbol (*info->symbols);
1233 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1234 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1235 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1236 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1237 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1238 }
1239 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1240 {
1241 elf_symbol_type * es;
1242 unsigned int type;
1243
1244 es = *(elf_symbol_type **)(info->symbols);
1245 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1246
1247 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1248 }
1249 }
1250
1251 info->bytes_per_chunk = 4;
1252 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1253
1254 if (little)
1255 {
1256 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1257 if (status != 0 && is_thumb)
1258 {
1259 info->bytes_per_chunk = 2;
1260
1261 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1262 b[3] = b[2] = 0;
1263 }
1264
1265 if (status != 0)
1266 {
1267 info->memory_error_func (status, pc, info);
1268 return -1;
1269 }
1270
1271 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1272 }
1273 else
1274 {
1275 status = info->read_memory_func
1276 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1277 if (status != 0)
1278 {
1279 info->memory_error_func (status, pc, info);
1280 return -1;
1281 }
1282
1283 if (is_thumb)
1284 {
1285 if (pc & 0x2)
1286 {
1287 given = (b[2] << 8) | b[3];
1288
1289 status = info->read_memory_func
1290 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1291 if (status != 0)
1292 {
1293 info->memory_error_func (status, pc + 4, info);
1294 return -1;
1295 }
1296
1297 given |= (b[0] << 24) | (b[1] << 16);
1298 }
1299 else
1300 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1301 }
1302 else
1303 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1304 }
1305
1306 if (info->flags & INSN_HAS_RELOC)
1307 /* If the instruction has a reloc associated with it, then
1308 the offset field in the instruction will actually be the
1309 addend for the reloc. (We are using REL type relocs).
1310 In such cases, we can ignore the pc when computing
1311 addresses, since the addend is not currently pc-relative. */
1312 pc = 0;
1313
1314 if (is_thumb)
1315 status = print_insn_thumb (pc, info, given);
1316 else
1317 status = print_insn_arm (pc, info, given);
1318
1319 return status;
1320 }
1321
1322 int
1323 print_insn_big_arm (pc, info)
1324 bfd_vma pc;
1325 struct disassemble_info * info;
1326 {
1327 return print_insn (pc, info, FALSE);
1328 }
1329
1330 int
1331 print_insn_little_arm (pc, info)
1332 bfd_vma pc;
1333 struct disassemble_info * info;
1334 {
1335 return print_insn (pc, info, TRUE);
1336 }
1337
1338 void
1339 print_arm_disassembler_options (FILE * stream)
1340 {
1341 int i;
1342
1343 fprintf (stream, _("\n\
1344 The following ARM specific disassembler options are supported for use with\n\
1345 the -M switch:\n"));
1346
1347 for (i = NUM_ARM_REGNAMES; i--;)
1348 fprintf (stream, " reg-names-%s %*c%s\n",
1349 regnames[i].name,
1350 (int)(14 - strlen (regnames[i].name)), ' ',
1351 regnames[i].description);
1352
1353 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1354 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
1355 }