darwin fix
[qemu/mdroth.git] / arm-dis.c
blob1e027efc7081397a1de4bd6135eee62adc50da9c
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)
12 any later version.
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
17 more details.
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. */
23 #include "dis-asm.h"
25 struct arm_opcode {
26 unsigned long value, mask; /* recognise instruction if (op&mask)==value */
27 char *assembler; /* how to disassemble this instruction */
30 struct thumb_opcode
32 unsigned short value, mask; /* recognise instruction if (op&mask)==value */
33 char * assembler; /* how to disassemble this instruction */
36 /* format of the assembler string :
38 %% %
39 %<bitfield>d print the bitfield in decimal
40 %<bitfield>x print the bitfield in hex
41 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
42 %<bitfield>r print as an ARM register
43 %<bitfield>f print a floating point constant if >7 else a
44 floating point register
45 %<code>y print a single precision VFP reg.
46 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
47 %<code>z print a double precision VFP reg
48 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
49 %c print condition code (always bits 28-31)
50 %P print floating point precision in arithmetic insn
51 %Q print floating point precision in ldf/stf insn
52 %R print floating point rounding mode
53 %<bitnum>'c print specified char iff bit is one
54 %<bitnum>`c print specified char iff bit is zero
55 %<bitnum>?ab print a if bit is one else print b
56 %p print 'p' iff bits 12-15 are 15
57 %t print 't' iff bit 21 set and bit 24 clear
58 %o print operand2 (immediate or register + shift)
59 %a print address for ldr/str instruction
60 %s print address for ldr/str halfword/signextend instruction
61 %b print branch destination
62 %B print arm BLX(1) destination
63 %A print address for ldc/stc/ldf/stf instruction
64 %m print register mask for ldm/stm instruction
65 %C print the PSR sub type.
66 %F print the COUNT field of a LFM/SFM instruction.
67 Thumb specific format options:
68 %D print Thumb register (bits 0..2 as high number if bit 7 set)
69 %S print Thumb register (bits 3..5 as high number if bit 6 set)
70 %<bitfield>I print bitfield as a signed decimal
71 (top bit of range being the sign bit)
72 %M print Thumb register mask
73 %N print Thumb register mask (with LR)
74 %O print Thumb register mask (with PC)
75 %T print Thumb condition code (always bits 8-11)
76 %I print cirrus signed shift immediate: bits 0..3|4..6
77 %<bitfield>B print Thumb branch destination (signed displacement)
78 %<bitfield>W print (bitfield * 4) as a decimal
79 %<bitfield>H print (bitfield * 2) as a decimal
80 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
83 /* Note: There is a partial ordering in this table - it must be searched from
84 the top to obtain a correct match. */
86 static struct arm_opcode arm_opcodes[] =
88 /* ARM instructions. */
89 {0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
90 {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
91 {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
92 {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
93 {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
94 {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
95 {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
97 /* V5J instruction. */
98 {0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
100 /* XScale instructions. */
101 {0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
102 {0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
103 {0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
104 {0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
105 {0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
106 {0xf450f000, 0xfc70f000, "pld\t%a"},
108 /* V5 Instructions. */
109 {0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
110 {0xfa000000, 0xfe000000, "blx\t%B"},
111 {0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
112 {0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
113 {0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
114 {0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
115 {0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
116 {0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
117 {0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
119 /* V5E "El Segundo" Instructions. */
120 {0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
121 {0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
122 {0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
123 {0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
124 {0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
125 {0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
127 {0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
128 {0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
130 {0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
131 {0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
132 {0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
133 {0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
135 {0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
136 {0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
137 {0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
138 {0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
140 {0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
141 {0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
143 {0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
144 {0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
145 {0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
146 {0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
148 {0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
149 {0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
151 /* ARM Instructions. */
152 {0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
153 {0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
154 {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
155 {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
156 {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
157 {0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
158 {0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
159 {0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
160 {0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
161 {0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
162 {0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
163 {0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
164 {0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
165 {0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
166 {0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
167 {0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
168 {0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
169 {0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
170 {0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
171 {0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
172 {0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
173 {0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
174 {0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
175 {0x06000010, 0x0e000010, "undefined"},
176 {0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
177 {0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
178 {0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
179 {0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
180 {0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
182 /* Floating point coprocessor (FPA) instructions */
183 {0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
184 {0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
185 {0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
186 {0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
187 {0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
188 {0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
189 {0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
190 {0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
191 {0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
192 {0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
193 {0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
194 {0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
195 {0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
196 {0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
197 {0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
198 {0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
199 {0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
200 {0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
201 {0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
202 {0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
203 {0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
204 {0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
205 {0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
206 {0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
207 {0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
208 {0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
209 {0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
210 {0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
211 {0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
212 {0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
213 {0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
214 {0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
215 {0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
216 {0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
217 {0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
218 {0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
219 {0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
220 {0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
221 {0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
222 {0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
223 {0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
224 {0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
225 {0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
227 /* Floating point coprocessor (VFP) instructions */
228 {0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
229 {0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
230 {0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
231 {0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %1y"},
232 {0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
233 {0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
234 {0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
235 {0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
236 {0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
237 {0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
238 {0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
239 {0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
240 {0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
241 {0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
242 {0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
243 {0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
244 {0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
245 {0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
246 {0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
247 {0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
248 {0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
249 {0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
250 {0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
251 {0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
252 {0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
253 {0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
254 {0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
255 {0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
256 {0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
257 {0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
258 {0x0ef1fa10, 0x0fffffff, "fmstat%c"},
259 {0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
260 {0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
261 {0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
262 {0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
263 {0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
264 {0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
265 {0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
266 {0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
267 {0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
268 {0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
269 {0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
270 {0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
271 {0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
272 {0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
273 {0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
274 {0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
275 {0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
276 {0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
277 {0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
278 {0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
279 {0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
280 {0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
281 {0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
282 {0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
283 {0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
284 {0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
285 {0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
286 {0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
287 {0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
288 {0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
289 {0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
290 {0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
291 {0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
292 {0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
293 {0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
294 {0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
295 {0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
296 {0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
297 {0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
298 {0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
299 {0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
300 {0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
302 /* Cirrus coprocessor instructions. */
303 {0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
304 {0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
305 {0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
306 {0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
307 {0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
308 {0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
309 {0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
310 {0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
311 {0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
312 {0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
313 {0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
314 {0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
315 {0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
316 {0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
317 {0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
318 {0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
319 {0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
320 {0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
321 {0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
322 {0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
323 {0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
324 {0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
325 {0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
326 {0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
327 {0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
328 {0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
329 {0x0e100610, 0x0ff0fff0, "cfmval32%c\tmvax%0-3d, mvfx%16-19d"},
330 {0x0e000610, 0x0ff0fff0, "cfmv32al%c\tmvfx%0-3d, mvax%16-19d"},
331 {0x0e100630, 0x0ff0fff0, "cfmvam32%c\tmvax%0-3d, mvfx%16-19d"},
332 {0x0e000630, 0x0ff0fff0, "cfmv32am%c\tmvfx%0-3d, mvax%16-19d"},
333 {0x0e100650, 0x0ff0fff0, "cfmvah32%c\tmvax%0-3d, mvfx%16-19d"},
334 {0x0e000650, 0x0ff0fff0, "cfmv32ah%c\tmvfx%0-3d, mvax%16-19d"},
335 {0x0e000670, 0x0ff0fff0, "cfmv32a%c\tmvfx%0-3d, mvax%16-19d"},
336 {0x0e100670, 0x0ff0fff0, "cfmva32%c\tmvax%0-3d, mvfx%16-19d"},
337 {0x0e000690, 0x0ff0fff0, "cfmv64a%c\tmvdx%0-3d, mvax%16-19d"},
338 {0x0e100690, 0x0ff0fff0, "cfmva64%c\tmvax%0-3d, mvdx%16-19d"},
339 {0x0e1006b0, 0x0ff0fff0, "cfmvsc32%c\tdspsc, mvfx%16-19d"},
340 {0x0e0006b0, 0x0ff0fff0, "cfmv32sc%c\tmvfx%0-3d, dspsc"},
341 {0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
342 {0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
343 {0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
344 {0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
345 {0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
346 {0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
347 {0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
348 {0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
349 {0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
350 {0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
351 {0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
352 {0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
353 {0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
354 {0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
355 {0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
356 {0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
357 {0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
358 {0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
359 {0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
360 {0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
361 {0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
362 {0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
363 {0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
364 {0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
365 {0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
366 {0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
367 {0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
368 {0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
369 {0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
370 {0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
371 {0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
372 {0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
373 {0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
374 {0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
375 {0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
376 {0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
377 {0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
378 {0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
379 {0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
380 {0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
381 {0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
382 {0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
383 {0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
384 {0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
385 {0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
386 {0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
388 /* Generic coprocessor instructions */
389 {0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
390 {0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
391 {0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
392 {0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
393 {0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
395 /* The rest. */
396 {0x00000000, 0x00000000, "undefined instruction %0-31x"},
397 {0x00000000, 0x00000000, 0}
400 #define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */
402 static struct thumb_opcode thumb_opcodes[] =
404 /* Thumb instructions. */
406 /* ARM V5 ISA extends Thumb. */
407 {0xbe00, 0xff00, "bkpt\t%0-7x"},
408 {0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */
409 /* Note: this is BLX(2). BLX(1) is done in arm-dis.c/print_insn_thumb()
410 as an extension of the special processing there for Thumb BL.
411 BL and BLX(1) involve 2 successive 16-bit instructions, which must
412 always appear together in the correct order. So, the empty
413 string is put in this table, and the string interpreter takes <empty>
414 to mean it has a pair of BL-ish instructions. */
415 {0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
416 /* Format 5 instructions do not update the PSR. */
417 {0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"},
418 /* Format 4. */
419 {0x4000, 0xFFC0, "and\t%0-2r, %3-5r"},
420 {0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"},
421 {0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"},
422 {0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"},
423 {0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"},
424 {0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"},
425 {0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"},
426 {0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"},
427 {0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
428 {0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"},
429 {0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
430 {0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
431 {0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"},
432 {0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"},
433 {0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"},
434 {0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"},
435 /* format 13 */
436 {0xB000, 0xFF80, "add\tsp, #%0-6W"},
437 {0xB080, 0xFF80, "sub\tsp, #%0-6W"},
438 /* format 5 */
439 {0x4700, 0xFF80, "bx\t%S"},
440 {0x4400, 0xFF00, "add\t%D, %S"},
441 {0x4500, 0xFF00, "cmp\t%D, %S"},
442 {0x4600, 0xFF00, "mov\t%D, %S"},
443 /* format 14 */
444 {0xB400, 0xFE00, "push\t%N"},
445 {0xBC00, 0xFE00, "pop\t%O"},
446 /* format 2 */
447 {0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"},
448 {0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
449 {0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"},
450 {0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
451 /* format 8 */
452 {0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
453 {0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
454 {0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
455 /* format 7 */
456 {0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
457 {0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
458 /* format 1 */
459 {0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"},
460 {0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"},
461 {0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"},
462 /* format 3 */
463 {0x2000, 0xF800, "mov\t%8-10r, #%0-7d"},
464 {0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
465 {0x3000, 0xF800, "add\t%8-10r, #%0-7d"},
466 {0x3800, 0xF800, "sub\t%8-10r, #%0-7d"},
467 /* format 6 */
468 {0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
469 /* format 9 */
470 {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
471 {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
472 {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
473 {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
474 /* format 10 */
475 {0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
476 {0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
477 /* format 11 */
478 {0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
479 {0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
480 /* format 12 */
481 {0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
482 {0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
483 /* format 15 */
484 {0xC000, 0xF800, "stmia\t%8-10r!,%M"},
485 {0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
486 /* format 18 */
487 {0xE000, 0xF800, "b\t%0-10B"},
488 {0xE800, 0xF800, "undefined"},
489 /* format 19 */
490 {0xF000, 0xF800, ""}, /* special processing required in disassembler */
491 {0xF800, 0xF800, "second half of BL instruction %0-15x"},
492 /* format 16 */
493 {0xD000, 0xFF00, "beq\t%0-7B"},
494 {0xD100, 0xFF00, "bne\t%0-7B"},
495 {0xD200, 0xFF00, "bcs\t%0-7B"},
496 {0xD300, 0xFF00, "bcc\t%0-7B"},
497 {0xD400, 0xFF00, "bmi\t%0-7B"},
498 {0xD500, 0xFF00, "bpl\t%0-7B"},
499 {0xD600, 0xFF00, "bvs\t%0-7B"},
500 {0xD700, 0xFF00, "bvc\t%0-7B"},
501 {0xD800, 0xFF00, "bhi\t%0-7B"},
502 {0xD900, 0xFF00, "bls\t%0-7B"},
503 {0xDA00, 0xFF00, "bge\t%0-7B"},
504 {0xDB00, 0xFF00, "blt\t%0-7B"},
505 {0xDC00, 0xFF00, "bgt\t%0-7B"},
506 {0xDD00, 0xFF00, "ble\t%0-7B"},
507 /* format 17 */
508 {0xDE00, 0xFF00, "bal\t%0-7B"},
509 {0xDF00, 0xFF00, "swi\t%0-7d"},
510 /* format 9 */
511 {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
512 {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
513 {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
514 {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
515 /* the rest */
516 {0x0000, 0x0000, "undefined instruction %0-15x"},
517 {0x0000, 0x0000, 0}
520 #define BDISP23(x) ((((((x) & 0x07ff) << 11) | (((x) & 0x07ff0000) >> 16)) \
521 ^ 0x200000) - 0x200000) /* 23bit */
523 #ifndef streq
524 #define streq(a,b) (strcmp ((a), (b)) == 0)
525 #endif
527 #ifndef strneq
528 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
529 #endif
531 #ifndef NUM_ELEM
532 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
533 #endif
535 static char * arm_conditional[] =
536 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
537 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
539 typedef struct
541 const char * name;
542 const char * description;
543 const char * reg_names[16];
545 arm_regname;
547 static arm_regname regnames[] =
549 { "raw" , "Select raw register names",
550 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
551 { "gcc", "Select register names used by GCC",
552 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
553 { "std", "Select register names used in ARM's ISA documentation",
554 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
555 { "apcs", "Select register names used in the APCS",
556 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
557 { "atpcs", "Select register names used in the ATPCS",
558 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
559 { "special-atpcs", "Select special register names used in the ATPCS",
560 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}
563 /* Default to STD register name set. */
564 static unsigned int regname_selected = 2;
566 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
567 #define arm_regnames regnames[regname_selected].reg_names
569 static boolean force_thumb = false;
571 static char * arm_fp_const[] =
572 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
574 static char * arm_shift[] =
575 {"lsl", "lsr", "asr", "ror"};
577 /* Forward declarations. */
578 static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
579 static int print_insn_arm1 PARAMS ((bfd_vma, struct disassemble_info *, long));
580 static int print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
581 static void parse_disassembler_options PARAMS ((char *));
582 int get_arm_regname_num_options (void);
583 int set_arm_regname_option (int option);
584 int get_arm_regnames (int option, const char **setname,
585 const char **setdescription,
586 const char ***register_names);
588 /* Functions. */
590 get_arm_regname_num_options ()
592 return NUM_ARM_REGNAMES;
596 set_arm_regname_option (option)
597 int option;
599 int old = regname_selected;
600 regname_selected = option;
601 return old;
605 get_arm_regnames (option, setname, setdescription, register_names)
606 int option;
607 const char **setname;
608 const char **setdescription;
609 const char ***register_names;
611 *setname = regnames[option].name;
612 *setdescription = regnames[option].description;
613 *register_names = regnames[option].reg_names;
614 return 16;
617 static void
618 arm_decode_shift (given, func, stream)
619 long given;
620 fprintf_ftype func;
621 void * stream;
623 func (stream, "%s", arm_regnames[given & 0xf]);
625 if ((given & 0xff0) != 0)
627 if ((given & 0x10) == 0)
629 int amount = (given & 0xf80) >> 7;
630 int shift = (given & 0x60) >> 5;
632 if (amount == 0)
634 if (shift == 3)
636 func (stream, ", rrx");
637 return;
640 amount = 32;
643 func (stream, ", %s #%d", arm_shift[shift], amount);
645 else
646 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
647 arm_regnames[(given & 0xf00) >> 8]);
651 /* Print one instruction from PC on INFO->STREAM.
652 Return the size of the instruction (always 4 on ARM). */
654 static int
655 print_insn_arm1 (pc, info, given)
656 bfd_vma pc;
657 struct disassemble_info * info;
658 long given;
660 struct arm_opcode * insn;
661 void * stream = info->stream;
662 fprintf_ftype func = info->fprintf_func;
664 for (insn = arm_opcodes; insn->assembler; insn++)
666 if ((given & insn->mask) == insn->value)
668 char * c;
670 for (c = insn->assembler; *c; c++)
672 if (*c == '%')
674 switch (*++c)
676 case '%':
677 func (stream, "%%");
678 break;
680 case 'a':
681 if (((given & 0x000f0000) == 0x000f0000)
682 && ((given & 0x02000000) == 0))
684 int offset = given & 0xfff;
686 func (stream, "[pc");
688 if (given & 0x01000000)
690 if ((given & 0x00800000) == 0)
691 offset = - offset;
693 /* Pre-indexed. */
694 func (stream, ", #%d]", offset);
696 offset += pc + 8;
698 /* Cope with the possibility of write-back
699 being used. Probably a very dangerous thing
700 for the programmer to do, but who are we to
701 argue ? */
702 if (given & 0x00200000)
703 func (stream, "!");
705 else
707 /* Post indexed. */
708 func (stream, "], #%d", offset);
710 /* ie ignore the offset. */
711 offset = pc + 8;
714 func (stream, "\t; ");
715 info->print_address_func (offset, info);
717 else
719 func (stream, "[%s",
720 arm_regnames[(given >> 16) & 0xf]);
721 if ((given & 0x01000000) != 0)
723 if ((given & 0x02000000) == 0)
725 int offset = given & 0xfff;
726 if (offset)
727 func (stream, ", %s#%d",
728 (((given & 0x00800000) == 0)
729 ? "-" : ""), offset);
731 else
733 func (stream, ", %s",
734 (((given & 0x00800000) == 0)
735 ? "-" : ""));
736 arm_decode_shift (given, func, stream);
739 func (stream, "]%s",
740 ((given & 0x00200000) != 0) ? "!" : "");
742 else
744 if ((given & 0x02000000) == 0)
746 int offset = given & 0xfff;
747 if (offset)
748 func (stream, "], %s#%d",
749 (((given & 0x00800000) == 0)
750 ? "-" : ""), offset);
751 else
752 func (stream, "]");
754 else
756 func (stream, "], %s",
757 (((given & 0x00800000) == 0)
758 ? "-" : ""));
759 arm_decode_shift (given, func, stream);
763 break;
765 case 's':
766 if ((given & 0x004f0000) == 0x004f0000)
768 /* PC relative with immediate offset. */
769 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
771 if ((given & 0x00800000) == 0)
772 offset = -offset;
774 func (stream, "[pc, #%d]\t; ", offset);
776 (*info->print_address_func)
777 (offset + pc + 8, info);
779 else
781 func (stream, "[%s",
782 arm_regnames[(given >> 16) & 0xf]);
783 if ((given & 0x01000000) != 0)
785 /* Pre-indexed. */
786 if ((given & 0x00400000) == 0x00400000)
788 /* Immediate. */
789 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
790 if (offset)
791 func (stream, ", %s#%d",
792 (((given & 0x00800000) == 0)
793 ? "-" : ""), offset);
795 else
797 /* Register. */
798 func (stream, ", %s%s",
799 (((given & 0x00800000) == 0)
800 ? "-" : ""),
801 arm_regnames[given & 0xf]);
804 func (stream, "]%s",
805 ((given & 0x00200000) != 0) ? "!" : "");
807 else
809 /* Post-indexed. */
810 if ((given & 0x00400000) == 0x00400000)
812 /* Immediate. */
813 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
814 if (offset)
815 func (stream, "], %s#%d",
816 (((given & 0x00800000) == 0)
817 ? "-" : ""), offset);
818 else
819 func (stream, "]");
821 else
823 /* Register. */
824 func (stream, "], %s%s",
825 (((given & 0x00800000) == 0)
826 ? "-" : ""),
827 arm_regnames[given & 0xf]);
831 break;
833 case 'b':
834 (*info->print_address_func)
835 (BDISP (given) * 4 + pc + 8, info);
836 break;
838 case 'c':
839 func (stream, "%s",
840 arm_conditional [(given >> 28) & 0xf]);
841 break;
843 case 'm':
845 int started = 0;
846 int reg;
848 func (stream, "{");
849 for (reg = 0; reg < 16; reg++)
850 if ((given & (1 << reg)) != 0)
852 if (started)
853 func (stream, ", ");
854 started = 1;
855 func (stream, "%s", arm_regnames[reg]);
857 func (stream, "}");
859 break;
861 case 'o':
862 if ((given & 0x02000000) != 0)
864 int rotate = (given & 0xf00) >> 7;
865 int immed = (given & 0xff);
866 immed = (((immed << (32 - rotate))
867 | (immed >> rotate)) & 0xffffffff);
868 func (stream, "#%d\t; 0x%x", immed, immed);
870 else
871 arm_decode_shift (given, func, stream);
872 break;
874 case 'p':
875 if ((given & 0x0000f000) == 0x0000f000)
876 func (stream, "p");
877 break;
879 case 't':
880 if ((given & 0x01200000) == 0x00200000)
881 func (stream, "t");
882 break;
884 case 'A':
885 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
886 if ((given & 0x01000000) != 0)
888 int offset = given & 0xff;
889 if (offset)
890 func (stream, ", %s#%d]%s",
891 ((given & 0x00800000) == 0 ? "-" : ""),
892 offset * 4,
893 ((given & 0x00200000) != 0 ? "!" : ""));
894 else
895 func (stream, "]");
897 else
899 int offset = given & 0xff;
900 if (offset)
901 func (stream, "], %s#%d",
902 ((given & 0x00800000) == 0 ? "-" : ""),
903 offset * 4);
904 else
905 func (stream, "]");
907 break;
909 case 'B':
910 /* Print ARM V5 BLX(1) address: pc+25 bits. */
912 bfd_vma address;
913 bfd_vma offset = 0;
915 if (given & 0x00800000)
916 /* Is signed, hi bits should be ones. */
917 offset = (-1) ^ 0x00ffffff;
919 /* Offset is (SignExtend(offset field)<<2). */
920 offset += given & 0x00ffffff;
921 offset <<= 2;
922 address = offset + pc + 8;
924 if (given & 0x01000000)
925 /* H bit allows addressing to 2-byte boundaries. */
926 address += 2;
928 info->print_address_func (address, info);
930 break;
932 case 'I':
933 /* Print a Cirrus/DSP shift immediate. */
934 /* Immediates are 7bit signed ints with bits 0..3 in
935 bits 0..3 of opcode and bits 4..6 in bits 5..7
936 of opcode. */
938 int imm;
940 imm = (given & 0xf) | ((given & 0xe0) >> 1);
942 /* Is ``imm'' a negative number? */
943 if (imm & 0x40)
944 imm |= (-1 << 7);
946 func (stream, "%d", imm);
949 break;
951 case 'C':
952 func (stream, "_");
953 if (given & 0x80000)
954 func (stream, "f");
955 if (given & 0x40000)
956 func (stream, "s");
957 if (given & 0x20000)
958 func (stream, "x");
959 if (given & 0x10000)
960 func (stream, "c");
961 break;
963 case 'F':
964 switch (given & 0x00408000)
966 case 0:
967 func (stream, "4");
968 break;
969 case 0x8000:
970 func (stream, "1");
971 break;
972 case 0x00400000:
973 func (stream, "2");
974 break;
975 default:
976 func (stream, "3");
978 break;
980 case 'P':
981 switch (given & 0x00080080)
983 case 0:
984 func (stream, "s");
985 break;
986 case 0x80:
987 func (stream, "d");
988 break;
989 case 0x00080000:
990 func (stream, "e");
991 break;
992 default:
993 func (stream, _("<illegal precision>"));
994 break;
996 break;
997 case 'Q':
998 switch (given & 0x00408000)
1000 case 0:
1001 func (stream, "s");
1002 break;
1003 case 0x8000:
1004 func (stream, "d");
1005 break;
1006 case 0x00400000:
1007 func (stream, "e");
1008 break;
1009 default:
1010 func (stream, "p");
1011 break;
1013 break;
1014 case 'R':
1015 switch (given & 0x60)
1017 case 0:
1018 break;
1019 case 0x20:
1020 func (stream, "p");
1021 break;
1022 case 0x40:
1023 func (stream, "m");
1024 break;
1025 default:
1026 func (stream, "z");
1027 break;
1029 break;
1031 case '0': case '1': case '2': case '3': case '4':
1032 case '5': case '6': case '7': case '8': case '9':
1034 int bitstart = *c++ - '0';
1035 int bitend = 0;
1036 while (*c >= '0' && *c <= '9')
1037 bitstart = (bitstart * 10) + *c++ - '0';
1039 switch (*c)
1041 case '-':
1042 c++;
1044 while (*c >= '0' && *c <= '9')
1045 bitend = (bitend * 10) + *c++ - '0';
1047 if (!bitend)
1048 abort ();
1050 switch (*c)
1052 case 'r':
1054 long reg;
1056 reg = given >> bitstart;
1057 reg &= (2 << (bitend - bitstart)) - 1;
1059 func (stream, "%s", arm_regnames[reg]);
1061 break;
1062 case 'd':
1064 long reg;
1066 reg = given >> bitstart;
1067 reg &= (2 << (bitend - bitstart)) - 1;
1069 func (stream, "%d", reg);
1071 break;
1072 case 'x':
1074 long reg;
1076 reg = given >> bitstart;
1077 reg &= (2 << (bitend - bitstart)) - 1;
1079 func (stream, "0x%08x", reg);
1081 /* Some SWI instructions have special
1082 meanings. */
1083 if ((given & 0x0fffffff) == 0x0FF00000)
1084 func (stream, "\t; IMB");
1085 else if ((given & 0x0fffffff) == 0x0FF00001)
1086 func (stream, "\t; IMBRange");
1088 break;
1089 case 'X':
1091 long reg;
1093 reg = given >> bitstart;
1094 reg &= (2 << (bitend - bitstart)) - 1;
1096 func (stream, "%01x", reg & 0xf);
1098 break;
1099 case 'f':
1101 long reg;
1103 reg = given >> bitstart;
1104 reg &= (2 << (bitend - bitstart)) - 1;
1106 if (reg > 7)
1107 func (stream, "#%s",
1108 arm_fp_const[reg & 7]);
1109 else
1110 func (stream, "f%d", reg);
1112 break;
1113 default:
1114 abort ();
1116 break;
1118 case 'y':
1119 case 'z':
1121 int single = *c == 'y';
1122 int regno;
1124 switch (bitstart)
1126 case 4: /* Sm pair */
1127 func (stream, "{");
1128 /* Fall through. */
1129 case 0: /* Sm, Dm */
1130 regno = given & 0x0000000f;
1131 if (single)
1133 regno <<= 1;
1134 regno += (given >> 5) & 1;
1136 break;
1138 case 1: /* Sd, Dd */
1139 regno = (given >> 12) & 0x0000000f;
1140 if (single)
1142 regno <<= 1;
1143 regno += (given >> 22) & 1;
1145 break;
1147 case 2: /* Sn, Dn */
1148 regno = (given >> 16) & 0x0000000f;
1149 if (single)
1151 regno <<= 1;
1152 regno += (given >> 7) & 1;
1154 break;
1156 case 3: /* List */
1157 func (stream, "{");
1158 regno = (given >> 12) & 0x0000000f;
1159 if (single)
1161 regno <<= 1;
1162 regno += (given >> 22) & 1;
1164 break;
1167 default:
1168 abort ();
1171 func (stream, "%c%d", single ? 's' : 'd', regno);
1173 if (bitstart == 3)
1175 int count = given & 0xff;
1177 if (single == 0)
1178 count >>= 1;
1180 if (--count)
1182 func (stream, "-%c%d",
1183 single ? 's' : 'd',
1184 regno + count);
1187 func (stream, "}");
1189 else if (bitstart == 4)
1190 func (stream, ", %c%d}", single ? 's' : 'd',
1191 regno + 1);
1193 break;
1196 case '`':
1197 c++;
1198 if ((given & (1 << bitstart)) == 0)
1199 func (stream, "%c", *c);
1200 break;
1201 case '\'':
1202 c++;
1203 if ((given & (1 << bitstart)) != 0)
1204 func (stream, "%c", *c);
1205 break;
1206 case '?':
1207 ++c;
1208 if ((given & (1 << bitstart)) != 0)
1209 func (stream, "%c", *c++);
1210 else
1211 func (stream, "%c", *++c);
1212 break;
1213 default:
1214 abort ();
1216 break;
1218 default:
1219 abort ();
1223 else
1224 func (stream, "%c", *c);
1226 return 4;
1229 abort ();
1232 /* Print one instruction from PC on INFO->STREAM.
1233 Return the size of the instruction. */
1235 static int
1236 print_insn_thumb (pc, info, given)
1237 bfd_vma pc;
1238 struct disassemble_info * info;
1239 long given;
1241 struct thumb_opcode * insn;
1242 void * stream = info->stream;
1243 fprintf_ftype func = info->fprintf_func;
1245 for (insn = thumb_opcodes; insn->assembler; insn++)
1247 if ((given & insn->mask) == insn->value)
1249 char * c = insn->assembler;
1251 /* Special processing for Thumb 2 instruction BL sequence: */
1252 if (!*c) /* Check for empty (not NULL) assembler string. */
1254 long offset;
1256 info->bytes_per_chunk = 4;
1257 info->bytes_per_line = 4;
1259 offset = BDISP23 (given);
1260 offset = offset * 2 + pc + 4;
1262 if ((given & 0x10000000) == 0)
1264 func (stream, "blx\t");
1265 offset &= 0xfffffffc;
1267 else
1268 func (stream, "bl\t");
1270 info->print_address_func (offset, info);
1271 return 4;
1273 else
1275 info->bytes_per_chunk = 2;
1276 info->bytes_per_line = 4;
1278 given &= 0xffff;
1280 for (; *c; c++)
1282 if (*c == '%')
1284 int domaskpc = 0;
1285 int domasklr = 0;
1287 switch (*++c)
1289 case '%':
1290 func (stream, "%%");
1291 break;
1293 case 'S':
1295 long reg;
1297 reg = (given >> 3) & 0x7;
1298 if (given & (1 << 6))
1299 reg += 8;
1301 func (stream, "%s", arm_regnames[reg]);
1303 break;
1305 case 'D':
1307 long reg;
1309 reg = given & 0x7;
1310 if (given & (1 << 7))
1311 reg += 8;
1313 func (stream, "%s", arm_regnames[reg]);
1315 break;
1317 case 'T':
1318 func (stream, "%s",
1319 arm_conditional [(given >> 8) & 0xf]);
1320 break;
1322 case 'N':
1323 if (given & (1 << 8))
1324 domasklr = 1;
1325 /* Fall through. */
1326 case 'O':
1327 if (*c == 'O' && (given & (1 << 8)))
1328 domaskpc = 1;
1329 /* Fall through. */
1330 case 'M':
1332 int started = 0;
1333 int reg;
1335 func (stream, "{");
1337 /* It would be nice if we could spot
1338 ranges, and generate the rS-rE format: */
1339 for (reg = 0; (reg < 8); reg++)
1340 if ((given & (1 << reg)) != 0)
1342 if (started)
1343 func (stream, ", ");
1344 started = 1;
1345 func (stream, "%s", arm_regnames[reg]);
1348 if (domasklr)
1350 if (started)
1351 func (stream, ", ");
1352 started = 1;
1353 func (stream, arm_regnames[14] /* "lr" */);
1356 if (domaskpc)
1358 if (started)
1359 func (stream, ", ");
1360 func (stream, arm_regnames[15] /* "pc" */);
1363 func (stream, "}");
1365 break;
1368 case '0': case '1': case '2': case '3': case '4':
1369 case '5': case '6': case '7': case '8': case '9':
1371 int bitstart = *c++ - '0';
1372 int bitend = 0;
1374 while (*c >= '0' && *c <= '9')
1375 bitstart = (bitstart * 10) + *c++ - '0';
1377 switch (*c)
1379 case '-':
1381 long reg;
1383 c++;
1384 while (*c >= '0' && *c <= '9')
1385 bitend = (bitend * 10) + *c++ - '0';
1386 if (!bitend)
1387 abort ();
1388 reg = given >> bitstart;
1389 reg &= (2 << (bitend - bitstart)) - 1;
1390 switch (*c)
1392 case 'r':
1393 func (stream, "%s", arm_regnames[reg]);
1394 break;
1396 case 'd':
1397 func (stream, "%d", reg);
1398 break;
1400 case 'H':
1401 func (stream, "%d", reg << 1);
1402 break;
1404 case 'W':
1405 func (stream, "%d", reg << 2);
1406 break;
1408 case 'a':
1409 /* PC-relative address -- the bottom two
1410 bits of the address are dropped
1411 before the calculation. */
1412 info->print_address_func
1413 (((pc + 4) & ~3) + (reg << 2), info);
1414 break;
1416 case 'x':
1417 func (stream, "0x%04x", reg);
1418 break;
1420 case 'I':
1421 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1422 func (stream, "%d", reg);
1423 break;
1425 case 'B':
1426 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1427 (*info->print_address_func)
1428 (reg * 2 + pc + 4, info);
1429 break;
1431 default:
1432 abort ();
1435 break;
1437 case '\'':
1438 c++;
1439 if ((given & (1 << bitstart)) != 0)
1440 func (stream, "%c", *c);
1441 break;
1443 case '?':
1444 ++c;
1445 if ((given & (1 << bitstart)) != 0)
1446 func (stream, "%c", *c++);
1447 else
1448 func (stream, "%c", *++c);
1449 break;
1451 default:
1452 abort ();
1455 break;
1457 default:
1458 abort ();
1461 else
1462 func (stream, "%c", *c);
1465 return 2;
1469 /* No match. */
1470 abort ();
1473 /* Parse an individual disassembler option. */
1475 void
1476 parse_arm_disassembler_option (option)
1477 char * option;
1479 if (option == NULL)
1480 return;
1482 if (strneq (option, "reg-names-", 10))
1484 int i;
1486 option += 10;
1488 for (i = NUM_ARM_REGNAMES; i--;)
1489 if (streq (option, regnames[i].name))
1491 regname_selected = i;
1492 break;
1495 if (i < 0)
1496 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1498 else if (streq (option, "force-thumb"))
1499 force_thumb = 1;
1500 else if (streq (option, "no-force-thumb"))
1501 force_thumb = 0;
1502 else
1503 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1505 return;
1508 /* Parse the string of disassembler options, spliting it at whitespaces. */
1510 static void
1511 parse_disassembler_options (options)
1512 char * options;
1514 char * space;
1516 if (options == NULL)
1517 return;
1521 space = strchr (options, ' ');
1523 if (space)
1525 * space = '\0';
1526 parse_arm_disassembler_option (options);
1527 * space = ' ';
1528 options = space + 1;
1530 else
1531 parse_arm_disassembler_option (options);
1533 while (space);
1536 /* NOTE: There are no checks in these routines that
1537 the relevant number of data bytes exist. */
1540 print_insn_arm (pc, info)
1541 bfd_vma pc;
1542 struct disassemble_info * info;
1544 unsigned char b[4];
1545 long given;
1546 int status;
1547 int is_thumb;
1548 int little;
1550 if (info->disassembler_options)
1552 parse_disassembler_options (info->disassembler_options);
1554 /* To avoid repeated parsing of these options, we remove them here. */
1555 info->disassembler_options = NULL;
1558 is_thumb = force_thumb;
1559 if (pc & 1)
1561 is_thumb = 1;
1562 pc &= ~(bfd_vma) 1;
1565 #if 0
1566 if (!is_thumb && info->symbols != NULL)
1568 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1570 coff_symbol_type * cs;
1572 cs = coffsymbol (*info->symbols);
1573 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1574 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1575 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1576 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1577 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1579 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1581 elf_symbol_type * es;
1582 unsigned int type;
1584 es = *(elf_symbol_type **)(info->symbols);
1585 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1587 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1590 #endif
1592 little = (info->endian == BFD_ENDIAN_LITTLE);
1593 info->bytes_per_chunk = 4;
1594 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1596 if (little)
1598 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1599 if (status != 0 && is_thumb)
1601 info->bytes_per_chunk = 2;
1603 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1604 b[3] = b[2] = 0;
1607 if (status != 0)
1609 info->memory_error_func (status, pc, info);
1610 return -1;
1613 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1615 else
1617 status = info->read_memory_func
1618 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1619 if (status != 0)
1621 info->memory_error_func (status, pc, info);
1622 return -1;
1625 if (is_thumb)
1627 if (pc & 0x2)
1629 given = (b[2] << 8) | b[3];
1631 status = info->read_memory_func
1632 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1633 if (status != 0)
1635 info->memory_error_func (status, pc + 4, info);
1636 return -1;
1639 given |= (b[0] << 24) | (b[1] << 16);
1641 else
1642 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1644 else
1645 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1648 if (info->flags & INSN_HAS_RELOC)
1649 /* If the instruction has a reloc associated with it, then
1650 the offset field in the instruction will actually be the
1651 addend for the reloc. (We are using REL type relocs).
1652 In such cases, we can ignore the pc when computing
1653 addresses, since the addend is not currently pc-relative. */
1654 pc = 0;
1655 if (is_thumb)
1656 status = print_insn_thumb (pc, info, given);
1657 else
1658 status = print_insn_arm1 (pc, info, given);
1660 return status;
1663 void
1664 print_arm_disassembler_options (FILE * stream)
1666 int i;
1668 fprintf (stream, _("\n\
1669 The following ARM specific disassembler options are supported for use with\n\
1670 the -M switch:\n"));
1672 for (i = NUM_ARM_REGNAMES; i--;)
1673 fprintf (stream, " reg-names-%s %*c%s\n",
1674 regnames[i].name,
1675 (int)(14 - strlen (regnames[i].name)), ' ',
1676 regnames[i].description);
1678 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1679 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");