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"
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" }},
74 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
75 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
76 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
77 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
80 static char * iwmmxt_wwnames
[] =
83 static char * iwmmxt_wwssnames
[] =
84 {"b", "bus", "b", "bss",
85 "h", "hus", "h", "hss",
86 "w", "wus", "w", "wss",
87 "d", "dus", "d", "dss"
90 /* Default to GCC register name set. */
91 static unsigned int regname_selected
= 1;
93 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
94 #define arm_regnames regnames[regname_selected].reg_names
96 static bfd_boolean force_thumb
= FALSE
;
98 static char * arm_fp_const
[] =
99 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
101 static char * arm_shift
[] =
102 {"lsl", "lsr", "asr", "ror"};
104 /* Forward declarations. */
105 static void arm_decode_shift
106 PARAMS ((long, fprintf_ftype
, void *));
107 static int print_insn_arm
108 PARAMS ((bfd_vma
, struct disassemble_info
*, long));
109 static int print_insn_thumb
110 PARAMS ((bfd_vma
, struct disassemble_info
*, long));
111 static void parse_disassembler_options
113 static int print_insn
114 PARAMS ((bfd_vma
, struct disassemble_info
*, bfd_boolean
));
115 static int set_iwmmxt_regnames
118 int get_arm_regname_num_options
120 int set_arm_regname_option
123 PARAMS ((int, const char **, const char **, const char ***));
127 get_arm_regname_num_options ()
129 return NUM_ARM_REGNAMES
;
133 set_arm_regname_option (option
)
136 int old
= regname_selected
;
137 regname_selected
= option
;
142 get_arm_regnames (option
, setname
, setdescription
, register_names
)
144 const char **setname
;
145 const char **setdescription
;
146 const char ***register_names
;
148 *setname
= regnames
[option
].name
;
149 *setdescription
= regnames
[option
].description
;
150 *register_names
= regnames
[option
].reg_names
;
155 arm_decode_shift (given
, func
, stream
)
160 func (stream
, "%s", arm_regnames
[given
& 0xf]);
162 if ((given
& 0xff0) != 0)
164 if ((given
& 0x10) == 0)
166 int amount
= (given
& 0xf80) >> 7;
167 int shift
= (given
& 0x60) >> 5;
173 func (stream
, ", rrx");
180 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
183 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
184 arm_regnames
[(given
& 0xf00) >> 8]);
189 set_iwmmxt_regnames ()
191 const char * setname
;
192 const char * setdesc
;
193 const char ** regnames
;
194 int iwmmxt_regnames
= 0;
195 int num_regnames
= get_arm_regname_num_options ();
197 get_arm_regnames (iwmmxt_regnames
, &setname
,
198 &setdesc
, ®names
);
199 while ((strcmp ("iwmmxt_regnames", setname
))
200 && (iwmmxt_regnames
< num_regnames
))
201 get_arm_regnames (++iwmmxt_regnames
, &setname
, &setdesc
, ®names
);
203 return iwmmxt_regnames
;
206 /* Print one instruction from PC on INFO->STREAM.
207 Return the size of the instruction (always 4 on ARM). */
210 print_insn_arm (pc
, info
, given
)
212 struct disassemble_info
*info
;
215 const struct arm_opcode
*insn
;
216 void *stream
= info
->stream
;
217 fprintf_ftype func
= info
->fprintf_func
;
218 static int iwmmxt_regnames
= 0;
220 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
222 if (insn
->value
== FIRST_IWMMXT_INSN
223 && info
->mach
!= bfd_mach_arm_XScale
224 && info
->mach
!= bfd_mach_arm_iWMMXt
)
225 insn
= insn
+ IWMMXT_INSN_COUNT
;
227 if ((given
& insn
->mask
) == insn
->value
)
231 for (c
= insn
->assembler
; *c
; c
++)
242 if (((given
& 0x000f0000) == 0x000f0000)
243 && ((given
& 0x02000000) == 0))
245 int offset
= given
& 0xfff;
247 func (stream
, "[pc");
249 if (given
& 0x01000000)
251 if ((given
& 0x00800000) == 0)
255 func (stream
, ", #%d]", offset
);
259 /* Cope with the possibility of write-back
260 being used. Probably a very dangerous thing
261 for the programmer to do, but who are we to
263 if (given
& 0x00200000)
269 func (stream
, "], #%d", offset
);
271 /* ie ignore the offset. */
275 func (stream
, "\t; ");
276 info
->print_address_func (offset
, info
);
281 arm_regnames
[(given
>> 16) & 0xf]);
282 if ((given
& 0x01000000) != 0)
284 if ((given
& 0x02000000) == 0)
286 int offset
= given
& 0xfff;
288 func (stream
, ", %s#%d",
289 (((given
& 0x00800000) == 0)
290 ? "-" : ""), offset
);
294 func (stream
, ", %s",
295 (((given
& 0x00800000) == 0)
297 arm_decode_shift (given
, func
, stream
);
301 ((given
& 0x00200000) != 0) ? "!" : "");
305 if ((given
& 0x02000000) == 0)
307 int offset
= given
& 0xfff;
309 func (stream
, "], %s#%d",
310 (((given
& 0x00800000) == 0)
311 ? "-" : ""), offset
);
317 func (stream
, "], %s",
318 (((given
& 0x00800000) == 0)
320 arm_decode_shift (given
, func
, stream
);
327 if ((given
& 0x004f0000) == 0x004f0000)
329 /* PC relative with immediate offset. */
330 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
332 if ((given
& 0x00800000) == 0)
335 func (stream
, "[pc, #%d]\t; ", offset
);
337 (*info
->print_address_func
)
338 (offset
+ pc
+ 8, info
);
343 arm_regnames
[(given
>> 16) & 0xf]);
344 if ((given
& 0x01000000) != 0)
347 if ((given
& 0x00400000) == 0x00400000)
350 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
352 func (stream
, ", %s#%d",
353 (((given
& 0x00800000) == 0)
354 ? "-" : ""), offset
);
359 func (stream
, ", %s%s",
360 (((given
& 0x00800000) == 0)
362 arm_regnames
[given
& 0xf]);
366 ((given
& 0x00200000) != 0) ? "!" : "");
371 if ((given
& 0x00400000) == 0x00400000)
374 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
376 func (stream
, "], %s#%d",
377 (((given
& 0x00800000) == 0)
378 ? "-" : ""), offset
);
385 func (stream
, "], %s%s",
386 (((given
& 0x00800000) == 0)
388 arm_regnames
[given
& 0xf]);
395 (*info
->print_address_func
)
396 (BDISP (given
) * 4 + pc
+ 8, info
);
401 arm_conditional
[(given
>> 28) & 0xf]);
410 for (reg
= 0; reg
< 16; reg
++)
411 if ((given
& (1 << reg
)) != 0)
416 func (stream
, "%s", arm_regnames
[reg
]);
423 if ((given
& 0x02000000) != 0)
425 int rotate
= (given
& 0xf00) >> 7;
426 int immed
= (given
& 0xff);
427 immed
= (((immed
<< (32 - rotate
))
428 | (immed
>> rotate
)) & 0xffffffff);
429 func (stream
, "#%d\t; 0x%x", immed
, immed
);
432 arm_decode_shift (given
, func
, stream
);
436 if ((given
& 0x0000f000) == 0x0000f000)
441 if ((given
& 0x01200000) == 0x00200000)
446 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
447 if ((given
& 0x01000000) != 0)
449 int offset
= given
& 0xff;
451 func (stream
, ", %s#%d]%s",
452 ((given
& 0x00800000) == 0 ? "-" : ""),
454 ((given
& 0x00200000) != 0 ? "!" : ""));
460 int offset
= given
& 0xff;
462 func (stream
, "], %s#%d",
463 ((given
& 0x00800000) == 0 ? "-" : ""),
471 /* Print ARM V5 BLX(1) address: pc+25 bits. */
476 if (given
& 0x00800000)
477 /* Is signed, hi bits should be ones. */
478 offset
= (-1) ^ 0x00ffffff;
480 /* Offset is (SignExtend(offset field)<<2). */
481 offset
+= given
& 0x00ffffff;
483 address
= offset
+ pc
+ 8;
485 if (given
& 0x01000000)
486 /* H bit allows addressing to 2-byte boundaries. */
489 info
->print_address_func (address
, info
);
494 /* Print a Cirrus/DSP shift immediate. */
495 /* Immediates are 7bit signed ints with bits 0..3 in
496 bits 0..3 of opcode and bits 4..6 in bits 5..7
501 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
503 /* Is ``imm'' a negative number? */
507 func (stream
, "%d", imm
);
525 switch (given
& 0x00408000)
542 switch (given
& 0x00080080)
554 func (stream
, _("<illegal precision>"));
559 switch (given
& 0x00408000)
576 switch (given
& 0x60)
592 case '0': case '1': case '2': case '3': case '4':
593 case '5': case '6': case '7': case '8': case '9':
595 int bitstart
= *c
++ - '0';
597 while (*c
>= '0' && *c
<= '9')
598 bitstart
= (bitstart
* 10) + *c
++ - '0';
605 while (*c
>= '0' && *c
<= '9')
606 bitend
= (bitend
* 10) + *c
++ - '0';
617 reg
= given
>> bitstart
;
618 reg
&= (2 << (bitend
- bitstart
)) - 1;
620 func (stream
, "%s", arm_regnames
[reg
]);
627 reg
= given
>> bitstart
;
628 reg
&= (2 << (bitend
- bitstart
)) - 1;
630 func (stream
, "%d", reg
);
637 reg
= given
>> bitstart
;
638 reg
&= (2 << (bitend
- bitstart
)) - 1;
640 func (stream
, "0x%08x", reg
);
642 /* Some SWI instructions have special
644 if ((given
& 0x0fffffff) == 0x0FF00000)
645 func (stream
, "\t; IMB");
646 else if ((given
& 0x0fffffff) == 0x0FF00001)
647 func (stream
, "\t; IMBRange");
654 reg
= given
>> bitstart
;
655 reg
&= (2 << (bitend
- bitstart
)) - 1;
657 func (stream
, "%01x", reg
& 0xf);
664 reg
= given
>> bitstart
;
665 reg
&= (2 << (bitend
- bitstart
)) - 1;
669 arm_fp_const
[reg
& 7]);
671 func (stream
, "f%d", reg
);
679 if (bitstart
!= bitend
)
681 reg
= given
>> bitstart
;
682 reg
&= (2 << (bitend
- bitstart
)) - 1;
683 if (bitend
- bitstart
== 1)
684 func (stream
, "%s", iwmmxt_wwnames
[reg
]);
686 func (stream
, "%s", iwmmxt_wwssnames
[reg
]);
690 reg
= (((given
>> 8) & 0x1) |
691 ((given
>> 22) & 0x1));
692 func (stream
, "%s", iwmmxt_wwnames
[reg
]);
700 int current_regnames
;
702 if (! iwmmxt_regnames
)
703 iwmmxt_regnames
= set_iwmmxt_regnames ();
704 current_regnames
= set_arm_regname_option
707 reg
= given
>> bitstart
;
708 reg
&= (2 << (bitend
- bitstart
)) - 1;
709 func (stream
, "%s", arm_regnames
[reg
]);
710 set_arm_regname_option (current_regnames
);
717 int current_regnames
;
719 if (! iwmmxt_regnames
)
720 iwmmxt_regnames
= set_iwmmxt_regnames ();
721 current_regnames
= set_arm_regname_option
722 (iwmmxt_regnames
+ 1);
724 reg
= given
>> bitstart
;
725 reg
&= (2 << (bitend
- bitstart
)) - 1;
726 func (stream
, "%s", arm_regnames
[reg
]);
727 set_arm_regname_option (current_regnames
);
739 int single
= *c
== 'y';
744 case 4: /* Sm pair */
748 regno
= given
& 0x0000000f;
752 regno
+= (given
>> 5) & 1;
757 regno
= (given
>> 12) & 0x0000000f;
761 regno
+= (given
>> 22) & 1;
766 regno
= (given
>> 16) & 0x0000000f;
770 regno
+= (given
>> 7) & 1;
776 regno
= (given
>> 12) & 0x0000000f;
780 regno
+= (given
>> 22) & 1;
789 func (stream
, "%c%d", single
? 's' : 'd', regno
);
793 int count
= given
& 0xff;
800 func (stream
, "-%c%d",
807 else if (bitstart
== 4)
808 func (stream
, ", %c%d}", single
? 's' : 'd',
816 if ((given
& (1 << bitstart
)) == 0)
817 func (stream
, "%c", *c
);
821 if ((given
& (1 << bitstart
)) != 0)
822 func (stream
, "%c", *c
);
826 if ((given
& (1 << bitstart
)) != 0)
827 func (stream
, "%c", *c
++);
829 func (stream
, "%c", *++c
);
837 switch (given
& 0x00400100)
839 case 0x00000000: func (stream
, "b"); break;
840 case 0x00400000: func (stream
, "h"); break;
841 case 0x00000100: func (stream
, "w"); break;
842 case 0x00400100: func (stream
, "d"); break;
851 /* given (20, 23) | given (0, 3) */
852 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
853 func (stream
, "%d", value
);
858 /* This is like the 'A' operator, except that if
859 the width field "M" is zero, then the offset is
860 *not* multiplied by four. */
862 int offset
= given
& 0xff;
863 int multiplier
= (given
& 0x00000100) ? 4 : 1;
865 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
869 if ((given
& 0x01000000) != 0)
870 func (stream
, ", %s#%d]%s",
871 ((given
& 0x00800000) == 0 ? "-" : ""),
873 ((given
& 0x00200000) != 0 ? "!" : ""));
875 func (stream
, "], %s#%d",
876 ((given
& 0x00800000) == 0 ? "-" : ""),
877 offset
* multiplier
);
890 func (stream
, "%c", *c
);
898 /* Print one instruction from PC on INFO->STREAM.
899 Return the size of the instruction. */
902 print_insn_thumb (pc
, info
, given
)
904 struct disassemble_info
*info
;
907 const struct thumb_opcode
*insn
;
908 void *stream
= info
->stream
;
909 fprintf_ftype func
= info
->fprintf_func
;
911 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
913 if ((given
& insn
->mask
) == insn
->value
)
915 char * c
= insn
->assembler
;
917 /* Special processing for Thumb 2 instruction BL sequence: */
918 if (!*c
) /* Check for empty (not NULL) assembler string. */
922 info
->bytes_per_chunk
= 4;
923 info
->bytes_per_line
= 4;
925 offset
= BDISP23 (given
);
926 offset
= offset
* 2 + pc
+ 4;
928 if ((given
& 0x10000000) == 0)
930 func (stream
, "blx\t");
931 offset
&= 0xfffffffc;
934 func (stream
, "bl\t");
936 info
->print_address_func (offset
, info
);
941 info
->bytes_per_chunk
= 2;
942 info
->bytes_per_line
= 4;
963 reg
= (given
>> 3) & 0x7;
964 if (given
& (1 << 6))
967 func (stream
, "%s", arm_regnames
[reg
]);
976 if (given
& (1 << 7))
979 func (stream
, "%s", arm_regnames
[reg
]);
985 arm_conditional
[(given
>> 8) & 0xf]);
989 if (given
& (1 << 8))
993 if (*c
== 'O' && (given
& (1 << 8)))
1003 /* It would be nice if we could spot
1004 ranges, and generate the rS-rE format: */
1005 for (reg
= 0; (reg
< 8); reg
++)
1006 if ((given
& (1 << reg
)) != 0)
1009 func (stream
, ", ");
1011 func (stream
, "%s", arm_regnames
[reg
]);
1017 func (stream
, ", ");
1019 func (stream
, arm_regnames
[14] /* "lr" */);
1025 func (stream
, ", ");
1026 func (stream
, arm_regnames
[15] /* "pc" */);
1034 case '0': case '1': case '2': case '3': case '4':
1035 case '5': case '6': case '7': case '8': case '9':
1037 int bitstart
= *c
++ - '0';
1040 while (*c
>= '0' && *c
<= '9')
1041 bitstart
= (bitstart
* 10) + *c
++ - '0';
1050 while (*c
>= '0' && *c
<= '9')
1051 bitend
= (bitend
* 10) + *c
++ - '0';
1054 reg
= given
>> bitstart
;
1055 reg
&= (2 << (bitend
- bitstart
)) - 1;
1059 func (stream
, "%s", arm_regnames
[reg
]);
1063 func (stream
, "%d", reg
);
1067 func (stream
, "%d", reg
<< 1);
1071 func (stream
, "%d", reg
<< 2);
1075 /* PC-relative address -- the bottom two
1076 bits of the address are dropped
1077 before the calculation. */
1078 info
->print_address_func
1079 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
1083 func (stream
, "0x%04x", reg
);
1087 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
1088 func (stream
, "%d", reg
);
1092 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
1093 (*info
->print_address_func
)
1094 (reg
* 2 + pc
+ 4, info
);
1105 if ((given
& (1 << bitstart
)) != 0)
1106 func (stream
, "%c", *c
);
1111 if ((given
& (1 << bitstart
)) != 0)
1112 func (stream
, "%c", *c
++);
1114 func (stream
, "%c", *++c
);
1128 func (stream
, "%c", *c
);
1139 /* Parse an individual disassembler option. */
1142 parse_arm_disassembler_option (option
)
1148 if (strneq (option
, "reg-names-", 10))
1154 for (i
= NUM_ARM_REGNAMES
; i
--;)
1155 if (streq (option
, regnames
[i
].name
))
1157 regname_selected
= i
;
1162 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
1164 else if (streq (option
, "force-thumb"))
1166 else if (streq (option
, "no-force-thumb"))
1169 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
1174 /* Parse the string of disassembler options, spliting it at whitespaces. */
1177 parse_disassembler_options (options
)
1182 if (options
== NULL
)
1187 space
= strchr (options
, ' ');
1192 parse_arm_disassembler_option (options
);
1194 options
= space
+ 1;
1197 parse_arm_disassembler_option (options
);
1202 /* NOTE: There are no checks in these routines that
1203 the relevant number of data bytes exist. */
1206 print_insn (pc
, info
, little
)
1208 struct disassemble_info
* info
;
1216 if (info
->disassembler_options
)
1218 parse_disassembler_options (info
->disassembler_options
);
1220 /* To avoid repeated parsing of these options, we remove them here. */
1221 info
->disassembler_options
= NULL
;
1224 is_thumb
= force_thumb
;
1226 if (!is_thumb
&& info
->symbols
!= NULL
)
1228 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
1230 coff_symbol_type
* cs
;
1232 cs
= coffsymbol (*info
->symbols
);
1233 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
1234 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
1235 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
1236 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
1237 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
1239 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
)
1241 elf_symbol_type
* es
;
1244 es
= *(elf_symbol_type
**)(info
->symbols
);
1245 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
1247 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
1251 info
->bytes_per_chunk
= 4;
1252 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
1256 status
= info
->read_memory_func (pc
, (bfd_byte
*) &b
[0], 4, info
);
1257 if (status
!= 0 && is_thumb
)
1259 info
->bytes_per_chunk
= 2;
1261 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
1267 info
->memory_error_func (status
, pc
, info
);
1271 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
1275 status
= info
->read_memory_func
1276 (pc
& ~ 0x3, (bfd_byte
*) &b
[0], 4, info
);
1279 info
->memory_error_func (status
, pc
, info
);
1287 given
= (b
[2] << 8) | b
[3];
1289 status
= info
->read_memory_func
1290 ((pc
+ 4) & ~ 0x3, (bfd_byte
*) b
, 4, info
);
1293 info
->memory_error_func (status
, pc
+ 4, info
);
1297 given
|= (b
[0] << 24) | (b
[1] << 16);
1300 given
= (b
[0] << 8) | b
[1] | (b
[2] << 24) | (b
[3] << 16);
1303 given
= (b
[0] << 24) | (b
[1] << 16) | (b
[2] << 8) | (b
[3]);
1306 if (info
->flags
& INSN_HAS_RELOC
)
1307 /* If the instruction has a reloc associated with it, then
1308 the offset field in the instruction will actually be the
1309 addend for the reloc. (We are using REL type relocs).
1310 In such cases, we can ignore the pc when computing
1311 addresses, since the addend is not currently pc-relative. */
1315 status
= print_insn_thumb (pc
, info
, given
);
1317 status
= print_insn_arm (pc
, info
, given
);
1323 print_insn_big_arm (pc
, info
)
1325 struct disassemble_info
* info
;
1327 return print_insn (pc
, info
, FALSE
);
1331 print_insn_little_arm (pc
, info
)
1333 struct disassemble_info
* info
;
1335 return print_insn (pc
, info
, TRUE
);
1339 print_arm_disassembler_options (FILE * stream
)
1343 fprintf (stream
, _("\n\
1344 The following ARM specific disassembler options are supported for use with\n\
1345 the -M switch:\n"));
1347 for (i
= NUM_ARM_REGNAMES
; i
--;)
1348 fprintf (stream
, " reg-names-%s %*c%s\n",
1350 (int)(14 - strlen (regnames
[i
].name
)), ' ',
1351 regnames
[i
].description
);
1353 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
1354 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");