1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
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 ()
106 return NUM_ARM_REGNAMES
;
110 set_arm_regname_option (option
)
113 int old
= regname_selected
;
114 regname_selected
= option
;
119 get_arm_regnames (option
, setname
, setdescription
, register_names
)
121 const char **setname
;
122 const char **setdescription
;
123 const char ***register_names
;
125 *setname
= regnames
[option
].name
;
126 *setdescription
= regnames
[option
].description
;
127 *register_names
= regnames
[option
].reg_names
;
132 arm_decode_shift (given
, func
, stream
)
137 func (stream
, "%s", arm_regnames
[given
& 0xf]);
139 if ((given
& 0xff0) != 0)
141 if ((given
& 0x10) == 0)
143 int amount
= (given
& 0xf80) >> 7;
144 int shift
= (given
& 0x60) >> 5;
150 func (stream
, ", rrx");
157 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
160 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
161 arm_regnames
[(given
& 0xf00) >> 8]);
165 /* Print one instruction from PC on INFO->STREAM.
166 Return the size of the instruction (always 4 on ARM). */
169 print_insn_arm (pc
, info
, given
)
171 struct disassemble_info
* info
;
174 struct arm_opcode
* insn
;
175 void * stream
= info
->stream
;
176 fprintf_ftype func
= info
->fprintf_func
;
178 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
180 if ((given
& insn
->mask
) == insn
->value
)
184 for (c
= insn
->assembler
; *c
; c
++)
195 if (((given
& 0x000f0000) == 0x000f0000)
196 && ((given
& 0x02000000) == 0))
198 int offset
= given
& 0xfff;
200 func (stream
, "[pc");
202 if (given
& 0x01000000)
204 if ((given
& 0x00800000) == 0)
208 func (stream
, ", #%d]", offset
);
212 /* Cope with the possibility of write-back
213 being used. Probably a very dangerous thing
214 for the programmer to do, but who are we to
216 if (given
& 0x00200000)
222 func (stream
, "], #%d", offset
);
224 /* ie ignore the offset. */
228 func (stream
, "\t; ");
229 info
->print_address_func (offset
, info
);
234 arm_regnames
[(given
>> 16) & 0xf]);
235 if ((given
& 0x01000000) != 0)
237 if ((given
& 0x02000000) == 0)
239 int offset
= given
& 0xfff;
241 func (stream
, ", %s#%d",
242 (((given
& 0x00800000) == 0)
243 ? "-" : ""), offset
);
247 func (stream
, ", %s",
248 (((given
& 0x00800000) == 0)
250 arm_decode_shift (given
, func
, stream
);
254 ((given
& 0x00200000) != 0) ? "!" : "");
258 if ((given
& 0x02000000) == 0)
260 int offset
= given
& 0xfff;
262 func (stream
, "], %s#%d",
263 (((given
& 0x00800000) == 0)
264 ? "-" : ""), offset
);
270 func (stream
, "], %s",
271 (((given
& 0x00800000) == 0)
273 arm_decode_shift (given
, func
, stream
);
280 if ((given
& 0x004f0000) == 0x004f0000)
282 /* PC relative with immediate offset. */
283 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
285 if ((given
& 0x00800000) == 0)
288 func (stream
, "[pc, #%d]\t; ", offset
);
290 (*info
->print_address_func
)
291 (offset
+ pc
+ 8, info
);
296 arm_regnames
[(given
>> 16) & 0xf]);
297 if ((given
& 0x01000000) != 0)
300 if ((given
& 0x00400000) == 0x00400000)
303 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
305 func (stream
, ", %s#%d",
306 (((given
& 0x00800000) == 0)
307 ? "-" : ""), offset
);
312 func (stream
, ", %s%s",
313 (((given
& 0x00800000) == 0)
315 arm_regnames
[given
& 0xf]);
319 ((given
& 0x00200000) != 0) ? "!" : "");
324 if ((given
& 0x00400000) == 0x00400000)
327 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
329 func (stream
, "], %s#%d",
330 (((given
& 0x00800000) == 0)
331 ? "-" : ""), offset
);
338 func (stream
, "], %s%s",
339 (((given
& 0x00800000) == 0)
341 arm_regnames
[given
& 0xf]);
348 (*info
->print_address_func
)
349 (BDISP (given
) * 4 + pc
+ 8, info
);
354 arm_conditional
[(given
>> 28) & 0xf]);
363 for (reg
= 0; reg
< 16; reg
++)
364 if ((given
& (1 << reg
)) != 0)
369 func (stream
, "%s", arm_regnames
[reg
]);
376 if ((given
& 0x02000000) != 0)
378 int rotate
= (given
& 0xf00) >> 7;
379 int immed
= (given
& 0xff);
380 immed
= (((immed
<< (32 - rotate
))
381 | (immed
>> rotate
)) & 0xffffffff);
382 func (stream
, "#%d\t; 0x%x", immed
, immed
);
385 arm_decode_shift (given
, func
, stream
);
389 if ((given
& 0x0000f000) == 0x0000f000)
394 if ((given
& 0x01200000) == 0x00200000)
399 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
400 if ((given
& 0x01000000) != 0)
402 int offset
= given
& 0xff;
404 func (stream
, ", %s#%d]%s",
405 ((given
& 0x00800000) == 0 ? "-" : ""),
407 ((given
& 0x00200000) != 0 ? "!" : ""));
413 int offset
= given
& 0xff;
415 func (stream
, "], %s#%d",
416 ((given
& 0x00800000) == 0 ? "-" : ""),
424 /* Print ARM V5 BLX(1) address: pc+25 bits. */
429 if (given
& 0x00800000)
430 /* Is signed, hi bits should be ones. */
431 offset
= (-1) ^ 0x00ffffff;
433 /* Offset is (SignExtend(offset field)<<2). */
434 offset
+= given
& 0x00ffffff;
436 address
= offset
+ pc
+ 8;
438 if (given
& 0x01000000)
439 /* H bit allows addressing to 2-byte boundaries. */
442 info
->print_address_func (address
, info
);
447 /* Print a Cirrus/DSP shift immediate. */
448 /* Immediates are 7bit signed ints with bits 0..3 in
449 bits 0..3 of opcode and bits 4..6 in bits 5..7
454 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
456 /* Is ``imm'' a negative number? */
460 func (stream
, "%d", imm
);
478 switch (given
& 0x00408000)
495 switch (given
& 0x00080080)
507 func (stream
, _("<illegal precision>"));
512 switch (given
& 0x00408000)
529 switch (given
& 0x60)
545 case '0': case '1': case '2': case '3': case '4':
546 case '5': case '6': case '7': case '8': case '9':
548 int bitstart
= *c
++ - '0';
550 while (*c
>= '0' && *c
<= '9')
551 bitstart
= (bitstart
* 10) + *c
++ - '0';
558 while (*c
>= '0' && *c
<= '9')
559 bitend
= (bitend
* 10) + *c
++ - '0';
570 reg
= given
>> bitstart
;
571 reg
&= (2 << (bitend
- bitstart
)) - 1;
573 func (stream
, "%s", arm_regnames
[reg
]);
580 reg
= given
>> bitstart
;
581 reg
&= (2 << (bitend
- bitstart
)) - 1;
583 func (stream
, "%d", reg
);
590 reg
= given
>> bitstart
;
591 reg
&= (2 << (bitend
- bitstart
)) - 1;
593 func (stream
, "0x%08x", reg
);
595 /* Some SWI instructions have special
597 if ((given
& 0x0fffffff) == 0x0FF00000)
598 func (stream
, "\t; IMB");
599 else if ((given
& 0x0fffffff) == 0x0FF00001)
600 func (stream
, "\t; IMBRange");
607 reg
= given
>> bitstart
;
608 reg
&= (2 << (bitend
- bitstart
)) - 1;
610 func (stream
, "%01x", reg
& 0xf);
617 reg
= given
>> bitstart
;
618 reg
&= (2 << (bitend
- bitstart
)) - 1;
622 arm_fp_const
[reg
& 7]);
624 func (stream
, "f%d", reg
);
635 int single
= *c
== 'y';
640 case 4: /* Sm pair */
644 regno
= given
& 0x0000000f;
648 regno
+= (given
>> 5) & 1;
653 regno
= (given
>> 12) & 0x0000000f;
657 regno
+= (given
>> 22) & 1;
662 regno
= (given
>> 16) & 0x0000000f;
666 regno
+= (given
>> 7) & 1;
672 regno
= (given
>> 12) & 0x0000000f;
676 regno
+= (given
>> 22) & 1;
685 func (stream
, "%c%d", single
? 's' : 'd', regno
);
689 int count
= given
& 0xff;
696 func (stream
, "-%c%d",
703 else if (bitstart
== 4)
704 func (stream
, ", %c%d}", single
? 's' : 'd',
712 if ((given
& (1 << bitstart
)) == 0)
713 func (stream
, "%c", *c
);
717 if ((given
& (1 << bitstart
)) != 0)
718 func (stream
, "%c", *c
);
722 if ((given
& (1 << bitstart
)) != 0)
723 func (stream
, "%c", *c
++);
725 func (stream
, "%c", *++c
);
738 func (stream
, "%c", *c
);
746 /* Print one instruction from PC on INFO->STREAM.
747 Return the size of the instruction. */
750 print_insn_thumb (pc
, info
, given
)
752 struct disassemble_info
* info
;
755 struct thumb_opcode
* insn
;
756 void * stream
= info
->stream
;
757 fprintf_ftype func
= info
->fprintf_func
;
759 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
761 if ((given
& insn
->mask
) == insn
->value
)
763 char * c
= insn
->assembler
;
765 /* Special processing for Thumb 2 instruction BL sequence: */
766 if (!*c
) /* Check for empty (not NULL) assembler string. */
770 info
->bytes_per_chunk
= 4;
771 info
->bytes_per_line
= 4;
773 offset
= BDISP23 (given
);
774 offset
= offset
* 2 + pc
+ 4;
776 if ((given
& 0x10000000) == 0)
778 func (stream
, "blx\t");
779 offset
&= 0xfffffffc;
782 func (stream
, "bl\t");
784 info
->print_address_func (offset
, info
);
789 info
->bytes_per_chunk
= 2;
790 info
->bytes_per_line
= 4;
811 reg
= (given
>> 3) & 0x7;
812 if (given
& (1 << 6))
815 func (stream
, "%s", arm_regnames
[reg
]);
824 if (given
& (1 << 7))
827 func (stream
, "%s", arm_regnames
[reg
]);
833 arm_conditional
[(given
>> 8) & 0xf]);
837 if (given
& (1 << 8))
841 if (*c
== 'O' && (given
& (1 << 8)))
851 /* It would be nice if we could spot
852 ranges, and generate the rS-rE format: */
853 for (reg
= 0; (reg
< 8); reg
++)
854 if ((given
& (1 << reg
)) != 0)
859 func (stream
, "%s", arm_regnames
[reg
]);
867 func (stream
, arm_regnames
[14] /* "lr" */);
874 func (stream
, arm_regnames
[15] /* "pc" */);
882 case '0': case '1': case '2': case '3': case '4':
883 case '5': case '6': case '7': case '8': case '9':
885 int bitstart
= *c
++ - '0';
888 while (*c
>= '0' && *c
<= '9')
889 bitstart
= (bitstart
* 10) + *c
++ - '0';
898 while (*c
>= '0' && *c
<= '9')
899 bitend
= (bitend
* 10) + *c
++ - '0';
902 reg
= given
>> bitstart
;
903 reg
&= (2 << (bitend
- bitstart
)) - 1;
907 func (stream
, "%s", arm_regnames
[reg
]);
911 func (stream
, "%d", reg
);
915 func (stream
, "%d", reg
<< 1);
919 func (stream
, "%d", reg
<< 2);
923 /* PC-relative address -- the bottom two
924 bits of the address are dropped
925 before the calculation. */
926 info
->print_address_func
927 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
931 func (stream
, "0x%04x", reg
);
935 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
936 func (stream
, "%d", reg
);
940 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
941 (*info
->print_address_func
)
942 (reg
* 2 + pc
+ 4, info
);
953 if ((given
& (1 << bitstart
)) != 0)
954 func (stream
, "%c", *c
);
959 if ((given
& (1 << bitstart
)) != 0)
960 func (stream
, "%c", *c
++);
962 func (stream
, "%c", *++c
);
976 func (stream
, "%c", *c
);
987 /* Parse an individual disassembler option. */
990 parse_arm_disassembler_option (option
)
996 if (strneq (option
, "reg-names-", 10))
1002 for (i
= NUM_ARM_REGNAMES
; i
--;)
1003 if (streq (option
, regnames
[i
].name
))
1005 regname_selected
= i
;
1010 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
1012 else if (streq (option
, "force-thumb"))
1014 else if (streq (option
, "no-force-thumb"))
1017 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
1022 /* Parse the string of disassembler options, spliting it at whitespaces. */
1025 parse_disassembler_options (options
)
1030 if (options
== NULL
)
1035 space
= strchr (options
, ' ');
1040 parse_arm_disassembler_option (options
);
1042 options
= space
+ 1;
1045 parse_arm_disassembler_option (options
);
1050 /* NOTE: There are no checks in these routines that
1051 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");