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