1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
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)
7 This file is part of libopcodes.
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)
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
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. */
27 #include "coff/internal.h"
31 /* FIXME: This shouldn't be done here */
33 #include "elf/internal.h"
37 #define streq(a,b) (strcmp ((a), (b)) == 0)
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
48 static char * arm_conditional
[] =
49 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
50 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
55 const char * description
;
56 const char * reg_names
[16];
60 static arm_regname regnames
[] =
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" }}
76 /* Default to GCC register name set. */
77 static unsigned int regname_selected
= 1;
79 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
80 #define arm_regnames regnames[regname_selected].reg_names
82 static boolean force_thumb
= false;
84 static char * arm_fp_const
[] =
85 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
87 static char * arm_shift
[] =
88 {"lsl", "lsr", "asr", "ror"};
90 /* Forward declarations. */
91 static void arm_decode_shift
PARAMS ((long, fprintf_ftype
, void *));
92 static int print_insn_arm
PARAMS ((bfd_vma
, struct disassemble_info
*, long));
93 static int print_insn_thumb
PARAMS ((bfd_vma
, struct disassemble_info
*, long));
94 static void parse_disassembler_options
PARAMS ((char *));
95 static int print_insn
PARAMS ((bfd_vma
, struct disassemble_info
*, boolean
));
96 int get_arm_regname_num_options (void);
97 int set_arm_regname_option (int option
);
98 int get_arm_regnames (int option
, const char **setname
,
99 const char **setdescription
,
100 const char ***register_names
);
104 get_arm_regname_num_options (void)
106 return NUM_ARM_REGNAMES
;
110 set_arm_regname_option (int option
)
112 int old
= regname_selected
;
113 regname_selected
= option
;
118 get_arm_regnames (int option
, const char **setname
,
119 const char **setdescription
,
120 const char ***register_names
)
122 *setname
= regnames
[option
].name
;
123 *setdescription
= regnames
[option
].description
;
124 *register_names
= regnames
[option
].reg_names
;
129 arm_decode_shift (given
, func
, stream
)
134 func (stream
, "%s", arm_regnames
[given
& 0xf]);
136 if ((given
& 0xff0) != 0)
138 if ((given
& 0x10) == 0)
140 int amount
= (given
& 0xf80) >> 7;
141 int shift
= (given
& 0x60) >> 5;
147 func (stream
, ", rrx");
154 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
157 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
158 arm_regnames
[(given
& 0xf00) >> 8]);
162 /* Print one instruction from PC on INFO->STREAM.
163 Return the size of the instruction (always 4 on ARM). */
165 print_insn_arm (pc
, info
, given
)
167 struct disassemble_info
* info
;
170 struct arm_opcode
* insn
;
171 void * stream
= info
->stream
;
172 fprintf_ftype func
= info
->fprintf_func
;
174 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
176 if ((given
& insn
->mask
) == insn
->value
)
180 for (c
= insn
->assembler
; *c
; c
++)
191 if (((given
& 0x000f0000) == 0x000f0000)
192 && ((given
& 0x02000000) == 0))
194 int offset
= given
& 0xfff;
196 func (stream
, "[pc");
198 if (given
& 0x01000000)
200 if ((given
& 0x00800000) == 0)
204 func (stream
, ", #%d]", offset
);
208 /* Cope with the possibility of write-back
209 being used. Probably a very dangerous thing
210 for the programmer to do, but who are we to
212 if (given
& 0x00200000)
218 func (stream
, "], #%d", offset
);
220 offset
= pc
+ 8; /* ie ignore the offset. */
223 func (stream
, "\t; ");
224 info
->print_address_func (offset
, info
);
229 arm_regnames
[(given
>> 16) & 0xf]);
230 if ((given
& 0x01000000) != 0)
232 if ((given
& 0x02000000) == 0)
234 int offset
= given
& 0xfff;
236 func (stream
, ", %s#%d",
237 (((given
& 0x00800000) == 0)
238 ? "-" : ""), offset
);
242 func (stream
, ", %s",
243 (((given
& 0x00800000) == 0)
245 arm_decode_shift (given
, func
, stream
);
249 ((given
& 0x00200000) != 0) ? "!" : "");
253 if ((given
& 0x02000000) == 0)
255 int offset
= given
& 0xfff;
257 func (stream
, "], %s#%d",
258 (((given
& 0x00800000) == 0)
259 ? "-" : ""), offset
);
265 func (stream
, "], %s",
266 (((given
& 0x00800000) == 0)
268 arm_decode_shift (given
, func
, stream
);
275 if ((given
& 0x004f0000) == 0x004f0000)
277 /* PC relative with immediate offset. */
278 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
280 if ((given
& 0x00800000) == 0)
283 func (stream
, "[pc, #%d]\t; ", offset
);
285 (*info
->print_address_func
)
286 (offset
+ pc
+ 8, info
);
291 arm_regnames
[(given
>> 16) & 0xf]);
292 if ((given
& 0x01000000) != 0)
295 if ((given
& 0x00400000) == 0x00400000)
298 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
300 func (stream
, ", %s#%d",
301 (((given
& 0x00800000) == 0)
302 ? "-" : ""), offset
);
307 func (stream
, ", %s%s",
308 (((given
& 0x00800000) == 0)
310 arm_regnames
[given
& 0xf]);
314 ((given
& 0x00200000) != 0) ? "!" : "");
319 if ((given
& 0x00400000) == 0x00400000)
322 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
324 func (stream
, "], %s#%d",
325 (((given
& 0x00800000) == 0)
326 ? "-" : ""), offset
);
333 func (stream
, "], %s%s",
334 (((given
& 0x00800000) == 0)
336 arm_regnames
[given
& 0xf]);
343 (*info
->print_address_func
)
344 (BDISP (given
) * 4 + pc
+ 8, info
);
349 arm_conditional
[(given
>> 28) & 0xf]);
358 for (reg
= 0; reg
< 16; reg
++)
359 if ((given
& (1 << reg
)) != 0)
364 func (stream
, "%s", arm_regnames
[reg
]);
371 if ((given
& 0x02000000) != 0)
373 int rotate
= (given
& 0xf00) >> 7;
374 int immed
= (given
& 0xff);
375 immed
= (((immed
<< (32 - rotate
))
376 | (immed
>> rotate
)) & 0xffffffff);
377 func (stream
, "#%d\t; 0x%x", immed
, immed
);
380 arm_decode_shift (given
, func
, stream
);
384 if ((given
& 0x0000f000) == 0x0000f000)
389 if ((given
& 0x01200000) == 0x00200000)
394 if ((given
& 0x00000020) == 0x00000020)
401 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
402 if ((given
& 0x01000000) != 0)
404 int offset
= given
& 0xff;
406 func (stream
, ", %s#%d]%s",
407 ((given
& 0x00800000) == 0 ? "-" : ""),
409 ((given
& 0x00200000) != 0 ? "!" : ""));
415 int offset
= given
& 0xff;
417 func (stream
, "], %s#%d",
418 ((given
& 0x00800000) == 0 ? "-" : ""),
426 /* Print ARM V5 BLX(1) address: pc+25 bits. */
431 if (given
& 0x00800000)
432 /* Is signed, hi bits should be ones. */
433 offset
= (-1) ^ 0x00ffffff;
435 /* Offset is (SignExtend(offset field)<<2). */
436 offset
+= given
& 0x00ffffff;
438 address
= offset
+ pc
+ 8;
440 if (given
& 0x01000000)
441 /* H bit allows addressing to 2-byte boundaries. */
444 info
->print_address_func (address
, info
);
449 /* Print a Cirrus/DSP shift immediate. */
450 /* Immediates are 7bit signed ints with bits 0..3 in
451 bits 0..3 of opcode and bits 4..6 in bits 5..7
456 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
458 /* Is ``imm'' a negative number? */
462 func (stream
, "%d", imm
);
480 switch (given
& 0x00408000)
497 switch (given
& 0x00080080)
509 func (stream
, _("<illegal precision>"));
514 switch (given
& 0x00408000)
531 switch (given
& 0x60)
547 case '0': case '1': case '2': case '3': case '4':
548 case '5': case '6': case '7': case '8': case '9':
550 int bitstart
= *c
++ - '0';
552 while (*c
>= '0' && *c
<= '9')
553 bitstart
= (bitstart
* 10) + *c
++ - '0';
560 while (*c
>= '0' && *c
<= '9')
561 bitend
= (bitend
* 10) + *c
++ - '0';
572 reg
= given
>> bitstart
;
573 reg
&= (2 << (bitend
- bitstart
)) - 1;
575 func (stream
, "%s", arm_regnames
[reg
]);
582 reg
= given
>> bitstart
;
583 reg
&= (2 << (bitend
- bitstart
)) - 1;
585 func (stream
, "%d", reg
);
592 reg
= given
>> bitstart
;
593 reg
&= (2 << (bitend
- bitstart
)) - 1;
595 func (stream
, "0x%08x", reg
);
597 /* Some SWI instructions have special
599 if ((given
& 0x0fffffff) == 0x0FF00000)
600 func (stream
, "\t; IMB");
601 else if ((given
& 0x0fffffff) == 0x0FF00001)
602 func (stream
, "\t; IMBRange");
609 reg
= given
>> bitstart
;
610 reg
&= (2 << (bitend
- bitstart
)) - 1;
612 func (stream
, "%01x", reg
& 0xf);
619 reg
= given
>> bitstart
;
620 reg
&= (2 << (bitend
- bitstart
)) - 1;
624 arm_fp_const
[reg
& 7]);
626 func (stream
, "f%d", reg
);
637 int single
= *c
== 'y';
642 case 4: /* Sm pair */
646 regno
= given
& 0x0000000f;
650 regno
+= (given
>> 5) & 1;
655 regno
= (given
>> 12) & 0x0000000f;
659 regno
+= (given
>> 22) & 1;
664 regno
= (given
>> 16) & 0x0000000f;
668 regno
+= (given
>> 7) & 1;
674 regno
= (given
>> 12) & 0x0000000f;
678 regno
+= (given
>> 22) & 1;
687 func (stream
, "%c%d", single
? 's' : 'd', regno
);
691 int count
= given
& 0xff;
698 func (stream
, "-%c%d",
705 else if (bitstart
== 4)
706 func (stream
, ", %c%d}", single
? 's' : 'd',
714 if ((given
& (1 << bitstart
)) == 0)
715 func (stream
, "%c", *c
);
719 if ((given
& (1 << bitstart
)) != 0)
720 func (stream
, "%c", *c
);
724 if ((given
& (1 << bitstart
)) != 0)
725 func (stream
, "%c", *c
++);
727 func (stream
, "%c", *++c
);
740 func (stream
, "%c", *c
);
748 /* Print one instruction from PC on INFO->STREAM.
749 Return the size of the instruction. */
751 print_insn_thumb (pc
, info
, given
)
753 struct disassemble_info
* info
;
756 struct thumb_opcode
* insn
;
757 void * stream
= info
->stream
;
758 fprintf_ftype func
= info
->fprintf_func
;
760 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
762 if ((given
& insn
->mask
) == insn
->value
)
764 char * c
= insn
->assembler
;
766 /* Special processing for Thumb 2 instruction BL sequence: */
767 if (!*c
) /* Check for empty (not NULL) assembler string. */
771 info
->bytes_per_chunk
= 4;
772 info
->bytes_per_line
= 4;
774 offset
= BDISP23 (given
);
776 if ((given
& 0x10000000) == 0)
778 func (stream
, "blx\t");
780 /* The spec says that bit 1 of the branch's destination
781 address comes from bit 1 of the instruction's
782 address and not from the offset in the instruction. */
785 /* func (stream, "*malformed!* "); */
789 offset
|= ((pc
& 0x2) >> 1);
792 func (stream
, "bl\t");
794 info
->print_address_func (offset
* 2 + pc
+ 4, info
);
799 info
->bytes_per_chunk
= 2;
800 info
->bytes_per_line
= 4;
821 reg
= (given
>> 3) & 0x7;
822 if (given
& (1 << 6))
825 func (stream
, "%s", arm_regnames
[reg
]);
834 if (given
& (1 << 7))
837 func (stream
, "%s", arm_regnames
[reg
]);
843 arm_conditional
[(given
>> 8) & 0xf]);
847 if (given
& (1 << 8))
851 if (*c
== 'O' && (given
& (1 << 8)))
861 /* It would be nice if we could spot
862 ranges, and generate the rS-rE format: */
863 for (reg
= 0; (reg
< 8); reg
++)
864 if ((given
& (1 << reg
)) != 0)
869 func (stream
, "%s", arm_regnames
[reg
]);
877 func (stream
, arm_regnames
[14] /* "lr" */);
884 func (stream
, arm_regnames
[15] /* "pc" */);
892 case '0': case '1': case '2': case '3': case '4':
893 case '5': case '6': case '7': case '8': case '9':
895 int bitstart
= *c
++ - '0';
898 while (*c
>= '0' && *c
<= '9')
899 bitstart
= (bitstart
* 10) + *c
++ - '0';
908 while (*c
>= '0' && *c
<= '9')
909 bitend
= (bitend
* 10) + *c
++ - '0';
912 reg
= given
>> bitstart
;
913 reg
&= (2 << (bitend
- bitstart
)) - 1;
917 func (stream
, "%s", arm_regnames
[reg
]);
921 func (stream
, "%d", reg
);
925 func (stream
, "%d", reg
<< 1);
929 func (stream
, "%d", reg
<< 2);
933 /* PC-relative address -- the bottom two
934 bits of the address are dropped
935 before the calculation. */
936 info
->print_address_func
937 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
941 func (stream
, "0x%04x", reg
);
945 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
946 func (stream
, "%d", reg
);
950 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
951 (*info
->print_address_func
)
952 (reg
* 2 + pc
+ 4, info
);
963 if ((given
& (1 << bitstart
)) != 0)
964 func (stream
, "%c", *c
);
969 if ((given
& (1 << bitstart
)) != 0)
970 func (stream
, "%c", *c
++);
972 func (stream
, "%c", *++c
);
986 func (stream
, "%c", *c
);
997 /* Parse an individual disassembler option. */
999 parse_arm_disassembler_option (option
)
1005 if (strneq (option
, "reg-names-", 10))
1011 for (i
= NUM_ARM_REGNAMES
; i
--;)
1012 if (streq (option
, regnames
[i
].name
))
1014 regname_selected
= i
;
1019 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
1021 else if (streq (option
, "force-thumb"))
1023 else if (streq (option
, "no-force-thumb"))
1026 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
1031 /* Parse the string of disassembler options, spliting it at whitespaces. */
1033 parse_disassembler_options (options
)
1038 if (options
== NULL
)
1043 space
= strchr (options
, ' ');
1048 parse_arm_disassembler_option (options
);
1050 options
= space
+ 1;
1053 parse_arm_disassembler_option (options
);
1058 /* NOTE: There are no checks in these routines that
1059 the relevant number of data bytes exist. */
1061 print_insn (pc
, info
, little
)
1063 struct disassemble_info
* info
;
1071 if (info
->disassembler_options
)
1073 parse_disassembler_options (info
->disassembler_options
);
1075 /* To avoid repeated parsing of these options, we remove them here. */
1076 info
->disassembler_options
= NULL
;
1079 is_thumb
= force_thumb
;
1081 if (!is_thumb
&& info
->symbols
!= NULL
)
1083 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
1085 coff_symbol_type
* cs
;
1087 cs
= coffsymbol (*info
->symbols
);
1088 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
1089 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
1090 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
1091 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
1092 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
1094 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
)
1096 elf_symbol_type
* es
;
1099 es
= *(elf_symbol_type
**)(info
->symbols
);
1100 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
1102 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
1106 info
->bytes_per_chunk
= 4;
1107 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
1111 status
= info
->read_memory_func (pc
, (bfd_byte
*) &b
[0], 4, info
);
1112 if (status
!= 0 && is_thumb
)
1114 info
->bytes_per_chunk
= 2;
1116 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
1122 info
->memory_error_func (status
, pc
, info
);
1126 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
1130 status
= info
->read_memory_func
1131 (pc
& ~ 0x3, (bfd_byte
*) &b
[0], 4, info
);
1134 info
->memory_error_func (status
, pc
, info
);
1142 given
= (b
[2] << 8) | b
[3];
1144 status
= info
->read_memory_func
1145 ((pc
+ 4) & ~ 0x3, (bfd_byte
*) b
, 4, info
);
1148 info
->memory_error_func (status
, pc
+ 4, info
);
1152 given
|= (b
[0] << 24) | (b
[1] << 16);
1155 given
= (b
[0] << 8) | b
[1] | (b
[2] << 24) | (b
[3] << 16);
1158 given
= (b
[0] << 24) | (b
[1] << 16) | (b
[2] << 8) | (b
[3]);
1161 if (info
->flags
& INSN_HAS_RELOC
)
1162 /* If the instruction has a reloc associated with it, then
1163 the offset field in the instruction will actually be the
1164 addend for the reloc. (We are using REL type relocs).
1165 In such cases, we can ignore the pc when computing
1166 addresses, since the addend is not currently pc-relative. */
1170 status
= print_insn_thumb (pc
, info
, given
);
1172 status
= print_insn_arm (pc
, info
, given
);
1178 print_insn_big_arm (pc
, info
)
1180 struct disassemble_info
* info
;
1182 return print_insn (pc
, info
, false);
1186 print_insn_little_arm (pc
, info
)
1188 struct disassemble_info
* info
;
1190 return print_insn (pc
, info
, true);
1194 print_arm_disassembler_options (FILE * stream
)
1198 fprintf (stream
, _("\n\
1199 The following ARM specific disassembler options are supported for use with\n\
1200 the -M switch:\n"));
1202 for (i
= NUM_ARM_REGNAMES
; i
--;)
1203 fprintf (stream
, " reg-names-%s %*c%s\n",
1205 (int)(14 - strlen (regnames
[i
].name
)), ' ',
1206 regnames
[i
].description
);
1208 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
1209 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");