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 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
395 if ((given
& 0x01000000) != 0)
397 int offset
= given
& 0xff;
399 func (stream
, ", %s#%d]%s",
400 ((given
& 0x00800000) == 0 ? "-" : ""),
402 ((given
& 0x00200000) != 0 ? "!" : ""));
408 int offset
= given
& 0xff;
410 func (stream
, "], %s#%d",
411 ((given
& 0x00800000) == 0 ? "-" : ""),
419 /* Print ARM V5 BLX(1) address: pc+25 bits. */
424 if (given
& 0x00800000)
425 /* Is signed, hi bits should be ones. */
426 offset
= (-1) ^ 0x00ffffff;
428 /* Offset is (SignExtend(offset field)<<2). */
429 offset
+= given
& 0x00ffffff;
431 address
= offset
+ pc
+ 8;
433 if (given
& 0x01000000)
434 /* H bit allows addressing to 2-byte boundaries. */
437 info
->print_address_func (address
, info
);
442 /* Print a Cirrus/DSP shift immediate. */
443 /* Immediates are 7bit signed ints with bits 0..3 in
444 bits 0..3 of opcode and bits 4..6 in bits 5..7
449 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
451 /* Is ``imm'' a negative number? */
455 func (stream
, "%d", imm
);
473 switch (given
& 0x00408000)
490 switch (given
& 0x00080080)
502 func (stream
, _("<illegal precision>"));
507 switch (given
& 0x00408000)
524 switch (given
& 0x60)
540 case '0': case '1': case '2': case '3': case '4':
541 case '5': case '6': case '7': case '8': case '9':
543 int bitstart
= *c
++ - '0';
545 while (*c
>= '0' && *c
<= '9')
546 bitstart
= (bitstart
* 10) + *c
++ - '0';
553 while (*c
>= '0' && *c
<= '9')
554 bitend
= (bitend
* 10) + *c
++ - '0';
565 reg
= given
>> bitstart
;
566 reg
&= (2 << (bitend
- bitstart
)) - 1;
568 func (stream
, "%s", arm_regnames
[reg
]);
575 reg
= given
>> bitstart
;
576 reg
&= (2 << (bitend
- bitstart
)) - 1;
578 func (stream
, "%d", reg
);
585 reg
= given
>> bitstart
;
586 reg
&= (2 << (bitend
- bitstart
)) - 1;
588 func (stream
, "0x%08x", reg
);
590 /* Some SWI instructions have special
592 if ((given
& 0x0fffffff) == 0x0FF00000)
593 func (stream
, "\t; IMB");
594 else if ((given
& 0x0fffffff) == 0x0FF00001)
595 func (stream
, "\t; IMBRange");
602 reg
= given
>> bitstart
;
603 reg
&= (2 << (bitend
- bitstart
)) - 1;
605 func (stream
, "%01x", reg
& 0xf);
612 reg
= given
>> bitstart
;
613 reg
&= (2 << (bitend
- bitstart
)) - 1;
617 arm_fp_const
[reg
& 7]);
619 func (stream
, "f%d", reg
);
630 int single
= *c
== 'y';
635 case 4: /* Sm pair */
639 regno
= given
& 0x0000000f;
643 regno
+= (given
>> 5) & 1;
648 regno
= (given
>> 12) & 0x0000000f;
652 regno
+= (given
>> 22) & 1;
657 regno
= (given
>> 16) & 0x0000000f;
661 regno
+= (given
>> 7) & 1;
667 regno
= (given
>> 12) & 0x0000000f;
671 regno
+= (given
>> 22) & 1;
680 func (stream
, "%c%d", single
? 's' : 'd', regno
);
684 int count
= given
& 0xff;
691 func (stream
, "-%c%d",
698 else if (bitstart
== 4)
699 func (stream
, ", %c%d}", single
? 's' : 'd',
707 if ((given
& (1 << bitstart
)) == 0)
708 func (stream
, "%c", *c
);
712 if ((given
& (1 << bitstart
)) != 0)
713 func (stream
, "%c", *c
);
717 if ((given
& (1 << bitstart
)) != 0)
718 func (stream
, "%c", *c
++);
720 func (stream
, "%c", *++c
);
733 func (stream
, "%c", *c
);
741 /* Print one instruction from PC on INFO->STREAM.
742 Return the size of the instruction. */
744 print_insn_thumb (pc
, info
, given
)
746 struct disassemble_info
* info
;
749 struct thumb_opcode
* insn
;
750 void * stream
= info
->stream
;
751 fprintf_ftype func
= info
->fprintf_func
;
753 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
755 if ((given
& insn
->mask
) == insn
->value
)
757 char * c
= insn
->assembler
;
759 /* Special processing for Thumb 2 instruction BL sequence: */
760 if (!*c
) /* Check for empty (not NULL) assembler string. */
764 info
->bytes_per_chunk
= 4;
765 info
->bytes_per_line
= 4;
767 offset
= BDISP23 (given
);
769 if ((given
& 0x10000000) == 0)
771 func (stream
, "blx\t");
773 /* The spec says that bit 1 of the branch's destination
774 address comes from bit 1 of the instruction's
775 address and not from the offset in the instruction. */
778 /* func (stream, "*malformed!* "); */
782 offset
|= ((pc
& 0x2) >> 1);
785 func (stream
, "bl\t");
787 info
->print_address_func (offset
* 2 + pc
+ 4, info
);
792 info
->bytes_per_chunk
= 2;
793 info
->bytes_per_line
= 4;
814 reg
= (given
>> 3) & 0x7;
815 if (given
& (1 << 6))
818 func (stream
, "%s", arm_regnames
[reg
]);
827 if (given
& (1 << 7))
830 func (stream
, "%s", arm_regnames
[reg
]);
836 arm_conditional
[(given
>> 8) & 0xf]);
840 if (given
& (1 << 8))
844 if (*c
== 'O' && (given
& (1 << 8)))
854 /* It would be nice if we could spot
855 ranges, and generate the rS-rE format: */
856 for (reg
= 0; (reg
< 8); reg
++)
857 if ((given
& (1 << reg
)) != 0)
862 func (stream
, "%s", arm_regnames
[reg
]);
870 func (stream
, arm_regnames
[14] /* "lr" */);
877 func (stream
, arm_regnames
[15] /* "pc" */);
885 case '0': case '1': case '2': case '3': case '4':
886 case '5': case '6': case '7': case '8': case '9':
888 int bitstart
= *c
++ - '0';
891 while (*c
>= '0' && *c
<= '9')
892 bitstart
= (bitstart
* 10) + *c
++ - '0';
901 while (*c
>= '0' && *c
<= '9')
902 bitend
= (bitend
* 10) + *c
++ - '0';
905 reg
= given
>> bitstart
;
906 reg
&= (2 << (bitend
- bitstart
)) - 1;
910 func (stream
, "%s", arm_regnames
[reg
]);
914 func (stream
, "%d", reg
);
918 func (stream
, "%d", reg
<< 1);
922 func (stream
, "%d", reg
<< 2);
926 /* PC-relative address -- the bottom two
927 bits of the address are dropped
928 before the calculation. */
929 info
->print_address_func
930 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
934 func (stream
, "0x%04x", reg
);
938 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
939 func (stream
, "%d", reg
);
943 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
944 (*info
->print_address_func
)
945 (reg
* 2 + pc
+ 4, info
);
956 if ((given
& (1 << bitstart
)) != 0)
957 func (stream
, "%c", *c
);
962 if ((given
& (1 << bitstart
)) != 0)
963 func (stream
, "%c", *c
++);
965 func (stream
, "%c", *++c
);
979 func (stream
, "%c", *c
);
990 /* Parse an individual disassembler option. */
992 parse_arm_disassembler_option (option
)
998 if (strneq (option
, "reg-names-", 10))
1004 for (i
= NUM_ARM_REGNAMES
; i
--;)
1005 if (streq (option
, regnames
[i
].name
))
1007 regname_selected
= i
;
1012 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
1014 else if (streq (option
, "force-thumb"))
1016 else if (streq (option
, "no-force-thumb"))
1019 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
1024 /* Parse the string of disassembler options, spliting it at whitespaces. */
1026 parse_disassembler_options (options
)
1031 if (options
== NULL
)
1036 space
= strchr (options
, ' ');
1041 parse_arm_disassembler_option (options
);
1043 options
= space
+ 1;
1046 parse_arm_disassembler_option (options
);
1051 /* NOTE: There are no checks in these routines that
1052 the relevant number of data bytes exist. */
1054 print_insn (pc
, info
, little
)
1056 struct disassemble_info
* info
;
1064 if (info
->disassembler_options
)
1066 parse_disassembler_options (info
->disassembler_options
);
1068 /* To avoid repeated parsing of these options, we remove them here. */
1069 info
->disassembler_options
= NULL
;
1072 is_thumb
= force_thumb
;
1074 if (!is_thumb
&& info
->symbols
!= NULL
)
1076 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
1078 coff_symbol_type
* cs
;
1080 cs
= coffsymbol (*info
->symbols
);
1081 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
1082 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
1083 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
1084 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
1085 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
1087 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
)
1089 elf_symbol_type
* es
;
1092 es
= *(elf_symbol_type
**)(info
->symbols
);
1093 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
1095 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
1099 info
->bytes_per_chunk
= 4;
1100 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
1104 status
= info
->read_memory_func (pc
, (bfd_byte
*) &b
[0], 4, info
);
1105 if (status
!= 0 && is_thumb
)
1107 info
->bytes_per_chunk
= 2;
1109 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
1115 info
->memory_error_func (status
, pc
, info
);
1119 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
1123 status
= info
->read_memory_func
1124 (pc
& ~ 0x3, (bfd_byte
*) &b
[0], 4, info
);
1127 info
->memory_error_func (status
, pc
, info
);
1135 given
= (b
[2] << 8) | b
[3];
1137 status
= info
->read_memory_func
1138 ((pc
+ 4) & ~ 0x3, (bfd_byte
*) b
, 4, info
);
1141 info
->memory_error_func (status
, pc
+ 4, info
);
1145 given
|= (b
[0] << 24) | (b
[1] << 16);
1148 given
= (b
[0] << 8) | b
[1] | (b
[2] << 24) | (b
[3] << 16);
1151 given
= (b
[0] << 24) | (b
[1] << 16) | (b
[2] << 8) | (b
[3]);
1154 if (info
->flags
& INSN_HAS_RELOC
)
1155 /* If the instruction has a reloc associated with it, then
1156 the offset field in the instruction will actually be the
1157 addend for the reloc. (We are using REL type relocs).
1158 In such cases, we can ignore the pc when computing
1159 addresses, since the addend is not currently pc-relative. */
1163 status
= print_insn_thumb (pc
, info
, given
);
1165 status
= print_insn_arm (pc
, info
, given
);
1171 print_insn_big_arm (pc
, info
)
1173 struct disassemble_info
* info
;
1175 return print_insn (pc
, info
, false);
1179 print_insn_little_arm (pc
, info
)
1181 struct disassemble_info
* info
;
1183 return print_insn (pc
, info
, true);
1187 print_arm_disassembler_options (FILE * stream
)
1191 fprintf (stream
, _("\n\
1192 The following ARM specific disassembler options are supported for use with\n\
1193 the -M switch:\n"));
1195 for (i
= NUM_ARM_REGNAMES
; i
--;)
1196 fprintf (stream
, " reg-names-%s %*c%s\n",
1198 (int)(14 - strlen (regnames
[i
].name
)), ' ',
1199 regnames
[i
].description
);
1201 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
1202 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");