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)
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"
30 #include "safe-ctype.h"
32 /* FIXME: This shouldn't be done here. */
34 #include "elf/internal.h"
38 #define streq(a,b) (strcmp ((a), (b)) == 0)
42 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
46 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
49 static char * arm_conditional
[] =
50 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
51 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
56 const char * description
;
57 const char * reg_names
[16];
61 static arm_regname regnames
[] =
63 { "raw" , "Select raw register names",
64 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
65 { "gcc", "Select register names used by GCC",
66 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
67 { "std", "Select register names used in ARM's ISA documentation",
68 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
69 { "apcs", "Select register names used in the APCS",
70 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
71 { "atpcs", "Select register names used in the ATPCS",
72 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
73 { "special-atpcs", "Select special register names used in the ATPCS",
74 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
75 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
76 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
77 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
78 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
81 static char * iwmmxt_wwnames
[] =
84 static char * iwmmxt_wwssnames
[] =
85 {"b", "bus", "b", "bss",
86 "h", "hus", "h", "hss",
87 "w", "wus", "w", "wss",
88 "d", "dus", "d", "dss"
91 /* Default to GCC register name set. */
92 static unsigned int regname_selected
= 1;
94 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
95 #define arm_regnames regnames[regname_selected].reg_names
97 static bfd_boolean force_thumb
= FALSE
;
99 static char * arm_fp_const
[] =
100 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
102 static char * arm_shift
[] =
103 {"lsl", "lsr", "asr", "ror"};
105 /* Forward declarations. */
106 static void arm_decode_shift
107 PARAMS ((long, fprintf_ftype
, void *));
108 static int print_insn_arm
109 PARAMS ((bfd_vma
, struct disassemble_info
*, long));
110 static int print_insn_thumb
111 PARAMS ((bfd_vma
, struct disassemble_info
*, long));
112 static void parse_disassembler_options
114 static int print_insn
115 PARAMS ((bfd_vma
, struct disassemble_info
*, bfd_boolean
));
116 static int set_iwmmxt_regnames
119 int get_arm_regname_num_options
121 int set_arm_regname_option
124 PARAMS ((int, const char **, const char **, const char ***));
128 get_arm_regname_num_options ()
130 return NUM_ARM_REGNAMES
;
134 set_arm_regname_option (option
)
137 int old
= regname_selected
;
138 regname_selected
= option
;
143 get_arm_regnames (option
, setname
, setdescription
, register_names
)
145 const char **setname
;
146 const char **setdescription
;
147 const char ***register_names
;
149 *setname
= regnames
[option
].name
;
150 *setdescription
= regnames
[option
].description
;
151 *register_names
= regnames
[option
].reg_names
;
156 arm_decode_shift (given
, func
, stream
)
161 func (stream
, "%s", arm_regnames
[given
& 0xf]);
163 if ((given
& 0xff0) != 0)
165 if ((given
& 0x10) == 0)
167 int amount
= (given
& 0xf80) >> 7;
168 int shift
= (given
& 0x60) >> 5;
174 func (stream
, ", rrx");
181 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
184 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
185 arm_regnames
[(given
& 0xf00) >> 8]);
190 set_iwmmxt_regnames ()
192 const char * setname
;
193 const char * setdesc
;
194 const char ** regnames
;
195 int iwmmxt_regnames
= 0;
196 int num_regnames
= get_arm_regname_num_options ();
198 get_arm_regnames (iwmmxt_regnames
, &setname
,
199 &setdesc
, ®names
);
200 while ((strcmp ("iwmmxt_regnames", setname
))
201 && (iwmmxt_regnames
< num_regnames
))
202 get_arm_regnames (++iwmmxt_regnames
, &setname
, &setdesc
, ®names
);
204 return iwmmxt_regnames
;
207 /* Print one instruction from PC on INFO->STREAM.
208 Return the size of the instruction (always 4 on ARM). */
211 print_insn_arm (pc
, info
, given
)
213 struct disassemble_info
*info
;
216 const struct arm_opcode
*insn
;
217 void *stream
= info
->stream
;
218 fprintf_ftype func
= info
->fprintf_func
;
219 static int iwmmxt_regnames
= 0;
221 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
223 if (insn
->value
== FIRST_IWMMXT_INSN
224 && info
->mach
!= bfd_mach_arm_XScale
225 && info
->mach
!= bfd_mach_arm_iWMMXt
)
226 insn
= insn
+ IWMMXT_INSN_COUNT
;
228 if ((given
& insn
->mask
) == insn
->value
)
232 for (c
= insn
->assembler
; *c
; c
++)
243 if (((given
& 0x000f0000) == 0x000f0000)
244 && ((given
& 0x02000000) == 0))
246 int offset
= given
& 0xfff;
248 func (stream
, "[pc");
250 if (given
& 0x01000000)
252 if ((given
& 0x00800000) == 0)
256 func (stream
, ", #%d]", offset
);
260 /* Cope with the possibility of write-back
261 being used. Probably a very dangerous thing
262 for the programmer to do, but who are we to
264 if (given
& 0x00200000)
270 func (stream
, "], #%d", offset
);
272 /* ie ignore the offset. */
276 func (stream
, "\t; ");
277 info
->print_address_func (offset
, info
);
282 arm_regnames
[(given
>> 16) & 0xf]);
283 if ((given
& 0x01000000) != 0)
285 if ((given
& 0x02000000) == 0)
287 int offset
= given
& 0xfff;
289 func (stream
, ", %s#%d",
290 (((given
& 0x00800000) == 0)
291 ? "-" : ""), offset
);
295 func (stream
, ", %s",
296 (((given
& 0x00800000) == 0)
298 arm_decode_shift (given
, func
, stream
);
302 ((given
& 0x00200000) != 0) ? "!" : "");
306 if ((given
& 0x02000000) == 0)
308 int offset
= given
& 0xfff;
310 func (stream
, "], %s#%d",
311 (((given
& 0x00800000) == 0)
312 ? "-" : ""), offset
);
318 func (stream
, "], %s",
319 (((given
& 0x00800000) == 0)
321 arm_decode_shift (given
, func
, stream
);
328 if ((given
& 0x004f0000) == 0x004f0000)
330 /* PC relative with immediate offset. */
331 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
333 if ((given
& 0x00800000) == 0)
336 func (stream
, "[pc, #%d]\t; ", offset
);
338 (*info
->print_address_func
)
339 (offset
+ pc
+ 8, info
);
344 arm_regnames
[(given
>> 16) & 0xf]);
345 if ((given
& 0x01000000) != 0)
348 if ((given
& 0x00400000) == 0x00400000)
351 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
353 func (stream
, ", %s#%d",
354 (((given
& 0x00800000) == 0)
355 ? "-" : ""), offset
);
360 func (stream
, ", %s%s",
361 (((given
& 0x00800000) == 0)
363 arm_regnames
[given
& 0xf]);
367 ((given
& 0x00200000) != 0) ? "!" : "");
372 if ((given
& 0x00400000) == 0x00400000)
375 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
377 func (stream
, "], %s#%d",
378 (((given
& 0x00800000) == 0)
379 ? "-" : ""), offset
);
386 func (stream
, "], %s%s",
387 (((given
& 0x00800000) == 0)
389 arm_regnames
[given
& 0xf]);
396 (*info
->print_address_func
)
397 (BDISP (given
) * 4 + pc
+ 8, info
);
402 arm_conditional
[(given
>> 28) & 0xf]);
411 for (reg
= 0; reg
< 16; reg
++)
412 if ((given
& (1 << reg
)) != 0)
417 func (stream
, "%s", arm_regnames
[reg
]);
424 if ((given
& 0x02000000) != 0)
426 int rotate
= (given
& 0xf00) >> 7;
427 int immed
= (given
& 0xff);
428 immed
= (((immed
<< (32 - rotate
))
429 | (immed
>> rotate
)) & 0xffffffff);
430 func (stream
, "#%d\t; 0x%x", immed
, immed
);
433 arm_decode_shift (given
, func
, stream
);
437 if ((given
& 0x0000f000) == 0x0000f000)
442 if ((given
& 0x01200000) == 0x00200000)
447 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
448 if ((given
& 0x01000000) != 0)
450 int offset
= given
& 0xff;
452 func (stream
, ", %s#%d]%s",
453 ((given
& 0x00800000) == 0 ? "-" : ""),
455 ((given
& 0x00200000) != 0 ? "!" : ""));
461 int offset
= given
& 0xff;
463 func (stream
, "], %s#%d",
464 ((given
& 0x00800000) == 0 ? "-" : ""),
472 /* Print ARM V5 BLX(1) address: pc+25 bits. */
477 if (given
& 0x00800000)
478 /* Is signed, hi bits should be ones. */
479 offset
= (-1) ^ 0x00ffffff;
481 /* Offset is (SignExtend(offset field)<<2). */
482 offset
+= given
& 0x00ffffff;
484 address
= offset
+ pc
+ 8;
486 if (given
& 0x01000000)
487 /* H bit allows addressing to 2-byte boundaries. */
490 info
->print_address_func (address
, info
);
495 /* Print a Cirrus/DSP shift immediate. */
496 /* Immediates are 7bit signed ints with bits 0..3 in
497 bits 0..3 of opcode and bits 4..6 in bits 5..7
502 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
504 /* Is ``imm'' a negative number? */
508 func (stream
, "%d", imm
);
526 switch (given
& 0x00408000)
543 switch (given
& 0x00080080)
555 func (stream
, _("<illegal precision>"));
560 switch (given
& 0x00408000)
577 switch (given
& 0x60)
593 case '0': case '1': case '2': case '3': case '4':
594 case '5': case '6': case '7': case '8': case '9':
596 int bitstart
= *c
++ - '0';
598 while (*c
>= '0' && *c
<= '9')
599 bitstart
= (bitstart
* 10) + *c
++ - '0';
606 while (*c
>= '0' && *c
<= '9')
607 bitend
= (bitend
* 10) + *c
++ - '0';
618 reg
= given
>> bitstart
;
619 reg
&= (2 << (bitend
- bitstart
)) - 1;
621 func (stream
, "%s", arm_regnames
[reg
]);
628 reg
= given
>> bitstart
;
629 reg
&= (2 << (bitend
- bitstart
)) - 1;
631 func (stream
, "%d", reg
);
638 reg
= given
>> bitstart
;
639 reg
&= (2 << (bitend
- bitstart
)) - 1;
641 func (stream
, "0x%08x", reg
);
643 /* Some SWI instructions have special
645 if ((given
& 0x0fffffff) == 0x0FF00000)
646 func (stream
, "\t; IMB");
647 else if ((given
& 0x0fffffff) == 0x0FF00001)
648 func (stream
, "\t; IMBRange");
655 reg
= given
>> bitstart
;
656 reg
&= (2 << (bitend
- bitstart
)) - 1;
658 func (stream
, "%01x", reg
& 0xf);
665 reg
= given
>> bitstart
;
666 reg
&= (2 << (bitend
- bitstart
)) - 1;
670 arm_fp_const
[reg
& 7]);
672 func (stream
, "f%d", reg
);
680 if (bitstart
!= bitend
)
682 reg
= given
>> bitstart
;
683 reg
&= (2 << (bitend
- bitstart
)) - 1;
684 if (bitend
- bitstart
== 1)
685 func (stream
, "%s", iwmmxt_wwnames
[reg
]);
687 func (stream
, "%s", iwmmxt_wwssnames
[reg
]);
691 reg
= (((given
>> 8) & 0x1) |
692 ((given
>> 22) & 0x1));
693 func (stream
, "%s", iwmmxt_wwnames
[reg
]);
701 int current_regnames
;
703 if (! iwmmxt_regnames
)
704 iwmmxt_regnames
= set_iwmmxt_regnames ();
705 current_regnames
= set_arm_regname_option
708 reg
= given
>> bitstart
;
709 reg
&= (2 << (bitend
- bitstart
)) - 1;
710 func (stream
, "%s", arm_regnames
[reg
]);
711 set_arm_regname_option (current_regnames
);
718 int current_regnames
;
720 if (! iwmmxt_regnames
)
721 iwmmxt_regnames
= set_iwmmxt_regnames ();
722 current_regnames
= set_arm_regname_option
723 (iwmmxt_regnames
+ 1);
725 reg
= given
>> bitstart
;
726 reg
&= (2 << (bitend
- bitstart
)) - 1;
727 func (stream
, "%s", arm_regnames
[reg
]);
728 set_arm_regname_option (current_regnames
);
740 int single
= *c
== 'y';
745 case 4: /* Sm pair */
749 regno
= given
& 0x0000000f;
753 regno
+= (given
>> 5) & 1;
758 regno
= (given
>> 12) & 0x0000000f;
762 regno
+= (given
>> 22) & 1;
767 regno
= (given
>> 16) & 0x0000000f;
771 regno
+= (given
>> 7) & 1;
777 regno
= (given
>> 12) & 0x0000000f;
781 regno
+= (given
>> 22) & 1;
790 func (stream
, "%c%d", single
? 's' : 'd', regno
);
794 int count
= given
& 0xff;
801 func (stream
, "-%c%d",
808 else if (bitstart
== 4)
809 func (stream
, ", %c%d}", single
? 's' : 'd',
817 if ((given
& (1 << bitstart
)) == 0)
818 func (stream
, "%c", *c
);
822 if ((given
& (1 << bitstart
)) != 0)
823 func (stream
, "%c", *c
);
827 if ((given
& (1 << bitstart
)) != 0)
828 func (stream
, "%c", *c
++);
830 func (stream
, "%c", *++c
);
838 switch (given
& 0x00400100)
840 case 0x00000000: func (stream
, "b"); break;
841 case 0x00400000: func (stream
, "h"); break;
842 case 0x00000100: func (stream
, "w"); break;
843 case 0x00400100: func (stream
, "d"); break;
852 /* given (20, 23) | given (0, 3) */
853 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
854 func (stream
, "%d", value
);
859 /* This is like the 'A' operator, except that if
860 the width field "M" is zero, then the offset is
861 *not* multiplied by four. */
863 int offset
= given
& 0xff;
864 int multiplier
= (given
& 0x00000100) ? 4 : 1;
866 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
870 if ((given
& 0x01000000) != 0)
871 func (stream
, ", %s#%d]%s",
872 ((given
& 0x00800000) == 0 ? "-" : ""),
874 ((given
& 0x00200000) != 0 ? "!" : ""));
876 func (stream
, "], %s#%d",
877 ((given
& 0x00800000) == 0 ? "-" : ""),
878 offset
* multiplier
);
891 func (stream
, "%c", *c
);
899 /* Print one instruction from PC on INFO->STREAM.
900 Return the size of the instruction. */
903 print_insn_thumb (pc
, info
, given
)
905 struct disassemble_info
*info
;
908 const struct thumb_opcode
*insn
;
909 void *stream
= info
->stream
;
910 fprintf_ftype func
= info
->fprintf_func
;
912 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
914 if ((given
& insn
->mask
) == insn
->value
)
916 char * c
= insn
->assembler
;
918 /* Special processing for Thumb 2 instruction BL sequence: */
919 if (!*c
) /* Check for empty (not NULL) assembler string. */
923 info
->bytes_per_chunk
= 4;
924 info
->bytes_per_line
= 4;
926 offset
= BDISP23 (given
);
927 offset
= offset
* 2 + pc
+ 4;
929 if ((given
& 0x10000000) == 0)
931 func (stream
, "blx\t");
932 offset
&= 0xfffffffc;
935 func (stream
, "bl\t");
937 info
->print_address_func (offset
, info
);
942 info
->bytes_per_chunk
= 2;
943 info
->bytes_per_line
= 4;
964 reg
= (given
>> 3) & 0x7;
965 if (given
& (1 << 6))
968 func (stream
, "%s", arm_regnames
[reg
]);
977 if (given
& (1 << 7))
980 func (stream
, "%s", arm_regnames
[reg
]);
986 arm_conditional
[(given
>> 8) & 0xf]);
990 if (given
& (1 << 8))
994 if (*c
== 'O' && (given
& (1 << 8)))
1004 /* It would be nice if we could spot
1005 ranges, and generate the rS-rE format: */
1006 for (reg
= 0; (reg
< 8); reg
++)
1007 if ((given
& (1 << reg
)) != 0)
1010 func (stream
, ", ");
1012 func (stream
, "%s", arm_regnames
[reg
]);
1018 func (stream
, ", ");
1020 func (stream
, arm_regnames
[14] /* "lr" */);
1026 func (stream
, ", ");
1027 func (stream
, arm_regnames
[15] /* "pc" */);
1035 case '0': case '1': case '2': case '3': case '4':
1036 case '5': case '6': case '7': case '8': case '9':
1038 int bitstart
= *c
++ - '0';
1041 while (*c
>= '0' && *c
<= '9')
1042 bitstart
= (bitstart
* 10) + *c
++ - '0';
1051 while (*c
>= '0' && *c
<= '9')
1052 bitend
= (bitend
* 10) + *c
++ - '0';
1055 reg
= given
>> bitstart
;
1056 reg
&= (2 << (bitend
- bitstart
)) - 1;
1060 func (stream
, "%s", arm_regnames
[reg
]);
1064 func (stream
, "%d", reg
);
1068 func (stream
, "%d", reg
<< 1);
1072 func (stream
, "%d", reg
<< 2);
1076 /* PC-relative address -- the bottom two
1077 bits of the address are dropped
1078 before the calculation. */
1079 info
->print_address_func
1080 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
1084 func (stream
, "0x%04x", reg
);
1088 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
1089 func (stream
, "%d", reg
);
1093 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
1094 (*info
->print_address_func
)
1095 (reg
* 2 + pc
+ 4, info
);
1106 if ((given
& (1 << bitstart
)) != 0)
1107 func (stream
, "%c", *c
);
1112 if ((given
& (1 << bitstart
)) != 0)
1113 func (stream
, "%c", *c
++);
1115 func (stream
, "%c", *++c
);
1129 func (stream
, "%c", *c
);
1140 /* Parse an individual disassembler option. */
1143 parse_arm_disassembler_option (option
)
1149 if (strneq (option
, "reg-names-", 10))
1155 for (i
= NUM_ARM_REGNAMES
; i
--;)
1156 if (strneq (option
, regnames
[i
].name
, strlen (regnames
[i
].name
)))
1158 regname_selected
= i
;
1163 /* XXX - should break 'option' at following delimiter. */
1164 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
1166 else if (strneq (option
, "force-thumb", 11))
1168 else if (strneq (option
, "no-force-thumb", 14))
1171 /* XXX - should break 'option' at following delimiter. */
1172 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
1177 /* Parse the string of disassembler options, spliting it at whitespaces
1178 or commas. (Whitespace separators supported for backwards compatibility). */
1181 parse_disassembler_options (options
)
1184 if (options
== NULL
)
1189 parse_arm_disassembler_option (options
);
1191 /* Skip forward to next seperator. */
1192 while ((*options
) && (! ISSPACE (*options
)) && (*options
!= ','))
1194 /* Skip forward past seperators. */
1195 while (ISSPACE (*options
) || (*options
== ','))
1200 /* NOTE: There are no checks in these routines that
1201 the relevant number of data bytes exist. */
1204 print_insn (pc
, info
, little
)
1206 struct disassemble_info
* info
;
1214 if (info
->disassembler_options
)
1216 parse_disassembler_options (info
->disassembler_options
);
1218 /* To avoid repeated parsing of these options, we remove them here. */
1219 info
->disassembler_options
= NULL
;
1222 is_thumb
= force_thumb
;
1224 if (!is_thumb
&& info
->symbols
!= NULL
)
1226 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
1228 coff_symbol_type
* cs
;
1230 cs
= coffsymbol (*info
->symbols
);
1231 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
1232 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
1233 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
1234 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
1235 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
1237 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
)
1239 elf_symbol_type
* es
;
1242 es
= *(elf_symbol_type
**)(info
->symbols
);
1243 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
1245 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
1249 info
->bytes_per_chunk
= 4;
1250 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
1254 status
= info
->read_memory_func (pc
, (bfd_byte
*) &b
[0], 4, info
);
1255 if (status
!= 0 && is_thumb
)
1257 info
->bytes_per_chunk
= 2;
1259 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
1265 info
->memory_error_func (status
, pc
, info
);
1269 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
1273 status
= info
->read_memory_func
1274 (pc
& ~ 0x3, (bfd_byte
*) &b
[0], 4, info
);
1277 info
->memory_error_func (status
, pc
, info
);
1285 given
= (b
[2] << 8) | b
[3];
1287 status
= info
->read_memory_func
1288 ((pc
+ 4) & ~ 0x3, (bfd_byte
*) b
, 4, info
);
1291 info
->memory_error_func (status
, pc
+ 4, info
);
1295 given
|= (b
[0] << 24) | (b
[1] << 16);
1298 given
= (b
[0] << 8) | b
[1] | (b
[2] << 24) | (b
[3] << 16);
1301 given
= (b
[0] << 24) | (b
[1] << 16) | (b
[2] << 8) | (b
[3]);
1304 if (info
->flags
& INSN_HAS_RELOC
)
1305 /* If the instruction has a reloc associated with it, then
1306 the offset field in the instruction will actually be the
1307 addend for the reloc. (We are using REL type relocs).
1308 In such cases, we can ignore the pc when computing
1309 addresses, since the addend is not currently pc-relative. */
1313 status
= print_insn_thumb (pc
, info
, given
);
1315 status
= print_insn_arm (pc
, info
, given
);
1321 print_insn_big_arm (pc
, info
)
1323 struct disassemble_info
* info
;
1325 return print_insn (pc
, info
, FALSE
);
1329 print_insn_little_arm (pc
, info
)
1331 struct disassemble_info
* info
;
1333 return print_insn (pc
, info
, TRUE
);
1337 print_arm_disassembler_options (FILE * stream
)
1341 fprintf (stream
, _("\n\
1342 The following ARM specific disassembler options are supported for use with\n\
1343 the -M switch:\n"));
1345 for (i
= NUM_ARM_REGNAMES
; i
--;)
1346 fprintf (stream
, " reg-names-%s %*c%s\n",
1348 (int)(14 - strlen (regnames
[i
].name
)), ' ',
1349 regnames
[i
].description
);
1351 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
1352 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");