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)
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 #define WORD_ADDRESS(pc) ((pc) & ~0x3)
51 static char * arm_conditional[] =
52 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
53 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
58 const char * description;
59 const char * reg_names[16];
63 static arm_regname regnames[] =
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"}}
83 static char * iwmmxt_wwnames[] =
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"
93 /* Default to GCC register name set. */
94 static unsigned int regname_selected = 1;
96 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
97 #define arm_regnames regnames[regname_selected].reg_names
99 static bfd_boolean force_thumb = FALSE;
101 static char * arm_fp_const[] =
102 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
104 static char * arm_shift[] =
105 {"lsl", "lsr", "asr", "ror"};
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
116 static int print_insn
117 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
118 static int set_iwmmxt_regnames
121 int get_arm_regname_num_options
123 int set_arm_regname_option
126 PARAMS ((int, const char **, const char **, const char ***));
130 get_arm_regname_num_options ()
132 return NUM_ARM_REGNAMES;
136 set_arm_regname_option (option)
139 int old = regname_selected;
140 regname_selected = option;
145 get_arm_regnames (option, setname, setdescription, register_names)
147 const char **setname;
148 const char **setdescription;
149 const char ***register_names;
151 *setname = regnames[option].name;
152 *setdescription = regnames[option].description;
153 *register_names = regnames[option].reg_names;
158 arm_decode_shift (given, func, stream)
163 func (stream, "%s", arm_regnames[given & 0xf]);
165 if ((given & 0xff0) != 0)
167 if ((given & 0x10) == 0)
169 int amount = (given & 0xf80) >> 7;
170 int shift = (given & 0x60) >> 5;
176 func (stream, ", rrx");
183 func (stream, ", %s #%d", arm_shift[shift], amount);
186 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
187 arm_regnames[(given & 0xf00) >> 8]);
192 set_iwmmxt_regnames ()
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 ();
200 get_arm_regnames (iwmmxt_regnames, &setname,
201 &setdesc, ®names);
202 while ((strcmp ("iwmmxt_regnames", setname))
203 && (iwmmxt_regnames < num_regnames))
204 get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, ®names);
206 return iwmmxt_regnames;
209 /* Print one instruction from PC on INFO->STREAM.
210 Return the size of the instruction (always 4 on ARM). */
213 print_insn_arm (pc, info, given)
215 struct disassemble_info *info;
218 const struct arm_opcode *insn;
219 void *stream = info->stream;
220 fprintf_ftype func = info->fprintf_func;
221 static int iwmmxt_regnames = 0;
223 for (insn = arm_opcodes; insn->assembler; insn++)
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;
230 if ((given & insn->mask) == insn->value)
234 for (c = insn->assembler; *c; c++)
245 if (((given & 0x000f0000) == 0x000f0000)
246 && ((given & 0x02000000) == 0))
248 int offset = given & 0xfff;
250 func (stream, "[pc");
252 if (given & 0x01000000)
254 if ((given & 0x00800000) == 0)
258 func (stream, ", #%d]", offset);
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
266 if (given & 0x00200000)
272 func (stream, "], #%d", offset);
274 /* ie ignore the offset. */
278 func (stream, "\t; ");
279 info->print_address_func (offset, info);
284 arm_regnames[(given >> 16) & 0xf]);
285 if ((given & 0x01000000) != 0)
287 if ((given & 0x02000000) == 0)
289 int offset = given & 0xfff;
291 func (stream, ", #%s%d",
292 (((given & 0x00800000) == 0)
293 ? "-" : ""), offset);
297 func (stream, ", %s",
298 (((given & 0x00800000) == 0)
300 arm_decode_shift (given, func, stream);
304 ((given & 0x00200000) != 0) ? "!" : "");
308 if ((given & 0x02000000) == 0)
310 int offset = given & 0xfff;
312 func (stream, "], #%s%d",
313 (((given & 0x00800000) == 0)
314 ? "-" : ""), offset);
320 func (stream, "], %s",
321 (((given & 0x00800000) == 0)
323 arm_decode_shift (given, func, stream);
330 if ((given & 0x004f0000) == 0x004f0000)
332 /* PC relative with immediate offset. */
333 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
335 if ((given & 0x00800000) == 0)
338 func (stream, "[pc, #%d]\t; ", offset);
340 (*info->print_address_func)
341 (offset + pc + 8, info);
346 arm_regnames[(given >> 16) & 0xf]);
347 if ((given & 0x01000000) != 0)
350 if ((given & 0x00400000) == 0x00400000)
353 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
355 func (stream, ", #%s%d",
356 (((given & 0x00800000) == 0)
357 ? "-" : ""), offset);
362 func (stream, ", %s%s",
363 (((given & 0x00800000) == 0)
365 arm_regnames[given & 0xf]);
369 ((given & 0x00200000) != 0) ? "!" : "");
374 if ((given & 0x00400000) == 0x00400000)
377 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
379 func (stream, "], #%s%d",
380 (((given & 0x00800000) == 0)
381 ? "-" : ""), offset);
388 func (stream, "], %s%s",
389 (((given & 0x00800000) == 0)
391 arm_regnames[given & 0xf]);
398 (*info->print_address_func)
399 (BDISP (given) * 4 + pc + 8, info);
404 arm_conditional [(given >> 28) & 0xf]);
413 for (reg = 0; reg < 16; reg++)
414 if ((given & (1 << reg)) != 0)
419 func (stream, "%s", arm_regnames[reg]);
426 if ((given & 0x02000000) != 0)
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);
435 arm_decode_shift (given, func, stream);
439 if ((given & 0x0000f000) == 0x0000f000)
444 if ((given & 0x01200000) == 0x00200000)
449 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
451 if ((given & (1 << 24)) != 0)
453 int offset = given & 0xff;
456 func (stream, ", #%s%d]%s",
457 ((given & 0x00800000) == 0 ? "-" : ""),
459 ((given & 0x00200000) != 0 ? "!" : ""));
465 int offset = given & 0xff;
469 if (given & (1 << 21))
472 func (stream, ", #%s%d",
473 ((given & 0x00800000) == 0 ? "-" : ""),
477 func (stream, ", {%d}", offset);
482 /* Print ARM V5 BLX(1) address: pc+25 bits. */
487 if (given & 0x00800000)
488 /* Is signed, hi bits should be ones. */
489 offset = (-1) ^ 0x00ffffff;
491 /* Offset is (SignExtend(offset field)<<2). */
492 offset += given & 0x00ffffff;
494 address = offset + pc + 8;
496 if (given & 0x01000000)
497 /* H bit allows addressing to 2-byte boundaries. */
500 info->print_address_func (address, info);
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
512 imm = (given & 0xf) | ((given & 0xe0) >> 1);
514 /* Is ``imm'' a negative number? */
518 func (stream, "%d", imm);
536 switch (given & 0x00408000)
553 switch (given & 0x00080080)
565 func (stream, _("<illegal precision>"));
570 switch (given & 0x00408000)
587 switch (given & 0x60)
603 case '0': case '1': case '2': case '3': case '4':
604 case '5': case '6': case '7': case '8': case '9':
606 int bitstart = *c++ - '0';
608 while (*c >= '0' && *c <= '9')
609 bitstart = (bitstart * 10) + *c++ - '0';
616 while (*c >= '0' && *c <= '9')
617 bitend = (bitend * 10) + *c++ - '0';
628 reg = given >> bitstart;
629 reg &= (2 << (bitend - bitstart)) - 1;
631 func (stream, "%s", arm_regnames[reg]);
638 reg = given >> bitstart;
639 reg &= (2 << (bitend - bitstart)) - 1;
641 func (stream, "%d", reg);
648 reg = given >> bitstart;
649 reg &= (2 << (bitend - bitstart)) - 1;
651 func (stream, "%d", reg + 1);
658 reg = given >> bitstart;
659 reg &= (2 << (bitend - bitstart)) - 1;
661 func (stream, "0x%08x", reg);
663 /* Some SWI instructions have special
665 if ((given & 0x0fffffff) == 0x0FF00000)
666 func (stream, "\t; IMB");
667 else if ((given & 0x0fffffff) == 0x0FF00001)
668 func (stream, "\t; IMBRange");
675 reg = given >> bitstart;
676 reg &= (2 << (bitend - bitstart)) - 1;
678 func (stream, "%01x", reg & 0xf);
685 reg = given >> bitstart;
686 reg &= (2 << (bitend - bitstart)) - 1;
690 arm_fp_const[reg & 7]);
692 func (stream, "f%d", reg);
700 if (bitstart != bitend)
702 reg = given >> bitstart;
703 reg &= (2 << (bitend - bitstart)) - 1;
704 if (bitend - bitstart == 1)
705 func (stream, "%s", iwmmxt_wwnames[reg]);
707 func (stream, "%s", iwmmxt_wwssnames[reg]);
711 reg = (((given >> 8) & 0x1) |
712 ((given >> 22) & 0x1));
713 func (stream, "%s", iwmmxt_wwnames[reg]);
721 int current_regnames;
723 if (! iwmmxt_regnames)
724 iwmmxt_regnames = set_iwmmxt_regnames ();
725 current_regnames = set_arm_regname_option
728 reg = given >> bitstart;
729 reg &= (2 << (bitend - bitstart)) - 1;
730 func (stream, "%s", arm_regnames[reg]);
731 set_arm_regname_option (current_regnames);
738 int current_regnames;
740 if (! iwmmxt_regnames)
741 iwmmxt_regnames = set_iwmmxt_regnames ();
742 current_regnames = set_arm_regname_option
743 (iwmmxt_regnames + 1);
745 reg = given >> bitstart;
746 reg &= (2 << (bitend - bitstart)) - 1;
747 func (stream, "%s", arm_regnames[reg]);
748 set_arm_regname_option (current_regnames);
760 int single = *c == 'y';
765 case 4: /* Sm pair */
769 regno = given & 0x0000000f;
773 regno += (given >> 5) & 1;
778 regno = (given >> 12) & 0x0000000f;
782 regno += (given >> 22) & 1;
787 regno = (given >> 16) & 0x0000000f;
791 regno += (given >> 7) & 1;
797 regno = (given >> 12) & 0x0000000f;
801 regno += (given >> 22) & 1;
810 func (stream, "%c%d", single ? 's' : 'd', regno);
814 int count = given & 0xff;
821 func (stream, "-%c%d",
828 else if (bitstart == 4)
829 func (stream, ", %c%d}", single ? 's' : 'd',
837 if ((given & (1 << bitstart)) == 0)
838 func (stream, "%c", *c);
842 if ((given & (1 << bitstart)) != 0)
843 func (stream, "%c", *c);
847 if ((given & (1 << bitstart)) != 0)
848 func (stream, "%c", *c++);
850 func (stream, "%c", *++c);
858 switch (given & 0x00400100)
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;
872 /* given (20, 23) | given (0, 3) */
873 value = ((given >> 16) & 0xf0) | (given & 0xf);
874 func (stream, "%d", value);
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. */
883 int offset = given & 0xff;
884 int multiplier = (given & 0x00000100) ? 4 : 1;
886 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
890 if ((given & 0x01000000) != 0)
891 func (stream, ", #%s%d]%s",
892 ((given & 0x00800000) == 0 ? "-" : ""),
894 ((given & 0x00200000) != 0 ? "!" : ""));
896 func (stream, "], #%s%d",
897 ((given & 0x00800000) == 0 ? "-" : ""),
898 offset * multiplier);
909 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
910 func (stream, "%d", imm);
920 func (stream, "%c", *c);
928 /* Print one instruction from PC on INFO->STREAM.
929 Return the size of the instruction. */
932 print_insn_thumb (pc, info, given)
934 struct disassemble_info *info;
937 const struct thumb_opcode *insn;
938 void *stream = info->stream;
939 fprintf_ftype func = info->fprintf_func;
941 for (insn = thumb_opcodes; insn->assembler; insn++)
943 if ((given & insn->mask) == insn->value)
945 char * c = insn->assembler;
947 /* Special processing for Thumb 2 instruction BL sequence: */
948 if (!*c) /* Check for empty (not NULL) assembler string. */
952 info->bytes_per_chunk = 4;
953 info->bytes_per_line = 4;
955 offset = BDISP23 (given);
956 offset = offset * 2 + pc + 4;
958 if ((given & 0x10000000) == 0)
960 func (stream, "blx\t");
961 offset &= 0xfffffffc;
964 func (stream, "bl\t");
966 info->print_address_func (offset, info);
971 info->bytes_per_chunk = 2;
972 info->bytes_per_line = 4;
993 reg = (given >> 3) & 0x7;
994 if (given & (1 << 6))
997 func (stream, "%s", arm_regnames[reg]);
1006 if (given & (1 << 7))
1009 func (stream, "%s", arm_regnames[reg]);
1015 arm_conditional [(given >> 8) & 0xf]);
1019 if (given & (1 << 8))
1023 if (*c == 'O' && (given & (1 << 8)))
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)
1039 func (stream, ", ");
1041 func (stream, "%s", arm_regnames[reg]);
1047 func (stream, ", ");
1049 func (stream, arm_regnames[14] /* "lr" */);
1055 func (stream, ", ");
1056 func (stream, arm_regnames[15] /* "pc" */);
1064 case '0': case '1': case '2': case '3': case '4':
1065 case '5': case '6': case '7': case '8': case '9':
1067 int bitstart = *c++ - '0';
1070 while (*c >= '0' && *c <= '9')
1071 bitstart = (bitstart * 10) + *c++ - '0';
1080 while (*c >= '0' && *c <= '9')
1081 bitend = (bitend * 10) + *c++ - '0';
1084 reg = given >> bitstart;
1085 reg &= (2 << (bitend - bitstart)) - 1;
1089 func (stream, "%s", arm_regnames[reg]);
1093 func (stream, "%d", reg);
1097 func (stream, "%d", reg << 1);
1101 func (stream, "%d", reg << 2);
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);
1113 func (stream, "0x%04x", reg);
1117 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1118 func (stream, "%d", reg);
1122 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1123 (*info->print_address_func)
1124 (reg * 2 + pc + 4, info);
1135 if ((given & (1 << bitstart)) != 0)
1136 func (stream, "%c", *c);
1141 if ((given & (1 << bitstart)) != 0)
1142 func (stream, "%c", *c++);
1144 func (stream, "%c", *++c);
1158 func (stream, "%c", *c);
1169 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
1170 being displayed in symbol relative addresses. */
1173 arm_symbol_is_valid (asymbol * sym,
1174 struct disassemble_info * info ATTRIBUTE_UNUSED)
1181 name = bfd_asymbol_name (sym);
1183 return (name && *name != '$');
1186 /* Parse an individual disassembler option. */
1189 parse_arm_disassembler_option (option)
1195 if (strneq (option, "reg-names-", 10))
1201 for (i = NUM_ARM_REGNAMES; i--;)
1202 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1204 regname_selected = i;
1209 /* XXX - should break 'option' at following delimiter. */
1210 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1212 else if (strneq (option, "force-thumb", 11))
1214 else if (strneq (option, "no-force-thumb", 14))
1217 /* XXX - should break 'option' at following delimiter. */
1218 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1223 /* Parse the string of disassembler options, spliting it at whitespaces
1224 or commas. (Whitespace separators supported for backwards compatibility). */
1227 parse_disassembler_options (options)
1230 if (options == NULL)
1235 parse_arm_disassembler_option (options);
1237 /* Skip forward to next seperator. */
1238 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1240 /* Skip forward past seperators. */
1241 while (ISSPACE (*options) || (*options == ','))
1246 /* NOTE: There are no checks in these routines that
1247 the relevant number of data bytes exist. */
1250 print_insn (pc, info, little)
1252 struct disassemble_info * info;
1258 int is_thumb, second_half_valid = 1;
1260 if (info->disassembler_options)
1262 parse_disassembler_options (info->disassembler_options);
1264 /* To avoid repeated parsing of these options, we remove them here. */
1265 info->disassembler_options = NULL;
1268 is_thumb = force_thumb;
1270 if (!is_thumb && info->symbols != NULL)
1272 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1274 coff_symbol_type * cs;
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);
1283 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1285 elf_symbol_type * es;
1288 es = *(elf_symbol_type **)(info->symbols);
1289 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1291 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1295 info->bytes_per_chunk = 4;
1296 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1300 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1301 if (status != 0 && is_thumb)
1303 info->bytes_per_chunk = 2;
1304 second_half_valid = 0;
1306 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1312 info->memory_error_func (status, pc, info);
1316 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1320 status = info->read_memory_func
1321 (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info);
1324 info->memory_error_func (status, WORD_ADDRESS (pc), info);
1332 given = (b[2] << 8) | b[3];
1334 status = info->read_memory_func
1335 (WORD_ADDRESS (pc + 4), (bfd_byte *) b, 4, info);
1337 second_half_valid = 0;
1339 given |= (b[0] << 24) | (b[1] << 16);
1342 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1345 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
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. */
1357 status = print_insn_thumb (pc, info, given);
1359 status = print_insn_arm (pc, info, given);
1361 if (is_thumb && status == 4 && second_half_valid == 0)
1363 info->memory_error_func (status, WORD_ADDRESS (pc + 4), info);
1371 print_insn_big_arm (pc, info)
1373 struct disassemble_info * info;
1375 return print_insn (pc, info, FALSE);
1379 print_insn_little_arm (pc, info)
1381 struct disassemble_info * info;
1383 return print_insn (pc, info, TRUE);
1387 print_arm_disassembler_options (FILE * stream)
1391 fprintf (stream, _("\n\
1392 The following ARM specific disassembler options are supported for use with\n\
1393 the -M switch:\n"));
1395 for (i = NUM_ARM_REGNAMES; i--;)
1396 fprintf (stream, " reg-names-%s %*c%s\n",
1398 (int)(14 - strlen (regnames[i].name)), ' ',
1399 regnames[i].description);
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");