ARM thumb disassembly (Paul Brook)
[qemu] / arm-dis.c
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)
6
7 This file is part of libopcodes. 
8
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. 
13
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. 
18
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.  */
22
23 #include "dis-asm.h"
24
25 struct arm_opcode {
26     unsigned long value, mask;  /* recognise instruction if (op&mask)==value */
27     char *assembler;            /* how to disassemble this instruction */
28 };
29
30 struct thumb_opcode
31 {
32     unsigned short value, mask; /* recognise instruction if (op&mask)==value */
33     char * assembler;           /* how to disassemble this instruction */
34 };
35
36 /* format of the assembler string :
37    
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
81 */
82
83 /* Note: There is a partial ordering in this table - it must be searched from
84    the top to obtain a correct match. */
85
86 static struct arm_opcode arm_opcodes[] =
87 {
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"},
96
97     /* V5J instruction.  */
98     {0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
99
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"},
107     
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}"},
118
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"},
126
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"},
129
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"},
134
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"},
139
140     {0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
141     {0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
142
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"},
147
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"},
150
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"},
181
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"},
226
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"},
301
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"},
387
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"},
394
395     /* The rest.  */
396     {0x00000000, 0x00000000, "undefined instruction %0-31x"},
397     {0x00000000, 0x00000000, 0}
398 };
399
400 #define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */
401
402 static struct thumb_opcode thumb_opcodes[] =
403 {
404   /* Thumb instructions.  */
405
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}
518 };
519
520 #define BDISP23(x) ((((((x) & 0x07ff) << 11) | (((x) & 0x07ff0000) >> 16)) \
521                      ^ 0x200000) - 0x200000) /* 23bit */
522
523 #ifndef streq
524 #define streq(a,b)      (strcmp ((a), (b)) == 0)
525 #endif
526
527 #ifndef strneq
528 #define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
529 #endif
530
531 #ifndef NUM_ELEM
532 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
533 #endif
534
535 static char * arm_conditional[] =
536 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
537  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
538
539 typedef struct
540 {
541   const char * name;
542   const char * description;
543   const char * reg_names[16];
544 }
545 arm_regname;
546
547 static arm_regname regnames[] =
548 {
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" }}
561 };
562
563 /* Default to STD register name set.  */
564 static unsigned int regname_selected = 2;
565
566 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
567 #define arm_regnames      regnames[regname_selected].reg_names
568
569 static boolean force_thumb = false;
570
571 static char * arm_fp_const[] =
572 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
573
574 static char * arm_shift[] = 
575 {"lsl", "lsr", "asr", "ror"};
576 \f
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);
587 \f
588 /* Functions.  */
589 int
590 get_arm_regname_num_options ()
591 {
592   return NUM_ARM_REGNAMES;
593 }
594
595 int
596 set_arm_regname_option (option)
597      int option;
598 {
599   int old = regname_selected;
600   regname_selected = option;
601   return old;
602 }
603
604 int
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;
610 {
611   *setname = regnames[option].name;
612   *setdescription = regnames[option].description;
613   *register_names = regnames[option].reg_names;
614   return 16;
615 }
616
617 static void
618 arm_decode_shift (given, func, stream)
619      long given;
620      fprintf_ftype func;
621      void * stream;
622 {
623   func (stream, "%s", arm_regnames[given & 0xf]);
624   
625   if ((given & 0xff0) != 0)
626     {
627       if ((given & 0x10) == 0)
628         {
629           int amount = (given & 0xf80) >> 7;
630           int shift = (given & 0x60) >> 5;
631           
632           if (amount == 0)
633             {
634               if (shift == 3)
635                 {
636                   func (stream, ", rrx");
637                   return;
638                 }
639               
640               amount = 32;
641             }
642           
643           func (stream, ", %s #%d", arm_shift[shift], amount);
644         }
645       else
646         func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
647               arm_regnames[(given & 0xf00) >> 8]);
648     }
649 }
650
651 /* Print one instruction from PC on INFO->STREAM.
652    Return the size of the instruction (always 4 on ARM). */
653
654 static int
655 print_insn_arm1 (pc, info, given)
656      bfd_vma                   pc;
657      struct disassemble_info * info;
658      long                      given;
659 {
660   struct arm_opcode *  insn;
661   void *               stream = info->stream;
662   fprintf_ftype        func   = info->fprintf_func;
663
664   for (insn = arm_opcodes; insn->assembler; insn++)
665     {
666       if ((given & insn->mask) == insn->value)
667         {
668           char * c;
669           
670           for (c = insn->assembler; *c; c++)
671             {
672               if (*c == '%')
673                 {
674                   switch (*++c)
675                     {
676                     case '%':
677                       func (stream, "%%");
678                       break;
679
680                     case 'a':
681                       if (((given & 0x000f0000) == 0x000f0000)
682                           && ((given & 0x02000000) == 0))
683                         {
684                           int offset = given & 0xfff;
685                           
686                           func (stream, "[pc");
687  
688                           if (given & 0x01000000)
689                             {
690                               if ((given & 0x00800000) == 0)
691                                 offset = - offset;
692                           
693                               /* Pre-indexed.  */
694                               func (stream, ", #%d]", offset);
695
696                               offset += pc + 8;
697
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, "!");
704                             }
705                           else
706                             {
707                               /* Post indexed.  */
708                               func (stream, "], #%d", offset);
709
710                               /* ie ignore the offset.  */
711                               offset = pc + 8;
712                             }
713                           
714                           func (stream, "\t; ");
715                           info->print_address_func (offset, info);
716                         }
717                       else
718                         {
719                           func (stream, "[%s", 
720                                 arm_regnames[(given >> 16) & 0xf]);
721                           if ((given & 0x01000000) != 0)
722                             {
723                               if ((given & 0x02000000) == 0)
724                                 {
725                                   int offset = given & 0xfff;
726                                   if (offset)
727                                     func (stream, ", %s#%d",
728                                           (((given & 0x00800000) == 0)
729                                            ? "-" : ""), offset);
730                                 }
731                               else
732                                 {
733                                   func (stream, ", %s",
734                                         (((given & 0x00800000) == 0)
735                                          ? "-" : ""));
736                                   arm_decode_shift (given, func, stream);
737                                 }
738
739                               func (stream, "]%s", 
740                                     ((given & 0x00200000) != 0) ? "!" : "");
741                             }
742                           else
743                             {
744                               if ((given & 0x02000000) == 0)
745                                 {
746                                   int offset = given & 0xfff;
747                                   if (offset)
748                                     func (stream, "], %s#%d",
749                                           (((given & 0x00800000) == 0)
750                                            ? "-" : ""), offset);
751                                   else 
752                                     func (stream, "]");
753                                 }
754                               else
755                                 {
756                                   func (stream, "], %s",
757                                         (((given & 0x00800000) == 0) 
758                                          ? "-" : ""));
759                                   arm_decode_shift (given, func, stream);
760                                 }
761                             }
762                         }
763                       break;
764
765                     case 's':
766                       if ((given & 0x004f0000) == 0x004f0000)
767                         {
768                           /* PC relative with immediate offset.  */
769                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
770                           
771                           if ((given & 0x00800000) == 0)
772                             offset = -offset;
773                           
774                           func (stream, "[pc, #%d]\t; ", offset);
775                           
776                           (*info->print_address_func)
777                             (offset + pc + 8, info);
778                         }
779                       else
780                         {
781                           func (stream, "[%s", 
782                                 arm_regnames[(given >> 16) & 0xf]);
783                           if ((given & 0x01000000) != 0)
784                             {
785                               /* Pre-indexed.  */
786                               if ((given & 0x00400000) == 0x00400000)
787                                 {
788                                   /* Immediate.  */
789                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
790                                   if (offset)
791                                     func (stream, ", %s#%d",
792                                           (((given & 0x00800000) == 0)
793                                            ? "-" : ""), offset);
794                                 }
795                               else
796                                 {
797                                   /* Register.  */
798                                   func (stream, ", %s%s",
799                                         (((given & 0x00800000) == 0)
800                                          ? "-" : ""),
801                                         arm_regnames[given & 0xf]);
802                                 }
803
804                               func (stream, "]%s", 
805                                     ((given & 0x00200000) != 0) ? "!" : "");
806                             }
807                           else
808                             {
809                               /* Post-indexed.  */
810                               if ((given & 0x00400000) == 0x00400000)
811                                 {
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, "]");
820                                 }
821                               else
822                                 {
823                                   /* Register.  */
824                                   func (stream, "], %s%s",
825                                         (((given & 0x00800000) == 0)
826                                          ? "-" : ""),
827                                         arm_regnames[given & 0xf]);
828                                 }
829                             }
830                         }
831                       break;
832                           
833                     case 'b':
834                       (*info->print_address_func)
835                         (BDISP (given) * 4 + pc + 8, info);
836                       break;
837
838                     case 'c':
839                       func (stream, "%s",
840                             arm_conditional [(given >> 28) & 0xf]);
841                       break;
842
843                     case 'm':
844                       {
845                         int started = 0;
846                         int reg;
847
848                         func (stream, "{");
849                         for (reg = 0; reg < 16; reg++)
850                           if ((given & (1 << reg)) != 0)
851                             {
852                               if (started)
853                                 func (stream, ", ");
854                               started = 1;
855                               func (stream, "%s", arm_regnames[reg]);
856                             }
857                         func (stream, "}");
858                       }
859                       break;
860
861                     case 'o':
862                       if ((given & 0x02000000) != 0)
863                         {
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);
869                         }
870                       else
871                         arm_decode_shift (given, func, stream);
872                       break;
873
874                     case 'p':
875                       if ((given & 0x0000f000) == 0x0000f000)
876                         func (stream, "p");
877                       break;
878
879                     case 't':
880                       if ((given & 0x01200000) == 0x00200000)
881                         func (stream, "t");
882                       break;
883
884                     case 'A':
885                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
886                       if ((given & 0x01000000) != 0)
887                         {
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, "]");
896                         }
897                       else
898                         {
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, "]");
906                         }
907                       break;
908
909                     case 'B':
910                       /* Print ARM V5 BLX(1) address: pc+25 bits.  */
911                       {
912                         bfd_vma address;
913                         bfd_vma offset = 0;
914                         
915                         if (given & 0x00800000)
916                           /* Is signed, hi bits should be ones.  */
917                           offset = (-1) ^ 0x00ffffff;
918
919                         /* Offset is (SignExtend(offset field)<<2).  */
920                         offset += given & 0x00ffffff;
921                         offset <<= 2;
922                         address = offset + pc + 8;
923                         
924                         if (given & 0x01000000)
925                           /* H bit allows addressing to 2-byte boundaries.  */
926                           address += 2;
927
928                         info->print_address_func (address, info);
929                       }
930                       break;
931
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.  */
937                       {
938                         int imm;
939
940                         imm = (given & 0xf) | ((given & 0xe0) >> 1);
941
942                         /* Is ``imm'' a negative number?  */
943                         if (imm & 0x40)
944                           imm |= (-1 << 7);
945
946                         func (stream, "%d", imm);
947                       }
948
949                       break;
950
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;
962
963                     case 'F':
964                       switch (given & 0x00408000)
965                         {
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");
977                         }
978                       break;
979                         
980                     case 'P':
981                       switch (given & 0x00080080)
982                         {
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;
995                         }
996                       break;
997                     case 'Q':
998                       switch (given & 0x00408000)
999                         {
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;
1012                         }
1013                       break;
1014                     case 'R':
1015                       switch (given & 0x60)
1016                         {
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;
1028                         }
1029                       break;
1030
1031                     case '0': case '1': case '2': case '3': case '4': 
1032                     case '5': case '6': case '7': case '8': case '9':
1033                       {
1034                         int bitstart = *c++ - '0';
1035                         int bitend = 0;
1036                         while (*c >= '0' && *c <= '9')
1037                           bitstart = (bitstart * 10) + *c++ - '0';
1038
1039                         switch (*c)
1040                           {
1041                           case '-':
1042                             c++;
1043                             
1044                             while (*c >= '0' && *c <= '9')
1045                               bitend = (bitend * 10) + *c++ - '0';
1046                             
1047                             if (!bitend)
1048                               abort ();
1049                             
1050                             switch (*c)
1051                               {
1052                               case 'r':
1053                                 {
1054                                   long reg;
1055                                   
1056                                   reg = given >> bitstart;
1057                                   reg &= (2 << (bitend - bitstart)) - 1;
1058                                   
1059                                   func (stream, "%s", arm_regnames[reg]);
1060                                 }
1061                                 break;
1062                               case 'd':
1063                                 {
1064                                   long reg;
1065                                   
1066                                   reg = given >> bitstart;
1067                                   reg &= (2 << (bitend - bitstart)) - 1;
1068                                   
1069                                   func (stream, "%d", reg);
1070                                 }
1071                                 break;
1072                               case 'x':
1073                                 {
1074                                   long reg;
1075                                   
1076                                   reg = given >> bitstart;
1077                                   reg &= (2 << (bitend - bitstart)) - 1;
1078                                   
1079                                   func (stream, "0x%08x", reg);
1080                                   
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");
1087                                 }
1088                                 break;
1089                               case 'X':
1090                                 {
1091                                   long reg;
1092                                   
1093                                   reg = given >> bitstart;
1094                                   reg &= (2 << (bitend - bitstart)) - 1;
1095                                   
1096                                   func (stream, "%01x", reg & 0xf);
1097                                 }
1098                                 break;
1099                               case 'f':
1100                                 {
1101                                   long reg;
1102                                   
1103                                   reg = given >> bitstart;
1104                                   reg &= (2 << (bitend - bitstart)) - 1;
1105                                   
1106                                   if (reg > 7)
1107                                     func (stream, "#%s",
1108                                           arm_fp_const[reg & 7]);
1109                                   else
1110                                     func (stream, "f%d", reg);
1111                                 }
1112                                 break;
1113                               default:
1114                                 abort ();
1115                               }
1116                             break;
1117
1118                           case 'y':
1119                           case 'z':
1120                             {
1121                               int single = *c == 'y';
1122                               int regno;
1123
1124                               switch (bitstart)
1125                                 {
1126                                 case 4: /* Sm pair */
1127                                   func (stream, "{");
1128                                   /* Fall through.  */
1129                                 case 0: /* Sm, Dm */
1130                                   regno = given & 0x0000000f;
1131                                   if (single)
1132                                     {
1133                                       regno <<= 1;
1134                                       regno += (given >> 5) & 1;
1135                                     }
1136                                   break;
1137
1138                                 case 1: /* Sd, Dd */
1139                                   regno = (given >> 12) & 0x0000000f;
1140                                   if (single)
1141                                     {
1142                                       regno <<= 1;
1143                                       regno += (given >> 22) & 1;
1144                                     }
1145                                   break;
1146
1147                                 case 2: /* Sn, Dn */
1148                                   regno = (given >> 16) & 0x0000000f;
1149                                   if (single)
1150                                     {
1151                                       regno <<= 1;
1152                                       regno += (given >> 7) & 1;
1153                                     }
1154                                   break;
1155
1156                                 case 3: /* List */
1157                                   func (stream, "{");
1158                                   regno = (given >> 12) & 0x0000000f;
1159                                   if (single)
1160                                     {
1161                                       regno <<= 1;
1162                                       regno += (given >> 22) & 1;
1163                                     }
1164                                   break;
1165
1166                                   
1167                                 default:
1168                                   abort ();
1169                                 }
1170
1171                               func (stream, "%c%d", single ? 's' : 'd', regno);
1172
1173                               if (bitstart == 3)
1174                                 {
1175                                   int count = given & 0xff;
1176
1177                                   if (single == 0)
1178                                     count >>= 1;
1179
1180                                   if (--count)
1181                                     {
1182                                       func (stream, "-%c%d",
1183                                             single ? 's' : 'd',
1184                                             regno + count);
1185                                     }
1186
1187                                   func (stream, "}");
1188                                 }
1189                               else if (bitstart == 4)
1190                                 func (stream, ", %c%d}", single ? 's' : 'd',
1191                                       regno + 1);
1192
1193                               break;
1194                             }
1195
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 ();
1215                           }
1216                         break;
1217
1218                       default:
1219                         abort ();
1220                       }
1221                     }
1222                 }
1223               else
1224                 func (stream, "%c", *c);
1225             }
1226           return 4;
1227         }
1228     }
1229   abort ();
1230 }
1231
1232 /* Print one instruction from PC on INFO->STREAM.
1233    Return the size of the instruction. */
1234
1235 static int
1236 print_insn_thumb (pc, info, given)
1237      bfd_vma                   pc;
1238      struct disassemble_info * info;
1239      long                      given;
1240 {
1241   struct thumb_opcode * insn;
1242   void *                stream = info->stream;
1243   fprintf_ftype         func = info->fprintf_func;
1244
1245   for (insn = thumb_opcodes; insn->assembler; insn++)
1246     {
1247       if ((given & insn->mask) == insn->value)
1248         {
1249           char * c = insn->assembler;
1250
1251           /* Special processing for Thumb 2 instruction BL sequence:  */
1252           if (!*c) /* Check for empty (not NULL) assembler string.  */
1253             {
1254               long offset;
1255               
1256               info->bytes_per_chunk = 4;
1257               info->bytes_per_line  = 4;
1258
1259               offset = BDISP23 (given);
1260               offset = offset * 2 + pc + 4;
1261
1262               if ((given & 0x10000000) == 0)
1263                 {
1264                   func (stream, "blx\t");
1265                   offset &= 0xfffffffc;
1266                 }
1267               else
1268                 func (stream, "bl\t");
1269
1270               info->print_address_func (offset, info);
1271               return 4;
1272             }
1273           else
1274             {
1275               info->bytes_per_chunk = 2;
1276               info->bytes_per_line  = 4;
1277                       
1278               given &= 0xffff;
1279               
1280               for (; *c; c++)
1281                 {
1282                   if (*c == '%')
1283                     {
1284                       int domaskpc = 0;
1285                       int domasklr = 0;
1286                       
1287                       switch (*++c)
1288                         {
1289                         case '%':
1290                           func (stream, "%%");
1291                           break;
1292
1293                         case 'S':
1294                           {
1295                             long reg;
1296                             
1297                             reg = (given >> 3) & 0x7;
1298                             if (given & (1 << 6))
1299                               reg += 8;
1300                             
1301                             func (stream, "%s", arm_regnames[reg]);
1302                           }
1303                           break;
1304
1305                         case 'D':
1306                           {
1307                             long reg;
1308                             
1309                             reg = given & 0x7;
1310                             if (given & (1 << 7))
1311                              reg += 8;
1312                             
1313                             func (stream, "%s", arm_regnames[reg]);
1314                           }
1315                           break;
1316
1317                         case 'T':
1318                           func (stream, "%s",
1319                                 arm_conditional [(given >> 8) & 0xf]);
1320                           break;
1321
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':
1331                           {
1332                             int started = 0;
1333                             int reg;
1334                             
1335                             func (stream, "{");
1336                             
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)
1341                                 {
1342                                   if (started)
1343                                     func (stream, ", ");
1344                                   started = 1;
1345                                   func (stream, "%s", arm_regnames[reg]);
1346                                 }
1347
1348                             if (domasklr)
1349                               {
1350                                 if (started)
1351                                   func (stream, ", ");
1352                                 started = 1;
1353                                 func (stream, arm_regnames[14] /* "lr" */);
1354                               }
1355
1356                             if (domaskpc)
1357                               {
1358                                 if (started)
1359                                   func (stream, ", ");
1360                                 func (stream, arm_regnames[15] /* "pc" */);
1361                               }
1362
1363                             func (stream, "}");
1364                           }
1365                           break;
1366
1367
1368                         case '0': case '1': case '2': case '3': case '4': 
1369                         case '5': case '6': case '7': case '8': case '9':
1370                           {
1371                             int bitstart = *c++ - '0';
1372                             int bitend = 0;
1373                             
1374                             while (*c >= '0' && *c <= '9')
1375                               bitstart = (bitstart * 10) + *c++ - '0';
1376
1377                             switch (*c)
1378                               {
1379                               case '-':
1380                                 {
1381                                   long reg;
1382                                   
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)
1391                                     {
1392                                     case 'r':
1393                                       func (stream, "%s", arm_regnames[reg]);
1394                                       break;
1395
1396                                     case 'd':
1397                                       func (stream, "%d", reg);
1398                                       break;
1399
1400                                     case 'H':
1401                                       func (stream, "%d", reg << 1);
1402                                       break;
1403
1404                                     case 'W':
1405                                       func (stream, "%d", reg << 2);
1406                                       break;
1407
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;
1415
1416                                     case 'x':
1417                                       func (stream, "0x%04x", reg);
1418                                       break;
1419
1420                                     case 'I':
1421                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1422                                       func (stream, "%d", reg);
1423                                       break;
1424
1425                                     case 'B':
1426                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1427                                       (*info->print_address_func)
1428                                         (reg * 2 + pc + 4, info);
1429                                       break;
1430
1431                                     default:
1432                                       abort ();
1433                                     }
1434                                 }
1435                                 break;
1436
1437                               case '\'':
1438                                 c++;
1439                                 if ((given & (1 << bitstart)) != 0)
1440                                   func (stream, "%c", *c);
1441                                 break;
1442
1443                               case '?':
1444                                 ++c;
1445                                 if ((given & (1 << bitstart)) != 0)
1446                                   func (stream, "%c", *c++);
1447                                 else
1448                                   func (stream, "%c", *++c);
1449                                 break;
1450
1451                               default:
1452                                  abort ();
1453                               }
1454                           }
1455                           break;
1456
1457                         default:
1458                           abort ();
1459                         }
1460                     }
1461                   else
1462                     func (stream, "%c", *c);
1463                 }
1464              }
1465           return 2;
1466        }
1467     }
1468
1469   /* No match.  */
1470   abort ();
1471 }
1472
1473 /* Parse an individual disassembler option.  */
1474
1475 void
1476 parse_arm_disassembler_option (option)
1477      char * option;
1478 {
1479   if (option == NULL)
1480     return;
1481       
1482   if (strneq (option, "reg-names-", 10))
1483     {
1484       int i;
1485         
1486       option += 10;
1487
1488       for (i = NUM_ARM_REGNAMES; i--;)
1489         if (streq (option, regnames[i].name))
1490           {
1491             regname_selected = i;
1492             break;
1493           }
1494       
1495       if (i < 0)
1496         fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1497     }
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);
1504   
1505   return;
1506 }
1507
1508 /* Parse the string of disassembler options, spliting it at whitespaces.  */
1509
1510 static void
1511 parse_disassembler_options (options)
1512      char * options;
1513 {
1514   char * space;
1515   
1516   if (options == NULL)
1517     return;
1518
1519   do
1520     {
1521       space = strchr (options, ' ');
1522
1523       if (space)
1524         {
1525           * space = '\0';
1526           parse_arm_disassembler_option (options);
1527           * space = ' ';
1528           options = space + 1;
1529         }
1530       else
1531         parse_arm_disassembler_option (options);
1532     }
1533   while (space);
1534 }
1535
1536 /* NOTE: There are no checks in these routines that
1537    the relevant number of data bytes exist.  */
1538
1539 int
1540 print_insn_arm (pc, info)
1541      bfd_vma pc;
1542      struct disassemble_info * info;
1543 {
1544   unsigned char      b[4];
1545   long               given;
1546   int                status;
1547   int                is_thumb;
1548   int little;
1549
1550   if (info->disassembler_options)
1551     {
1552       parse_disassembler_options (info->disassembler_options);
1553       
1554       /* To avoid repeated parsing of these options, we remove them here.  */
1555       info->disassembler_options = NULL;
1556     }
1557   
1558   is_thumb = force_thumb;
1559   if (pc & 1)
1560     {
1561       is_thumb = 1;
1562       pc &= ~(bfd_vma) 1;
1563     }
1564   
1565 #if 0
1566   if (!is_thumb && info->symbols != NULL)
1567     {
1568       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1569         {
1570           coff_symbol_type * cs;
1571           
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);
1578         }
1579       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1580         {
1581           elf_symbol_type *  es;
1582           unsigned int       type;
1583           
1584           es = *(elf_symbol_type **)(info->symbols);
1585           type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1586           
1587           is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1588         }
1589     }
1590 #endif
1591   
1592   little = (info->endian == BFD_ENDIAN_LITTLE);
1593   info->bytes_per_chunk = 4;
1594   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1595
1596   if (little)
1597     {
1598       status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1599       if (status != 0 && is_thumb)
1600         {
1601           info->bytes_per_chunk = 2;
1602           
1603           status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1604           b[3] = b[2] = 0;
1605         }
1606       
1607       if (status != 0)
1608         {
1609           info->memory_error_func (status, pc, info);
1610           return -1;
1611         }
1612       
1613       given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1614     }
1615   else
1616     {
1617       status = info->read_memory_func
1618         (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1619       if (status != 0)
1620         {
1621           info->memory_error_func (status, pc, info);
1622           return -1;
1623         }
1624       
1625       if (is_thumb)
1626         {
1627           if (pc & 0x2)
1628             {
1629               given = (b[2] << 8) | b[3];
1630               
1631               status = info->read_memory_func
1632                 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1633               if (status != 0)
1634                 {
1635                   info->memory_error_func (status, pc + 4, info);
1636                   return -1;
1637                 }
1638               
1639               given |= (b[0] << 24) | (b[1] << 16);
1640             }
1641           else
1642             given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1643         }
1644       else
1645         given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1646     }
1647   
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);
1659
1660   return status;
1661 }
1662
1663 void
1664 print_arm_disassembler_options (FILE * stream)
1665 {
1666   int i;
1667
1668   fprintf (stream, _("\n\
1669 The following ARM specific disassembler options are supported for use with\n\
1670 the -M switch:\n"));
1671   
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);
1677
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");
1680 }