* ecoff.c: Convert to ISO-C.
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
6 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
7
8 This file is part of GAS, the GNU Assembler.
9
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 02111-1307, USA. */
24
25 #include <string.h>
26 #define NO_RELOC 0
27 #include "as.h"
28 #include "safe-ctype.h"
29
30 /* Need TARGET_CPU. */
31 #include "config.h"
32 #include "subsegs.h"
33 #include "obstack.h"
34 #include "symbols.h"
35 #include "listing.h"
36
37 #ifdef OBJ_ELF
38 #include "elf/arm.h"
39 #include "dwarf2dbg.h"
40 #endif
41
42 /* XXX Set this to 1 after the next binutils release */
43 #define WARN_DEPRECATED 0
44
45 /* The following bitmasks control CPU extensions: */
46 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
47 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
48 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
49 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
50 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
51 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
52 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
53 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
54 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
55 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
56 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
57 #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
58
59 /* Co-processor space extensions. */
60 #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
61 #define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
62 #define ARM_CEXT_IWMMXT 0x00200000 /* Intel Wireless MMX technology coprocessor. */
63
64 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
65 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
66 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
67 three more to cover cores prior to ARM6. Finally, there are cores which
68 implement further extensions in the co-processor space. */
69 #define ARM_ARCH_V1 ARM_EXT_V1
70 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
71 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
72 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
73 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
74 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
75 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
76 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
77 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
78 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
79 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
80 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
81 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
82 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
83 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
84 #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)
85
86 /* Processors with specific extensions in the co-processor space. */
87 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
88 #define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
89
90 /* Some useful combinations: */
91 #define ARM_ANY 0x0000ffff /* Any basic core. */
92 #define ARM_ALL 0x00ffffff /* Any core + co-processor */
93 #define CPROC_ANY 0x00ff0000 /* Any co-processor */
94 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
95
96
97 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
98 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
99 #define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
100 #define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
101 #define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
102 #define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
103 #define FPU_NONE 0
104
105 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
106 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
107
108 #define FPU_ARCH_VFP FPU_VFP_EXT_NONE
109 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
110 #define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
111 #define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
112
113 /* Types of processor to assemble for. */
114 #define ARM_1 ARM_ARCH_V1
115 #define ARM_2 ARM_ARCH_V2
116 #define ARM_3 ARM_ARCH_V2S
117 #define ARM_250 ARM_ARCH_V2S
118 #define ARM_6 ARM_ARCH_V3
119 #define ARM_7 ARM_ARCH_V3
120 #define ARM_8 ARM_ARCH_V4
121 #define ARM_9 ARM_ARCH_V4T
122 #define ARM_STRONG ARM_ARCH_V4
123 #define ARM_CPU_MASK 0x0000000f /* XXX? */
124
125 #ifndef CPU_DEFAULT
126 #if defined __XSCALE__
127 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
128 #else
129 #if defined __thumb__
130 #define CPU_DEFAULT (ARM_ARCH_V5T)
131 #else
132 #define CPU_DEFAULT ARM_ANY
133 #endif
134 #endif
135 #endif
136
137 #ifdef TE_LINUX
138 #define FPU_DEFAULT FPU_ARCH_FPA
139 #endif
140
141 #ifdef TE_NetBSD
142 #ifdef OBJ_ELF
143 #define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
144 #else
145 /* Legacy a.out format. */
146 #define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
147 #endif
148 #endif
149
150 /* For backwards compatibility we default to the FPA. */
151 #ifndef FPU_DEFAULT
152 #define FPU_DEFAULT FPU_ARCH_FPA
153 #endif
154
155 #define streq(a, b) (strcmp (a, b) == 0)
156 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
157
158 static unsigned long cpu_variant;
159 static int target_oabi = 0;
160
161 /* Flags stored in private area of BFD structure. */
162 static int uses_apcs_26 = FALSE;
163 static int atpcs = FALSE;
164 static int support_interwork = FALSE;
165 static int uses_apcs_float = FALSE;
166 static int pic_code = FALSE;
167
168 /* Variables that we set while parsing command-line options. Once all
169 options have been read we re-process these values to set the real
170 assembly flags. */
171 static int legacy_cpu = -1;
172 static int legacy_fpu = -1;
173
174 static int mcpu_cpu_opt = -1;
175 static int mcpu_fpu_opt = -1;
176 static int march_cpu_opt = -1;
177 static int march_fpu_opt = -1;
178 static int mfpu_opt = -1;
179
180 /* This array holds the chars that always start a comment. If the
181 pre-processor is disabled, these aren't very useful. */
182 const char comment_chars[] = "@";
183
184 /* This array holds the chars that only start a comment at the beginning of
185 a line. If the line seems to have the form '# 123 filename'
186 .line and .file directives will appear in the pre-processed output. */
187 /* Note that input_file.c hand checks for '#' at the beginning of the
188 first line of the input file. This is because the compiler outputs
189 #NO_APP at the beginning of its output. */
190 /* Also note that comments like this one will always work. */
191 const char line_comment_chars[] = "#";
192
193 const char line_separator_chars[] = ";";
194
195 /* Chars that can be used to separate mant
196 from exp in floating point numbers. */
197 const char EXP_CHARS[] = "eE";
198
199 /* Chars that mean this number is a floating point constant. */
200 /* As in 0f12.456 */
201 /* or 0d1.2345e12 */
202
203 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
204
205 /* Prefix characters that indicate the start of an immediate
206 value. */
207 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
208
209 #ifdef OBJ_ELF
210 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
211 symbolS * GOT_symbol;
212 #endif
213
214 /* Size of relocation record. */
215 const int md_reloc_size = 8;
216
217 /* 0: assemble for ARM,
218 1: assemble for Thumb,
219 2: assemble for Thumb even though target CPU does not support thumb
220 instructions. */
221 static int thumb_mode = 0;
222
223 typedef struct arm_fix
224 {
225 int thumb_mode;
226 } arm_fix_data;
227
228 struct arm_it
229 {
230 const char * error;
231 unsigned long instruction;
232 int size;
233 struct
234 {
235 bfd_reloc_code_real_type type;
236 expressionS exp;
237 int pc_rel;
238 } reloc;
239 };
240
241 struct arm_it inst;
242
243 enum asm_shift_index
244 {
245 SHIFT_LSL = 0,
246 SHIFT_LSR,
247 SHIFT_ASR,
248 SHIFT_ROR,
249 SHIFT_RRX
250 };
251
252 struct asm_shift_properties
253 {
254 enum asm_shift_index index;
255 unsigned long bit_field;
256 unsigned int allows_0 : 1;
257 unsigned int allows_32 : 1;
258 };
259
260 static const struct asm_shift_properties shift_properties [] =
261 {
262 { SHIFT_LSL, 0, 1, 0},
263 { SHIFT_LSR, 0x20, 0, 1},
264 { SHIFT_ASR, 0x40, 0, 1},
265 { SHIFT_ROR, 0x60, 0, 0},
266 { SHIFT_RRX, 0x60, 0, 0}
267 };
268
269 struct asm_shift_name
270 {
271 const char * name;
272 const struct asm_shift_properties * properties;
273 };
274
275 static const struct asm_shift_name shift_names [] =
276 {
277 { "asl", shift_properties + SHIFT_LSL },
278 { "lsl", shift_properties + SHIFT_LSL },
279 { "lsr", shift_properties + SHIFT_LSR },
280 { "asr", shift_properties + SHIFT_ASR },
281 { "ror", shift_properties + SHIFT_ROR },
282 { "rrx", shift_properties + SHIFT_RRX },
283 { "ASL", shift_properties + SHIFT_LSL },
284 { "LSL", shift_properties + SHIFT_LSL },
285 { "LSR", shift_properties + SHIFT_LSR },
286 { "ASR", shift_properties + SHIFT_ASR },
287 { "ROR", shift_properties + SHIFT_ROR },
288 { "RRX", shift_properties + SHIFT_RRX }
289 };
290
291 #define NO_SHIFT_RESTRICT 1
292 #define SHIFT_RESTRICT 0
293
294 #define NUM_FLOAT_VALS 8
295
296 const char * fp_const[] =
297 {
298 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
299 };
300
301 /* Number of littlenums required to hold an extended precision number. */
302 #define MAX_LITTLENUMS 6
303
304 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
305
306 #define FAIL (-1)
307 #define SUCCESS (0)
308
309 /* Whether a Co-processor load/store operation accepts write-back forms. */
310 #define CP_WB_OK 1
311 #define CP_NO_WB 0
312
313 #define SUFF_S 1
314 #define SUFF_D 2
315 #define SUFF_E 3
316 #define SUFF_P 4
317
318 #define CP_T_X 0x00008000
319 #define CP_T_Y 0x00400000
320 #define CP_T_Pre 0x01000000
321 #define CP_T_UD 0x00800000
322 #define CP_T_WB 0x00200000
323
324 #define CONDS_BIT 0x00100000
325 #define LOAD_BIT 0x00100000
326
327 #define DOUBLE_LOAD_FLAG 0x00000001
328
329 struct asm_cond
330 {
331 const char * template;
332 unsigned long value;
333 };
334
335 #define COND_ALWAYS 0xe0000000
336 #define COND_MASK 0xf0000000
337
338 static const struct asm_cond conds[] =
339 {
340 {"eq", 0x00000000},
341 {"ne", 0x10000000},
342 {"cs", 0x20000000}, {"hs", 0x20000000},
343 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
344 {"mi", 0x40000000},
345 {"pl", 0x50000000},
346 {"vs", 0x60000000},
347 {"vc", 0x70000000},
348 {"hi", 0x80000000},
349 {"ls", 0x90000000},
350 {"ge", 0xa0000000},
351 {"lt", 0xb0000000},
352 {"gt", 0xc0000000},
353 {"le", 0xd0000000},
354 {"al", 0xe0000000},
355 {"nv", 0xf0000000}
356 };
357
358 struct asm_psr
359 {
360 const char *template;
361 bfd_boolean cpsr;
362 unsigned long field;
363 };
364
365 /* The bit that distinguishes CPSR and SPSR. */
366 #define SPSR_BIT (1 << 22)
367
368 /* How many bits to shift the PSR_xxx bits up by. */
369 #define PSR_SHIFT 16
370
371 #define PSR_c (1 << 0)
372 #define PSR_x (1 << 1)
373 #define PSR_s (1 << 2)
374 #define PSR_f (1 << 3)
375
376 static const struct asm_psr psrs[] =
377 {
378 {"CPSR", TRUE, PSR_c | PSR_f},
379 {"CPSR_all", TRUE, PSR_c | PSR_f},
380 {"SPSR", FALSE, PSR_c | PSR_f},
381 {"SPSR_all", FALSE, PSR_c | PSR_f},
382 {"CPSR_flg", TRUE, PSR_f},
383 {"CPSR_f", TRUE, PSR_f},
384 {"SPSR_flg", FALSE, PSR_f},
385 {"SPSR_f", FALSE, PSR_f},
386 {"CPSR_c", TRUE, PSR_c},
387 {"CPSR_ctl", TRUE, PSR_c},
388 {"SPSR_c", FALSE, PSR_c},
389 {"SPSR_ctl", FALSE, PSR_c},
390 {"CPSR_x", TRUE, PSR_x},
391 {"CPSR_s", TRUE, PSR_s},
392 {"SPSR_x", FALSE, PSR_x},
393 {"SPSR_s", FALSE, PSR_s},
394 /* Combinations of flags. */
395 {"CPSR_fs", TRUE, PSR_f | PSR_s},
396 {"CPSR_fx", TRUE, PSR_f | PSR_x},
397 {"CPSR_fc", TRUE, PSR_f | PSR_c},
398 {"CPSR_sf", TRUE, PSR_s | PSR_f},
399 {"CPSR_sx", TRUE, PSR_s | PSR_x},
400 {"CPSR_sc", TRUE, PSR_s | PSR_c},
401 {"CPSR_xf", TRUE, PSR_x | PSR_f},
402 {"CPSR_xs", TRUE, PSR_x | PSR_s},
403 {"CPSR_xc", TRUE, PSR_x | PSR_c},
404 {"CPSR_cf", TRUE, PSR_c | PSR_f},
405 {"CPSR_cs", TRUE, PSR_c | PSR_s},
406 {"CPSR_cx", TRUE, PSR_c | PSR_x},
407 {"CPSR_fsx", TRUE, PSR_f | PSR_s | PSR_x},
408 {"CPSR_fsc", TRUE, PSR_f | PSR_s | PSR_c},
409 {"CPSR_fxs", TRUE, PSR_f | PSR_x | PSR_s},
410 {"CPSR_fxc", TRUE, PSR_f | PSR_x | PSR_c},
411 {"CPSR_fcs", TRUE, PSR_f | PSR_c | PSR_s},
412 {"CPSR_fcx", TRUE, PSR_f | PSR_c | PSR_x},
413 {"CPSR_sfx", TRUE, PSR_s | PSR_f | PSR_x},
414 {"CPSR_sfc", TRUE, PSR_s | PSR_f | PSR_c},
415 {"CPSR_sxf", TRUE, PSR_s | PSR_x | PSR_f},
416 {"CPSR_sxc", TRUE, PSR_s | PSR_x | PSR_c},
417 {"CPSR_scf", TRUE, PSR_s | PSR_c | PSR_f},
418 {"CPSR_scx", TRUE, PSR_s | PSR_c | PSR_x},
419 {"CPSR_xfs", TRUE, PSR_x | PSR_f | PSR_s},
420 {"CPSR_xfc", TRUE, PSR_x | PSR_f | PSR_c},
421 {"CPSR_xsf", TRUE, PSR_x | PSR_s | PSR_f},
422 {"CPSR_xsc", TRUE, PSR_x | PSR_s | PSR_c},
423 {"CPSR_xcf", TRUE, PSR_x | PSR_c | PSR_f},
424 {"CPSR_xcs", TRUE, PSR_x | PSR_c | PSR_s},
425 {"CPSR_cfs", TRUE, PSR_c | PSR_f | PSR_s},
426 {"CPSR_cfx", TRUE, PSR_c | PSR_f | PSR_x},
427 {"CPSR_csf", TRUE, PSR_c | PSR_s | PSR_f},
428 {"CPSR_csx", TRUE, PSR_c | PSR_s | PSR_x},
429 {"CPSR_cxf", TRUE, PSR_c | PSR_x | PSR_f},
430 {"CPSR_cxs", TRUE, PSR_c | PSR_x | PSR_s},
431 {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
432 {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
433 {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
434 {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
435 {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
436 {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
437 {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
438 {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
439 {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
440 {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
441 {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
442 {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
443 {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
444 {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
445 {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
446 {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
447 {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
448 {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
449 {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
450 {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
451 {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
452 {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
453 {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
454 {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
455 {"SPSR_fs", FALSE, PSR_f | PSR_s},
456 {"SPSR_fx", FALSE, PSR_f | PSR_x},
457 {"SPSR_fc", FALSE, PSR_f | PSR_c},
458 {"SPSR_sf", FALSE, PSR_s | PSR_f},
459 {"SPSR_sx", FALSE, PSR_s | PSR_x},
460 {"SPSR_sc", FALSE, PSR_s | PSR_c},
461 {"SPSR_xf", FALSE, PSR_x | PSR_f},
462 {"SPSR_xs", FALSE, PSR_x | PSR_s},
463 {"SPSR_xc", FALSE, PSR_x | PSR_c},
464 {"SPSR_cf", FALSE, PSR_c | PSR_f},
465 {"SPSR_cs", FALSE, PSR_c | PSR_s},
466 {"SPSR_cx", FALSE, PSR_c | PSR_x},
467 {"SPSR_fsx", FALSE, PSR_f | PSR_s | PSR_x},
468 {"SPSR_fsc", FALSE, PSR_f | PSR_s | PSR_c},
469 {"SPSR_fxs", FALSE, PSR_f | PSR_x | PSR_s},
470 {"SPSR_fxc", FALSE, PSR_f | PSR_x | PSR_c},
471 {"SPSR_fcs", FALSE, PSR_f | PSR_c | PSR_s},
472 {"SPSR_fcx", FALSE, PSR_f | PSR_c | PSR_x},
473 {"SPSR_sfx", FALSE, PSR_s | PSR_f | PSR_x},
474 {"SPSR_sfc", FALSE, PSR_s | PSR_f | PSR_c},
475 {"SPSR_sxf", FALSE, PSR_s | PSR_x | PSR_f},
476 {"SPSR_sxc", FALSE, PSR_s | PSR_x | PSR_c},
477 {"SPSR_scf", FALSE, PSR_s | PSR_c | PSR_f},
478 {"SPSR_scx", FALSE, PSR_s | PSR_c | PSR_x},
479 {"SPSR_xfs", FALSE, PSR_x | PSR_f | PSR_s},
480 {"SPSR_xfc", FALSE, PSR_x | PSR_f | PSR_c},
481 {"SPSR_xsf", FALSE, PSR_x | PSR_s | PSR_f},
482 {"SPSR_xsc", FALSE, PSR_x | PSR_s | PSR_c},
483 {"SPSR_xcf", FALSE, PSR_x | PSR_c | PSR_f},
484 {"SPSR_xcs", FALSE, PSR_x | PSR_c | PSR_s},
485 {"SPSR_cfs", FALSE, PSR_c | PSR_f | PSR_s},
486 {"SPSR_cfx", FALSE, PSR_c | PSR_f | PSR_x},
487 {"SPSR_csf", FALSE, PSR_c | PSR_s | PSR_f},
488 {"SPSR_csx", FALSE, PSR_c | PSR_s | PSR_x},
489 {"SPSR_cxf", FALSE, PSR_c | PSR_x | PSR_f},
490 {"SPSR_cxs", FALSE, PSR_c | PSR_x | PSR_s},
491 {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
492 {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
493 {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
494 {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
495 {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
496 {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
497 {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
498 {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
499 {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
500 {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
501 {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
502 {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
503 {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
504 {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
505 {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
506 {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
507 {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
508 {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
509 {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
510 {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
511 {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
512 {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
513 {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
514 {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
515 };
516
517 enum wreg_type
518 {
519 IWMMXT_REG_WR = 0,
520 IWMMXT_REG_WC = 1,
521 IWMMXT_REG_WR_OR_WC = 2,
522 IWMMXT_REG_WCG
523 };
524
525 enum iwmmxt_insn_type
526 {
527 check_rd,
528 check_wr,
529 check_wrwr,
530 check_wrwrwr,
531 check_wrwrwcg,
532 check_tbcst,
533 check_tmovmsk,
534 check_tmia,
535 check_tmcrr,
536 check_tmrrc,
537 check_tmcr,
538 check_tmrc,
539 check_tinsr,
540 check_textrc,
541 check_waligni,
542 check_textrm,
543 check_wshufh
544 };
545
546 enum vfp_dp_reg_pos
547 {
548 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
549 };
550
551 enum vfp_sp_reg_pos
552 {
553 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
554 };
555
556 enum vfp_ldstm_type
557 {
558 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
559 };
560
561 /* VFP system registers. */
562 struct vfp_reg
563 {
564 const char *name;
565 unsigned long regno;
566 };
567
568 static const struct vfp_reg vfp_regs[] =
569 {
570 {"fpsid", 0x00000000},
571 {"FPSID", 0x00000000},
572 {"fpscr", 0x00010000},
573 {"FPSCR", 0x00010000},
574 {"fpexc", 0x00080000},
575 {"FPEXC", 0x00080000}
576 };
577
578 /* Structure for a hash table entry for a register. */
579 struct reg_entry
580 {
581 const char * name;
582 int number;
583 bfd_boolean builtin;
584 };
585
586 /* Some well known registers that we refer to directly elsewhere. */
587 #define REG_SP 13
588 #define REG_LR 14
589 #define REG_PC 15
590
591 #define wr_register(reg) ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
592 #define wc_register(reg) ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
593 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
594
595 /* These are the standard names. Users can add aliases with .req.
596 and delete them with .unreq. */
597
598 /* Integer Register Numbers. */
599 static const struct reg_entry rn_table[] =
600 {
601 {"r0", 0, TRUE}, {"r1", 1, TRUE}, {"r2", 2, TRUE}, {"r3", 3, TRUE},
602 {"r4", 4, TRUE}, {"r5", 5, TRUE}, {"r6", 6, TRUE}, {"r7", 7, TRUE},
603 {"r8", 8, TRUE}, {"r9", 9, TRUE}, {"r10", 10, TRUE}, {"r11", 11, TRUE},
604 {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
605 /* ATPCS Synonyms. */
606 {"a1", 0, TRUE}, {"a2", 1, TRUE}, {"a3", 2, TRUE}, {"a4", 3, TRUE},
607 {"v1", 4, TRUE}, {"v2", 5, TRUE}, {"v3", 6, TRUE}, {"v4", 7, TRUE},
608 {"v5", 8, TRUE}, {"v6", 9, TRUE}, {"v7", 10, TRUE}, {"v8", 11, TRUE},
609 /* Well-known aliases. */
610 {"wr", 7, TRUE}, {"sb", 9, TRUE}, {"sl", 10, TRUE}, {"fp", 11, TRUE},
611 {"ip", 12, TRUE}, {"sp", REG_SP, TRUE}, {"lr", REG_LR, TRUE}, {"pc", REG_PC, TRUE},
612 {NULL, 0, TRUE}
613 };
614
615 #define WR_PREFIX 0x200
616 #define WC_PREFIX 0x400
617
618 static const struct reg_entry iwmmxt_table[] =
619 {
620 /* Intel Wireless MMX technology register names. */
621 { "wr0", 0x0 | WR_PREFIX, TRUE}, {"wr1", 0x1 | WR_PREFIX, TRUE},
622 { "wr2", 0x2 | WR_PREFIX, TRUE}, {"wr3", 0x3 | WR_PREFIX, TRUE},
623 { "wr4", 0x4 | WR_PREFIX, TRUE}, {"wr5", 0x5 | WR_PREFIX, TRUE},
624 { "wr6", 0x6 | WR_PREFIX, TRUE}, {"wr7", 0x7 | WR_PREFIX, TRUE},
625 { "wr8", 0x8 | WR_PREFIX, TRUE}, {"wr9", 0x9 | WR_PREFIX, TRUE},
626 { "wr10", 0xa | WR_PREFIX, TRUE}, {"wr11", 0xb | WR_PREFIX, TRUE},
627 { "wr12", 0xc | WR_PREFIX, TRUE}, {"wr13", 0xd | WR_PREFIX, TRUE},
628 { "wr14", 0xe | WR_PREFIX, TRUE}, {"wr15", 0xf | WR_PREFIX, TRUE},
629 { "wcid", 0x0 | WC_PREFIX, TRUE}, {"wcon", 0x1 | WC_PREFIX, TRUE},
630 {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
631 {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
632 {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
633
634 { "wR0", 0x0 | WR_PREFIX, TRUE}, {"wR1", 0x1 | WR_PREFIX, TRUE},
635 { "wR2", 0x2 | WR_PREFIX, TRUE}, {"wR3", 0x3 | WR_PREFIX, TRUE},
636 { "wR4", 0x4 | WR_PREFIX, TRUE}, {"wR5", 0x5 | WR_PREFIX, TRUE},
637 { "wR6", 0x6 | WR_PREFIX, TRUE}, {"wR7", 0x7 | WR_PREFIX, TRUE},
638 { "wR8", 0x8 | WR_PREFIX, TRUE}, {"wR9", 0x9 | WR_PREFIX, TRUE},
639 { "wR10", 0xa | WR_PREFIX, TRUE}, {"wR11", 0xb | WR_PREFIX, TRUE},
640 { "wR12", 0xc | WR_PREFIX, TRUE}, {"wR13", 0xd | WR_PREFIX, TRUE},
641 { "wR14", 0xe | WR_PREFIX, TRUE}, {"wR15", 0xf | WR_PREFIX, TRUE},
642 { "wCID", 0x0 | WC_PREFIX, TRUE}, {"wCon", 0x1 | WC_PREFIX, TRUE},
643 {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
644 {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
645 {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
646 {NULL, 0, TRUE}
647 };
648
649 /* Co-processor Numbers. */
650 static const struct reg_entry cp_table[] =
651 {
652 {"p0", 0, TRUE}, {"p1", 1, TRUE}, {"p2", 2, TRUE}, {"p3", 3, TRUE},
653 {"p4", 4, TRUE}, {"p5", 5, TRUE}, {"p6", 6, TRUE}, {"p7", 7, TRUE},
654 {"p8", 8, TRUE}, {"p9", 9, TRUE}, {"p10", 10, TRUE}, {"p11", 11, TRUE},
655 {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
656 {NULL, 0, TRUE}
657 };
658
659 /* Co-processor Register Numbers. */
660 static const struct reg_entry cn_table[] =
661 {
662 {"c0", 0, TRUE}, {"c1", 1, TRUE}, {"c2", 2, TRUE}, {"c3", 3, TRUE},
663 {"c4", 4, TRUE}, {"c5", 5, TRUE}, {"c6", 6, TRUE}, {"c7", 7, TRUE},
664 {"c8", 8, TRUE}, {"c9", 9, TRUE}, {"c10", 10, TRUE}, {"c11", 11, TRUE},
665 {"c12", 12, TRUE}, {"c13", 13, TRUE}, {"c14", 14, TRUE}, {"c15", 15, TRUE},
666 /* Not really valid, but kept for back-wards compatibility. */
667 {"cr0", 0, TRUE}, {"cr1", 1, TRUE}, {"cr2", 2, TRUE}, {"cr3", 3, TRUE},
668 {"cr4", 4, TRUE}, {"cr5", 5, TRUE}, {"cr6", 6, TRUE}, {"cr7", 7, TRUE},
669 {"cr8", 8, TRUE}, {"cr9", 9, TRUE}, {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
670 {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
671 {NULL, 0, TRUE}
672 };
673
674 /* FPA Registers. */
675 static const struct reg_entry fn_table[] =
676 {
677 {"f0", 0, TRUE}, {"f1", 1, TRUE}, {"f2", 2, TRUE}, {"f3", 3, TRUE},
678 {"f4", 4, TRUE}, {"f5", 5, TRUE}, {"f6", 6, TRUE}, {"f7", 7, TRUE},
679 {NULL, 0, TRUE}
680 };
681
682 /* VFP SP Registers. */
683 static const struct reg_entry sn_table[] =
684 {
685 {"s0", 0, TRUE}, {"s1", 1, TRUE}, {"s2", 2, TRUE}, {"s3", 3, TRUE},
686 {"s4", 4, TRUE}, {"s5", 5, TRUE}, {"s6", 6, TRUE}, {"s7", 7, TRUE},
687 {"s8", 8, TRUE}, {"s9", 9, TRUE}, {"s10", 10, TRUE}, {"s11", 11, TRUE},
688 {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
689 {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
690 {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
691 {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
692 {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
693 {NULL, 0, TRUE}
694 };
695
696 /* VFP DP Registers. */
697 static const struct reg_entry dn_table[] =
698 {
699 {"d0", 0, TRUE}, {"d1", 1, TRUE}, {"d2", 2, TRUE}, {"d3", 3, TRUE},
700 {"d4", 4, TRUE}, {"d5", 5, TRUE}, {"d6", 6, TRUE}, {"d7", 7, TRUE},
701 {"d8", 8, TRUE}, {"d9", 9, TRUE}, {"d10", 10, TRUE}, {"d11", 11, TRUE},
702 {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
703 {NULL, 0, TRUE}
704 };
705
706 /* Maverick DSP coprocessor registers. */
707 static const struct reg_entry mav_mvf_table[] =
708 {
709 {"mvf0", 0, TRUE}, {"mvf1", 1, TRUE}, {"mvf2", 2, TRUE}, {"mvf3", 3, TRUE},
710 {"mvf4", 4, TRUE}, {"mvf5", 5, TRUE}, {"mvf6", 6, TRUE}, {"mvf7", 7, TRUE},
711 {"mvf8", 8, TRUE}, {"mvf9", 9, TRUE}, {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
712 {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
713 {NULL, 0, TRUE}
714 };
715
716 static const struct reg_entry mav_mvd_table[] =
717 {
718 {"mvd0", 0, TRUE}, {"mvd1", 1, TRUE}, {"mvd2", 2, TRUE}, {"mvd3", 3, TRUE},
719 {"mvd4", 4, TRUE}, {"mvd5", 5, TRUE}, {"mvd6", 6, TRUE}, {"mvd7", 7, TRUE},
720 {"mvd8", 8, TRUE}, {"mvd9", 9, TRUE}, {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
721 {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
722 {NULL, 0, TRUE}
723 };
724
725 static const struct reg_entry mav_mvfx_table[] =
726 {
727 {"mvfx0", 0, TRUE}, {"mvfx1", 1, TRUE}, {"mvfx2", 2, TRUE}, {"mvfx3", 3, TRUE},
728 {"mvfx4", 4, TRUE}, {"mvfx5", 5, TRUE}, {"mvfx6", 6, TRUE}, {"mvfx7", 7, TRUE},
729 {"mvfx8", 8, TRUE}, {"mvfx9", 9, TRUE}, {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
730 {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
731 {NULL, 0, TRUE}
732 };
733
734 static const struct reg_entry mav_mvdx_table[] =
735 {
736 {"mvdx0", 0, TRUE}, {"mvdx1", 1, TRUE}, {"mvdx2", 2, TRUE}, {"mvdx3", 3, TRUE},
737 {"mvdx4", 4, TRUE}, {"mvdx5", 5, TRUE}, {"mvdx6", 6, TRUE}, {"mvdx7", 7, TRUE},
738 {"mvdx8", 8, TRUE}, {"mvdx9", 9, TRUE}, {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
739 {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
740 {NULL, 0, TRUE}
741 };
742
743 static const struct reg_entry mav_mvax_table[] =
744 {
745 {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
746 {NULL, 0, TRUE}
747 };
748
749 static const struct reg_entry mav_dspsc_table[] =
750 {
751 {"dspsc", 0, TRUE},
752 {NULL, 0, TRUE}
753 };
754
755 struct reg_map
756 {
757 const struct reg_entry *names;
758 int max_regno;
759 struct hash_control *htab;
760 const char *expected;
761 };
762
763 struct reg_map all_reg_maps[] =
764 {
765 {rn_table, 15, NULL, N_("ARM register expected")},
766 {cp_table, 15, NULL, N_("bad or missing co-processor number")},
767 {cn_table, 15, NULL, N_("co-processor register expected")},
768 {fn_table, 7, NULL, N_("FPA register expected")},
769 {sn_table, 31, NULL, N_("VFP single precision register expected")},
770 {dn_table, 15, NULL, N_("VFP double precision register expected")},
771 {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")},
772 {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")},
773 {mav_mvfx_table, 15, NULL, N_("Maverick MVFX register expected")},
774 {mav_mvdx_table, 15, NULL, N_("Maverick MVDX register expected")},
775 {mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
776 {mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
777 {iwmmxt_table, 23, NULL, N_("Intel Wireless MMX technology register expected")},
778 };
779
780 /* Enumeration matching entries in table above. */
781 enum arm_reg_type
782 {
783 REG_TYPE_RN = 0,
784 #define REG_TYPE_FIRST REG_TYPE_RN
785 REG_TYPE_CP = 1,
786 REG_TYPE_CN = 2,
787 REG_TYPE_FN = 3,
788 REG_TYPE_SN = 4,
789 REG_TYPE_DN = 5,
790 REG_TYPE_MVF = 6,
791 REG_TYPE_MVD = 7,
792 REG_TYPE_MVFX = 8,
793 REG_TYPE_MVDX = 9,
794 REG_TYPE_MVAX = 10,
795 REG_TYPE_DSPSC = 11,
796 REG_TYPE_IWMMXT = 12,
797
798 REG_TYPE_MAX = 13
799 };
800
801 /* Functions called by parser. */
802 /* ARM instructions. */
803 static void do_arit PARAMS ((char *));
804 static void do_cmp PARAMS ((char *));
805 static void do_mov PARAMS ((char *));
806 static void do_ldst PARAMS ((char *));
807 static void do_ldstt PARAMS ((char *));
808 static void do_ldmstm PARAMS ((char *));
809 static void do_branch PARAMS ((char *));
810 static void do_swi PARAMS ((char *));
811
812 /* Pseudo Op codes. */
813 static void do_adr PARAMS ((char *));
814 static void do_adrl PARAMS ((char *));
815 static void do_empty PARAMS ((char *));
816
817 /* ARM v2. */
818 static void do_mul PARAMS ((char *));
819 static void do_mla PARAMS ((char *));
820
821 /* ARM v2S. */
822 static void do_swap PARAMS ((char *));
823
824 /* ARM v3. */
825 static void do_msr PARAMS ((char *));
826 static void do_mrs PARAMS ((char *));
827
828 /* ARM v3M. */
829 static void do_mull PARAMS ((char *));
830
831 /* ARM v4. */
832 static void do_ldstv4 PARAMS ((char *));
833
834 /* ARM v4T. */
835 static void do_bx PARAMS ((char *));
836
837 /* ARM v5T. */
838 static void do_blx PARAMS ((char *));
839 static void do_bkpt PARAMS ((char *));
840 static void do_clz PARAMS ((char *));
841 static void do_lstc2 PARAMS ((char *));
842 static void do_cdp2 PARAMS ((char *));
843 static void do_co_reg2 PARAMS ((char *));
844
845 /* ARM v5TExP. */
846 static void do_smla PARAMS ((char *));
847 static void do_smlal PARAMS ((char *));
848 static void do_smul PARAMS ((char *));
849 static void do_qadd PARAMS ((char *));
850
851 /* ARM v5TE. */
852 static void do_pld PARAMS ((char *));
853 static void do_ldrd PARAMS ((char *));
854 static void do_co_reg2c PARAMS ((char *));
855
856 /* ARM v5TEJ. */
857 static void do_bxj PARAMS ((char *));
858
859 /* Coprocessor Instructions. */
860 static void do_cdp PARAMS ((char *));
861 static void do_lstc PARAMS ((char *));
862 static void do_co_reg PARAMS ((char *));
863
864 /* FPA instructions. */
865 static void do_fpa_ctrl PARAMS ((char *));
866 static void do_fpa_ldst PARAMS ((char *));
867 static void do_fpa_ldmstm PARAMS ((char *));
868 static void do_fpa_dyadic PARAMS ((char *));
869 static void do_fpa_monadic PARAMS ((char *));
870 static void do_fpa_cmp PARAMS ((char *));
871 static void do_fpa_from_reg PARAMS ((char *));
872 static void do_fpa_to_reg PARAMS ((char *));
873
874 /* VFP instructions. */
875 static void do_vfp_sp_monadic PARAMS ((char *));
876 static void do_vfp_dp_monadic PARAMS ((char *));
877 static void do_vfp_sp_dyadic PARAMS ((char *));
878 static void do_vfp_dp_dyadic PARAMS ((char *));
879 static void do_vfp_reg_from_sp PARAMS ((char *));
880 static void do_vfp_sp_from_reg PARAMS ((char *));
881 static void do_vfp_sp_reg2 PARAMS ((char *));
882 static void do_vfp_reg_from_dp PARAMS ((char *));
883 static void do_vfp_reg2_from_dp PARAMS ((char *));
884 static void do_vfp_dp_from_reg PARAMS ((char *));
885 static void do_vfp_dp_from_reg2 PARAMS ((char *));
886 static void do_vfp_reg_from_ctrl PARAMS ((char *));
887 static void do_vfp_ctrl_from_reg PARAMS ((char *));
888 static void do_vfp_sp_ldst PARAMS ((char *));
889 static void do_vfp_dp_ldst PARAMS ((char *));
890 static void do_vfp_sp_ldstmia PARAMS ((char *));
891 static void do_vfp_sp_ldstmdb PARAMS ((char *));
892 static void do_vfp_dp_ldstmia PARAMS ((char *));
893 static void do_vfp_dp_ldstmdb PARAMS ((char *));
894 static void do_vfp_xp_ldstmia PARAMS ((char *));
895 static void do_vfp_xp_ldstmdb PARAMS ((char *));
896 static void do_vfp_sp_compare_z PARAMS ((char *));
897 static void do_vfp_dp_compare_z PARAMS ((char *));
898 static void do_vfp_dp_sp_cvt PARAMS ((char *));
899 static void do_vfp_sp_dp_cvt PARAMS ((char *));
900
901 /* XScale. */
902 static void do_xsc_mia PARAMS ((char *));
903 static void do_xsc_mar PARAMS ((char *));
904 static void do_xsc_mra PARAMS ((char *));
905
906 /* Maverick. */
907 static void do_mav_binops PARAMS ((char *, int, enum arm_reg_type,
908 enum arm_reg_type));
909 static void do_mav_binops_1a PARAMS ((char *));
910 static void do_mav_binops_1b PARAMS ((char *));
911 static void do_mav_binops_1c PARAMS ((char *));
912 static void do_mav_binops_1d PARAMS ((char *));
913 static void do_mav_binops_1e PARAMS ((char *));
914 static void do_mav_binops_1f PARAMS ((char *));
915 static void do_mav_binops_1g PARAMS ((char *));
916 static void do_mav_binops_1h PARAMS ((char *));
917 static void do_mav_binops_1i PARAMS ((char *));
918 static void do_mav_binops_1j PARAMS ((char *));
919 static void do_mav_binops_1k PARAMS ((char *));
920 static void do_mav_binops_1l PARAMS ((char *));
921 static void do_mav_binops_1m PARAMS ((char *));
922 static void do_mav_binops_1n PARAMS ((char *));
923 static void do_mav_binops_1o PARAMS ((char *));
924 static void do_mav_binops_2a PARAMS ((char *));
925 static void do_mav_binops_2b PARAMS ((char *));
926 static void do_mav_binops_2c PARAMS ((char *));
927 static void do_mav_binops_3a PARAMS ((char *));
928 static void do_mav_binops_3b PARAMS ((char *));
929 static void do_mav_binops_3c PARAMS ((char *));
930 static void do_mav_binops_3d PARAMS ((char *));
931 static void do_mav_triple PARAMS ((char *, int, enum arm_reg_type,
932 enum arm_reg_type,
933 enum arm_reg_type));
934 static void do_mav_triple_4a PARAMS ((char *));
935 static void do_mav_triple_4b PARAMS ((char *));
936 static void do_mav_triple_5a PARAMS ((char *));
937 static void do_mav_triple_5b PARAMS ((char *));
938 static void do_mav_triple_5c PARAMS ((char *));
939 static void do_mav_triple_5d PARAMS ((char *));
940 static void do_mav_triple_5e PARAMS ((char *));
941 static void do_mav_triple_5f PARAMS ((char *));
942 static void do_mav_triple_5g PARAMS ((char *));
943 static void do_mav_triple_5h PARAMS ((char *));
944 static void do_mav_quad PARAMS ((char *, int, enum arm_reg_type,
945 enum arm_reg_type,
946 enum arm_reg_type,
947 enum arm_reg_type));
948 static void do_mav_quad_6a PARAMS ((char *));
949 static void do_mav_quad_6b PARAMS ((char *));
950 static void do_mav_dspsc_1 PARAMS ((char *));
951 static void do_mav_dspsc_2 PARAMS ((char *));
952 static void do_mav_shift PARAMS ((char *, enum arm_reg_type,
953 enum arm_reg_type));
954 static void do_mav_shift_1 PARAMS ((char *));
955 static void do_mav_shift_2 PARAMS ((char *));
956 static void do_mav_ldst PARAMS ((char *, enum arm_reg_type));
957 static void do_mav_ldst_1 PARAMS ((char *));
958 static void do_mav_ldst_2 PARAMS ((char *));
959 static void do_mav_ldst_3 PARAMS ((char *));
960 static void do_mav_ldst_4 PARAMS ((char *));
961
962 static int mav_reg_required_here PARAMS ((char **, int,
963 enum arm_reg_type));
964 static int mav_parse_offset PARAMS ((char **, int *));
965
966 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
967 int, int));
968 static int arm_reg_parse PARAMS ((char **, struct hash_control *));
969 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
970 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
971 static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
972 fragS *));
973 static int add_to_lit_pool PARAMS ((void));
974 static unsigned validate_immediate PARAMS ((unsigned));
975 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
976 unsigned int *));
977 static int validate_offset_imm PARAMS ((unsigned int, int));
978 static void opcode_select PARAMS ((int));
979 static void end_of_line PARAMS ((char *));
980 static int reg_required_here PARAMS ((char **, int));
981 static int psr_required_here PARAMS ((char **));
982 static int co_proc_number PARAMS ((char **));
983 static int cp_opc_expr PARAMS ((char **, int, int));
984 static int cp_reg_required_here PARAMS ((char **, int));
985 static int fp_reg_required_here PARAMS ((char **, int));
986 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
987 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
988 static void vfp_sp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
989 static void vfp_dp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
990 static long vfp_sp_reg_list PARAMS ((char **, enum vfp_sp_reg_pos));
991 static long vfp_dp_reg_list PARAMS ((char **));
992 static int vfp_psr_required_here PARAMS ((char **str));
993 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
994 static int cp_address_offset PARAMS ((char **));
995 static int cp_address_required_here PARAMS ((char **, int));
996 static int my_get_float_expression PARAMS ((char **));
997 static int skip_past_comma PARAMS ((char **));
998 static int walk_no_bignums PARAMS ((symbolS *));
999 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
1000 static int data_op2 PARAMS ((char **));
1001 static int fp_op2 PARAMS ((char **));
1002 static long reg_list PARAMS ((char **));
1003 static void thumb_load_store PARAMS ((char *, int, int));
1004 static int decode_shift PARAMS ((char **, int));
1005 static int ldst_extend PARAMS ((char **));
1006 static int ldst_extend_v4 PARAMS ((char **));
1007 static void thumb_add_sub PARAMS ((char *, int));
1008 static void insert_reg PARAMS ((const struct reg_entry *,
1009 struct hash_control *));
1010 static void thumb_shift PARAMS ((char *, int));
1011 static void thumb_mov_compare PARAMS ((char *, int));
1012 static void build_arm_ops_hsh PARAMS ((void));
1013 static void set_constant_flonums PARAMS ((void));
1014 static valueT md_chars_to_number PARAMS ((char *, int));
1015 static void build_reg_hsh PARAMS ((struct reg_map *));
1016 static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));
1017 static int create_register_alias PARAMS ((char *, char *));
1018 static void output_inst PARAMS ((const char *));
1019 static int accum0_required_here PARAMS ((char **));
1020 static int ld_mode_required_here PARAMS ((char **));
1021 static void do_branch25 PARAMS ((char *));
1022 static symbolS * find_real_start PARAMS ((symbolS *));
1023 #ifdef OBJ_ELF
1024 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1025 #endif
1026
1027 static int wreg_required_here PARAMS ((char **, int, enum wreg_type));
1028 static void do_iwmmxt_byte_addr PARAMS ((char *));
1029 static void do_iwmmxt_tandc PARAMS ((char *));
1030 static void do_iwmmxt_tbcst PARAMS ((char *));
1031 static void do_iwmmxt_textrc PARAMS ((char *));
1032 static void do_iwmmxt_textrm PARAMS ((char *));
1033 static void do_iwmmxt_tinsr PARAMS ((char *));
1034 static void do_iwmmxt_tmcr PARAMS ((char *));
1035 static void do_iwmmxt_tmcrr PARAMS ((char *));
1036 static void do_iwmmxt_tmia PARAMS ((char *));
1037 static void do_iwmmxt_tmovmsk PARAMS ((char *));
1038 static void do_iwmmxt_tmrc PARAMS ((char *));
1039 static void do_iwmmxt_tmrrc PARAMS ((char *));
1040 static void do_iwmmxt_torc PARAMS ((char *));
1041 static void do_iwmmxt_waligni PARAMS ((char *));
1042 static void do_iwmmxt_wmov PARAMS ((char *));
1043 static void do_iwmmxt_word_addr PARAMS ((char *));
1044 static void do_iwmmxt_wrwr PARAMS ((char *));
1045 static void do_iwmmxt_wrwrwcg PARAMS ((char *));
1046 static void do_iwmmxt_wrwrwr PARAMS ((char *));
1047 static void do_iwmmxt_wshufh PARAMS ((char *));
1048 static void do_iwmmxt_wzero PARAMS ((char *));
1049 static int cp_byte_address_offset PARAMS ((char **));
1050 static int cp_byte_address_required_here PARAMS ((char **));
1051
1052 /* ARM instructions take 4bytes in the object file, Thumb instructions
1053 take 2: */
1054 #define INSN_SIZE 4
1055
1056 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1057 #define MAV_MODE1 0x100c
1058
1059 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
1060 #define MAV_MODE2 0x0c10
1061
1062 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
1063 #define MAV_MODE3 0x1000
1064
1065 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
1066 #define MAV_MODE4 0x0c0010
1067
1068 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
1069 #define MAV_MODE5 0x00100c
1070
1071 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
1072 #define MAV_MODE6 0x00100c05
1073
1074 struct asm_opcode
1075 {
1076 /* Basic string to match. */
1077 const char * template;
1078
1079 /* Basic instruction code. */
1080 unsigned long value;
1081
1082 /* Offset into the template where the condition code (if any) will be.
1083 If zero, then the instruction is never conditional. */
1084 unsigned cond_offset;
1085
1086 /* Which architecture variant provides this instruction. */
1087 unsigned long variant;
1088
1089 /* Function to call to parse args. */
1090 void (* parms) PARAMS ((char *));
1091 };
1092
1093 static const struct asm_opcode insns[] =
1094 {
1095 /* Core ARM Instructions. */
1096 {"and", 0xe0000000, 3, ARM_EXT_V1, do_arit},
1097 {"ands", 0xe0100000, 3, ARM_EXT_V1, do_arit},
1098 {"eor", 0xe0200000, 3, ARM_EXT_V1, do_arit},
1099 {"eors", 0xe0300000, 3, ARM_EXT_V1, do_arit},
1100 {"sub", 0xe0400000, 3, ARM_EXT_V1, do_arit},
1101 {"subs", 0xe0500000, 3, ARM_EXT_V1, do_arit},
1102 {"rsb", 0xe0600000, 3, ARM_EXT_V1, do_arit},
1103 {"rsbs", 0xe0700000, 3, ARM_EXT_V1, do_arit},
1104 {"add", 0xe0800000, 3, ARM_EXT_V1, do_arit},
1105 {"adds", 0xe0900000, 3, ARM_EXT_V1, do_arit},
1106 {"adc", 0xe0a00000, 3, ARM_EXT_V1, do_arit},
1107 {"adcs", 0xe0b00000, 3, ARM_EXT_V1, do_arit},
1108 {"sbc", 0xe0c00000, 3, ARM_EXT_V1, do_arit},
1109 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1, do_arit},
1110 {"rsc", 0xe0e00000, 3, ARM_EXT_V1, do_arit},
1111 {"rscs", 0xe0f00000, 3, ARM_EXT_V1, do_arit},
1112 {"orr", 0xe1800000, 3, ARM_EXT_V1, do_arit},
1113 {"orrs", 0xe1900000, 3, ARM_EXT_V1, do_arit},
1114 {"bic", 0xe1c00000, 3, ARM_EXT_V1, do_arit},
1115 {"bics", 0xe1d00000, 3, ARM_EXT_V1, do_arit},
1116
1117 {"tst", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1118 {"tsts", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1119 {"tstp", 0xe110f000, 3, ARM_EXT_V1, do_cmp},
1120 {"teq", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1121 {"teqs", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1122 {"teqp", 0xe130f000, 3, ARM_EXT_V1, do_cmp},
1123 {"cmp", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1124 {"cmps", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1125 {"cmpp", 0xe150f000, 3, ARM_EXT_V1, do_cmp},
1126 {"cmn", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1127 {"cmns", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1128 {"cmnp", 0xe170f000, 3, ARM_EXT_V1, do_cmp},
1129
1130 {"mov", 0xe1a00000, 3, ARM_EXT_V1, do_mov},
1131 {"movs", 0xe1b00000, 3, ARM_EXT_V1, do_mov},
1132 {"mvn", 0xe1e00000, 3, ARM_EXT_V1, do_mov},
1133 {"mvns", 0xe1f00000, 3, ARM_EXT_V1, do_mov},
1134
1135 {"ldr", 0xe4100000, 3, ARM_EXT_V1, do_ldst},
1136 {"ldrb", 0xe4500000, 3, ARM_EXT_V1, do_ldst},
1137 {"ldrt", 0xe4300000, 3, ARM_EXT_V1, do_ldstt},
1138 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1, do_ldstt},
1139 {"str", 0xe4000000, 3, ARM_EXT_V1, do_ldst},
1140 {"strb", 0xe4400000, 3, ARM_EXT_V1, do_ldst},
1141 {"strt", 0xe4200000, 3, ARM_EXT_V1, do_ldstt},
1142 {"strbt", 0xe4600000, 3, ARM_EXT_V1, do_ldstt},
1143
1144 {"stmia", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1145 {"stmib", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1146 {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1147 {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1148 {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1149 {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1150 {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1151 {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1152
1153 {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1154 {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1155 {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1156 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1157 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1158 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1159 {"ldmea", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1160 {"ldmed", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1161
1162 {"swi", 0xef000000, 3, ARM_EXT_V1, do_swi},
1163 #ifdef TE_WINCE
1164 /* XXX This is the wrong place to do this. Think multi-arch. */
1165 {"bl", 0xeb000000, 2, ARM_EXT_V1, do_branch},
1166 {"b", 0xea000000, 1, ARM_EXT_V1, do_branch},
1167 #else
1168 {"bl", 0xebfffffe, 2, ARM_EXT_V1, do_branch},
1169 {"b", 0xeafffffe, 1, ARM_EXT_V1, do_branch},
1170 #endif
1171
1172 /* Pseudo ops. */
1173 {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr},
1174 {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl},
1175 {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty},
1176
1177 /* ARM 2 multiplies. */
1178 {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul},
1179 {"muls", 0xe0100090, 3, ARM_EXT_V2, do_mul},
1180 {"mla", 0xe0200090, 3, ARM_EXT_V2, do_mla},
1181 {"mlas", 0xe0300090, 3, ARM_EXT_V2, do_mla},
1182
1183 /* Generic copressor instructions. */
1184 {"cdp", 0xee000000, 3, ARM_EXT_V2, do_cdp},
1185 {"ldc", 0xec100000, 3, ARM_EXT_V2, do_lstc},
1186 {"ldcl", 0xec500000, 3, ARM_EXT_V2, do_lstc},
1187 {"stc", 0xec000000, 3, ARM_EXT_V2, do_lstc},
1188 {"stcl", 0xec400000, 3, ARM_EXT_V2, do_lstc},
1189 {"mcr", 0xee000010, 3, ARM_EXT_V2, do_co_reg},
1190 {"mrc", 0xee100010, 3, ARM_EXT_V2, do_co_reg},
1191
1192 /* ARM 3 - swp instructions. */
1193 {"swp", 0xe1000090, 3, ARM_EXT_V2S, do_swap},
1194 {"swpb", 0xe1400090, 3, ARM_EXT_V2S, do_swap},
1195
1196 /* ARM 6 Status register instructions. */
1197 {"mrs", 0xe10f0000, 3, ARM_EXT_V3, do_mrs},
1198 {"msr", 0xe120f000, 3, ARM_EXT_V3, do_msr},
1199 /* ScottB: our code uses 0xe128f000 for msr.
1200 NickC: but this is wrong because the bits 16 through 19 are
1201 handled by the PSR_xxx defines above. */
1202
1203 /* ARM 7M long multiplies. */
1204 {"smull", 0xe0c00090, 5, ARM_EXT_V3M, do_mull},
1205 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M, do_mull},
1206 {"umull", 0xe0800090, 5, ARM_EXT_V3M, do_mull},
1207 {"umulls", 0xe0900090, 5, ARM_EXT_V3M, do_mull},
1208 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M, do_mull},
1209 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M, do_mull},
1210 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M, do_mull},
1211 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M, do_mull},
1212
1213 /* ARM Architecture 4. */
1214 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4, do_ldstv4},
1215 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4, do_ldstv4},
1216 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4, do_ldstv4},
1217 {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4},
1218
1219 /* ARM Architecture 4T. */
1220 /* Note: bx (and blx) are required on V5, even if the processor does
1221 not support Thumb. */
1222 {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1223
1224 /* ARM Architecture 5T. */
1225 /* Note: blx has 2 variants, so the .value is set dynamically.
1226 Only one of the variants has conditional execution. */
1227 {"blx", 0xe0000000, 3, ARM_EXT_V5, do_blx},
1228 {"clz", 0xe16f0f10, 3, ARM_EXT_V5, do_clz},
1229 {"bkpt", 0xe1200070, 0, ARM_EXT_V5, do_bkpt},
1230 {"ldc2", 0xfc100000, 0, ARM_EXT_V5, do_lstc2},
1231 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5, do_lstc2},
1232 {"stc2", 0xfc000000, 0, ARM_EXT_V5, do_lstc2},
1233 {"stc2l", 0xfc400000, 0, ARM_EXT_V5, do_lstc2},
1234 {"cdp2", 0xfe000000, 0, ARM_EXT_V5, do_cdp2},
1235 {"mcr2", 0xfe000010, 0, ARM_EXT_V5, do_co_reg2},
1236 {"mrc2", 0xfe100010, 0, ARM_EXT_V5, do_co_reg2},
1237
1238 /* ARM Architecture 5TExP. */
1239 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP, do_smla},
1240 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP, do_smla},
1241 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP, do_smla},
1242 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP, do_smla},
1243
1244 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP, do_smla},
1245 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP, do_smla},
1246
1247 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP, do_smlal},
1248 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP, do_smlal},
1249 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP, do_smlal},
1250 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP, do_smlal},
1251
1252 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP, do_smul},
1253 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP, do_smul},
1254 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP, do_smul},
1255 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP, do_smul},
1256
1257 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP, do_smul},
1258 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP, do_smul},
1259
1260 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP, do_qadd},
1261 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP, do_qadd},
1262 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP, do_qadd},
1263 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP, do_qadd},
1264
1265 /* ARM Architecture 5TE. */
1266 {"pld", 0xf450f000, 0, ARM_EXT_V5E, do_pld},
1267 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E, do_ldrd},
1268 {"strd", 0xe00000f0, 3, ARM_EXT_V5E, do_ldrd},
1269
1270 {"mcrr", 0xec400000, 4, ARM_EXT_V5E, do_co_reg2c},
1271 {"mrrc", 0xec500000, 4, ARM_EXT_V5E, do_co_reg2c},
1272
1273 /* ARM Architecture 5TEJ. */
1274 {"bxj", 0xe12fff20, 3, ARM_EXT_V5J, do_bxj},
1275
1276 /* Core FPA instruction set (V1). */
1277 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1278 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1279 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1280 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1281
1282 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1283 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1284 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1285 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1286
1287 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1288 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1289 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1290 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1291
1292 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1293 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1294 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1295 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1296 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1297 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1298 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1299 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1300 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1301 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1302 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1303 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1304
1305 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1306 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1307 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1308 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1309 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1310 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1311 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1312 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1313 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1314 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1315 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1316 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1317
1318 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1319 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1320 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1321 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1322 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1323 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1324 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1325 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1326 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1327 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1328 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1329 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1330
1331 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1332 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1333 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1334 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1335 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1336 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1337 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1338 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1339 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1340 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1341 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1342 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1343
1344 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1345 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1346 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1347 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1348 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1349 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1350 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1351 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1352 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1353 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1354 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1355 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1356
1357 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1358 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1359 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1360 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1361 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1362 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1363 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1364 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1365 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1366 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1367 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1368 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1369
1370 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1371 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1372 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1373 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1374 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1375 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1376 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1377 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1378 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1379 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1380 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1381 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1382
1383 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1384 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1385 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1386 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1387 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1388 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1389 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1390 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1391 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1392 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1393 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1394 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1395
1396 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1397 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1398 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1399 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1400 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1401 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1402 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1403 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1404 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1405 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1406 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1407 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1408
1409 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1410 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1411 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1412 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1413 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1414 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1415 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1416 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1417 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1418 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1419 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1420 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1421
1422 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1423 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1424 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1425 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1426 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1427 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1428 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1429 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1430 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1431 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1432 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1433 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1434
1435 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1436 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1437 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1438 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1439 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1440 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1441 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1442 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1443 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1444 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1445 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1446 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1447
1448 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1449 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1450 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1451 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1452 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1453 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1454 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1455 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1456 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1457 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1458 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1459 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1460
1461 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1462 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1463 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1464 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1465 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1466 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1467 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1468 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1469 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1470 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1471 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1472 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1473
1474 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1475 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1476 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1477 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1478 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1479 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1480 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1481 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1482 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1483 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1484 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1485 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1486
1487 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1488 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1489 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1490 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1491 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1492 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1493 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1494 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1495 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1496 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1497 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1498 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1499
1500 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1501 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1502 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1503 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1504 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1505 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1506 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1507 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1508 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1509 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1510 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1511 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1512
1513 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1514 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1515 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1516 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1517 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1518 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1519 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1520 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1521 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1522 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1523 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1524 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1525
1526 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1527 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1528 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1529 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1530 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1531 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1532 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1533 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1534 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1535 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1536 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1537 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1538
1539 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1540 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1541 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1542 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1543 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1544 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1545 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1546 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1547 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1548 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1549 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1550 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1551
1552 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1553 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1554 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1555 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1556 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1557 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1558 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1559 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1560 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1561 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1562 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1563 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1564
1565 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1566 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1567 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1568 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1569 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1570 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1571 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1572 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1573 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1574 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1575 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1576 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1577
1578 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1579 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1580 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1581 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1582 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1583 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1584 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1585 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1586 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1587 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1588 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1589 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1590
1591 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1592 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1593 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1594 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1595 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1596 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1597 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1598 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1599 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1600 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1601 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1602 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1603
1604 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1605 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1606 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1607 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1608 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1609 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1610 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1611 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1612 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1613 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1614 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1615 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1616
1617 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1618 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1619 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1620 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1621 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1622 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1623 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1624 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1625 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1626 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1627 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1628 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1629
1630 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1631 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1632 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1633 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1634 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1635 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1636 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1637 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1638 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1639 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1640 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1641 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1642
1643 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1644 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1645 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1646 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1647 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1648 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1649 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1650 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1651 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1652 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1653 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1654 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1655
1656 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1657 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1658 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1659 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1660 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1661 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1662 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1663 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1664 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1665 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1666 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1667 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1668
1669 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1670 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1671 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1672 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1673 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1674 not be an optional suffix, but part of the instruction. To be
1675 compatible, we accept either. */
1676 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1677 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1678
1679 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1680 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1681 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1682 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1683 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1684 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1685 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1686 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1687 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1688 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1689 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1690 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1691
1692 /* The implementation of the FIX instruction is broken on some
1693 assemblers, in that it accepts a precision specifier as well as a
1694 rounding specifier, despite the fact that this is meaningless.
1695 To be more compatible, we accept it as well, though of course it
1696 does not set any bits. */
1697 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1698 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1699 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1700 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1701 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1702 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1703 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1704 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1705 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1706 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1707 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1708 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1709 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1710
1711 /* Instructions that were new with the real FPA, call them V2. */
1712 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1713 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1714 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1715 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1716 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1717 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1718
1719 /* VFP V1xD (single precision). */
1720 /* Moves and type conversions. */
1721 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1722 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1723 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1724 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1725 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1726 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1727 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1728 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1729 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1730 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1731 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1732 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1733
1734 /* Memory operations. */
1735 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1736 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1737 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1738 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1739 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1740 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1741 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1742 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1743 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1744 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1745 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1746 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1747 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1748 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1749 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1750 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1751 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1752 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1753
1754 /* Monadic operations. */
1755 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1756 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1757 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1758
1759 /* Dyadic operations. */
1760 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1761 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1762 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1763 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1764 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1765 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1766 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1767 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1768 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1769
1770 /* Comparisons. */
1771 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1772 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1773 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1774 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1775
1776 /* VFP V1 (Double precision). */
1777 /* Moves and type conversions. */
1778 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1779 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1780 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1781 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1782 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1783 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1784 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1785 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1786 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1787 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1788 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1789 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1790 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1791
1792 /* Memory operations. */
1793 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1794 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1795 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1796 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1797 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1798 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1799 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1800 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1801 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1802 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1803
1804 /* Monadic operations. */
1805 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1806 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1807 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1808
1809 /* Dyadic operations. */
1810 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1811 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1812 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1813 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1814 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1815 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1816 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1817 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1818 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1819
1820 /* Comparisons. */
1821 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1822 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1823 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1824 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1825
1826 /* VFP V2. */
1827 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1828 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1829 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2, do_vfp_dp_from_reg2},
1830 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_dp},
1831
1832 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1833 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE, do_xsc_mia},
1834 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1835 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1836 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1837 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1838 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1839 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE, do_xsc_mar},
1840 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE, do_xsc_mra},
1841
1842 /* Intel Wireless MMX technology instructions. */
1843 {"tandcb", 0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1844 {"tandch", 0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1845 {"tandcw", 0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1846 {"tbcstb", 0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1847 {"tbcsth", 0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1848 {"tbcstw", 0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1849 {"textrcb", 0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1850 {"textrch", 0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1851 {"textrcw", 0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1852 {"textrmub", 0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1853 {"textrmuh", 0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1854 {"textrmuw", 0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1855 {"textrmsb", 0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1856 {"textrmsh", 0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1857 {"textrmsw", 0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1858 {"tinsrb", 0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1859 {"tinsrh", 0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1860 {"tinsrw", 0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1861 {"tmcr", 0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
1862 {"tmcrr", 0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
1863 {"tmia", 0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1864 {"tmiaph", 0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1865 {"tmiabb", 0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1866 {"tmiabt", 0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1867 {"tmiatb", 0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1868 {"tmiatt", 0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1869 {"tmovmskb", 0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1870 {"tmovmskh", 0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1871 {"tmovmskw", 0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1872 {"tmrc", 0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
1873 {"tmrrc", 0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
1874 {"torcb", 0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1875 {"torch", 0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1876 {"torcw", 0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1877 {"waccb", 0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1878 {"wacch", 0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1879 {"waccw", 0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1880 {"waddbss", 0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1881 {"waddb", 0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1882 {"waddbus", 0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1883 {"waddhss", 0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1884 {"waddh", 0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1885 {"waddhus", 0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1886 {"waddwss", 0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1887 {"waddw", 0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1888 {"waddwus", 0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1889 {"waligni", 0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
1890 {"walignr0", 0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1891 {"walignr1", 0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1892 {"walignr2", 0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1893 {"walignr3", 0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1894 {"wand", 0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1895 {"wandn", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1896 {"wavg2b", 0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1897 {"wavg2br", 0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1898 {"wavg2h", 0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1899 {"wavg2hr", 0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1900 {"wcmpeqb", 0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1901 {"wcmpeqh", 0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1902 {"wcmpeqw", 0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1903 {"wcmpgtub", 0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1904 {"wcmpgtuh", 0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1905 {"wcmpgtuw", 0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1906 {"wcmpgtsb", 0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1907 {"wcmpgtsh", 0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1908 {"wcmpgtsw", 0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1909 {"wldrb", 0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1910 {"wldrh", 0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1911 {"wldrw", 0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1912 {"wldrd", 0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1913 {"wmacs", 0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1914 {"wmacsz", 0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1915 {"wmacu", 0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1916 {"wmacuz", 0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1917 {"wmadds", 0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1918 {"wmaddu", 0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1919 {"wmaxsb", 0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1920 {"wmaxsh", 0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1921 {"wmaxsw", 0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1922 {"wmaxub", 0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1923 {"wmaxuh", 0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1924 {"wmaxuw", 0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1925 {"wminsb", 0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1926 {"wminsh", 0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1927 {"wminsw", 0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1928 {"wminub", 0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1929 {"wminuh", 0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1930 {"wminuw", 0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1931 {"wmov", 0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
1932 {"wmulsm", 0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1933 {"wmulsl", 0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1934 {"wmulum", 0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1935 {"wmulul", 0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1936 {"wor", 0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1937 {"wpackhss", 0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1938 {"wpackhus", 0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1939 {"wpackwss", 0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1940 {"wpackwus", 0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1941 {"wpackdss", 0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1942 {"wpackdus", 0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1943 {"wrorh", 0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1944 {"wrorhg", 0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1945 {"wrorw", 0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1946 {"wrorwg", 0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1947 {"wrord", 0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1948 {"wrordg", 0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1949 {"wsadb", 0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1950 {"wsadbz", 0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1951 {"wsadh", 0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1952 {"wsadhz", 0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1953 {"wshufh", 0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
1954 {"wsllh", 0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1955 {"wsllhg", 0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1956 {"wsllw", 0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1957 {"wsllwg", 0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1958 {"wslld", 0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1959 {"wslldg", 0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1960 {"wsrah", 0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1961 {"wsrahg", 0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1962 {"wsraw", 0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1963 {"wsrawg", 0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1964 {"wsrad", 0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1965 {"wsradg", 0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1966 {"wsrlh", 0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1967 {"wsrlhg", 0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1968 {"wsrlw", 0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1969 {"wsrlwg", 0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1970 {"wsrld", 0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1971 {"wsrldg", 0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1972 {"wstrb", 0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1973 {"wstrh", 0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1974 {"wstrw", 0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1975 {"wstrd", 0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1976 {"wsubbss", 0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1977 {"wsubb", 0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1978 {"wsubbus", 0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1979 {"wsubhss", 0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1980 {"wsubh", 0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1981 {"wsubhus", 0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1982 {"wsubwss", 0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1983 {"wsubw", 0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1984 {"wsubwus", 0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1985 {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1986 {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1987 {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1988 {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1989 {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1990 {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1991 {"wunpckihb", 0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1992 {"wunpckihh", 0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1993 {"wunpckihw", 0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1994 {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1995 {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1996 {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1997 {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1998 {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1999 {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2000 {"wunpckilb", 0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2001 {"wunpckilh", 0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2002 {"wunpckilw", 0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2003 {"wxor", 0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2004 {"wzero", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2005
2006 /* Cirrus Maverick instructions. */
2007 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
2008 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
2009 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
2010 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
2011 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
2012 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
2013 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
2014 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
2015 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK, do_mav_binops_2a},
2016 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK, do_mav_binops_1a},
2017 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
2018 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
2019 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
2020 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
2021 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
2022 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
2023 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
2024 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
2025 {"cfmval32", 0xee100610, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2026 {"cfmv32al", 0xee000610, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2027 {"cfmvam32", 0xee100630, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2028 {"cfmv32am", 0xee000630, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2029 {"cfmvah32", 0xee100650, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2030 {"cfmv32ah", 0xee000650, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2031 {"cfmva32", 0xee100670, 7, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2032 {"cfmv32a", 0xee000670, 7, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2033 {"cfmva64", 0xee100690, 7, ARM_CEXT_MAVERICK, do_mav_binops_3c},
2034 {"cfmv64a", 0xee000690, 7, ARM_CEXT_MAVERICK, do_mav_binops_3d},
2035 {"cfmvsc32", 0xee1006b0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2036 {"cfmv32sc", 0xee0006b0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2037 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2038 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2039 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK, do_mav_binops_1f},
2040 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK, do_mav_binops_1g},
2041 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK, do_mav_binops_1h},
2042 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1i},
2043 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1j},
2044 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1k},
2045 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2046 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2047 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2048 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2049 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK, do_mav_triple_4a},
2050 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK, do_mav_triple_4b},
2051 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK, do_mav_shift_1},
2052 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK, do_mav_shift_2},
2053 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK, do_mav_triple_5a},
2054 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5b},
2055 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK, do_mav_triple_5c},
2056 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5d},
2057 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2058 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2059 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2060 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2061 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2062 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2063 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2064 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2065 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2066 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2067 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
2068 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
2069 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
2070 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
2071 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2072 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2073 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2074 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2075 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2076 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2077 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2078 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2079 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
2080 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
2081 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
2082 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
2083 };
2084
2085 /* Defines for various bits that we will want to toggle. */
2086 #define INST_IMMEDIATE 0x02000000
2087 #define OFFSET_REG 0x02000000
2088 #define HWOFFSET_IMM 0x00400000
2089 #define SHIFT_BY_REG 0x00000010
2090 #define PRE_INDEX 0x01000000
2091 #define INDEX_UP 0x00800000
2092 #define WRITE_BACK 0x00200000
2093 #define LDM_TYPE_2_OR_3 0x00400000
2094
2095 #define LITERAL_MASK 0xf000f000
2096 #define OPCODE_MASK 0xfe1fffff
2097 #define V4_STR_BIT 0x00000020
2098
2099 #define DATA_OP_SHIFT 21
2100
2101 /* Codes to distinguish the arithmetic instructions. */
2102 #define OPCODE_AND 0
2103 #define OPCODE_EOR 1
2104 #define OPCODE_SUB 2
2105 #define OPCODE_RSB 3
2106 #define OPCODE_ADD 4
2107 #define OPCODE_ADC 5
2108 #define OPCODE_SBC 6
2109 #define OPCODE_RSC 7
2110 #define OPCODE_TST 8
2111 #define OPCODE_TEQ 9
2112 #define OPCODE_CMP 10
2113 #define OPCODE_CMN 11
2114 #define OPCODE_ORR 12
2115 #define OPCODE_MOV 13
2116 #define OPCODE_BIC 14
2117 #define OPCODE_MVN 15
2118
2119 /* Thumb v1 (ARMv4T). */
2120 static void do_t_nop PARAMS ((char *));
2121 static void do_t_arit PARAMS ((char *));
2122 static void do_t_add PARAMS ((char *));
2123 static void do_t_asr PARAMS ((char *));
2124 static void do_t_branch9 PARAMS ((char *));
2125 static void do_t_branch12 PARAMS ((char *));
2126 static void do_t_branch23 PARAMS ((char *));
2127 static void do_t_bx PARAMS ((char *));
2128 static void do_t_compare PARAMS ((char *));
2129 static void do_t_ldmstm PARAMS ((char *));
2130 static void do_t_ldr PARAMS ((char *));
2131 static void do_t_ldrb PARAMS ((char *));
2132 static void do_t_ldrh PARAMS ((char *));
2133 static void do_t_lds PARAMS ((char *));
2134 static void do_t_lsl PARAMS ((char *));
2135 static void do_t_lsr PARAMS ((char *));
2136 static void do_t_mov PARAMS ((char *));
2137 static void do_t_push_pop PARAMS ((char *));
2138 static void do_t_str PARAMS ((char *));
2139 static void do_t_strb PARAMS ((char *));
2140 static void do_t_strh PARAMS ((char *));
2141 static void do_t_sub PARAMS ((char *));
2142 static void do_t_swi PARAMS ((char *));
2143 static void do_t_adr PARAMS ((char *));
2144
2145 /* Thumb v2 (ARMv5T). */
2146 static void do_t_blx PARAMS ((char *));
2147 static void do_t_bkpt PARAMS ((char *));
2148
2149 #define T_OPCODE_MUL 0x4340
2150 #define T_OPCODE_TST 0x4200
2151 #define T_OPCODE_CMN 0x42c0
2152 #define T_OPCODE_NEG 0x4240
2153 #define T_OPCODE_MVN 0x43c0
2154
2155 #define T_OPCODE_ADD_R3 0x1800
2156 #define T_OPCODE_SUB_R3 0x1a00
2157 #define T_OPCODE_ADD_HI 0x4400
2158 #define T_OPCODE_ADD_ST 0xb000
2159 #define T_OPCODE_SUB_ST 0xb080
2160 #define T_OPCODE_ADD_SP 0xa800
2161 #define T_OPCODE_ADD_PC 0xa000
2162 #define T_OPCODE_ADD_I8 0x3000
2163 #define T_OPCODE_SUB_I8 0x3800
2164 #define T_OPCODE_ADD_I3 0x1c00
2165 #define T_OPCODE_SUB_I3 0x1e00
2166
2167 #define T_OPCODE_ASR_R 0x4100
2168 #define T_OPCODE_LSL_R 0x4080
2169 #define T_OPCODE_LSR_R 0x40c0
2170 #define T_OPCODE_ASR_I 0x1000
2171 #define T_OPCODE_LSL_I 0x0000
2172 #define T_OPCODE_LSR_I 0x0800
2173
2174 #define T_OPCODE_MOV_I8 0x2000
2175 #define T_OPCODE_CMP_I8 0x2800
2176 #define T_OPCODE_CMP_LR 0x4280
2177 #define T_OPCODE_MOV_HR 0x4600
2178 #define T_OPCODE_CMP_HR 0x4500
2179
2180 #define T_OPCODE_LDR_PC 0x4800
2181 #define T_OPCODE_LDR_SP 0x9800
2182 #define T_OPCODE_STR_SP 0x9000
2183 #define T_OPCODE_LDR_IW 0x6800
2184 #define T_OPCODE_STR_IW 0x6000
2185 #define T_OPCODE_LDR_IH 0x8800
2186 #define T_OPCODE_STR_IH 0x8000
2187 #define T_OPCODE_LDR_IB 0x7800
2188 #define T_OPCODE_STR_IB 0x7000
2189 #define T_OPCODE_LDR_RW 0x5800
2190 #define T_OPCODE_STR_RW 0x5000
2191 #define T_OPCODE_LDR_RH 0x5a00
2192 #define T_OPCODE_STR_RH 0x5200
2193 #define T_OPCODE_LDR_RB 0x5c00
2194 #define T_OPCODE_STR_RB 0x5400
2195
2196 #define T_OPCODE_PUSH 0xb400
2197 #define T_OPCODE_POP 0xbc00
2198
2199 #define T_OPCODE_BRANCH 0xe7fe
2200
2201 static int thumb_reg PARAMS ((char ** str, int hi_lo));
2202
2203 #define THUMB_SIZE 2 /* Size of thumb instruction. */
2204 #define THUMB_REG_LO 0x1
2205 #define THUMB_REG_HI 0x2
2206 #define THUMB_REG_ANY 0x3
2207
2208 #define THUMB_H1 0x0080
2209 #define THUMB_H2 0x0040
2210
2211 #define THUMB_ASR 0
2212 #define THUMB_LSL 1
2213 #define THUMB_LSR 2
2214
2215 #define THUMB_MOVE 0
2216 #define THUMB_COMPARE 1
2217
2218 #define THUMB_LOAD 0
2219 #define THUMB_STORE 1
2220
2221 #define THUMB_PP_PC_LR 0x0100
2222
2223 /* These three are used for immediate shifts, do not alter. */
2224 #define THUMB_WORD 2
2225 #define THUMB_HALFWORD 1
2226 #define THUMB_BYTE 0
2227
2228 struct thumb_opcode
2229 {
2230 /* Basic string to match. */
2231 const char * template;
2232
2233 /* Basic instruction code. */
2234 unsigned long value;
2235
2236 int size;
2237
2238 /* Which CPU variants this exists for. */
2239 unsigned long variant;
2240
2241 /* Function to call to parse args. */
2242 void (* parms) PARAMS ((char *));
2243 };
2244
2245 static const struct thumb_opcode tinsns[] =
2246 {
2247 /* Thumb v1 (ARMv4T). */
2248 {"adc", 0x4140, 2, ARM_EXT_V4T, do_t_arit},
2249 {"add", 0x0000, 2, ARM_EXT_V4T, do_t_add},
2250 {"and", 0x4000, 2, ARM_EXT_V4T, do_t_arit},
2251 {"asr", 0x0000, 2, ARM_EXT_V4T, do_t_asr},
2252 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_V4T, do_t_branch12},
2253 {"beq", 0xd0fe, 2, ARM_EXT_V4T, do_t_branch9},
2254 {"bne", 0xd1fe, 2, ARM_EXT_V4T, do_t_branch9},
2255 {"bcs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
2256 {"bhs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
2257 {"bcc", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2258 {"bul", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2259 {"blo", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2260 {"bmi", 0xd4fe, 2, ARM_EXT_V4T, do_t_branch9},
2261 {"bpl", 0xd5fe, 2, ARM_EXT_V4T, do_t_branch9},
2262 {"bvs", 0xd6fe, 2, ARM_EXT_V4T, do_t_branch9},
2263 {"bvc", 0xd7fe, 2, ARM_EXT_V4T, do_t_branch9},
2264 {"bhi", 0xd8fe, 2, ARM_EXT_V4T, do_t_branch9},
2265 {"bls", 0xd9fe, 2, ARM_EXT_V4T, do_t_branch9},
2266 {"bge", 0xdafe, 2, ARM_EXT_V4T, do_t_branch9},
2267 {"blt", 0xdbfe, 2, ARM_EXT_V4T, do_t_branch9},
2268 {"bgt", 0xdcfe, 2, ARM_EXT_V4T, do_t_branch9},
2269 {"ble", 0xddfe, 2, ARM_EXT_V4T, do_t_branch9},
2270 {"bal", 0xdefe, 2, ARM_EXT_V4T, do_t_branch9},
2271 {"bic", 0x4380, 2, ARM_EXT_V4T, do_t_arit},
2272 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T, do_t_branch23},
2273 {"bx", 0x4700, 2, ARM_EXT_V4T, do_t_bx},
2274 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_V4T, do_t_arit},
2275 {"cmp", 0x0000, 2, ARM_EXT_V4T, do_t_compare},
2276 {"eor", 0x4040, 2, ARM_EXT_V4T, do_t_arit},
2277 {"ldmia", 0xc800, 2, ARM_EXT_V4T, do_t_ldmstm},
2278 {"ldr", 0x0000, 2, ARM_EXT_V4T, do_t_ldr},
2279 {"ldrb", 0x0000, 2, ARM_EXT_V4T, do_t_ldrb},
2280 {"ldrh", 0x0000, 2, ARM_EXT_V4T, do_t_ldrh},
2281 {"ldrsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2282 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2283 {"ldsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2284 {"ldsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2285 {"lsl", 0x0000, 2, ARM_EXT_V4T, do_t_lsl},
2286 {"lsr", 0x0000, 2, ARM_EXT_V4T, do_t_lsr},
2287 {"mov", 0x0000, 2, ARM_EXT_V4T, do_t_mov},
2288 {"mul", T_OPCODE_MUL, 2, ARM_EXT_V4T, do_t_arit},
2289 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_V4T, do_t_arit},
2290 {"neg", T_OPCODE_NEG, 2, ARM_EXT_V4T, do_t_arit},
2291 {"orr", 0x4300, 2, ARM_EXT_V4T, do_t_arit},
2292 {"pop", 0xbc00, 2, ARM_EXT_V4T, do_t_push_pop},
2293 {"push", 0xb400, 2, ARM_EXT_V4T, do_t_push_pop},
2294 {"ror", 0x41c0, 2, ARM_EXT_V4T, do_t_arit},
2295 {"sbc", 0x4180, 2, ARM_EXT_V4T, do_t_arit},
2296 {"stmia", 0xc000, 2, ARM_EXT_V4T, do_t_ldmstm},
2297 {"str", 0x0000, 2, ARM_EXT_V4T, do_t_str},
2298 {"strb", 0x0000, 2, ARM_EXT_V4T, do_t_strb},
2299 {"strh", 0x0000, 2, ARM_EXT_V4T, do_t_strh},
2300 {"swi", 0xdf00, 2, ARM_EXT_V4T, do_t_swi},
2301 {"sub", 0x0000, 2, ARM_EXT_V4T, do_t_sub},
2302 {"tst", T_OPCODE_TST, 2, ARM_EXT_V4T, do_t_arit},
2303 /* Pseudo ops: */
2304 {"adr", 0x0000, 2, ARM_EXT_V4T, do_t_adr},
2305 {"nop", 0x46C0, 2, ARM_EXT_V4T, do_t_nop}, /* mov r8,r8 */
2306 /* Thumb v2 (ARMv5T). */
2307 {"blx", 0, 0, ARM_EXT_V5T, do_t_blx},
2308 {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt},
2309 };
2310
2311 #define BAD_ARGS _("bad arguments to instruction")
2312 #define BAD_PC _("r15 not allowed here")
2313 #define BAD_COND _("instruction is not conditional")
2314 #define ERR_NO_ACCUM _("acc0 expected")
2315
2316 static struct hash_control * arm_ops_hsh = NULL;
2317 static struct hash_control * arm_tops_hsh = NULL;
2318 static struct hash_control * arm_cond_hsh = NULL;
2319 static struct hash_control * arm_shift_hsh = NULL;
2320 static struct hash_control * arm_psr_hsh = NULL;
2321
2322 /* This table describes all the machine specific pseudo-ops the assembler
2323 has to support. The fields are:
2324 pseudo-op name without dot
2325 function to call to execute this pseudo-op
2326 Integer arg to pass to the function. */
2327
2328 static void s_req PARAMS ((int));
2329 static void s_unreq PARAMS ((int));
2330 static void s_align PARAMS ((int));
2331 static void s_bss PARAMS ((int));
2332 static void s_even PARAMS ((int));
2333 static void s_ltorg PARAMS ((int));
2334 static void s_arm PARAMS ((int));
2335 static void s_thumb PARAMS ((int));
2336 static void s_code PARAMS ((int));
2337 static void s_force_thumb PARAMS ((int));
2338 static void s_thumb_func PARAMS ((int));
2339 static void s_thumb_set PARAMS ((int));
2340 #ifdef OBJ_ELF
2341 static void s_arm_elf_cons PARAMS ((int));
2342 #endif
2343
2344 static int my_get_expression PARAMS ((expressionS *, char **));
2345
2346 const pseudo_typeS md_pseudo_table[] =
2347 {
2348 /* Never called because '.req' does not start a line. */
2349 { "req", s_req, 0 },
2350 { "unreq", s_unreq, 0 },
2351 { "bss", s_bss, 0 },
2352 { "align", s_align, 0 },
2353 { "arm", s_arm, 0 },
2354 { "thumb", s_thumb, 0 },
2355 { "code", s_code, 0 },
2356 { "force_thumb", s_force_thumb, 0 },
2357 { "thumb_func", s_thumb_func, 0 },
2358 { "thumb_set", s_thumb_set, 0 },
2359 { "even", s_even, 0 },
2360 { "ltorg", s_ltorg, 0 },
2361 { "pool", s_ltorg, 0 },
2362 #ifdef OBJ_ELF
2363 { "word", s_arm_elf_cons, 4 },
2364 { "long", s_arm_elf_cons, 4 },
2365 #else
2366 { "word", cons, 4},
2367 #endif
2368 { "extend", float_cons, 'x' },
2369 { "ldouble", float_cons, 'x' },
2370 { "packed", float_cons, 'p' },
2371 { 0, 0, 0 }
2372 };
2373
2374 /* Other internal functions. */
2375 static int arm_parse_extension PARAMS ((char *, int *));
2376 static int arm_parse_cpu PARAMS ((char *));
2377 static int arm_parse_arch PARAMS ((char *));
2378 static int arm_parse_fpu PARAMS ((char *));
2379 #if 0 /* Suppressed - for now. */
2380 #if defined OBJ_COFF || defined OBJ_ELF
2381 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2382 #endif
2383 #endif
2384
2385 /* Stuff needed to resolve the label ambiguity
2386 As:
2387 ...
2388 label: <insn>
2389 may differ from:
2390 ...
2391 label:
2392 <insn>
2393 */
2394
2395 symbolS * last_label_seen;
2396 static int label_is_thumb_function_name = FALSE;
2397
2398 /* Literal Pool stuff. */
2399
2400 #define MAX_LITERAL_POOL_SIZE 1024
2401
2402 /* Literal pool structure. Held on a per-section
2403 and per-sub-section basis. */
2404 typedef struct literal_pool
2405 {
2406 expressionS literals [MAX_LITERAL_POOL_SIZE];
2407 unsigned int next_free_entry;
2408 unsigned int id;
2409 symbolS * symbol;
2410 segT section;
2411 subsegT sub_section;
2412 struct literal_pool * next;
2413 } literal_pool;
2414
2415 /* Pointer to a linked list of literal pools. */
2416 literal_pool * list_of_pools = NULL;
2417
2418 static literal_pool * find_literal_pool PARAMS ((void));
2419 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2420
2421 static literal_pool *
2422 find_literal_pool ()
2423 {
2424 literal_pool * pool;
2425
2426 for (pool = list_of_pools; pool != NULL; pool = pool->next)
2427 {
2428 if (pool->section == now_seg
2429 && pool->sub_section == now_subseg)
2430 break;
2431 }
2432
2433 return pool;
2434 }
2435
2436 static literal_pool *
2437 find_or_make_literal_pool ()
2438 {
2439 /* Next literal pool ID number. */
2440 static unsigned int latest_pool_num = 1;
2441 literal_pool * pool;
2442
2443 pool = find_literal_pool ();
2444
2445 if (pool == NULL)
2446 {
2447 /* Create a new pool. */
2448 pool = (literal_pool *) xmalloc (sizeof (* pool));
2449 if (! pool)
2450 return NULL;
2451
2452 pool->next_free_entry = 0;
2453 pool->section = now_seg;
2454 pool->sub_section = now_subseg;
2455 pool->next = list_of_pools;
2456 pool->symbol = NULL;
2457
2458 /* Add it to the list. */
2459 list_of_pools = pool;
2460 }
2461
2462 /* New pools, and emptied pools, will have a NULL symbol. */
2463 if (pool->symbol == NULL)
2464 {
2465 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2466 (valueT) 0, &zero_address_frag);
2467 pool->id = latest_pool_num ++;
2468 }
2469
2470 /* Done. */
2471 return pool;
2472 }
2473
2474 /* Add the literal in the global 'inst'
2475 structure to the relevent literal pool. */
2476 static int
2477 add_to_lit_pool ()
2478 {
2479 literal_pool * pool;
2480 unsigned int entry;
2481
2482 pool = find_or_make_literal_pool ();
2483
2484 /* Check if this literal value is already in the pool. */
2485 for (entry = 0; entry < pool->next_free_entry; entry ++)
2486 {
2487 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2488 && (inst.reloc.exp.X_op == O_constant)
2489 && (pool->literals[entry].X_add_number
2490 == inst.reloc.exp.X_add_number)
2491 && (pool->literals[entry].X_unsigned
2492 == inst.reloc.exp.X_unsigned))
2493 break;
2494
2495 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2496 && (inst.reloc.exp.X_op == O_symbol)
2497 && (pool->literals[entry].X_add_number
2498 == inst.reloc.exp.X_add_number)
2499 && (pool->literals[entry].X_add_symbol
2500 == inst.reloc.exp.X_add_symbol)
2501 && (pool->literals[entry].X_op_symbol
2502 == inst.reloc.exp.X_op_symbol))
2503 break;
2504 }
2505
2506 /* Do we need to create a new entry? */
2507 if (entry == pool->next_free_entry)
2508 {
2509 if (entry >= MAX_LITERAL_POOL_SIZE)
2510 {
2511 inst.error = _("literal pool overflow");
2512 return FAIL;
2513 }
2514
2515 pool->literals[entry] = inst.reloc.exp;
2516 pool->next_free_entry += 1;
2517 }
2518
2519 inst.reloc.exp.X_op = O_symbol;
2520 inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2521 inst.reloc.exp.X_add_symbol = pool->symbol;
2522
2523 return SUCCESS;
2524 }
2525
2526 /* Can't use symbol_new here, so have to create a symbol and then at
2527 a later date assign it a value. Thats what these functions do. */
2528
2529 static void
2530 symbol_locate (symbolP, name, segment, valu, frag)
2531 symbolS * symbolP;
2532 const char * name; /* It is copied, the caller can modify. */
2533 segT segment; /* Segment identifier (SEG_<something>). */
2534 valueT valu; /* Symbol value. */
2535 fragS * frag; /* Associated fragment. */
2536 {
2537 unsigned int name_length;
2538 char * preserved_copy_of_name;
2539
2540 name_length = strlen (name) + 1; /* +1 for \0. */
2541 obstack_grow (&notes, name, name_length);
2542 preserved_copy_of_name = obstack_finish (&notes);
2543 #ifdef STRIP_UNDERSCORE
2544 if (preserved_copy_of_name[0] == '_')
2545 preserved_copy_of_name++;
2546 #endif
2547
2548 #ifdef tc_canonicalize_symbol_name
2549 preserved_copy_of_name =
2550 tc_canonicalize_symbol_name (preserved_copy_of_name);
2551 #endif
2552
2553 S_SET_NAME (symbolP, preserved_copy_of_name);
2554
2555 S_SET_SEGMENT (symbolP, segment);
2556 S_SET_VALUE (symbolP, valu);
2557 symbol_clear_list_pointers (symbolP);
2558
2559 symbol_set_frag (symbolP, frag);
2560
2561 /* Link to end of symbol chain. */
2562 {
2563 extern int symbol_table_frozen;
2564 if (symbol_table_frozen)
2565 abort ();
2566 }
2567
2568 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2569
2570 obj_symbol_new_hook (symbolP);
2571
2572 #ifdef tc_symbol_new_hook
2573 tc_symbol_new_hook (symbolP);
2574 #endif
2575
2576 #ifdef DEBUG_SYMS
2577 verify_symbol_chain (symbol_rootP, symbol_lastP);
2578 #endif /* DEBUG_SYMS */
2579 }
2580
2581 /* Check that an immediate is valid.
2582 If so, convert it to the right format. */
2583
2584 static unsigned int
2585 validate_immediate (val)
2586 unsigned int val;
2587 {
2588 unsigned int a;
2589 unsigned int i;
2590
2591 #define rotate_left(v, n) (v << n | v >> (32 - n))
2592
2593 for (i = 0; i < 32; i += 2)
2594 if ((a = rotate_left (val, i)) <= 0xff)
2595 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
2596
2597 return FAIL;
2598 }
2599
2600 /* Check to see if an immediate can be computed as two separate immediate
2601 values, added together. We already know that this value cannot be
2602 computed by just one ARM instruction. */
2603
2604 static unsigned int
2605 validate_immediate_twopart (val, highpart)
2606 unsigned int val;
2607 unsigned int * highpart;
2608 {
2609 unsigned int a;
2610 unsigned int i;
2611
2612 for (i = 0; i < 32; i += 2)
2613 if (((a = rotate_left (val, i)) & 0xff) != 0)
2614 {
2615 if (a & 0xff00)
2616 {
2617 if (a & ~ 0xffff)
2618 continue;
2619 * highpart = (a >> 8) | ((i + 24) << 7);
2620 }
2621 else if (a & 0xff0000)
2622 {
2623 if (a & 0xff000000)
2624 continue;
2625 * highpart = (a >> 16) | ((i + 16) << 7);
2626 }
2627 else
2628 {
2629 assert (a & 0xff000000);
2630 * highpart = (a >> 24) | ((i + 8) << 7);
2631 }
2632
2633 return (a & 0xff) | (i << 7);
2634 }
2635
2636 return FAIL;
2637 }
2638
2639 static int
2640 validate_offset_imm (val, hwse)
2641 unsigned int val;
2642 int hwse;
2643 {
2644 if ((hwse && val > 255) || val > 4095)
2645 return FAIL;
2646 return val;
2647 }
2648
2649 \f
2650 #ifdef OBJ_ELF
2651 enum mstate
2652 {
2653 MAP_DATA,
2654 MAP_ARM,
2655 MAP_THUMB
2656 };
2657
2658 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2659 (This text is taken from version B-02 of the spec):
2660
2661 4.4.7 Mapping and tagging symbols
2662
2663 A section of an ARM ELF file can contain a mixture of ARM code,
2664 Thumb code, and data. There are inline transitions between code
2665 and data at literal pool boundaries. There can also be inline
2666 transitions between ARM code and Thumb code, for example in
2667 ARM-Thumb inter-working veneers. Linkers, machine-level
2668 debuggers, profiling tools, and disassembly tools need to map
2669 images accurately. For example, setting an ARM breakpoint on a
2670 Thumb location, or in a literal pool, can crash the program
2671 being debugged, ruining the debugging session.
2672
2673 ARM ELF entities are mapped (see section 4.4.7.1 below) and
2674 tagged (see section 4.4.7.2 below) using local symbols (with
2675 binding STB_LOCAL). To assist consumers, mapping and tagging
2676 symbols should be collated first in the symbol table, before
2677 other symbols with binding STB_LOCAL.
2678
2679 To allow properly collated mapping and tagging symbols to be
2680 skipped by consumers that have no interest in them, the first
2681 such symbol should have the name $m and its st_value field equal
2682 to the total number of mapping and tagging symbols (including
2683 the $m) in the symbol table.
2684
2685 4.4.7.1 Mapping symbols
2686
2687 $a Labels the first byte of a sequence of ARM instructions.
2688 Its type is STT_FUNC.
2689
2690 $d Labels the first byte of a sequence of data items.
2691 Its type is STT_OBJECT.
2692
2693 $t Labels the first byte of a sequence of Thumb instructions.
2694 Its type is STT_FUNC.
2695
2696 This list of mapping symbols may be extended in the future.
2697
2698 Section-relative mapping symbols
2699
2700 Mapping symbols defined in a section define a sequence of
2701 half-open address intervals that cover the address range of the
2702 section. Each interval starts at the address defined by a
2703 mapping symbol, and continues up to, but not including, the
2704 address defined by the next (in address order) mapping symbol or
2705 the end of the section. A corollary is that there must be a
2706 mapping symbol defined at the beginning of each section.
2707 Consumers can ignore the size of a section-relative mapping
2708 symbol. Producers can set it to 0.
2709
2710 Absolute mapping symbols
2711
2712 Because of the need to crystallize a Thumb address with the
2713 Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2714 STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2715 or $t.
2716
2717 The extent of a mapping symbol defined in SHN_ABS is [st_value,
2718 st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2719 where [x, y) denotes the half-open address range from x,
2720 inclusive, to y, exclusive.
2721
2722 In the absence of a mapping symbol, a consumer can interpret a
2723 function symbol with an odd value as the Thumb code address
2724 obtained by clearing the least significant bit of the
2725 value. This interpretation is deprecated, and it may not work in
2726 the future.
2727
2728 Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2729 the EABI (which is still under development), so they are not
2730 implemented here. */
2731
2732 static void
2733 mapping_state (enum mstate state)
2734 {
2735 static enum mstate mapstate = MAP_DATA;
2736 symbolS * symbolP;
2737 const char * symname;
2738 int type;
2739
2740 if (mapstate == state)
2741 /* The mapping symbol has already been emitted.
2742 There is nothing else to do. */
2743 return;
2744
2745 mapstate = state;
2746
2747 switch (state)
2748 {
2749 case MAP_DATA:
2750 symname = "$d";
2751 type = BSF_OBJECT;
2752 break;
2753 case MAP_ARM:
2754 symname = "$a";
2755 type = BSF_FUNCTION;
2756 break;
2757 case MAP_THUMB:
2758 symname = "$t";
2759 type = BSF_FUNCTION;
2760 break;
2761 default:
2762 abort ();
2763 }
2764
2765 symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2766 symbol_table_insert (symbolP);
2767 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2768
2769 switch (state)
2770 {
2771 case MAP_ARM:
2772 THUMB_SET_FUNC (symbolP, 0);
2773 ARM_SET_THUMB (symbolP, 0);
2774 ARM_SET_INTERWORK (symbolP, support_interwork);
2775 break;
2776
2777 case MAP_THUMB:
2778 THUMB_SET_FUNC (symbolP, 1);
2779 ARM_SET_THUMB (symbolP, 1);
2780 ARM_SET_INTERWORK (symbolP, support_interwork);
2781 break;
2782
2783 case MAP_DATA:
2784 default:
2785 return;
2786 }
2787 }
2788
2789 /* When we change sections we need to issue a new mapping symbol. */
2790
2791 void
2792 arm_elf_change_section (void)
2793 {
2794 flagword flags;
2795
2796 if (!SEG_NORMAL (now_seg))
2797 return;
2798
2799 flags = bfd_get_section_flags (stdoutput, now_seg);
2800
2801 /* We can ignore sections that only contain debug info. */
2802 if ((flags & SEC_ALLOC) == 0)
2803 return;
2804
2805 if (flags & SEC_CODE)
2806 {
2807 if (thumb_mode)
2808 mapping_state (MAP_THUMB);
2809 else
2810 mapping_state (MAP_ARM);
2811 }
2812 else
2813 /* This section does not contain code. Therefore it must contain data. */
2814 mapping_state (MAP_DATA);
2815 }
2816 #else
2817 #define mapping_state(a)
2818 #endif /* OBJ_ELF */
2819 \f
2820
2821 static void
2822 s_req (a)
2823 int a ATTRIBUTE_UNUSED;
2824 {
2825 as_bad (_("invalid syntax for .req directive"));
2826 }
2827
2828 /* The .unreq directive deletes an alias which was previously defined
2829 by .req. For example:
2830
2831 my_alias .req r11
2832 .unreq my_alias */
2833
2834 static void
2835 s_unreq (int a ATTRIBUTE_UNUSED)
2836 {
2837 char *name;
2838 char saved_char;
2839
2840 skip_whitespace (input_line_pointer);
2841 name = input_line_pointer;
2842
2843 while (*input_line_pointer != 0
2844 && *input_line_pointer != ' '
2845 && *input_line_pointer != '\n')
2846 ++input_line_pointer;
2847
2848 saved_char = *input_line_pointer;
2849 *input_line_pointer = 0;
2850
2851 if (*name)
2852 {
2853 enum arm_reg_type req_type = arm_reg_parse_any (name);
2854
2855 if (req_type != REG_TYPE_MAX)
2856 {
2857 char *temp_name = name;
2858 int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
2859
2860 if (req_no != FAIL)
2861 {
2862 struct reg_entry *req_entry;
2863
2864 /* Check to see if this alias is a builtin one. */
2865 req_entry = hash_delete (all_reg_maps[req_type].htab, name);
2866
2867 if (!req_entry)
2868 as_bad (_("unreq: missing hash entry for \"%s\""), name);
2869 else if (req_entry->builtin)
2870 /* FIXME: We are deleteing a built in register alias which
2871 points to a const data structure, so we only need to
2872 free up the memory used by the key in the hash table.
2873 Unfortunately we have not recorded this value, so this
2874 is a memory leak. */
2875 /* FIXME: Should we issue a warning message ? */
2876 ;
2877 else
2878 {
2879 /* Deleteing a user defined alias. We need to free the
2880 key and the value, but fortunately the key is the same
2881 as the value->name field. */
2882 free ((char *) req_entry->name);
2883 free (req_entry);
2884 }
2885 }
2886 else
2887 as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
2888 }
2889 else
2890 as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
2891 }
2892 else
2893 as_bad (_("invalid syntax for .unreq directive"));
2894
2895 *input_line_pointer = saved_char;
2896 demand_empty_rest_of_line ();
2897 }
2898
2899 static void
2900 s_bss (ignore)
2901 int ignore ATTRIBUTE_UNUSED;
2902 {
2903 /* We don't support putting frags in the BSS segment, we fake it by
2904 marking in_bss, then looking at s_skip for clues. */
2905 subseg_set (bss_section, 0);
2906 demand_empty_rest_of_line ();
2907 mapping_state (MAP_DATA);
2908 }
2909
2910 static void
2911 s_even (ignore)
2912 int ignore ATTRIBUTE_UNUSED;
2913 {
2914 /* Never make frag if expect extra pass. */
2915 if (!need_pass_2)
2916 frag_align (1, 0, 0);
2917
2918 record_alignment (now_seg, 1);
2919
2920 demand_empty_rest_of_line ();
2921 }
2922
2923 static void
2924 s_ltorg (ignored)
2925 int ignored ATTRIBUTE_UNUSED;
2926 {
2927 unsigned int entry;
2928 literal_pool * pool;
2929 char sym_name[20];
2930
2931 pool = find_literal_pool ();
2932 if (pool == NULL
2933 || pool->symbol == NULL
2934 || pool->next_free_entry == 0)
2935 return;
2936
2937 /* Align pool as you have word accesses.
2938 Only make a frag if we have to. */
2939 if (!need_pass_2)
2940 frag_align (2, 0, 0);
2941
2942 record_alignment (now_seg, 2);
2943
2944 sprintf (sym_name, "$$lit_\002%x", pool->id);
2945
2946 symbol_locate (pool->symbol, sym_name, now_seg,
2947 (valueT) frag_now_fix (), frag_now);
2948 symbol_table_insert (pool->symbol);
2949
2950 ARM_SET_THUMB (pool->symbol, thumb_mode);
2951
2952 #if defined OBJ_COFF || defined OBJ_ELF
2953 ARM_SET_INTERWORK (pool->symbol, support_interwork);
2954 #endif
2955
2956 for (entry = 0; entry < pool->next_free_entry; entry ++)
2957 /* First output the expression in the instruction to the pool. */
2958 emit_expr (&(pool->literals[entry]), 4); /* .word */
2959
2960 /* Mark the pool as empty. */
2961 pool->next_free_entry = 0;
2962 pool->symbol = NULL;
2963 }
2964
2965 /* Same as s_align_ptwo but align 0 => align 2. */
2966
2967 static void
2968 s_align (unused)
2969 int unused ATTRIBUTE_UNUSED;
2970 {
2971 register int temp;
2972 register long temp_fill;
2973 long max_alignment = 15;
2974
2975 temp = get_absolute_expression ();
2976 if (temp > max_alignment)
2977 as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
2978 else if (temp < 0)
2979 {
2980 as_bad (_("alignment negative. 0 assumed."));
2981 temp = 0;
2982 }
2983
2984 if (*input_line_pointer == ',')
2985 {
2986 input_line_pointer++;
2987 temp_fill = get_absolute_expression ();
2988 }
2989 else
2990 temp_fill = 0;
2991
2992 if (!temp)
2993 temp = 2;
2994
2995 /* Only make a frag if we HAVE to. */
2996 if (temp && !need_pass_2)
2997 frag_align (temp, (int) temp_fill, 0);
2998 demand_empty_rest_of_line ();
2999
3000 record_alignment (now_seg, temp);
3001 }
3002
3003 static void
3004 s_force_thumb (ignore)
3005 int ignore ATTRIBUTE_UNUSED;
3006 {
3007 /* If we are not already in thumb mode go into it, EVEN if
3008 the target processor does not support thumb instructions.
3009 This is used by gcc/config/arm/lib1funcs.asm for example
3010 to compile interworking support functions even if the
3011 target processor should not support interworking. */
3012 if (! thumb_mode)
3013 {
3014 thumb_mode = 2;
3015
3016 record_alignment (now_seg, 1);
3017 }
3018
3019 demand_empty_rest_of_line ();
3020 }
3021
3022 static void
3023 s_thumb_func (ignore)
3024 int ignore ATTRIBUTE_UNUSED;
3025 {
3026 if (! thumb_mode)
3027 opcode_select (16);
3028
3029 /* The following label is the name/address of the start of a Thumb function.
3030 We need to know this for the interworking support. */
3031 label_is_thumb_function_name = TRUE;
3032
3033 demand_empty_rest_of_line ();
3034 }
3035
3036 /* Perform a .set directive, but also mark the alias as
3037 being a thumb function. */
3038
3039 static void
3040 s_thumb_set (equiv)
3041 int equiv;
3042 {
3043 /* XXX the following is a duplicate of the code for s_set() in read.c
3044 We cannot just call that code as we need to get at the symbol that
3045 is created. */
3046 register char * name;
3047 register char delim;
3048 register char * end_name;
3049 register symbolS * symbolP;
3050
3051 /* Especial apologies for the random logic:
3052 This just grew, and could be parsed much more simply!
3053 Dean - in haste. */
3054 name = input_line_pointer;
3055 delim = get_symbol_end ();
3056 end_name = input_line_pointer;
3057 *end_name = delim;
3058
3059 SKIP_WHITESPACE ();
3060
3061 if (*input_line_pointer != ',')
3062 {
3063 *end_name = 0;
3064 as_bad (_("expected comma after name \"%s\""), name);
3065 *end_name = delim;
3066 ignore_rest_of_line ();
3067 return;
3068 }
3069
3070 input_line_pointer++;
3071 *end_name = 0;
3072
3073 if (name[0] == '.' && name[1] == '\0')
3074 {
3075 /* XXX - this should not happen to .thumb_set. */
3076 abort ();
3077 }
3078
3079 if ((symbolP = symbol_find (name)) == NULL
3080 && (symbolP = md_undefined_symbol (name)) == NULL)
3081 {
3082 #ifndef NO_LISTING
3083 /* When doing symbol listings, play games with dummy fragments living
3084 outside the normal fragment chain to record the file and line info
3085 for this symbol. */
3086 if (listing & LISTING_SYMBOLS)
3087 {
3088 extern struct list_info_struct * listing_tail;
3089 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3090
3091 memset (dummy_frag, 0, sizeof (fragS));
3092 dummy_frag->fr_type = rs_fill;
3093 dummy_frag->line = listing_tail;
3094 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3095 dummy_frag->fr_symbol = symbolP;
3096 }
3097 else
3098 #endif
3099 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3100
3101 #ifdef OBJ_COFF
3102 /* "set" symbols are local unless otherwise specified. */
3103 SF_SET_LOCAL (symbolP);
3104 #endif /* OBJ_COFF */
3105 } /* Make a new symbol. */
3106
3107 symbol_table_insert (symbolP);
3108
3109 * end_name = delim;
3110
3111 if (equiv
3112 && S_IS_DEFINED (symbolP)
3113 && S_GET_SEGMENT (symbolP) != reg_section)
3114 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3115
3116 pseudo_set (symbolP);
3117
3118 demand_empty_rest_of_line ();
3119
3120 /* XXX Now we come to the Thumb specific bit of code. */
3121
3122 THUMB_SET_FUNC (symbolP, 1);
3123 ARM_SET_THUMB (symbolP, 1);
3124 #if defined OBJ_ELF || defined OBJ_COFF
3125 ARM_SET_INTERWORK (symbolP, support_interwork);
3126 #endif
3127 }
3128
3129 static void
3130 opcode_select (width)
3131 int width;
3132 {
3133 switch (width)
3134 {
3135 case 16:
3136 if (! thumb_mode)
3137 {
3138 if (! (cpu_variant & ARM_EXT_V4T))
3139 as_bad (_("selected processor does not support THUMB opcodes"));
3140
3141 thumb_mode = 1;
3142 /* No need to force the alignment, since we will have been
3143 coming from ARM mode, which is word-aligned. */
3144 record_alignment (now_seg, 1);
3145 }
3146 mapping_state (MAP_THUMB);
3147 break;
3148
3149 case 32:
3150 if (thumb_mode)
3151 {
3152 if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3153 as_bad (_("selected processor does not support ARM opcodes"));
3154
3155 thumb_mode = 0;
3156
3157 if (!need_pass_2)
3158 frag_align (2, 0, 0);
3159
3160 record_alignment (now_seg, 1);
3161 }
3162 mapping_state (MAP_ARM);
3163 break;
3164
3165 default:
3166 as_bad (_("invalid instruction size selected (%d)"), width);
3167 }
3168 }
3169
3170 static void
3171 s_arm (ignore)
3172 int ignore ATTRIBUTE_UNUSED;
3173 {
3174 opcode_select (32);
3175 demand_empty_rest_of_line ();
3176 }
3177
3178 static void
3179 s_thumb (ignore)
3180 int ignore ATTRIBUTE_UNUSED;
3181 {
3182 opcode_select (16);
3183 demand_empty_rest_of_line ();
3184 }
3185
3186 static void
3187 s_code (unused)
3188 int unused ATTRIBUTE_UNUSED;
3189 {
3190 register int temp;
3191
3192 temp = get_absolute_expression ();
3193 switch (temp)
3194 {
3195 case 16:
3196 case 32:
3197 opcode_select (temp);
3198 break;
3199
3200 default:
3201 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3202 }
3203 }
3204
3205 static void
3206 end_of_line (str)
3207 char *str;
3208 {
3209 skip_whitespace (str);
3210
3211 if (*str != '\0' && !inst.error)
3212 inst.error = _("garbage following instruction");
3213 }
3214
3215 static int
3216 skip_past_comma (str)
3217 char ** str;
3218 {
3219 char * p = * str, c;
3220 int comma = 0;
3221
3222 while ((c = *p) == ' ' || c == ',')
3223 {
3224 p++;
3225 if (c == ',' && comma++)
3226 return FAIL;
3227 }
3228
3229 if (c == '\0')
3230 return FAIL;
3231
3232 *str = p;
3233 return comma ? SUCCESS : FAIL;
3234 }
3235
3236 /* A standard register must be given at this point.
3237 SHIFT is the place to put it in inst.instruction.
3238 Restores input start point on error.
3239 Returns the reg#, or FAIL. */
3240
3241 static int
3242 reg_required_here (str, shift)
3243 char ** str;
3244 int shift;
3245 {
3246 static char buff [128]; /* XXX */
3247 int reg;
3248 char * start = * str;
3249
3250 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3251 {
3252 if (shift >= 0)
3253 inst.instruction |= reg << shift;
3254 return reg;
3255 }
3256
3257 /* Restore the start point, we may have got a reg of the wrong class. */
3258 *str = start;
3259
3260 /* In the few cases where we might be able to accept something else
3261 this error can be overridden. */
3262 sprintf (buff, _("register expected, not '%.100s'"), start);
3263 inst.error = buff;
3264
3265 return FAIL;
3266 }
3267
3268 /* A Intel Wireless MMX technology register
3269 must be given at this point.
3270 Shift is the place to put it in inst.instruction.
3271 Restores input start point on err.
3272 Returns the reg#, or FAIL. */
3273
3274 static int
3275 wreg_required_here (str, shift, reg_type)
3276 char ** str;
3277 int shift;
3278 enum wreg_type reg_type;
3279 {
3280 static char buff [128];
3281 int reg;
3282 char * start = *str;
3283
3284 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3285 {
3286 if (wr_register (reg)
3287 && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3288 {
3289 if (shift >= 0)
3290 inst.instruction |= (reg ^ WR_PREFIX) << shift;
3291 return reg;
3292 }
3293 else if (wc_register (reg)
3294 && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3295 {
3296 if (shift >= 0)
3297 inst.instruction |= (reg ^ WC_PREFIX) << shift;
3298 return reg;
3299 }
3300 else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3301 {
3302 if (shift >= 0)
3303 inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3304 return reg;
3305 }
3306 }
3307
3308 /* Restore the start point, we may have got a reg of the wrong class. */
3309 *str = start;
3310
3311 /* In the few cases where we might be able to accept
3312 something else this error can be overridden. */
3313 sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3314 inst.error = buff;
3315
3316 return FAIL;
3317 }
3318
3319 static const struct asm_psr *
3320 arm_psr_parse (ccp)
3321 register char ** ccp;
3322 {
3323 char * start = * ccp;
3324 char c;
3325 char * p;
3326 const struct asm_psr * psr;
3327
3328 p = start;
3329
3330 /* Skip to the end of the next word in the input stream. */
3331 do
3332 {
3333 c = *p++;
3334 }
3335 while (ISALPHA (c) || c == '_');
3336
3337 /* Terminate the word. */
3338 *--p = 0;
3339
3340 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
3341 feature for ease of use and backwards compatibility. */
3342 if (!strncmp (start, "cpsr", 4))
3343 strncpy (start, "CPSR", 4);
3344 else if (!strncmp (start, "spsr", 4))
3345 strncpy (start, "SPSR", 4);
3346
3347 /* Now locate the word in the psr hash table. */
3348 psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3349
3350 /* Restore the input stream. */
3351 *p = c;
3352
3353 /* If we found a valid match, advance the
3354 stream pointer past the end of the word. */
3355 *ccp = p;
3356
3357 return psr;
3358 }
3359
3360 /* Parse the input looking for a PSR flag. */
3361
3362 static int
3363 psr_required_here (str)
3364 char ** str;
3365 {
3366 char * start = * str;
3367 const struct asm_psr * psr;
3368
3369 psr = arm_psr_parse (str);
3370
3371 if (psr)
3372 {
3373 /* If this is the SPSR that is being modified, set the R bit. */
3374 if (! psr->cpsr)
3375 inst.instruction |= SPSR_BIT;
3376
3377 /* Set the psr flags in the MSR instruction. */
3378 inst.instruction |= psr->field << PSR_SHIFT;
3379
3380 return SUCCESS;
3381 }
3382
3383 /* In the few cases where we might be able to accept
3384 something else this error can be overridden. */
3385 inst.error = _("flag for {c}psr instruction expected");
3386
3387 /* Restore the start point. */
3388 *str = start;
3389 return FAIL;
3390 }
3391
3392 static int
3393 co_proc_number (str)
3394 char **str;
3395 {
3396 int processor, pchar;
3397 char *start;
3398
3399 skip_whitespace (*str);
3400 start = *str;
3401
3402 /* The data sheet seems to imply that just a number on its own is valid
3403 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
3404 accept either. */
3405 if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3406 == FAIL)
3407 {
3408 *str = start;
3409
3410 pchar = *(*str)++;
3411 if (pchar >= '0' && pchar <= '9')
3412 {
3413 processor = pchar - '0';
3414 if (**str >= '0' && **str <= '9')
3415 {
3416 processor = processor * 10 + *(*str)++ - '0';
3417 if (processor > 15)
3418 {
3419 inst.error = _("illegal co-processor number");
3420 return FAIL;
3421 }
3422 }
3423 }
3424 else
3425 {
3426 inst.error = _("bad or missing co-processor number");
3427 return FAIL;
3428 }
3429 }
3430
3431 inst.instruction |= processor << 8;
3432 return SUCCESS;
3433 }
3434
3435 static int
3436 cp_opc_expr (str, where, length)
3437 char ** str;
3438 int where;
3439 int length;
3440 {
3441 expressionS expr;
3442
3443 skip_whitespace (* str);
3444
3445 memset (&expr, '\0', sizeof (expr));
3446
3447 if (my_get_expression (&expr, str))
3448 return FAIL;
3449 if (expr.X_op != O_constant)
3450 {
3451 inst.error = _("bad or missing expression");
3452 return FAIL;
3453 }
3454
3455 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3456 {
3457 inst.error = _("immediate co-processor expression too large");
3458 return FAIL;
3459 }
3460
3461 inst.instruction |= expr.X_add_number << where;
3462 return SUCCESS;
3463 }
3464
3465 static int
3466 cp_reg_required_here (str, where)
3467 char ** str;
3468 int where;
3469 {
3470 int reg;
3471 char * start = *str;
3472
3473 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3474 {
3475 inst.instruction |= reg << where;
3476 return reg;
3477 }
3478
3479 /* In the few cases where we might be able to accept something else
3480 this error can be overridden. */
3481 inst.error = _("co-processor register expected");
3482
3483 /* Restore the start point. */
3484 *str = start;
3485 return FAIL;
3486 }
3487
3488 static int
3489 fp_reg_required_here (str, where)
3490 char ** str;
3491 int where;
3492 {
3493 int reg;
3494 char * start = * str;
3495
3496 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3497 {
3498 inst.instruction |= reg << where;
3499 return reg;
3500 }
3501
3502 /* In the few cases where we might be able to accept something else
3503 this error can be overridden. */
3504 inst.error = _("floating point register expected");
3505
3506 /* Restore the start point. */
3507 *str = start;
3508 return FAIL;
3509 }
3510
3511 static int
3512 cp_address_offset (str)
3513 char ** str;
3514 {
3515 int offset;
3516
3517 skip_whitespace (* str);
3518
3519 if (! is_immediate_prefix (**str))
3520 {
3521 inst.error = _("immediate expression expected");
3522 return FAIL;
3523 }
3524
3525 (*str)++;
3526
3527 if (my_get_expression (& inst.reloc.exp, str))
3528 return FAIL;
3529
3530 if (inst.reloc.exp.X_op == O_constant)
3531 {
3532 offset = inst.reloc.exp.X_add_number;
3533
3534 if (offset & 3)
3535 {
3536 inst.error = _("co-processor address must be word aligned");
3537 return FAIL;
3538 }
3539
3540 if (offset > 1023 || offset < -1023)
3541 {
3542 inst.error = _("offset too large");
3543 return FAIL;
3544 }
3545
3546 if (offset >= 0)
3547 inst.instruction |= INDEX_UP;
3548 else
3549 offset = -offset;
3550
3551 inst.instruction |= offset >> 2;
3552 }
3553 else
3554 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3555
3556 return SUCCESS;
3557 }
3558
3559 static int
3560 cp_address_required_here (str, wb_ok)
3561 char ** str;
3562 int wb_ok;
3563 {
3564 char * p = * str;
3565 int pre_inc = 0;
3566 int write_back = 0;
3567
3568 if (*p == '[')
3569 {
3570 int reg;
3571
3572 p++;
3573 skip_whitespace (p);
3574
3575 if ((reg = reg_required_here (& p, 16)) == FAIL)
3576 return FAIL;
3577
3578 skip_whitespace (p);
3579
3580 if (*p == ']')
3581 {
3582 p++;
3583
3584 skip_whitespace (p);
3585
3586 if (*p == '\0')
3587 {
3588 /* As an extension to the official ARM syntax we allow:
3589
3590 [Rn]
3591
3592 as a short hand for:
3593
3594 [Rn,#0] */
3595 inst.instruction |= PRE_INDEX | INDEX_UP;
3596 *str = p;
3597 return SUCCESS;
3598 }
3599
3600 if (skip_past_comma (& p) == FAIL)
3601 {
3602 inst.error = _("comma expected after closing square bracket");
3603 return FAIL;
3604 }
3605
3606 skip_whitespace (p);
3607
3608 if (*p == '#')
3609 {
3610 if (wb_ok)
3611 {
3612 /* [Rn], #expr */
3613 write_back = WRITE_BACK;
3614
3615 if (reg == REG_PC)
3616 {
3617 inst.error = _("pc may not be used in post-increment");
3618 return FAIL;
3619 }
3620
3621 if (cp_address_offset (& p) == FAIL)
3622 return FAIL;
3623 }
3624 else
3625 pre_inc = PRE_INDEX | INDEX_UP;
3626 }
3627 else if (*p == '{')
3628 {
3629 int option;
3630
3631 /* [Rn], {<expr>} */
3632 p++;
3633
3634 skip_whitespace (p);
3635
3636 if (my_get_expression (& inst.reloc.exp, & p))
3637 return FAIL;
3638
3639 if (inst.reloc.exp.X_op == O_constant)
3640 {
3641 option = inst.reloc.exp.X_add_number;
3642
3643 if (option > 255 || option < 0)
3644 {
3645 inst.error = _("'option' field too large");
3646 return FAIL;
3647 }
3648
3649 skip_whitespace (p);
3650
3651 if (*p != '}')
3652 {
3653 inst.error = _("'}' expected at end of 'option' field");
3654 return FAIL;
3655 }
3656 else
3657 {
3658 p++;
3659 inst.instruction |= option;
3660 inst.instruction |= INDEX_UP;
3661 }
3662 }
3663 else
3664 {
3665 inst.error = _("non-constant expressions for 'option' field not supported");
3666 return FAIL;
3667 }
3668 }
3669 else
3670 {
3671 inst.error = _("# or { expected after comma");
3672 return FAIL;
3673 }
3674 }
3675 else
3676 {
3677 /* '['Rn, #expr']'[!] */
3678
3679 if (skip_past_comma (& p) == FAIL)
3680 {
3681 inst.error = _("pre-indexed expression expected");
3682 return FAIL;
3683 }
3684
3685 pre_inc = PRE_INDEX;
3686
3687 if (cp_address_offset (& p) == FAIL)
3688 return FAIL;
3689
3690 skip_whitespace (p);
3691
3692 if (*p++ != ']')
3693 {
3694 inst.error = _("missing ]");
3695 return FAIL;
3696 }
3697
3698 skip_whitespace (p);
3699
3700 if (wb_ok && *p == '!')
3701 {
3702 if (reg == REG_PC)
3703 {
3704 inst.error = _("pc may not be used with write-back");
3705 return FAIL;
3706 }
3707
3708 p++;
3709 write_back = WRITE_BACK;
3710 }
3711 }
3712 }
3713 else
3714 {
3715 if (my_get_expression (&inst.reloc.exp, &p))
3716 return FAIL;
3717
3718 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3719 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3720 inst.reloc.pc_rel = 1;
3721 inst.instruction |= (REG_PC << 16);
3722 pre_inc = PRE_INDEX;
3723 }
3724
3725 inst.instruction |= write_back | pre_inc;
3726 *str = p;
3727 return SUCCESS;
3728 }
3729
3730 static int
3731 cp_byte_address_offset (str)
3732 char ** str;
3733 {
3734 int offset;
3735
3736 skip_whitespace (* str);
3737
3738 if (! is_immediate_prefix (**str))
3739 {
3740 inst.error = _("immediate expression expected");
3741 return FAIL;
3742 }
3743
3744 (*str)++;
3745
3746 if (my_get_expression (& inst.reloc.exp, str))
3747 return FAIL;
3748
3749 if (inst.reloc.exp.X_op == O_constant)
3750 {
3751 offset = inst.reloc.exp.X_add_number;
3752
3753 if (offset > 255 || offset < -255)
3754 {
3755 inst.error = _("offset too large");
3756 return FAIL;
3757 }
3758
3759 if (offset >= 0)
3760 inst.instruction |= INDEX_UP;
3761 else
3762 offset = -offset;
3763
3764 inst.instruction |= offset;
3765 }
3766 else
3767 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3768
3769 return SUCCESS;
3770 }
3771
3772 static int
3773 cp_byte_address_required_here (str)
3774 char ** str;
3775 {
3776 char * p = * str;
3777 int pre_inc = 0;
3778 int write_back = 0;
3779
3780 if (*p == '[')
3781 {
3782 int reg;
3783
3784 p++;
3785 skip_whitespace (p);
3786
3787 if ((reg = reg_required_here (& p, 16)) == FAIL)
3788 return FAIL;
3789
3790 skip_whitespace (p);
3791
3792 if (*p == ']')
3793 {
3794 p++;
3795
3796 if (skip_past_comma (& p) == SUCCESS)
3797 {
3798 /* [Rn], #expr */
3799 write_back = WRITE_BACK;
3800
3801 if (reg == REG_PC)
3802 {
3803 inst.error = _("pc may not be used in post-increment");
3804 return FAIL;
3805 }
3806
3807 if (cp_byte_address_offset (& p) == FAIL)
3808 return FAIL;
3809 }
3810 else
3811 pre_inc = PRE_INDEX | INDEX_UP;
3812 }
3813 else
3814 {
3815 /* '['Rn, #expr']'[!] */
3816
3817 if (skip_past_comma (& p) == FAIL)
3818 {
3819 inst.error = _("pre-indexed expression expected");
3820 return FAIL;
3821 }
3822
3823 pre_inc = PRE_INDEX;
3824
3825 if (cp_byte_address_offset (& p) == FAIL)
3826 return FAIL;
3827
3828 skip_whitespace (p);
3829
3830 if (*p++ != ']')
3831 {
3832 inst.error = _("missing ]");
3833 return FAIL;
3834 }
3835
3836 skip_whitespace (p);
3837
3838 if (*p == '!')
3839 {
3840 if (reg == REG_PC)
3841 {
3842 inst.error = _("pc may not be used with write-back");
3843 return FAIL;
3844 }
3845
3846 p++;
3847 write_back = WRITE_BACK;
3848 }
3849 }
3850 }
3851 else
3852 {
3853 if (my_get_expression (&inst.reloc.exp, &p))
3854 return FAIL;
3855
3856 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3857 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3858 inst.reloc.pc_rel = 1;
3859 inst.instruction |= (REG_PC << 16);
3860 pre_inc = PRE_INDEX;
3861 }
3862
3863 inst.instruction |= write_back | pre_inc;
3864 *str = p;
3865 return SUCCESS;
3866 }
3867
3868 static void
3869 do_empty (str)
3870 char * str;
3871 {
3872 /* Do nothing really. */
3873 end_of_line (str);
3874 return;
3875 }
3876
3877 static void
3878 do_mrs (str)
3879 char *str;
3880 {
3881 int skip = 0;
3882
3883 /* Only one syntax. */
3884 skip_whitespace (str);
3885
3886 if (reg_required_here (&str, 12) == FAIL)
3887 {
3888 inst.error = BAD_ARGS;
3889 return;
3890 }
3891
3892 if (skip_past_comma (&str) == FAIL)
3893 {
3894 inst.error = _("comma expected after register name");
3895 return;
3896 }
3897
3898 skip_whitespace (str);
3899
3900 if ( strcmp (str, "CPSR") == 0
3901 || strcmp (str, "SPSR") == 0
3902 /* Lower case versions for backwards compatibility. */
3903 || strcmp (str, "cpsr") == 0
3904 || strcmp (str, "spsr") == 0)
3905 skip = 4;
3906
3907 /* This is for backwards compatibility with older toolchains. */
3908 else if ( strcmp (str, "cpsr_all") == 0
3909 || strcmp (str, "spsr_all") == 0)
3910 skip = 8;
3911 else
3912 {
3913 inst.error = _("CPSR or SPSR expected");
3914 return;
3915 }
3916
3917 if (* str == 's' || * str == 'S')
3918 inst.instruction |= SPSR_BIT;
3919 str += skip;
3920
3921 end_of_line (str);
3922 }
3923
3924 /* Two possible forms:
3925 "{C|S}PSR_<field>, Rm",
3926 "{C|S}PSR_f, #expression". */
3927
3928 static void
3929 do_msr (str)
3930 char * str;
3931 {
3932 skip_whitespace (str);
3933
3934 if (psr_required_here (& str) == FAIL)
3935 return;
3936
3937 if (skip_past_comma (& str) == FAIL)
3938 {
3939 inst.error = _("comma missing after psr flags");
3940 return;
3941 }
3942
3943 skip_whitespace (str);
3944
3945 if (reg_required_here (& str, 0) != FAIL)
3946 {
3947 inst.error = NULL;
3948 end_of_line (str);
3949 return;
3950 }
3951
3952 if (! is_immediate_prefix (* str))
3953 {
3954 inst.error =
3955 _("only a register or immediate value can follow a psr flag");
3956 return;
3957 }
3958
3959 str ++;
3960 inst.error = NULL;
3961
3962 if (my_get_expression (& inst.reloc.exp, & str))
3963 {
3964 inst.error =
3965 _("only a register or immediate value can follow a psr flag");
3966 return;
3967 }
3968
3969 #if 0 /* The first edition of the ARM architecture manual stated that
3970 writing anything other than the flags with an immediate operation
3971 had UNPREDICTABLE effects. This constraint was removed in the
3972 second edition of the specification. */
3973 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
3974 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
3975 {
3976 inst.error = _("immediate value cannot be used to set this field");
3977 return;
3978 }
3979 #endif
3980
3981 inst.instruction |= INST_IMMEDIATE;
3982
3983 if (inst.reloc.exp.X_add_symbol)
3984 {
3985 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3986 inst.reloc.pc_rel = 0;
3987 }
3988 else
3989 {
3990 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
3991
3992 if (value == (unsigned) FAIL)
3993 {
3994 inst.error = _("invalid constant");
3995 return;
3996 }
3997
3998 inst.instruction |= value;
3999 }
4000
4001 inst.error = NULL;
4002 end_of_line (str);
4003 }
4004
4005 /* Long Multiply Parser
4006 UMULL RdLo, RdHi, Rm, Rs
4007 SMULL RdLo, RdHi, Rm, Rs
4008 UMLAL RdLo, RdHi, Rm, Rs
4009 SMLAL RdLo, RdHi, Rm, Rs. */
4010
4011 static void
4012 do_mull (str)
4013 char * str;
4014 {
4015 int rdlo, rdhi, rm, rs;
4016
4017 /* Only one format "rdlo, rdhi, rm, rs". */
4018 skip_whitespace (str);
4019
4020 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4021 {
4022 inst.error = BAD_ARGS;
4023 return;
4024 }
4025
4026 if (skip_past_comma (&str) == FAIL
4027 || (rdhi = reg_required_here (&str, 16)) == FAIL)
4028 {
4029 inst.error = BAD_ARGS;
4030 return;
4031 }
4032
4033 if (skip_past_comma (&str) == FAIL
4034 || (rm = reg_required_here (&str, 0)) == FAIL)
4035 {
4036 inst.error = BAD_ARGS;
4037 return;
4038 }
4039
4040 /* rdhi, rdlo and rm must all be different. */
4041 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4042 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4043
4044 if (skip_past_comma (&str) == FAIL
4045 || (rs = reg_required_here (&str, 8)) == FAIL)
4046 {
4047 inst.error = BAD_ARGS;
4048 return;
4049 }
4050
4051 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4052 {
4053 inst.error = BAD_PC;
4054 return;
4055 }
4056
4057 end_of_line (str);
4058 return;
4059 }
4060
4061 static void
4062 do_mul (str)
4063 char * str;
4064 {
4065 int rd, rm;
4066
4067 /* Only one format "rd, rm, rs". */
4068 skip_whitespace (str);
4069
4070 if ((rd = reg_required_here (&str, 16)) == FAIL)
4071 {
4072 inst.error = BAD_ARGS;
4073 return;
4074 }
4075
4076 if (rd == REG_PC)
4077 {
4078 inst.error = BAD_PC;
4079 return;
4080 }
4081
4082 if (skip_past_comma (&str) == FAIL
4083 || (rm = reg_required_here (&str, 0)) == FAIL)
4084 {
4085 inst.error = BAD_ARGS;
4086 return;
4087 }
4088
4089 if (rm == REG_PC)
4090 {
4091 inst.error = BAD_PC;
4092 return;
4093 }
4094
4095 if (rm == rd)
4096 as_tsktsk (_("rd and rm should be different in mul"));
4097
4098 if (skip_past_comma (&str) == FAIL
4099 || (rm = reg_required_here (&str, 8)) == FAIL)
4100 {
4101 inst.error = BAD_ARGS;
4102 return;
4103 }
4104
4105 if (rm == REG_PC)
4106 {
4107 inst.error = BAD_PC;
4108 return;
4109 }
4110
4111 end_of_line (str);
4112 return;
4113 }
4114
4115 static void
4116 do_mla (str)
4117 char * str;
4118 {
4119 int rd, rm;
4120
4121 /* Only one format "rd, rm, rs, rn". */
4122 skip_whitespace (str);
4123
4124 if ((rd = reg_required_here (&str, 16)) == FAIL)
4125 {
4126 inst.error = BAD_ARGS;
4127 return;
4128 }
4129
4130 if (rd == REG_PC)
4131 {
4132 inst.error = BAD_PC;
4133 return;
4134 }
4135
4136 if (skip_past_comma (&str) == FAIL
4137 || (rm = reg_required_here (&str, 0)) == FAIL)
4138 {
4139 inst.error = BAD_ARGS;
4140 return;
4141 }
4142
4143 if (rm == REG_PC)
4144 {
4145 inst.error = BAD_PC;
4146 return;
4147 }
4148
4149 if (rm == rd)
4150 as_tsktsk (_("rd and rm should be different in mla"));
4151
4152 if (skip_past_comma (&str) == FAIL
4153 || (rd = reg_required_here (&str, 8)) == FAIL
4154 || skip_past_comma (&str) == FAIL
4155 || (rm = reg_required_here (&str, 12)) == FAIL)
4156 {
4157 inst.error = BAD_ARGS;
4158 return;
4159 }
4160
4161 if (rd == REG_PC || rm == REG_PC)
4162 {
4163 inst.error = BAD_PC;
4164 return;
4165 }
4166
4167 end_of_line (str);
4168 return;
4169 }
4170
4171 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4172 Advances *str to the next non-alphanumeric.
4173 Returns 0, or else FAIL (in which case sets inst.error).
4174
4175 (In a future XScale, there may be accumulators other than zero.
4176 At that time this routine and its callers can be upgraded to suit.) */
4177
4178 static int
4179 accum0_required_here (str)
4180 char ** str;
4181 {
4182 static char buff [128]; /* Note the address is taken. Hence, static. */
4183 char * p = * str;
4184 char c;
4185 int result = 0; /* The accum number. */
4186
4187 skip_whitespace (p);
4188
4189 *str = p; /* Advance caller's string pointer too. */
4190 c = *p++;
4191 while (ISALNUM (c))
4192 c = *p++;
4193
4194 *--p = 0; /* Aap nul into input buffer at non-alnum. */
4195
4196 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4197 {
4198 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4199 inst.error = buff;
4200 result = FAIL;
4201 }
4202
4203 *p = c; /* Unzap. */
4204 *str = p; /* Caller's string pointer to after match. */
4205 return result;
4206 }
4207
4208 /* Expects **str -> after a comma. May be leading blanks.
4209 Advances *str, recognizing a load mode, and setting inst.instruction.
4210 Returns rn, or else FAIL (in which case may set inst.error
4211 and not advance str)
4212
4213 Note: doesn't know Rd, so no err checks that require such knowledge. */
4214
4215 static int
4216 ld_mode_required_here (string)
4217 char ** string;
4218 {
4219 char * str = * string;
4220 int rn;
4221 int pre_inc = 0;
4222
4223 skip_whitespace (str);
4224
4225 if (* str == '[')
4226 {
4227 str++;
4228
4229 skip_whitespace (str);
4230
4231 if ((rn = reg_required_here (& str, 16)) == FAIL)
4232 return FAIL;
4233
4234 skip_whitespace (str);
4235
4236 if (* str == ']')
4237 {
4238 str ++;
4239
4240 if (skip_past_comma (& str) == SUCCESS)
4241 {
4242 /* [Rn],... (post inc) */
4243 if (ldst_extend_v4 (&str) == FAIL)
4244 return FAIL;
4245 }
4246 else /* [Rn] */
4247 {
4248 skip_whitespace (str);
4249
4250 if (* str == '!')
4251 {
4252 str ++;
4253 inst.instruction |= WRITE_BACK;
4254 }
4255
4256 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4257 pre_inc = 1;
4258 }
4259 }
4260 else /* [Rn,...] */
4261 {
4262 if (skip_past_comma (& str) == FAIL)
4263 {
4264 inst.error = _("pre-indexed expression expected");
4265 return FAIL;
4266 }
4267
4268 pre_inc = 1;
4269
4270 if (ldst_extend_v4 (&str) == FAIL)
4271 return FAIL;
4272
4273 skip_whitespace (str);
4274
4275 if (* str ++ != ']')
4276 {
4277 inst.error = _("missing ]");
4278 return FAIL;
4279 }
4280
4281 skip_whitespace (str);
4282
4283 if (* str == '!')
4284 {
4285 str ++;
4286 inst.instruction |= WRITE_BACK;
4287 }
4288 }
4289 }
4290 else if (* str == '=') /* ldr's "r,=label" syntax */
4291 /* We should never reach here, because <text> = <expression> is
4292 caught gas/read.c read_a_source_file() as a .set operation. */
4293 return FAIL;
4294 else /* PC +- 8 bit immediate offset. */
4295 {
4296 if (my_get_expression (& inst.reloc.exp, & str))
4297 return FAIL;
4298
4299 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
4300 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4301 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
4302 inst.reloc.pc_rel = 1;
4303 inst.instruction |= (REG_PC << 16);
4304
4305 rn = REG_PC;
4306 pre_inc = 1;
4307 }
4308
4309 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4310 * string = str;
4311
4312 return rn;
4313 }
4314
4315 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4316 SMLAxy{cond} Rd,Rm,Rs,Rn
4317 SMLAWy{cond} Rd,Rm,Rs,Rn
4318 Error if any register is R15. */
4319
4320 static void
4321 do_smla (str)
4322 char * str;
4323 {
4324 int rd, rm, rs, rn;
4325
4326 skip_whitespace (str);
4327
4328 if ((rd = reg_required_here (& str, 16)) == FAIL
4329 || skip_past_comma (& str) == FAIL
4330 || (rm = reg_required_here (& str, 0)) == FAIL
4331 || skip_past_comma (& str) == FAIL
4332 || (rs = reg_required_here (& str, 8)) == FAIL
4333 || skip_past_comma (& str) == FAIL
4334 || (rn = reg_required_here (& str, 12)) == FAIL)
4335 inst.error = BAD_ARGS;
4336
4337 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4338 inst.error = BAD_PC;
4339
4340 else
4341 end_of_line (str);
4342 }
4343
4344 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4345 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4346 Error if any register is R15.
4347 Warning if Rdlo == Rdhi. */
4348
4349 static void
4350 do_smlal (str)
4351 char * str;
4352 {
4353 int rdlo, rdhi, rm, rs;
4354
4355 skip_whitespace (str);
4356
4357 if ((rdlo = reg_required_here (& str, 12)) == FAIL
4358 || skip_past_comma (& str) == FAIL
4359 || (rdhi = reg_required_here (& str, 16)) == FAIL
4360 || skip_past_comma (& str) == FAIL
4361 || (rm = reg_required_here (& str, 0)) == FAIL
4362 || skip_past_comma (& str) == FAIL
4363 || (rs = reg_required_here (& str, 8)) == FAIL)
4364 {
4365 inst.error = BAD_ARGS;
4366 return;
4367 }
4368
4369 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4370 {
4371 inst.error = BAD_PC;
4372 return;
4373 }
4374
4375 if (rdlo == rdhi)
4376 as_tsktsk (_("rdhi and rdlo must be different"));
4377
4378 end_of_line (str);
4379 }
4380
4381 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4382 SMULxy{cond} Rd,Rm,Rs
4383 Error if any register is R15. */
4384
4385 static void
4386 do_smul (str)
4387 char * str;
4388 {
4389 int rd, rm, rs;
4390
4391 skip_whitespace (str);
4392
4393 if ((rd = reg_required_here (& str, 16)) == FAIL
4394 || skip_past_comma (& str) == FAIL
4395 || (rm = reg_required_here (& str, 0)) == FAIL
4396 || skip_past_comma (& str) == FAIL
4397 || (rs = reg_required_here (& str, 8)) == FAIL)
4398 inst.error = BAD_ARGS;
4399
4400 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4401 inst.error = BAD_PC;
4402
4403 else
4404 end_of_line (str);
4405 }
4406
4407 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4408 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4409 Error if any register is R15. */
4410
4411 static void
4412 do_qadd (str)
4413 char * str;
4414 {
4415 int rd, rm, rn;
4416
4417 skip_whitespace (str);
4418
4419 if ((rd = reg_required_here (& str, 12)) == FAIL
4420 || skip_past_comma (& str) == FAIL
4421 || (rm = reg_required_here (& str, 0)) == FAIL
4422 || skip_past_comma (& str) == FAIL
4423 || (rn = reg_required_here (& str, 16)) == FAIL)
4424 inst.error = BAD_ARGS;
4425
4426 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4427 inst.error = BAD_PC;
4428
4429 else
4430 end_of_line (str);
4431 }
4432
4433 /* ARM V5E (el Segundo)
4434 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4435 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4436
4437 These are equivalent to the XScale instructions MAR and MRA,
4438 respectively, when coproc == 0, opcode == 0, and CRm == 0.
4439
4440 Result unpredicatable if Rd or Rn is R15. */
4441
4442 static void
4443 do_co_reg2c (str)
4444 char * str;
4445 {
4446 int rd, rn;
4447
4448 skip_whitespace (str);
4449
4450 if (co_proc_number (& str) == FAIL)
4451 {
4452 if (!inst.error)
4453 inst.error = BAD_ARGS;
4454 return;
4455 }
4456
4457 if (skip_past_comma (& str) == FAIL
4458 || cp_opc_expr (& str, 4, 4) == FAIL)
4459 {
4460 if (!inst.error)
4461 inst.error = BAD_ARGS;
4462 return;
4463 }
4464
4465 if (skip_past_comma (& str) == FAIL
4466 || (rd = reg_required_here (& str, 12)) == FAIL)
4467 {
4468 if (!inst.error)
4469 inst.error = BAD_ARGS;
4470 return;
4471 }
4472
4473 if (skip_past_comma (& str) == FAIL
4474 || (rn = reg_required_here (& str, 16)) == FAIL)
4475 {
4476 if (!inst.error)
4477 inst.error = BAD_ARGS;
4478 return;
4479 }
4480
4481 /* Unpredictable result if rd or rn is R15. */
4482 if (rd == REG_PC || rn == REG_PC)
4483 as_tsktsk
4484 (_("Warning: instruction unpredictable when using r15"));
4485
4486 if (skip_past_comma (& str) == FAIL
4487 || cp_reg_required_here (& str, 0) == FAIL)
4488 {
4489 if (!inst.error)
4490 inst.error = BAD_ARGS;
4491 return;
4492 }
4493
4494 end_of_line (str);
4495 }
4496
4497 /* ARM V5 count-leading-zeroes instruction (argument parse)
4498 CLZ{<cond>} <Rd>, <Rm>
4499 Condition defaults to COND_ALWAYS.
4500 Error if Rd or Rm are R15. */
4501
4502 static void
4503 do_clz (str)
4504 char * str;
4505 {
4506 int rd, rm;
4507
4508 skip_whitespace (str);
4509
4510 if (((rd = reg_required_here (& str, 12)) == FAIL)
4511 || (skip_past_comma (& str) == FAIL)
4512 || ((rm = reg_required_here (& str, 0)) == FAIL))
4513 inst.error = BAD_ARGS;
4514
4515 else if (rd == REG_PC || rm == REG_PC )
4516 inst.error = BAD_PC;
4517
4518 else
4519 end_of_line (str);
4520 }
4521
4522 /* ARM V5 (argument parse)
4523 LDC2{L} <coproc>, <CRd>, <addressing mode>
4524 STC2{L} <coproc>, <CRd>, <addressing mode>
4525 Instruction is not conditional, and has 0xf in the condition field.
4526 Otherwise, it's the same as LDC/STC. */
4527
4528 static void
4529 do_lstc2 (str)
4530 char * str;
4531 {
4532 skip_whitespace (str);
4533
4534 if (co_proc_number (& str) == FAIL)
4535 {
4536 if (!inst.error)
4537 inst.error = BAD_ARGS;
4538 }
4539 else if (skip_past_comma (& str) == FAIL
4540 || cp_reg_required_here (& str, 12) == FAIL)
4541 {
4542 if (!inst.error)
4543 inst.error = BAD_ARGS;
4544 }
4545 else if (skip_past_comma (& str) == FAIL
4546 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4547 {
4548 if (! inst.error)
4549 inst.error = BAD_ARGS;
4550 }
4551 else
4552 end_of_line (str);
4553 }
4554
4555 /* ARM V5 (argument parse)
4556 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4557 Instruction is not conditional, and has 0xf in the condition field.
4558 Otherwise, it's the same as CDP. */
4559
4560 static void
4561 do_cdp2 (str)
4562 char * str;
4563 {
4564 skip_whitespace (str);
4565
4566 if (co_proc_number (& str) == FAIL)
4567 {
4568 if (!inst.error)
4569 inst.error = BAD_ARGS;
4570 return;
4571 }
4572
4573 if (skip_past_comma (& str) == FAIL
4574 || cp_opc_expr (& str, 20,4) == FAIL)
4575 {
4576 if (!inst.error)
4577 inst.error = BAD_ARGS;
4578 return;
4579 }
4580
4581 if (skip_past_comma (& str) == FAIL
4582 || cp_reg_required_here (& str, 12) == FAIL)
4583 {
4584 if (!inst.error)
4585 inst.error = BAD_ARGS;
4586 return;
4587 }
4588
4589 if (skip_past_comma (& str) == FAIL
4590 || cp_reg_required_here (& str, 16) == FAIL)
4591 {
4592 if (!inst.error)
4593 inst.error = BAD_ARGS;
4594 return;
4595 }
4596
4597 if (skip_past_comma (& str) == FAIL
4598 || cp_reg_required_here (& str, 0) == FAIL)
4599 {
4600 if (!inst.error)
4601 inst.error = BAD_ARGS;
4602 return;
4603 }
4604
4605 if (skip_past_comma (& str) == SUCCESS)
4606 {
4607 if (cp_opc_expr (& str, 5, 3) == FAIL)
4608 {
4609 if (!inst.error)
4610 inst.error = BAD_ARGS;
4611 return;
4612 }
4613 }
4614
4615 end_of_line (str);
4616 }
4617
4618 /* ARM V5 (argument parse)
4619 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4620 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4621 Instruction is not conditional, and has 0xf in the condition field.
4622 Otherwise, it's the same as MCR/MRC. */
4623
4624 static void
4625 do_co_reg2 (str)
4626 char * str;
4627 {
4628 skip_whitespace (str);
4629
4630 if (co_proc_number (& str) == FAIL)
4631 {
4632 if (!inst.error)
4633 inst.error = BAD_ARGS;
4634 return;
4635 }
4636
4637 if (skip_past_comma (& str) == FAIL
4638 || cp_opc_expr (& str, 21, 3) == FAIL)
4639 {
4640 if (!inst.error)
4641 inst.error = BAD_ARGS;
4642 return;
4643 }
4644
4645 if (skip_past_comma (& str) == FAIL
4646 || reg_required_here (& str, 12) == FAIL)
4647 {
4648 if (!inst.error)
4649 inst.error = BAD_ARGS;
4650 return;
4651 }
4652
4653 if (skip_past_comma (& str) == FAIL
4654 || cp_reg_required_here (& str, 16) == FAIL)
4655 {
4656 if (!inst.error)
4657 inst.error = BAD_ARGS;
4658 return;
4659 }
4660
4661 if (skip_past_comma (& str) == FAIL
4662 || cp_reg_required_here (& str, 0) == FAIL)
4663 {
4664 if (!inst.error)
4665 inst.error = BAD_ARGS;
4666 return;
4667 }
4668
4669 if (skip_past_comma (& str) == SUCCESS)
4670 {
4671 if (cp_opc_expr (& str, 5, 3) == FAIL)
4672 {
4673 if (!inst.error)
4674 inst.error = BAD_ARGS;
4675 return;
4676 }
4677 }
4678
4679 end_of_line (str);
4680 }
4681
4682 /* ARM v5TEJ. Jump to Jazelle code. */
4683 static void
4684 do_bxj (str)
4685 char * str;
4686 {
4687 int reg;
4688
4689 skip_whitespace (str);
4690
4691 if ((reg = reg_required_here (&str, 0)) == FAIL)
4692 {
4693 inst.error = BAD_ARGS;
4694 return;
4695 }
4696
4697 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
4698 if (reg == REG_PC)
4699 as_tsktsk (_("use of r15 in bxj is not really useful"));
4700
4701 end_of_line (str);
4702 }
4703
4704 /* THUMB V5 breakpoint instruction (argument parse)
4705 BKPT <immed_8>. */
4706
4707 static void
4708 do_t_bkpt (str)
4709 char * str;
4710 {
4711 expressionS expr;
4712 unsigned long number;
4713
4714 skip_whitespace (str);
4715
4716 /* Allow optional leading '#'. */
4717 if (is_immediate_prefix (*str))
4718 str ++;
4719
4720 memset (& expr, '\0', sizeof (expr));
4721 if (my_get_expression (& expr, & str)
4722 || (expr.X_op != O_constant
4723 /* As a convenience we allow 'bkpt' without an operand. */
4724 && expr.X_op != O_absent))
4725 {
4726 inst.error = _("bad expression");
4727 return;
4728 }
4729
4730 number = expr.X_add_number;
4731
4732 /* Check it fits an 8 bit unsigned. */
4733 if (number != (number & 0xff))
4734 {
4735 inst.error = _("immediate value out of range");
4736 return;
4737 }
4738
4739 inst.instruction |= number;
4740
4741 end_of_line (str);
4742 }
4743
4744 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4745 Expects inst.instruction is set for BLX(1).
4746 Note: this is cloned from do_branch, and the reloc changed to be a
4747 new one that can cope with setting one extra bit (the H bit). */
4748
4749 static void
4750 do_branch25 (str)
4751 char * str;
4752 {
4753 if (my_get_expression (& inst.reloc.exp, & str))
4754 return;
4755
4756 #ifdef OBJ_ELF
4757 {
4758 char * save_in;
4759
4760 /* ScottB: February 5, 1998 */
4761 /* Check to see of PLT32 reloc required for the instruction. */
4762
4763 /* arm_parse_reloc() works on input_line_pointer.
4764 We actually want to parse the operands to the branch instruction
4765 passed in 'str'. Save the input pointer and restore it later. */
4766 save_in = input_line_pointer;
4767 input_line_pointer = str;
4768
4769 if (inst.reloc.exp.X_op == O_symbol
4770 && *str == '('
4771 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4772 {
4773 inst.reloc.type = BFD_RELOC_ARM_PLT32;
4774 inst.reloc.pc_rel = 0;
4775 /* Modify str to point to after parsed operands, otherwise
4776 end_of_line() will complain about the (PLT) left in str. */
4777 str = input_line_pointer;
4778 }
4779 else
4780 {
4781 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
4782 inst.reloc.pc_rel = 1;
4783 }
4784
4785 input_line_pointer = save_in;
4786 }
4787 #else
4788 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
4789 inst.reloc.pc_rel = 1;
4790 #endif /* OBJ_ELF */
4791
4792 end_of_line (str);
4793 }
4794
4795 /* ARM V5 branch-link-exchange instruction (argument parse)
4796 BLX <target_addr> ie BLX(1)
4797 BLX{<condition>} <Rm> ie BLX(2)
4798 Unfortunately, there are two different opcodes for this mnemonic.
4799 So, the insns[].value is not used, and the code here zaps values
4800 into inst.instruction.
4801 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
4802
4803 static void
4804 do_blx (str)
4805 char * str;
4806 {
4807 char * mystr = str;
4808 int rm;
4809
4810 skip_whitespace (mystr);
4811 rm = reg_required_here (& mystr, 0);
4812
4813 /* The above may set inst.error. Ignore his opinion. */
4814 inst.error = 0;
4815
4816 if (rm != FAIL)
4817 {
4818 /* Arg is a register.
4819 Use the condition code our caller put in inst.instruction.
4820 Pass ourselves off as a BX with a funny opcode. */
4821 inst.instruction |= 0x012fff30;
4822 do_bx (str);
4823 }
4824 else
4825 {
4826 /* This must be is BLX <target address>, no condition allowed. */
4827 if (inst.instruction != COND_ALWAYS)
4828 {
4829 inst.error = BAD_COND;
4830 return;
4831 }
4832
4833 inst.instruction = 0xfafffffe;
4834
4835 /* Process like a B/BL, but with a different reloc.
4836 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
4837 do_branch25 (str);
4838 }
4839 }
4840
4841 /* ARM V5 Thumb BLX (argument parse)
4842 BLX <target_addr> which is BLX(1)
4843 BLX <Rm> which is BLX(2)
4844 Unfortunately, there are two different opcodes for this mnemonic.
4845 So, the tinsns[].value is not used, and the code here zaps values
4846 into inst.instruction. */
4847
4848 static void
4849 do_t_blx (str)
4850 char * str;
4851 {
4852 char * mystr = str;
4853 int rm;
4854
4855 skip_whitespace (mystr);
4856 inst.instruction = 0x4780;
4857
4858 /* Note that this call is to the ARM register recognizer. BLX(2)
4859 uses the ARM register space, not the Thumb one, so a call to
4860 thumb_reg() would be wrong. */
4861 rm = reg_required_here (& mystr, 3);
4862 inst.error = 0;
4863
4864 if (rm != FAIL)
4865 {
4866 /* It's BLX(2). The .instruction was zapped with rm & is final. */
4867 inst.size = 2;
4868 }
4869 else
4870 {
4871 /* No ARM register. This must be BLX(1). Change the .instruction. */
4872 inst.instruction = 0xf7ffeffe;
4873 inst.size = 4;
4874
4875 if (my_get_expression (& inst.reloc.exp, & mystr))
4876 return;
4877
4878 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
4879 inst.reloc.pc_rel = 1;
4880 }
4881
4882 end_of_line (mystr);
4883 }
4884
4885 /* ARM V5 breakpoint instruction (argument parse)
4886 BKPT <16 bit unsigned immediate>
4887 Instruction is not conditional.
4888 The bit pattern given in insns[] has the COND_ALWAYS condition,
4889 and it is an error if the caller tried to override that. */
4890
4891 static void
4892 do_bkpt (str)
4893 char * str;
4894 {
4895 expressionS expr;
4896 unsigned long number;
4897
4898 skip_whitespace (str);
4899
4900 /* Allow optional leading '#'. */
4901 if (is_immediate_prefix (* str))
4902 str++;
4903
4904 memset (& expr, '\0', sizeof (expr));
4905
4906 if (my_get_expression (& expr, & str)
4907 || (expr.X_op != O_constant
4908 /* As a convenience we allow 'bkpt' without an operand. */
4909 && expr.X_op != O_absent))
4910 {
4911 inst.error = _("bad expression");
4912 return;
4913 }
4914
4915 number = expr.X_add_number;
4916
4917 /* Check it fits a 16 bit unsigned. */
4918 if (number != (number & 0xffff))
4919 {
4920 inst.error = _("immediate value out of range");
4921 return;
4922 }
4923
4924 /* Top 12 of 16 bits to bits 19:8. */
4925 inst.instruction |= (number & 0xfff0) << 4;
4926
4927 /* Bottom 4 of 16 bits to bits 3:0. */
4928 inst.instruction |= number & 0xf;
4929
4930 end_of_line (str);
4931 }
4932
4933 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
4934
4935 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
4936
4937 static unsigned long
4938 check_iwmmxt_insn (str, insn_type, immediate_size)
4939 char * str;
4940 enum iwmmxt_insn_type insn_type;
4941 int immediate_size;
4942 {
4943 int reg = 0;
4944 const char * inst_error;
4945 expressionS expr;
4946 unsigned long number;
4947
4948 inst_error = inst.error;
4949 if (!inst.error)
4950 inst.error = BAD_ARGS;
4951 skip_whitespace (str);
4952
4953 switch (insn_type)
4954 {
4955 case check_rd:
4956 if ((reg = reg_required_here (&str, 12)) == FAIL)
4957 return FAIL;
4958 break;
4959
4960 case check_wr:
4961 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
4962 return FAIL;
4963 break;
4964
4965 case check_wrwr:
4966 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4967 || skip_past_comma (&str) == FAIL
4968 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4969 return FAIL;
4970 break;
4971
4972 case check_wrwrwr:
4973 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4974 || skip_past_comma (&str) == FAIL
4975 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4976 || skip_past_comma (&str) == FAIL
4977 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4978 return FAIL;
4979 break;
4980
4981 case check_wrwrwcg:
4982 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4983 || skip_past_comma (&str) == FAIL
4984 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4985 || skip_past_comma (&str) == FAIL
4986 || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
4987 return FAIL;
4988 break;
4989
4990 case check_tbcst:
4991 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4992 || skip_past_comma (&str) == FAIL
4993 || reg_required_here (&str, 12) == FAIL))
4994 return FAIL;
4995 break;
4996
4997 case check_tmovmsk:
4998 if ((reg_required_here (&str, 12) == FAIL
4999 || skip_past_comma (&str) == FAIL
5000 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
5001 return FAIL;
5002 break;
5003
5004 case check_tmia:
5005 if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
5006 || skip_past_comma (&str) == FAIL
5007 || reg_required_here (&str, 0) == FAIL
5008 || skip_past_comma (&str) == FAIL
5009 || reg_required_here (&str, 12) == FAIL))
5010 return FAIL;
5011 break;
5012
5013 case check_tmcrr:
5014 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5015 || skip_past_comma (&str) == FAIL
5016 || reg_required_here (&str, 12) == FAIL
5017 || skip_past_comma (&str) == FAIL
5018 || reg_required_here (&str, 16) == FAIL))
5019 return FAIL;
5020 break;
5021
5022 case check_tmrrc:
5023 if ((reg_required_here (&str, 12) == FAIL
5024 || skip_past_comma (&str) == FAIL
5025 || reg_required_here (&str, 16) == FAIL
5026 || skip_past_comma (&str) == FAIL
5027 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5028 return FAIL;
5029 break;
5030
5031 case check_tmcr:
5032 if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
5033 || skip_past_comma (&str) == FAIL
5034 || reg_required_here (&str, 12) == FAIL))
5035 return FAIL;
5036 break;
5037
5038 case check_tmrc:
5039 if ((reg_required_here (&str, 12) == FAIL
5040 || skip_past_comma (&str) == FAIL
5041 || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
5042 return FAIL;
5043 break;
5044
5045 case check_tinsr:
5046 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5047 || skip_past_comma (&str) == FAIL
5048 || reg_required_here (&str, 12) == FAIL
5049 || skip_past_comma (&str) == FAIL))
5050 return FAIL;
5051 break;
5052
5053 case check_textrc:
5054 if ((reg_required_here (&str, 12) == FAIL
5055 || skip_past_comma (&str) == FAIL))
5056 return FAIL;
5057 break;
5058
5059 case check_waligni:
5060 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5061 || skip_past_comma (&str) == FAIL
5062 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5063 || skip_past_comma (&str) == FAIL
5064 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5065 || skip_past_comma (&str) == FAIL))
5066 return FAIL;
5067 break;
5068
5069 case check_textrm:
5070 if ((reg_required_here (&str, 12) == FAIL
5071 || skip_past_comma (&str) == FAIL
5072 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5073 || skip_past_comma (&str) == FAIL))
5074 return FAIL;
5075 break;
5076
5077 case check_wshufh:
5078 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5079 || skip_past_comma (&str) == FAIL
5080 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5081 || skip_past_comma (&str) == FAIL))
5082 return FAIL;
5083 break;
5084 }
5085
5086 if (immediate_size == 0)
5087 {
5088 end_of_line (str);
5089 inst.error = inst_error;
5090 return reg;
5091 }
5092 else
5093 {
5094 skip_whitespace (str);
5095
5096 /* Allow optional leading '#'. */
5097 if (is_immediate_prefix (* str))
5098 str++;
5099
5100 memset (& expr, '\0', sizeof (expr));
5101
5102 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
5103 {
5104 inst.error = _("bad or missing expression");
5105 return FAIL;
5106 }
5107
5108 number = expr.X_add_number;
5109
5110 if (number != (number & immediate_size))
5111 {
5112 inst.error = _("immediate value out of range");
5113 return FAIL;
5114 }
5115 end_of_line (str);
5116 inst.error = inst_error;
5117 return number;
5118 }
5119 }
5120
5121 static void
5122 do_iwmmxt_byte_addr (str)
5123 char * str;
5124 {
5125 int op = (inst.instruction & 0x300) >> 8;
5126 int reg;
5127
5128 inst.instruction &= ~0x300;
5129 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5130
5131 skip_whitespace (str);
5132
5133 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5134 || skip_past_comma (& str) == FAIL
5135 || cp_byte_address_required_here (&str) == FAIL)
5136 {
5137 if (! inst.error)
5138 inst.error = BAD_ARGS;
5139 }
5140 else
5141 end_of_line (str);
5142
5143 if (wc_register (reg))
5144 {
5145 as_bad (_("non-word size not supported with control register"));
5146 inst.instruction |= 0xf0000100;
5147 inst.instruction &= ~0x00400000;
5148 }
5149 }
5150
5151 static void
5152 do_iwmmxt_tandc (str)
5153 char * str;
5154 {
5155 int reg;
5156
5157 reg = check_iwmmxt_insn (str, check_rd, 0);
5158
5159 if (reg != REG_PC && !inst.error)
5160 inst.error = _("only r15 allowed here");
5161 return;
5162 }
5163
5164 static void
5165 do_iwmmxt_tbcst (str)
5166 char * str;
5167 {
5168 check_iwmmxt_insn (str, check_tbcst, 0);
5169
5170 return;
5171 }
5172
5173 static void
5174 do_iwmmxt_textrc (str)
5175 char * str;
5176 {
5177 unsigned long number;
5178
5179 if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
5180 return;
5181
5182 inst.instruction |= number & 0x7;
5183 return;
5184 }
5185
5186 static void
5187 do_iwmmxt_textrm (str)
5188 char * str;
5189 {
5190 unsigned long number;
5191
5192 if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
5193 return;
5194
5195 inst.instruction |= number & 0x7;
5196 }
5197
5198 static void
5199 do_iwmmxt_tinsr (str)
5200 char * str;
5201 {
5202 unsigned long number;
5203
5204 if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
5205 return;
5206
5207 inst.instruction |= number & 0x7;
5208 return;
5209 }
5210
5211 static void
5212 do_iwmmxt_tmcr (str)
5213 char * str;
5214 {
5215 check_iwmmxt_insn (str, check_tmcr, 0);
5216
5217 return;
5218 }
5219
5220 static void
5221 do_iwmmxt_tmcrr (str)
5222 char * str;
5223 {
5224 check_iwmmxt_insn (str, check_tmcrr, 0);
5225
5226 return;
5227 }
5228
5229 static void
5230 do_iwmmxt_tmia (str)
5231 char * str;
5232 {
5233 check_iwmmxt_insn (str, check_tmia, 0);
5234
5235 return;
5236 }
5237
5238 static void
5239 do_iwmmxt_tmovmsk (str)
5240 char * str;
5241 {
5242 check_iwmmxt_insn (str, check_tmovmsk, 0);
5243
5244 return;
5245 }
5246
5247 static void
5248 do_iwmmxt_tmrc (str)
5249 char * str;
5250 {
5251 check_iwmmxt_insn (str, check_tmrc, 0);
5252
5253 return;
5254 }
5255
5256 static void
5257 do_iwmmxt_tmrrc (str)
5258 char * str;
5259 {
5260 check_iwmmxt_insn (str, check_tmrrc, 0);
5261
5262 return;
5263 }
5264
5265 static void
5266 do_iwmmxt_torc (str)
5267 char * str;
5268 {
5269 check_iwmmxt_insn (str, check_rd, 0);
5270 return;
5271 }
5272
5273 static void
5274 do_iwmmxt_waligni (str)
5275 char * str;
5276 {
5277 unsigned long number;
5278
5279 if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
5280 return;
5281
5282 inst.instruction |= ((number & 0x7) << 20);
5283 return;
5284 }
5285
5286 static void
5287 do_iwmmxt_wmov (str)
5288 char * str;
5289 {
5290 if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
5291 return;
5292
5293 inst.instruction |= ((inst.instruction >> 16) & 0xf);
5294 return;
5295 }
5296
5297 static void
5298 do_iwmmxt_word_addr (str)
5299 char * str;
5300 {
5301 int op = (inst.instruction & 0x300) >> 8;
5302 int reg;
5303
5304 inst.instruction &= ~0x300;
5305 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5306
5307 skip_whitespace (str);
5308
5309 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5310 || skip_past_comma (& str) == FAIL
5311 || cp_address_required_here (& str, CP_WB_OK) == FAIL)
5312 {
5313 if (! inst.error)
5314 inst.error = BAD_ARGS;
5315 }
5316 else
5317 end_of_line (str);
5318
5319 if (wc_register (reg))
5320 {
5321 if ((inst.instruction & COND_MASK) != COND_ALWAYS)
5322 as_bad (_("conditional execution not supported with control register"));
5323 if (op != 2)
5324 as_bad (_("non-word size not supported with control register"));
5325 inst.instruction |= 0xf0000100;
5326 inst.instruction &= ~0x00400000;
5327 }
5328 }
5329
5330 static void
5331 do_iwmmxt_wrwr (str)
5332 char * str;
5333 {
5334 check_iwmmxt_insn (str, check_wrwr, 0);
5335
5336 return;
5337 }
5338
5339 static void
5340 do_iwmmxt_wrwrwcg (str)
5341 char * str;
5342 {
5343 check_iwmmxt_insn (str, check_wrwrwcg, 0);
5344
5345 return;
5346 }
5347
5348 static void
5349 do_iwmmxt_wrwrwr (str)
5350 char * str;
5351 {
5352 check_iwmmxt_insn (str, check_wrwrwr, 0);
5353
5354 return;
5355 }
5356
5357 static void
5358 do_iwmmxt_wshufh (str)
5359 char * str;
5360 {
5361 unsigned long number;
5362
5363 if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5364 return;
5365
5366 inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5367 return;
5368 }
5369
5370 static void
5371 do_iwmmxt_wzero (str)
5372 char * str;
5373 {
5374 if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5375 return;
5376
5377 inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5378 return;
5379 }
5380
5381 /* Xscale multiply-accumulate (argument parse)
5382 MIAcc acc0,Rm,Rs
5383 MIAPHcc acc0,Rm,Rs
5384 MIAxycc acc0,Rm,Rs. */
5385
5386 static void
5387 do_xsc_mia (str)
5388 char * str;
5389 {
5390 int rs;
5391 int rm;
5392
5393 if (accum0_required_here (& str) == FAIL)
5394 inst.error = ERR_NO_ACCUM;
5395
5396 else if (skip_past_comma (& str) == FAIL
5397 || (rm = reg_required_here (& str, 0)) == FAIL)
5398 inst.error = BAD_ARGS;
5399
5400 else if (skip_past_comma (& str) == FAIL
5401 || (rs = reg_required_here (& str, 12)) == FAIL)
5402 inst.error = BAD_ARGS;
5403
5404 /* inst.instruction has now been zapped with both rm and rs. */
5405 else if (rm == REG_PC || rs == REG_PC)
5406 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
5407
5408 else
5409 end_of_line (str);
5410 }
5411
5412 /* Xscale move-accumulator-register (argument parse)
5413
5414 MARcc acc0,RdLo,RdHi. */
5415
5416 static void
5417 do_xsc_mar (str)
5418 char * str;
5419 {
5420 int rdlo, rdhi;
5421
5422 if (accum0_required_here (& str) == FAIL)
5423 inst.error = ERR_NO_ACCUM;
5424
5425 else if (skip_past_comma (& str) == FAIL
5426 || (rdlo = reg_required_here (& str, 12)) == FAIL)
5427 inst.error = BAD_ARGS;
5428
5429 else if (skip_past_comma (& str) == FAIL
5430 || (rdhi = reg_required_here (& str, 16)) == FAIL)
5431 inst.error = BAD_ARGS;
5432
5433 /* inst.instruction has now been zapped with both rdlo and rdhi. */
5434 else if (rdlo == REG_PC || rdhi == REG_PC)
5435 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
5436
5437 else
5438 end_of_line (str);
5439 }
5440
5441 /* Xscale move-register-accumulator (argument parse)
5442
5443 MRAcc RdLo,RdHi,acc0. */
5444
5445 static void
5446 do_xsc_mra (str)
5447 char * str;
5448 {
5449 int rdlo;
5450 int rdhi;
5451
5452 skip_whitespace (str);
5453
5454 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5455 inst.error = BAD_ARGS;
5456
5457 else if (skip_past_comma (& str) == FAIL
5458 || (rdhi = reg_required_here (& str, 16)) == FAIL)
5459 inst.error = BAD_ARGS;
5460
5461 else if (skip_past_comma (& str) == FAIL
5462 || accum0_required_here (& str) == FAIL)
5463 inst.error = ERR_NO_ACCUM;
5464
5465 /* inst.instruction has now been zapped with both rdlo and rdhi. */
5466 else if (rdlo == rdhi)
5467 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
5468
5469 else if (rdlo == REG_PC || rdhi == REG_PC)
5470 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
5471 else
5472 end_of_line (str);
5473 }
5474
5475 /* ARMv5TE: Preload-Cache
5476
5477 PLD <addr_mode>
5478
5479 Syntactically, like LDR with B=1, W=0, L=1. */
5480
5481 static void
5482 do_pld (str)
5483 char * str;
5484 {
5485 int rd;
5486
5487 skip_whitespace (str);
5488
5489 if (* str != '[')
5490 {
5491 inst.error = _("'[' expected after PLD mnemonic");
5492 return;
5493 }
5494
5495 ++str;
5496 skip_whitespace (str);
5497
5498 if ((rd = reg_required_here (& str, 16)) == FAIL)
5499 return;
5500
5501 skip_whitespace (str);
5502
5503 if (*str == ']')
5504 {
5505 /* [Rn], ... ? */
5506 ++str;
5507 skip_whitespace (str);
5508
5509 /* Post-indexed addressing is not allowed with PLD. */
5510 if (skip_past_comma (&str) == SUCCESS)
5511 {
5512 inst.error
5513 = _("post-indexed expression used in preload instruction");
5514 return;
5515 }
5516 else if (*str == '!') /* [Rn]! */
5517 {
5518 inst.error = _("writeback used in preload instruction");
5519 ++str;
5520 }
5521 else /* [Rn] */
5522 inst.instruction |= INDEX_UP | PRE_INDEX;
5523 }
5524 else /* [Rn, ...] */
5525 {
5526 if (skip_past_comma (& str) == FAIL)
5527 {
5528 inst.error = _("pre-indexed expression expected");
5529 return;
5530 }
5531
5532 if (ldst_extend (&str) == FAIL)
5533 return;
5534
5535 skip_whitespace (str);
5536
5537 if (* str != ']')
5538 {
5539 inst.error = _("missing ]");
5540 return;
5541 }
5542
5543 ++ str;
5544 skip_whitespace (str);
5545
5546 if (* str == '!') /* [Rn]! */
5547 {
5548 inst.error = _("writeback used in preload instruction");
5549 ++ str;
5550 }
5551
5552 inst.instruction |= PRE_INDEX;
5553 }
5554
5555 end_of_line (str);
5556 }
5557
5558 /* ARMv5TE load-consecutive (argument parse)
5559 Mode is like LDRH.
5560
5561 LDRccD R, mode
5562 STRccD R, mode. */
5563
5564 static void
5565 do_ldrd (str)
5566 char * str;
5567 {
5568 int rd;
5569 int rn;
5570
5571 skip_whitespace (str);
5572
5573 if ((rd = reg_required_here (& str, 12)) == FAIL)
5574 {
5575 inst.error = BAD_ARGS;
5576 return;
5577 }
5578
5579 if (skip_past_comma (& str) == FAIL
5580 || (rn = ld_mode_required_here (& str)) == FAIL)
5581 {
5582 if (!inst.error)
5583 inst.error = BAD_ARGS;
5584 return;
5585 }
5586
5587 /* inst.instruction has now been zapped with Rd and the addressing mode. */
5588 if (rd & 1) /* Unpredictable result if Rd is odd. */
5589 {
5590 inst.error = _("destination register must be even");
5591 return;
5592 }
5593
5594 if (rd == REG_LR)
5595 {
5596 inst.error = _("r14 not allowed here");
5597 return;
5598 }
5599
5600 if (((rd == rn) || (rd + 1 == rn))
5601 && ((inst.instruction & WRITE_BACK)
5602 || (!(inst.instruction & PRE_INDEX))))
5603 as_warn (_("pre/post-indexing used when modified address register is destination"));
5604
5605 /* For an index-register load, the index register must not overlap the
5606 destination (even if not write-back). */
5607 if ((inst.instruction & V4_STR_BIT) == 0
5608 && (inst.instruction & HWOFFSET_IMM) == 0)
5609 {
5610 int rm = inst.instruction & 0x0000000f;
5611
5612 if (rm == rd || (rm == rd + 1))
5613 as_warn (_("ldrd destination registers must not overlap index register"));
5614 }
5615
5616 end_of_line (str);
5617 }
5618
5619 /* Returns the index into fp_values of a floating point number,
5620 or -1 if not in the table. */
5621
5622 static int
5623 my_get_float_expression (str)
5624 char ** str;
5625 {
5626 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5627 char * save_in;
5628 expressionS exp;
5629 int i;
5630 int j;
5631
5632 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5633
5634 /* Look for a raw floating point number. */
5635 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5636 && is_end_of_line[(unsigned char) *save_in])
5637 {
5638 for (i = 0; i < NUM_FLOAT_VALS; i++)
5639 {
5640 for (j = 0; j < MAX_LITTLENUMS; j++)
5641 {
5642 if (words[j] != fp_values[i][j])
5643 break;
5644 }
5645
5646 if (j == MAX_LITTLENUMS)
5647 {
5648 *str = save_in;
5649 return i;
5650 }
5651 }
5652 }
5653
5654 /* Try and parse a more complex expression, this will probably fail
5655 unless the code uses a floating point prefix (eg "0f"). */
5656 save_in = input_line_pointer;
5657 input_line_pointer = *str;
5658 if (expression (&exp) == absolute_section
5659 && exp.X_op == O_big
5660 && exp.X_add_number < 0)
5661 {
5662 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5663 Ditto for 15. */
5664 if (gen_to_words (words, 5, (long) 15) == 0)
5665 {
5666 for (i = 0; i < NUM_FLOAT_VALS; i++)
5667 {
5668 for (j = 0; j < MAX_LITTLENUMS; j++)
5669 {
5670 if (words[j] != fp_values[i][j])
5671 break;
5672 }
5673
5674 if (j == MAX_LITTLENUMS)
5675 {
5676 *str = input_line_pointer;
5677 input_line_pointer = save_in;
5678 return i;
5679 }
5680 }
5681 }
5682 }
5683
5684 *str = input_line_pointer;
5685 input_line_pointer = save_in;
5686 return -1;
5687 }
5688
5689 /* Return TRUE if anything in the expression is a bignum. */
5690
5691 static int
5692 walk_no_bignums (sp)
5693 symbolS * sp;
5694 {
5695 if (symbol_get_value_expression (sp)->X_op == O_big)
5696 return 1;
5697
5698 if (symbol_get_value_expression (sp)->X_add_symbol)
5699 {
5700 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
5701 || (symbol_get_value_expression (sp)->X_op_symbol
5702 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
5703 }
5704
5705 return 0;
5706 }
5707
5708 static int in_my_get_expression = 0;
5709
5710 static int
5711 my_get_expression (ep, str)
5712 expressionS * ep;
5713 char ** str;
5714 {
5715 char * save_in;
5716 segT seg;
5717
5718 save_in = input_line_pointer;
5719 input_line_pointer = *str;
5720 in_my_get_expression = 1;
5721 seg = expression (ep);
5722 in_my_get_expression = 0;
5723
5724 if (ep->X_op == O_illegal)
5725 {
5726 /* We found a bad expression in md_operand(). */
5727 *str = input_line_pointer;
5728 input_line_pointer = save_in;
5729 return 1;
5730 }
5731
5732 #ifdef OBJ_AOUT
5733 if (seg != absolute_section
5734 && seg != text_section
5735 && seg != data_section
5736 && seg != bss_section
5737 && seg != undefined_section)
5738 {
5739 inst.error = _("bad_segment");
5740 *str = input_line_pointer;
5741 input_line_pointer = save_in;
5742 return 1;
5743 }
5744 #endif
5745
5746 /* Get rid of any bignums now, so that we don't generate an error for which
5747 we can't establish a line number later on. Big numbers are never valid
5748 in instructions, which is where this routine is always called. */
5749 if (ep->X_op == O_big
5750 || (ep->X_add_symbol
5751 && (walk_no_bignums (ep->X_add_symbol)
5752 || (ep->X_op_symbol
5753 && walk_no_bignums (ep->X_op_symbol)))))
5754 {
5755 inst.error = _("invalid constant");
5756 *str = input_line_pointer;
5757 input_line_pointer = save_in;
5758 return 1;
5759 }
5760
5761 *str = input_line_pointer;
5762 input_line_pointer = save_in;
5763 return 0;
5764 }
5765
5766 /* We handle all bad expressions here, so that we can report the faulty
5767 instruction in the error message. */
5768 void
5769 md_operand (expr)
5770 expressionS *expr;
5771 {
5772 if (in_my_get_expression)
5773 {
5774 expr->X_op = O_illegal;
5775 if (inst.error == NULL)
5776 inst.error = _("bad expression");
5777 }
5778 }
5779
5780 /* UNRESTRICT should be one if <shift> <register> is permitted for this
5781 instruction. */
5782
5783 static int
5784 decode_shift (str, unrestrict)
5785 char ** str;
5786 int unrestrict;
5787 {
5788 const struct asm_shift_name * shift;
5789 char * p;
5790 char c;
5791
5792 skip_whitespace (* str);
5793
5794 for (p = * str; ISALPHA (* p); p ++)
5795 ;
5796
5797 if (p == * str)
5798 {
5799 inst.error = _("shift expression expected");
5800 return FAIL;
5801 }
5802
5803 c = * p;
5804 * p = '\0';
5805 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
5806 * p = c;
5807
5808 if (shift == NULL)
5809 {
5810 inst.error = _("shift expression expected");
5811 return FAIL;
5812 }
5813
5814 assert (shift->properties->index == shift_properties[shift->properties->index].index);
5815
5816 if (shift->properties->index == SHIFT_RRX)
5817 {
5818 * str = p;
5819 inst.instruction |= shift->properties->bit_field;
5820 return SUCCESS;
5821 }
5822
5823 skip_whitespace (p);
5824
5825 if (unrestrict && reg_required_here (& p, 8) != FAIL)
5826 {
5827 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
5828 * str = p;
5829 return SUCCESS;
5830 }
5831 else if (! is_immediate_prefix (* p))
5832 {
5833 inst.error = (unrestrict
5834 ? _("shift requires register or #expression")
5835 : _("shift requires #expression"));
5836 * str = p;
5837 return FAIL;
5838 }
5839
5840 inst.error = NULL;
5841 p ++;
5842
5843 if (my_get_expression (& inst.reloc.exp, & p))
5844 return FAIL;
5845
5846 /* Validate some simple #expressions. */
5847 if (inst.reloc.exp.X_op == O_constant)
5848 {
5849 unsigned num = inst.reloc.exp.X_add_number;
5850
5851 /* Reject operations greater than 32. */
5852 if (num > 32
5853 /* Reject a shift of 0 unless the mode allows it. */
5854 || (num == 0 && shift->properties->allows_0 == 0)
5855 /* Reject a shift of 32 unless the mode allows it. */
5856 || (num == 32 && shift->properties->allows_32 == 0)
5857 )
5858 {
5859 /* As a special case we allow a shift of zero for
5860 modes that do not support it to be recoded as an
5861 logical shift left of zero (ie nothing). We warn
5862 about this though. */
5863 if (num == 0)
5864 {
5865 as_warn (_("shift of 0 ignored."));
5866 shift = & shift_names[0];
5867 assert (shift->properties->index == SHIFT_LSL);
5868 }
5869 else
5870 {
5871 inst.error = _("invalid immediate shift");
5872 return FAIL;
5873 }
5874 }
5875
5876 /* Shifts of 32 are encoded as 0, for those shifts that
5877 support it. */
5878 if (num == 32)
5879 num = 0;
5880
5881 inst.instruction |= (num << 7) | shift->properties->bit_field;
5882 }
5883 else
5884 {
5885 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
5886 inst.reloc.pc_rel = 0;
5887 inst.instruction |= shift->properties->bit_field;
5888 }
5889
5890 * str = p;
5891 return SUCCESS;
5892 }
5893
5894 /* Do those data_ops which can take a negative immediate constant
5895 by altering the instruction. A bit of a hack really.
5896 MOV <-> MVN
5897 AND <-> BIC
5898 ADC <-> SBC
5899 by inverting the second operand, and
5900 ADD <-> SUB
5901 CMP <-> CMN
5902 by negating the second operand. */
5903
5904 static int
5905 negate_data_op (instruction, value)
5906 unsigned long * instruction;
5907 unsigned long value;
5908 {
5909 int op, new_inst;
5910 unsigned long negated, inverted;
5911
5912 negated = validate_immediate (-value);
5913 inverted = validate_immediate (~value);
5914
5915 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
5916 switch (op)
5917 {
5918 /* First negates. */
5919 case OPCODE_SUB: /* ADD <-> SUB */
5920 new_inst = OPCODE_ADD;
5921 value = negated;
5922 break;
5923
5924 case OPCODE_ADD:
5925 new_inst = OPCODE_SUB;
5926 value = negated;
5927 break;
5928
5929 case OPCODE_CMP: /* CMP <-> CMN */
5930 new_inst = OPCODE_CMN;
5931 value = negated;
5932 break;
5933
5934 case OPCODE_CMN:
5935 new_inst = OPCODE_CMP;
5936 value = negated;
5937 break;
5938
5939 /* Now Inverted ops. */
5940 case OPCODE_MOV: /* MOV <-> MVN */
5941 new_inst = OPCODE_MVN;
5942 value = inverted;
5943 break;
5944
5945 case OPCODE_MVN:
5946 new_inst = OPCODE_MOV;
5947 value = inverted;
5948 break;
5949
5950 case OPCODE_AND: /* AND <-> BIC */
5951 new_inst = OPCODE_BIC;
5952 value = inverted;
5953 break;
5954
5955 case OPCODE_BIC:
5956 new_inst = OPCODE_AND;
5957 value = inverted;
5958 break;
5959
5960 case OPCODE_ADC: /* ADC <-> SBC */
5961 new_inst = OPCODE_SBC;
5962 value = inverted;
5963 break;
5964
5965 case OPCODE_SBC:
5966 new_inst = OPCODE_ADC;
5967 value = inverted;
5968 break;
5969
5970 /* We cannot do anything. */
5971 default:
5972 return FAIL;
5973 }
5974
5975 if (value == (unsigned) FAIL)
5976 return FAIL;
5977
5978 *instruction &= OPCODE_MASK;
5979 *instruction |= new_inst << DATA_OP_SHIFT;
5980 return value;
5981 }
5982
5983 static int
5984 data_op2 (str)
5985 char ** str;
5986 {
5987 int value;
5988 expressionS expr;
5989
5990 skip_whitespace (* str);
5991
5992 if (reg_required_here (str, 0) != FAIL)
5993 {
5994 if (skip_past_comma (str) == SUCCESS)
5995 /* Shift operation on register. */
5996 return decode_shift (str, NO_SHIFT_RESTRICT);
5997
5998 return SUCCESS;
5999 }
6000 else
6001 {
6002 /* Immediate expression. */
6003 if (is_immediate_prefix (**str))
6004 {
6005 (*str)++;
6006 inst.error = NULL;
6007
6008 if (my_get_expression (&inst.reloc.exp, str))
6009 return FAIL;
6010
6011 if (inst.reloc.exp.X_add_symbol)
6012 {
6013 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
6014 inst.reloc.pc_rel = 0;
6015 }
6016 else
6017 {
6018 if (skip_past_comma (str) == SUCCESS)
6019 {
6020 /* #x, y -- ie explicit rotation by Y. */
6021 if (my_get_expression (&expr, str))
6022 return FAIL;
6023
6024 if (expr.X_op != O_constant)
6025 {
6026 inst.error = _("constant expression expected");
6027 return FAIL;
6028 }
6029
6030 /* Rotate must be a multiple of 2. */
6031 if (((unsigned) expr.X_add_number) > 30
6032 || (expr.X_add_number & 1) != 0
6033 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
6034 {
6035 inst.error = _("invalid constant");
6036 return FAIL;
6037 }
6038 inst.instruction |= INST_IMMEDIATE;
6039 inst.instruction |= inst.reloc.exp.X_add_number;
6040 inst.instruction |= expr.X_add_number << 7;
6041 return SUCCESS;
6042 }
6043
6044 /* Implicit rotation, select a suitable one. */
6045 value = validate_immediate (inst.reloc.exp.X_add_number);
6046
6047 if (value == FAIL)
6048 {
6049 /* Can't be done. Perhaps the code reads something like
6050 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
6051 if ((value = negate_data_op (&inst.instruction,
6052 inst.reloc.exp.X_add_number))
6053 == FAIL)
6054 {
6055 inst.error = _("invalid constant");
6056 return FAIL;
6057 }
6058 }
6059
6060 inst.instruction |= value;
6061 }
6062
6063 inst.instruction |= INST_IMMEDIATE;
6064 return SUCCESS;
6065 }
6066
6067 (*str)++;
6068 inst.error = _("register or shift expression expected");
6069 return FAIL;
6070 }
6071 }
6072
6073 static int
6074 fp_op2 (str)
6075 char ** str;
6076 {
6077 skip_whitespace (* str);
6078
6079 if (fp_reg_required_here (str, 0) != FAIL)
6080 return SUCCESS;
6081 else
6082 {
6083 /* Immediate expression. */
6084 if (*((*str)++) == '#')
6085 {
6086 int i;
6087
6088 inst.error = NULL;
6089
6090 skip_whitespace (* str);
6091
6092 /* First try and match exact strings, this is to guarantee
6093 that some formats will work even for cross assembly. */
6094
6095 for (i = 0; fp_const[i]; i++)
6096 {
6097 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
6098 {
6099 char *start = *str;
6100
6101 *str += strlen (fp_const[i]);
6102 if (is_end_of_line[(unsigned char) **str])
6103 {
6104 inst.instruction |= i + 8;
6105 return SUCCESS;
6106 }
6107 *str = start;
6108 }
6109 }
6110
6111 /* Just because we didn't get a match doesn't mean that the
6112 constant isn't valid, just that it is in a format that we
6113 don't automatically recognize. Try parsing it with
6114 the standard expression routines. */
6115 if ((i = my_get_float_expression (str)) >= 0)
6116 {
6117 inst.instruction |= i + 8;
6118 return SUCCESS;
6119 }
6120
6121 inst.error = _("invalid floating point immediate expression");
6122 return FAIL;
6123 }
6124 inst.error =
6125 _("floating point register or immediate expression expected");
6126 return FAIL;
6127 }
6128 }
6129
6130 static void
6131 do_arit (str)
6132 char * str;
6133 {
6134 skip_whitespace (str);
6135
6136 if (reg_required_here (&str, 12) == FAIL
6137 || skip_past_comma (&str) == FAIL
6138 || reg_required_here (&str, 16) == FAIL
6139 || skip_past_comma (&str) == FAIL
6140 || data_op2 (&str) == FAIL)
6141 {
6142 if (!inst.error)
6143 inst.error = BAD_ARGS;
6144 return;
6145 }
6146
6147 end_of_line (str);
6148 return;
6149 }
6150
6151 static void
6152 do_adr (str)
6153 char * str;
6154 {
6155 /* This is a pseudo-op of the form "adr rd, label" to be converted
6156 into a relative address of the form "add rd, pc, #label-.-8". */
6157 skip_whitespace (str);
6158
6159 if (reg_required_here (&str, 12) == FAIL
6160 || skip_past_comma (&str) == FAIL
6161 || my_get_expression (&inst.reloc.exp, &str))
6162 {
6163 if (!inst.error)
6164 inst.error = BAD_ARGS;
6165 return;
6166 }
6167
6168 /* Frag hacking will turn this into a sub instruction if the offset turns
6169 out to be negative. */
6170 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
6171 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
6172 inst.reloc.pc_rel = 1;
6173
6174 end_of_line (str);
6175 }
6176
6177 static void
6178 do_adrl (str)
6179 char * str;
6180 {
6181 /* This is a pseudo-op of the form "adrl rd, label" to be converted
6182 into a relative address of the form:
6183 add rd, pc, #low(label-.-8)"
6184 add rd, rd, #high(label-.-8)" */
6185
6186 skip_whitespace (str);
6187
6188 if (reg_required_here (&str, 12) == FAIL
6189 || skip_past_comma (&str) == FAIL
6190 || my_get_expression (&inst.reloc.exp, &str))
6191 {
6192 if (!inst.error)
6193 inst.error = BAD_ARGS;
6194
6195 return;
6196 }
6197
6198 end_of_line (str);
6199 /* Frag hacking will turn this into a sub instruction if the offset turns
6200 out to be negative. */
6201 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
6202 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
6203 inst.reloc.pc_rel = 1;
6204 inst.size = INSN_SIZE * 2;
6205
6206 return;
6207 }
6208
6209 static void
6210 do_cmp (str)
6211 char * str;
6212 {
6213 skip_whitespace (str);
6214
6215 if (reg_required_here (&str, 16) == FAIL)
6216 {
6217 if (!inst.error)
6218 inst.error = BAD_ARGS;
6219 return;
6220 }
6221
6222 if (skip_past_comma (&str) == FAIL
6223 || data_op2 (&str) == FAIL)
6224 {
6225 if (!inst.error)
6226 inst.error = BAD_ARGS;
6227 return;
6228 }
6229
6230 end_of_line (str);
6231 return;
6232 }
6233
6234 static void
6235 do_mov (str)
6236 char * str;
6237 {
6238 skip_whitespace (str);
6239
6240 if (reg_required_here (&str, 12) == FAIL)
6241 {
6242 if (!inst.error)
6243 inst.error = BAD_ARGS;
6244 return;
6245 }
6246
6247 if (skip_past_comma (&str) == FAIL
6248 || data_op2 (&str) == FAIL)
6249 {
6250 if (!inst.error)
6251 inst.error = BAD_ARGS;
6252 return;
6253 }
6254
6255 end_of_line (str);
6256 return;
6257 }
6258
6259 static int
6260 ldst_extend (str)
6261 char ** str;
6262 {
6263 int add = INDEX_UP;
6264
6265 switch (**str)
6266 {
6267 case '#':
6268 case '$':
6269 (*str)++;
6270 if (my_get_expression (& inst.reloc.exp, str))
6271 return FAIL;
6272
6273 if (inst.reloc.exp.X_op == O_constant)
6274 {
6275 int value = inst.reloc.exp.X_add_number;
6276
6277 if (value < -4095 || value > 4095)
6278 {
6279 inst.error = _("address offset too large");
6280 return FAIL;
6281 }
6282
6283 if (value < 0)
6284 {
6285 value = -value;
6286 add = 0;
6287 }
6288
6289 inst.instruction |= add | value;
6290 }
6291 else
6292 {
6293 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6294 inst.reloc.pc_rel = 0;
6295 }
6296 return SUCCESS;
6297
6298 case '-':
6299 add = 0;
6300 /* Fall through. */
6301
6302 case '+':
6303 (*str)++;
6304 /* Fall through. */
6305
6306 default:
6307 if (reg_required_here (str, 0) == FAIL)
6308 return FAIL;
6309
6310 inst.instruction |= add | OFFSET_REG;
6311 if (skip_past_comma (str) == SUCCESS)
6312 return decode_shift (str, SHIFT_RESTRICT);
6313
6314 return SUCCESS;
6315 }
6316 }
6317
6318 static void
6319 do_ldst (str)
6320 char * str;
6321 {
6322 int pre_inc = 0;
6323 int conflict_reg;
6324 int value;
6325
6326 skip_whitespace (str);
6327
6328 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
6329 {
6330 if (!inst.error)
6331 inst.error = BAD_ARGS;
6332 return;
6333 }
6334
6335 if (skip_past_comma (&str) == FAIL)
6336 {
6337 inst.error = _("address expected");
6338 return;
6339 }
6340
6341 if (*str == '[')
6342 {
6343 int reg;
6344
6345 str++;
6346
6347 skip_whitespace (str);
6348
6349 if ((reg = reg_required_here (&str, 16)) == FAIL)
6350 return;
6351
6352 /* Conflicts can occur on stores as well as loads. */
6353 conflict_reg = (conflict_reg == reg);
6354
6355 skip_whitespace (str);
6356
6357 if (*str == ']')
6358 {
6359 str ++;
6360
6361 if (skip_past_comma (&str) == SUCCESS)
6362 {
6363 /* [Rn],... (post inc) */
6364 if (ldst_extend (&str) == FAIL)
6365 return;
6366 if (conflict_reg)
6367 as_warn (_("%s register same as write-back base"),
6368 ((inst.instruction & LOAD_BIT)
6369 ? _("destination") : _("source")));
6370 }
6371 else
6372 {
6373 /* [Rn] */
6374 skip_whitespace (str);
6375
6376 if (*str == '!')
6377 {
6378 if (conflict_reg)
6379 as_warn (_("%s register same as write-back base"),
6380 ((inst.instruction & LOAD_BIT)
6381 ? _("destination") : _("source")));
6382 str++;
6383 inst.instruction |= WRITE_BACK;
6384 }
6385
6386 inst.instruction |= INDEX_UP;
6387 pre_inc = 1;
6388 }
6389 }
6390 else
6391 {
6392 /* [Rn,...] */
6393 if (skip_past_comma (&str) == FAIL)
6394 {
6395 inst.error = _("pre-indexed expression expected");
6396 return;
6397 }
6398
6399 pre_inc = 1;
6400 if (ldst_extend (&str) == FAIL)
6401 return;
6402
6403 skip_whitespace (str);
6404
6405 if (*str++ != ']')
6406 {
6407 inst.error = _("missing ]");
6408 return;
6409 }
6410
6411 skip_whitespace (str);
6412
6413 if (*str == '!')
6414 {
6415 if (conflict_reg)
6416 as_warn (_("%s register same as write-back base"),
6417 ((inst.instruction & LOAD_BIT)
6418 ? _("destination") : _("source")));
6419 str++;
6420 inst.instruction |= WRITE_BACK;
6421 }
6422 }
6423 }
6424 else if (*str == '=')
6425 {
6426 if ((inst.instruction & LOAD_BIT) == 0)
6427 {
6428 inst.error = _("invalid pseudo operation");
6429 return;
6430 }
6431
6432 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6433 str++;
6434
6435 skip_whitespace (str);
6436
6437 if (my_get_expression (&inst.reloc.exp, &str))
6438 return;
6439
6440 if (inst.reloc.exp.X_op != O_constant
6441 && inst.reloc.exp.X_op != O_symbol)
6442 {
6443 inst.error = _("constant expression expected");
6444 return;
6445 }
6446
6447 if (inst.reloc.exp.X_op == O_constant)
6448 {
6449 value = validate_immediate (inst.reloc.exp.X_add_number);
6450
6451 if (value != FAIL)
6452 {
6453 /* This can be done with a mov instruction. */
6454 inst.instruction &= LITERAL_MASK;
6455 inst.instruction |= (INST_IMMEDIATE
6456 | (OPCODE_MOV << DATA_OP_SHIFT));
6457 inst.instruction |= value & 0xfff;
6458 end_of_line (str);
6459 return;
6460 }
6461
6462 value = validate_immediate (~inst.reloc.exp.X_add_number);
6463
6464 if (value != FAIL)
6465 {
6466 /* This can be done with a mvn instruction. */
6467 inst.instruction &= LITERAL_MASK;
6468 inst.instruction |= (INST_IMMEDIATE
6469 | (OPCODE_MVN << DATA_OP_SHIFT));
6470 inst.instruction |= value & 0xfff;
6471 end_of_line (str);
6472 return;
6473 }
6474 }
6475
6476 /* Insert into literal pool. */
6477 if (add_to_lit_pool () == FAIL)
6478 {
6479 if (!inst.error)
6480 inst.error = _("literal pool insertion failed");
6481 return;
6482 }
6483
6484 /* Change the instruction exp to point to the pool. */
6485 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6486 inst.reloc.pc_rel = 1;
6487 inst.instruction |= (REG_PC << 16);
6488 pre_inc = 1;
6489 }
6490 else
6491 {
6492 if (my_get_expression (&inst.reloc.exp, &str))
6493 return;
6494
6495 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6496 #ifndef TE_WINCE
6497 /* PC rel adjust. */
6498 inst.reloc.exp.X_add_number -= 8;
6499 #endif
6500 inst.reloc.pc_rel = 1;
6501 inst.instruction |= (REG_PC << 16);
6502 pre_inc = 1;
6503 }
6504
6505 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6506 end_of_line (str);
6507 return;
6508 }
6509
6510 static void
6511 do_ldstt (str)
6512 char * str;
6513 {
6514 int conflict_reg;
6515
6516 skip_whitespace (str);
6517
6518 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6519 {
6520 if (!inst.error)
6521 inst.error = BAD_ARGS;
6522 return;
6523 }
6524
6525 if (skip_past_comma (& str) == FAIL)
6526 {
6527 inst.error = _("address expected");
6528 return;
6529 }
6530
6531 if (*str == '[')
6532 {
6533 int reg;
6534
6535 str++;
6536
6537 skip_whitespace (str);
6538
6539 if ((reg = reg_required_here (&str, 16)) == FAIL)
6540 return;
6541
6542 /* ldrt/strt always use post-indexed addressing, so if the base is
6543 the same as Rd, we warn. */
6544 if (conflict_reg == reg)
6545 as_warn (_("%s register same as write-back base"),
6546 ((inst.instruction & LOAD_BIT)
6547 ? _("destination") : _("source")));
6548
6549 skip_whitespace (str);
6550
6551 if (*str == ']')
6552 {
6553 str ++;
6554
6555 if (skip_past_comma (&str) == SUCCESS)
6556 {
6557 /* [Rn],... (post inc) */
6558 if (ldst_extend (&str) == FAIL)
6559 return;
6560 }
6561 else
6562 {
6563 /* [Rn] */
6564 skip_whitespace (str);
6565
6566 /* Skip a write-back '!'. */
6567 if (*str == '!')
6568 str++;
6569
6570 inst.instruction |= INDEX_UP;
6571 }
6572 }
6573 else
6574 {
6575 inst.error = _("post-indexed expression expected");
6576 return;
6577 }
6578 }
6579 else
6580 {
6581 inst.error = _("post-indexed expression expected");
6582 return;
6583 }
6584
6585 end_of_line (str);
6586 return;
6587 }
6588
6589 static int
6590 ldst_extend_v4 (str)
6591 char ** str;
6592 {
6593 int add = INDEX_UP;
6594
6595 switch (**str)
6596 {
6597 case '#':
6598 case '$':
6599 (*str)++;
6600 if (my_get_expression (& inst.reloc.exp, str))
6601 return FAIL;
6602
6603 if (inst.reloc.exp.X_op == O_constant)
6604 {
6605 int value = inst.reloc.exp.X_add_number;
6606
6607 if (value < -255 || value > 255)
6608 {
6609 inst.error = _("address offset too large");
6610 return FAIL;
6611 }
6612
6613 if (value < 0)
6614 {
6615 value = -value;
6616 add = 0;
6617 }
6618
6619 /* Halfword and signextension instructions have the
6620 immediate value split across bits 11..8 and bits 3..0. */
6621 inst.instruction |= (add | HWOFFSET_IMM
6622 | ((value >> 4) << 8) | (value & 0xF));
6623 }
6624 else
6625 {
6626 inst.instruction |= HWOFFSET_IMM;
6627 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6628 inst.reloc.pc_rel = 0;
6629 }
6630 return SUCCESS;
6631
6632 case '-':
6633 add = 0;
6634 /* Fall through. */
6635
6636 case '+':
6637 (*str)++;
6638 /* Fall through. */
6639
6640 default:
6641 if (reg_required_here (str, 0) == FAIL)
6642 return FAIL;
6643
6644 inst.instruction |= add;
6645 return SUCCESS;
6646 }
6647 }
6648
6649 /* Halfword and signed-byte load/store operations. */
6650 static void
6651 do_ldstv4 (str)
6652 char * str;
6653 {
6654 int pre_inc = 0;
6655 int conflict_reg;
6656 int value;
6657
6658 skip_whitespace (str);
6659
6660 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6661 {
6662 if (!inst.error)
6663 inst.error = BAD_ARGS;
6664 return;
6665 }
6666
6667 if (skip_past_comma (& str) == FAIL)
6668 {
6669 inst.error = _("address expected");
6670 return;
6671 }
6672
6673 if (*str == '[')
6674 {
6675 int reg;
6676
6677 str++;
6678
6679 skip_whitespace (str);
6680
6681 if ((reg = reg_required_here (&str, 16)) == FAIL)
6682 return;
6683
6684 /* Conflicts can occur on stores as well as loads. */
6685 conflict_reg = (conflict_reg == reg);
6686
6687 skip_whitespace (str);
6688
6689 if (*str == ']')
6690 {
6691 str ++;
6692
6693 if (skip_past_comma (&str) == SUCCESS)
6694 {
6695 /* [Rn],... (post inc) */
6696 if (ldst_extend_v4 (&str) == FAIL)
6697 return;
6698 if (conflict_reg)
6699 as_warn (_("%s register same as write-back base"),
6700 ((inst.instruction & LOAD_BIT)
6701 ? _("destination") : _("source")));
6702 }
6703 else
6704 {
6705 /* [Rn] */
6706 inst.instruction |= HWOFFSET_IMM;
6707
6708 skip_whitespace (str);
6709
6710 if (*str == '!')
6711 {
6712 if (conflict_reg)
6713 as_warn (_("%s register same as write-back base"),
6714 ((inst.instruction & LOAD_BIT)
6715 ? _("destination") : _("source")));
6716 str++;
6717 inst.instruction |= WRITE_BACK;
6718 }
6719
6720 inst.instruction |= INDEX_UP;
6721 pre_inc = 1;
6722 }
6723 }
6724 else
6725 {
6726 /* [Rn,...] */
6727 if (skip_past_comma (&str) == FAIL)
6728 {
6729 inst.error = _("pre-indexed expression expected");
6730 return;
6731 }
6732
6733 pre_inc = 1;
6734 if (ldst_extend_v4 (&str) == FAIL)
6735 return;
6736
6737 skip_whitespace (str);
6738
6739 if (*str++ != ']')
6740 {
6741 inst.error = _("missing ]");
6742 return;
6743 }
6744
6745 skip_whitespace (str);
6746
6747 if (*str == '!')
6748 {
6749 if (conflict_reg)
6750 as_warn (_("%s register same as write-back base"),
6751 ((inst.instruction & LOAD_BIT)
6752 ? _("destination") : _("source")));
6753 str++;
6754 inst.instruction |= WRITE_BACK;
6755 }
6756 }
6757 }
6758 else if (*str == '=')
6759 {
6760 if ((inst.instruction & LOAD_BIT) == 0)
6761 {
6762 inst.error = _("invalid pseudo operation");
6763 return;
6764 }
6765
6766 /* XXX Does this work correctly for half-word/byte ops? */
6767 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6768 str++;
6769
6770 skip_whitespace (str);
6771
6772 if (my_get_expression (&inst.reloc.exp, &str))
6773 return;
6774
6775 if (inst.reloc.exp.X_op != O_constant
6776 && inst.reloc.exp.X_op != O_symbol)
6777 {
6778 inst.error = _("constant expression expected");
6779 return;
6780 }
6781
6782 if (inst.reloc.exp.X_op == O_constant)
6783 {
6784 value = validate_immediate (inst.reloc.exp.X_add_number);
6785
6786 if (value != FAIL)
6787 {
6788 /* This can be done with a mov instruction. */
6789 inst.instruction &= LITERAL_MASK;
6790 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6791 inst.instruction |= value & 0xfff;
6792 end_of_line (str);
6793 return;
6794 }
6795
6796 value = validate_immediate (~ inst.reloc.exp.X_add_number);
6797
6798 if (value != FAIL)
6799 {
6800 /* This can be done with a mvn instruction. */
6801 inst.instruction &= LITERAL_MASK;
6802 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6803 inst.instruction |= value & 0xfff;
6804 end_of_line (str);
6805 return;
6806 }
6807 }
6808
6809 /* Insert into literal pool. */
6810 if (add_to_lit_pool () == FAIL)
6811 {
6812 if (!inst.error)
6813 inst.error = _("literal pool insertion failed");
6814 return;
6815 }
6816
6817 /* Change the instruction exp to point to the pool. */
6818 inst.instruction |= HWOFFSET_IMM;
6819 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6820 inst.reloc.pc_rel = 1;
6821 inst.instruction |= (REG_PC << 16);
6822 pre_inc = 1;
6823 }
6824 else
6825 {
6826 if (my_get_expression (&inst.reloc.exp, &str))
6827 return;
6828
6829 inst.instruction |= HWOFFSET_IMM;
6830 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6831 #ifndef TE_WINCE
6832 /* PC rel adjust. */
6833 inst.reloc.exp.X_add_number -= 8;
6834 #endif
6835 inst.reloc.pc_rel = 1;
6836 inst.instruction |= (REG_PC << 16);
6837 pre_inc = 1;
6838 }
6839
6840 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6841 end_of_line (str);
6842 return;
6843 }
6844
6845 static long
6846 reg_list (strp)
6847 char ** strp;
6848 {
6849 char * str = * strp;
6850 long range = 0;
6851 int another_range;
6852
6853 /* We come back here if we get ranges concatenated by '+' or '|'. */
6854 do
6855 {
6856 another_range = 0;
6857
6858 if (*str == '{')
6859 {
6860 int in_range = 0;
6861 int cur_reg = -1;
6862
6863 str++;
6864 do
6865 {
6866 int reg;
6867
6868 skip_whitespace (str);
6869
6870 if ((reg = reg_required_here (& str, -1)) == FAIL)
6871 return FAIL;
6872
6873 if (in_range)
6874 {
6875 int i;
6876
6877 if (reg <= cur_reg)
6878 {
6879 inst.error = _("bad range in register list");
6880 return FAIL;
6881 }
6882
6883 for (i = cur_reg + 1; i < reg; i++)
6884 {
6885 if (range & (1 << i))
6886 as_tsktsk
6887 (_("Warning: duplicated register (r%d) in register list"),
6888 i);
6889 else
6890 range |= 1 << i;
6891 }
6892 in_range = 0;
6893 }
6894
6895 if (range & (1 << reg))
6896 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6897 reg);
6898 else if (reg <= cur_reg)
6899 as_tsktsk (_("Warning: register range not in ascending order"));
6900
6901 range |= 1 << reg;
6902 cur_reg = reg;
6903 }
6904 while (skip_past_comma (&str) != FAIL
6905 || (in_range = 1, *str++ == '-'));
6906 str--;
6907 skip_whitespace (str);
6908
6909 if (*str++ != '}')
6910 {
6911 inst.error = _("missing `}'");
6912 return FAIL;
6913 }
6914 }
6915 else
6916 {
6917 expressionS expr;
6918
6919 if (my_get_expression (&expr, &str))
6920 return FAIL;
6921
6922 if (expr.X_op == O_constant)
6923 {
6924 if (expr.X_add_number
6925 != (expr.X_add_number & 0x0000ffff))
6926 {
6927 inst.error = _("invalid register mask");
6928 return FAIL;
6929 }
6930
6931 if ((range & expr.X_add_number) != 0)
6932 {
6933 int regno = range & expr.X_add_number;
6934
6935 regno &= -regno;
6936 regno = (1 << regno) - 1;
6937 as_tsktsk
6938 (_("Warning: duplicated register (r%d) in register list"),
6939 regno);
6940 }
6941
6942 range |= expr.X_add_number;
6943 }
6944 else
6945 {
6946 if (inst.reloc.type != 0)
6947 {
6948 inst.error = _("expression too complex");
6949 return FAIL;
6950 }
6951
6952 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6953 inst.reloc.type = BFD_RELOC_ARM_MULTI;
6954 inst.reloc.pc_rel = 0;
6955 }
6956 }
6957
6958 skip_whitespace (str);
6959
6960 if (*str == '|' || *str == '+')
6961 {
6962 str++;
6963 another_range = 1;
6964 }
6965 }
6966 while (another_range);
6967
6968 *strp = str;
6969 return range;
6970 }
6971
6972 static void
6973 do_ldmstm (str)
6974 char * str;
6975 {
6976 int base_reg;
6977 long range;
6978
6979 skip_whitespace (str);
6980
6981 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
6982 return;
6983
6984 if (base_reg == REG_PC)
6985 {
6986 inst.error = _("r15 not allowed as base register");
6987 return;
6988 }
6989
6990 skip_whitespace (str);
6991
6992 if (*str == '!')
6993 {
6994 inst.instruction |= WRITE_BACK;
6995 str++;
6996 }
6997
6998 if (skip_past_comma (&str) == FAIL
6999 || (range = reg_list (&str)) == FAIL)
7000 {
7001 if (! inst.error)
7002 inst.error = BAD_ARGS;
7003 return;
7004 }
7005
7006 if (*str == '^')
7007 {
7008 str++;
7009 inst.instruction |= LDM_TYPE_2_OR_3;
7010 }
7011
7012 if (inst.instruction & WRITE_BACK)
7013 {
7014 /* Check for unpredictable uses of writeback. */
7015 if (inst.instruction & LOAD_BIT)
7016 {
7017 /* Not allowed in LDM type 2. */
7018 if ((inst.instruction & LDM_TYPE_2_OR_3)
7019 && ((range & (1 << REG_PC)) == 0))
7020 as_warn (_("writeback of base register is UNPREDICTABLE"));
7021 /* Only allowed if base reg not in list for other types. */
7022 else if (range & (1 << base_reg))
7023 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
7024 }
7025 else /* STM. */
7026 {
7027 /* Not allowed for type 2. */
7028 if (inst.instruction & LDM_TYPE_2_OR_3)
7029 as_warn (_("writeback of base register is UNPREDICTABLE"));
7030 /* Only allowed if base reg not in list, or first in list. */
7031 else if ((range & (1 << base_reg))
7032 && (range & ((1 << base_reg) - 1)))
7033 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
7034 }
7035 }
7036
7037 inst.instruction |= range;
7038 end_of_line (str);
7039 return;
7040 }
7041
7042 static void
7043 do_swi (str)
7044 char * str;
7045 {
7046 skip_whitespace (str);
7047
7048 /* Allow optional leading '#'. */
7049 if (is_immediate_prefix (*str))
7050 str++;
7051
7052 if (my_get_expression (& inst.reloc.exp, & str))
7053 return;
7054
7055 inst.reloc.type = BFD_RELOC_ARM_SWI;
7056 inst.reloc.pc_rel = 0;
7057 end_of_line (str);
7058
7059 return;
7060 }
7061
7062 static void
7063 do_swap (str)
7064 char * str;
7065 {
7066 int reg;
7067
7068 skip_whitespace (str);
7069
7070 if ((reg = reg_required_here (&str, 12)) == FAIL)
7071 return;
7072
7073 if (reg == REG_PC)
7074 {
7075 inst.error = _("r15 not allowed in swap");
7076 return;
7077 }
7078
7079 if (skip_past_comma (&str) == FAIL
7080 || (reg = reg_required_here (&str, 0)) == FAIL)
7081 {
7082 if (!inst.error)
7083 inst.error = BAD_ARGS;
7084 return;
7085 }
7086
7087 if (reg == REG_PC)
7088 {
7089 inst.error = _("r15 not allowed in swap");
7090 return;
7091 }
7092
7093 if (skip_past_comma (&str) == FAIL
7094 || *str++ != '[')
7095 {
7096 inst.error = BAD_ARGS;
7097 return;
7098 }
7099
7100 skip_whitespace (str);
7101
7102 if ((reg = reg_required_here (&str, 16)) == FAIL)
7103 return;
7104
7105 if (reg == REG_PC)
7106 {
7107 inst.error = BAD_PC;
7108 return;
7109 }
7110
7111 skip_whitespace (str);
7112
7113 if (*str++ != ']')
7114 {
7115 inst.error = _("missing ]");
7116 return;
7117 }
7118
7119 end_of_line (str);
7120 return;
7121 }
7122
7123 static void
7124 do_branch (str)
7125 char * str;
7126 {
7127 if (my_get_expression (&inst.reloc.exp, &str))
7128 return;
7129
7130 #ifdef OBJ_ELF
7131 {
7132 char * save_in;
7133
7134 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
7135 required for the instruction. */
7136
7137 /* arm_parse_reloc () works on input_line_pointer.
7138 We actually want to parse the operands to the branch instruction
7139 passed in 'str'. Save the input pointer and restore it later. */
7140 save_in = input_line_pointer;
7141 input_line_pointer = str;
7142 if (inst.reloc.exp.X_op == O_symbol
7143 && *str == '('
7144 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
7145 {
7146 inst.reloc.type = BFD_RELOC_ARM_PLT32;
7147 inst.reloc.pc_rel = 0;
7148 /* Modify str to point to after parsed operands, otherwise
7149 end_of_line() will complain about the (PLT) left in str. */
7150 str = input_line_pointer;
7151 }
7152 else
7153 {
7154 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
7155 inst.reloc.pc_rel = 1;
7156 }
7157 input_line_pointer = save_in;
7158 }
7159 #else
7160 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
7161 inst.reloc.pc_rel = 1;
7162 #endif /* OBJ_ELF */
7163
7164 end_of_line (str);
7165 return;
7166 }
7167
7168 static void
7169 do_bx (str)
7170 char * str;
7171 {
7172 int reg;
7173
7174 skip_whitespace (str);
7175
7176 if ((reg = reg_required_here (&str, 0)) == FAIL)
7177 {
7178 inst.error = BAD_ARGS;
7179 return;
7180 }
7181
7182 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
7183 if (reg == REG_PC)
7184 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
7185
7186 end_of_line (str);
7187 }
7188
7189 static void
7190 do_cdp (str)
7191 char * str;
7192 {
7193 /* Co-processor data operation.
7194 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
7195 skip_whitespace (str);
7196
7197 if (co_proc_number (&str) == FAIL)
7198 {
7199 if (!inst.error)
7200 inst.error = BAD_ARGS;
7201 return;
7202 }
7203
7204 if (skip_past_comma (&str) == FAIL
7205 || cp_opc_expr (&str, 20,4) == FAIL)
7206 {
7207 if (!inst.error)
7208 inst.error = BAD_ARGS;
7209 return;
7210 }
7211
7212 if (skip_past_comma (&str) == FAIL
7213 || cp_reg_required_here (&str, 12) == FAIL)
7214 {
7215 if (!inst.error)
7216 inst.error = BAD_ARGS;
7217 return;
7218 }
7219
7220 if (skip_past_comma (&str) == FAIL
7221 || cp_reg_required_here (&str, 16) == FAIL)
7222 {
7223 if (!inst.error)
7224 inst.error = BAD_ARGS;
7225 return;
7226 }
7227
7228 if (skip_past_comma (&str) == FAIL
7229 || cp_reg_required_here (&str, 0) == FAIL)
7230 {
7231 if (!inst.error)
7232 inst.error = BAD_ARGS;
7233 return;
7234 }
7235
7236 if (skip_past_comma (&str) == SUCCESS)
7237 {
7238 if (cp_opc_expr (&str, 5, 3) == FAIL)
7239 {
7240 if (!inst.error)
7241 inst.error = BAD_ARGS;
7242 return;
7243 }
7244 }
7245
7246 end_of_line (str);
7247 return;
7248 }
7249
7250 static void
7251 do_lstc (str)
7252 char * str;
7253 {
7254 /* Co-processor register load/store.
7255 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
7256
7257 skip_whitespace (str);
7258
7259 if (co_proc_number (&str) == FAIL)
7260 {
7261 if (!inst.error)
7262 inst.error = BAD_ARGS;
7263 return;
7264 }
7265
7266 if (skip_past_comma (&str) == FAIL
7267 || cp_reg_required_here (&str, 12) == FAIL)
7268 {
7269 if (!inst.error)
7270 inst.error = BAD_ARGS;
7271 return;
7272 }
7273
7274 if (skip_past_comma (&str) == FAIL
7275 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7276 {
7277 if (! inst.error)
7278 inst.error = BAD_ARGS;
7279 return;
7280 }
7281
7282 end_of_line (str);
7283 return;
7284 }
7285
7286 static void
7287 do_co_reg (str)
7288 char * str;
7289 {
7290 /* Co-processor register transfer.
7291 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
7292
7293 skip_whitespace (str);
7294
7295 if (co_proc_number (&str) == FAIL)
7296 {
7297 if (!inst.error)
7298 inst.error = BAD_ARGS;
7299 return;
7300 }
7301
7302 if (skip_past_comma (&str) == FAIL
7303 || cp_opc_expr (&str, 21, 3) == FAIL)
7304 {
7305 if (!inst.error)
7306 inst.error = BAD_ARGS;
7307 return;
7308 }
7309
7310 if (skip_past_comma (&str) == FAIL
7311 || reg_required_here (&str, 12) == FAIL)
7312 {
7313 if (!inst.error)
7314 inst.error = BAD_ARGS;
7315 return;
7316 }
7317
7318 if (skip_past_comma (&str) == FAIL
7319 || cp_reg_required_here (&str, 16) == FAIL)
7320 {
7321 if (!inst.error)
7322 inst.error = BAD_ARGS;
7323 return;
7324 }
7325
7326 if (skip_past_comma (&str) == FAIL
7327 || cp_reg_required_here (&str, 0) == FAIL)
7328 {
7329 if (!inst.error)
7330 inst.error = BAD_ARGS;
7331 return;
7332 }
7333
7334 if (skip_past_comma (&str) == SUCCESS)
7335 {
7336 if (cp_opc_expr (&str, 5, 3) == FAIL)
7337 {
7338 if (!inst.error)
7339 inst.error = BAD_ARGS;
7340 return;
7341 }
7342 }
7343
7344 end_of_line (str);
7345 return;
7346 }
7347
7348 static void
7349 do_fpa_ctrl (str)
7350 char * str;
7351 {
7352 /* FP control registers.
7353 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
7354
7355 skip_whitespace (str);
7356
7357 if (reg_required_here (&str, 12) == FAIL)
7358 {
7359 if (!inst.error)
7360 inst.error = BAD_ARGS;
7361 return;
7362 }
7363
7364 end_of_line (str);
7365 return;
7366 }
7367
7368 static void
7369 do_fpa_ldst (str)
7370 char * str;
7371 {
7372 skip_whitespace (str);
7373
7374 if (fp_reg_required_here (&str, 12) == FAIL)
7375 {
7376 if (!inst.error)
7377 inst.error = BAD_ARGS;
7378 return;
7379 }
7380
7381 if (skip_past_comma (&str) == FAIL
7382 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7383 {
7384 if (!inst.error)
7385 inst.error = BAD_ARGS;
7386 return;
7387 }
7388
7389 end_of_line (str);
7390 }
7391
7392 static void
7393 do_fpa_ldmstm (str)
7394 char * str;
7395 {
7396 int num_regs;
7397
7398 skip_whitespace (str);
7399
7400 if (fp_reg_required_here (&str, 12) == FAIL)
7401 {
7402 if (! inst.error)
7403 inst.error = BAD_ARGS;
7404 return;
7405 }
7406
7407 /* Get Number of registers to transfer. */
7408 if (skip_past_comma (&str) == FAIL
7409 || my_get_expression (&inst.reloc.exp, &str))
7410 {
7411 if (! inst.error)
7412 inst.error = _("constant expression expected");
7413 return;
7414 }
7415
7416 if (inst.reloc.exp.X_op != O_constant)
7417 {
7418 inst.error = _("constant value required for number of registers");
7419 return;
7420 }
7421
7422 num_regs = inst.reloc.exp.X_add_number;
7423
7424 if (num_regs < 1 || num_regs > 4)
7425 {
7426 inst.error = _("number of registers must be in the range [1:4]");
7427 return;
7428 }
7429
7430 switch (num_regs)
7431 {
7432 case 1:
7433 inst.instruction |= CP_T_X;
7434 break;
7435 case 2:
7436 inst.instruction |= CP_T_Y;
7437 break;
7438 case 3:
7439 inst.instruction |= CP_T_Y | CP_T_X;
7440 break;
7441 case 4:
7442 break;
7443 default:
7444 abort ();
7445 }
7446
7447 if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
7448 {
7449 int reg;
7450 int write_back;
7451 int offset;
7452
7453 /* The instruction specified "ea" or "fd", so we can only accept
7454 [Rn]{!}. The instruction does not really support stacking or
7455 unstacking, so we have to emulate these by setting appropriate
7456 bits and offsets. */
7457 if (skip_past_comma (&str) == FAIL
7458 || *str != '[')
7459 {
7460 if (! inst.error)
7461 inst.error = BAD_ARGS;
7462 return;
7463 }
7464
7465 str++;
7466 skip_whitespace (str);
7467
7468 if ((reg = reg_required_here (&str, 16)) == FAIL)
7469 return;
7470
7471 skip_whitespace (str);
7472
7473 if (*str != ']')
7474 {
7475 inst.error = BAD_ARGS;
7476 return;
7477 }
7478
7479 str++;
7480 if (*str == '!')
7481 {
7482 write_back = 1;
7483 str++;
7484 if (reg == REG_PC)
7485 {
7486 inst.error =
7487 _("r15 not allowed as base register with write-back");
7488 return;
7489 }
7490 }
7491 else
7492 write_back = 0;
7493
7494 if (inst.instruction & CP_T_Pre)
7495 {
7496 /* Pre-decrement. */
7497 offset = 3 * num_regs;
7498 if (write_back)
7499 inst.instruction |= CP_T_WB;
7500 }
7501 else
7502 {
7503 /* Post-increment. */
7504 if (write_back)
7505 {
7506 inst.instruction |= CP_T_WB;
7507 offset = 3 * num_regs;
7508 }
7509 else
7510 {
7511 /* No write-back, so convert this into a standard pre-increment
7512 instruction -- aesthetically more pleasing. */
7513 inst.instruction |= CP_T_Pre | CP_T_UD;
7514 offset = 0;
7515 }
7516 }
7517
7518 inst.instruction |= offset;
7519 }
7520 else if (skip_past_comma (&str) == FAIL
7521 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7522 {
7523 if (! inst.error)
7524 inst.error = BAD_ARGS;
7525 return;
7526 }
7527
7528 end_of_line (str);
7529 }
7530
7531 static void
7532 do_fpa_dyadic (str)
7533 char * str;
7534 {
7535 skip_whitespace (str);
7536
7537 if (fp_reg_required_here (&str, 12) == FAIL)
7538 {
7539 if (! inst.error)
7540 inst.error = BAD_ARGS;
7541 return;
7542 }
7543
7544 if (skip_past_comma (&str) == FAIL
7545 || fp_reg_required_here (&str, 16) == FAIL)
7546 {
7547 if (! inst.error)
7548 inst.error = BAD_ARGS;
7549 return;
7550 }
7551
7552 if (skip_past_comma (&str) == FAIL
7553 || fp_op2 (&str) == FAIL)
7554 {
7555 if (! inst.error)
7556 inst.error = BAD_ARGS;
7557 return;
7558 }
7559
7560 end_of_line (str);
7561 return;
7562 }
7563
7564 static void
7565 do_fpa_monadic (str)
7566 char * str;
7567 {
7568 skip_whitespace (str);
7569
7570 if (fp_reg_required_here (&str, 12) == FAIL)
7571 {
7572 if (! inst.error)
7573 inst.error = BAD_ARGS;
7574 return;
7575 }
7576
7577 if (skip_past_comma (&str) == FAIL
7578 || fp_op2 (&str) == FAIL)
7579 {
7580 if (! inst.error)
7581 inst.error = BAD_ARGS;
7582 return;
7583 }
7584
7585 end_of_line (str);
7586 return;
7587 }
7588
7589 static void
7590 do_fpa_cmp (str)
7591 char * str;
7592 {
7593 skip_whitespace (str);
7594
7595 if (fp_reg_required_here (&str, 16) == FAIL)
7596 {
7597 if (! inst.error)
7598 inst.error = BAD_ARGS;
7599 return;
7600 }
7601
7602 if (skip_past_comma (&str) == FAIL
7603 || fp_op2 (&str) == FAIL)
7604 {
7605 if (! inst.error)
7606 inst.error = BAD_ARGS;
7607 return;
7608 }
7609
7610 end_of_line (str);
7611 return;
7612 }
7613
7614 static void
7615 do_fpa_from_reg (str)
7616 char * str;
7617 {
7618 skip_whitespace (str);
7619
7620 if (fp_reg_required_here (&str, 16) == FAIL)
7621 {
7622 if (! inst.error)
7623 inst.error = BAD_ARGS;
7624 return;
7625 }
7626
7627 if (skip_past_comma (&str) == FAIL
7628 || reg_required_here (&str, 12) == FAIL)
7629 {
7630 if (! inst.error)
7631 inst.error = BAD_ARGS;
7632 return;
7633 }
7634
7635 end_of_line (str);
7636 return;
7637 }
7638
7639 static void
7640 do_fpa_to_reg (str)
7641 char * str;
7642 {
7643 skip_whitespace (str);
7644
7645 if (reg_required_here (&str, 12) == FAIL)
7646 return;
7647
7648 if (skip_past_comma (&str) == FAIL
7649 || fp_reg_required_here (&str, 0) == FAIL)
7650 {
7651 if (! inst.error)
7652 inst.error = BAD_ARGS;
7653 return;
7654 }
7655
7656 end_of_line (str);
7657 return;
7658 }
7659
7660 static int
7661 vfp_sp_reg_required_here (str, pos)
7662 char **str;
7663 enum vfp_sp_reg_pos pos;
7664 {
7665 int reg;
7666 char *start = *str;
7667
7668 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7669 {
7670 switch (pos)
7671 {
7672 case VFP_REG_Sd:
7673 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7674 break;
7675
7676 case VFP_REG_Sn:
7677 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7678 break;
7679
7680 case VFP_REG_Sm:
7681 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7682 break;
7683
7684 default:
7685 abort ();
7686 }
7687 return reg;
7688 }
7689
7690 /* In the few cases where we might be able to accept something else
7691 this error can be overridden. */
7692 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7693
7694 /* Restore the start point. */
7695 *str = start;
7696 return FAIL;
7697 }
7698
7699 static int
7700 vfp_dp_reg_required_here (str, pos)
7701 char **str;
7702 enum vfp_dp_reg_pos pos;
7703 {
7704 int reg;
7705 char *start = *str;
7706
7707 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7708 {
7709 switch (pos)
7710 {
7711 case VFP_REG_Dd:
7712 inst.instruction |= reg << 12;
7713 break;
7714
7715 case VFP_REG_Dn:
7716 inst.instruction |= reg << 16;
7717 break;
7718
7719 case VFP_REG_Dm:
7720 inst.instruction |= reg << 0;
7721 break;
7722
7723 default:
7724 abort ();
7725 }
7726 return reg;
7727 }
7728
7729 /* In the few cases where we might be able to accept something else
7730 this error can be overridden. */
7731 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7732
7733 /* Restore the start point. */
7734 *str = start;
7735 return FAIL;
7736 }
7737
7738 static void
7739 do_vfp_sp_monadic (str)
7740 char *str;
7741 {
7742 skip_whitespace (str);
7743
7744 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7745 return;
7746
7747 if (skip_past_comma (&str) == FAIL
7748 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7749 {
7750 if (! inst.error)
7751 inst.error = BAD_ARGS;
7752 return;
7753 }
7754
7755 end_of_line (str);
7756 return;
7757 }
7758
7759 static void
7760 do_vfp_dp_monadic (str)
7761 char *str;
7762 {
7763 skip_whitespace (str);
7764
7765 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7766 return;
7767
7768 if (skip_past_comma (&str) == FAIL
7769 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7770 {
7771 if (! inst.error)
7772 inst.error = BAD_ARGS;
7773 return;
7774 }
7775
7776 end_of_line (str);
7777 return;
7778 }
7779
7780 static void
7781 do_vfp_sp_dyadic (str)
7782 char *str;
7783 {
7784 skip_whitespace (str);
7785
7786 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7787 return;
7788
7789 if (skip_past_comma (&str) == FAIL
7790 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7791 || skip_past_comma (&str) == FAIL
7792 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7793 {
7794 if (! inst.error)
7795 inst.error = BAD_ARGS;
7796 return;
7797 }
7798
7799 end_of_line (str);
7800 return;
7801 }
7802
7803 static void
7804 do_vfp_dp_dyadic (str)
7805 char *str;
7806 {
7807 skip_whitespace (str);
7808
7809 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7810 return;
7811
7812 if (skip_past_comma (&str) == FAIL
7813 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7814 || skip_past_comma (&str) == FAIL
7815 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7816 {
7817 if (! inst.error)
7818 inst.error = BAD_ARGS;
7819 return;
7820 }
7821
7822 end_of_line (str);
7823 return;
7824 }
7825
7826 static void
7827 do_vfp_reg_from_sp (str)
7828 char *str;
7829 {
7830 skip_whitespace (str);
7831
7832 if (reg_required_here (&str, 12) == FAIL)
7833 return;
7834
7835 if (skip_past_comma (&str) == FAIL
7836 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7837 {
7838 if (! inst.error)
7839 inst.error = BAD_ARGS;
7840 return;
7841 }
7842
7843 end_of_line (str);
7844 return;
7845 }
7846
7847 static void
7848 do_vfp_sp_reg2 (str)
7849 char *str;
7850 {
7851 skip_whitespace (str);
7852
7853 if (reg_required_here (&str, 12) == FAIL)
7854 return;
7855
7856 if (skip_past_comma (&str) == FAIL
7857 || reg_required_here (&str, 16) == FAIL
7858 || skip_past_comma (&str) == FAIL)
7859 {
7860 if (! inst.error)
7861 inst.error = BAD_ARGS;
7862 return;
7863 }
7864
7865 /* We require exactly two consecutive SP registers. */
7866 if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
7867 {
7868 if (! inst.error)
7869 inst.error = _("only two consecutive VFP SP registers allowed here");
7870 }
7871
7872 end_of_line (str);
7873 return;
7874 }
7875
7876 static void
7877 do_vfp_sp_from_reg (str)
7878 char *str;
7879 {
7880 skip_whitespace (str);
7881
7882 if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7883 return;
7884
7885 if (skip_past_comma (&str) == FAIL
7886 || reg_required_here (&str, 12) == FAIL)
7887 {
7888 if (! inst.error)
7889 inst.error = BAD_ARGS;
7890 return;
7891 }
7892
7893 end_of_line (str);
7894 return;
7895 }
7896
7897 static void
7898 do_vfp_reg_from_dp (str)
7899 char *str;
7900 {
7901 skip_whitespace (str);
7902
7903 if (reg_required_here (&str, 12) == FAIL)
7904 return;
7905
7906 if (skip_past_comma (&str) == FAIL
7907 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7908 {
7909 if (! inst.error)
7910 inst.error = BAD_ARGS;
7911 return;
7912 }
7913
7914 end_of_line (str);
7915 return;
7916 }
7917
7918 static void
7919 do_vfp_reg2_from_dp (str)
7920 char *str;
7921 {
7922 skip_whitespace (str);
7923
7924 if (reg_required_here (&str, 12) == FAIL)
7925 return;
7926
7927 if (skip_past_comma (&str) == FAIL
7928 || reg_required_here (&str, 16) == FAIL
7929 || skip_past_comma (&str) == FAIL
7930 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7931 {
7932 if (! inst.error)
7933 inst.error = BAD_ARGS;
7934 return;
7935 }
7936
7937 end_of_line (str);
7938 return;
7939 }
7940
7941 static void
7942 do_vfp_dp_from_reg (str)
7943 char *str;
7944 {
7945 skip_whitespace (str);
7946
7947 if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7948 return;
7949
7950 if (skip_past_comma (&str) == FAIL
7951 || reg_required_here (&str, 12) == FAIL)
7952 {
7953 if (! inst.error)
7954 inst.error = BAD_ARGS;
7955 return;
7956 }
7957
7958 end_of_line (str);
7959 return;
7960 }
7961
7962 static void
7963 do_vfp_dp_from_reg2 (str)
7964 char *str;
7965 {
7966 skip_whitespace (str);
7967
7968 if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7969 return;
7970
7971 if (skip_past_comma (&str) == FAIL
7972 || reg_required_here (&str, 12) == FAIL
7973 || skip_past_comma (&str) == FAIL
7974 || reg_required_here (&str, 16))
7975 {
7976 if (! inst.error)
7977 inst.error = BAD_ARGS;
7978 return;
7979 }
7980
7981 end_of_line (str);
7982 return;
7983 }
7984
7985 static const struct vfp_reg *
7986 vfp_psr_parse (str)
7987 char **str;
7988 {
7989 char *start = *str;
7990 char c;
7991 char *p;
7992 const struct vfp_reg *vreg;
7993
7994 p = start;
7995
7996 /* Find the end of the current token. */
7997 do
7998 {
7999 c = *p++;
8000 }
8001 while (ISALPHA (c));
8002
8003 /* Mark it. */
8004 *--p = 0;
8005
8006 for (vreg = vfp_regs + 0;
8007 vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
8008 vreg++)
8009 {
8010 if (strcmp (start, vreg->name) == 0)
8011 {
8012 *p = c;
8013 *str = p;
8014 return vreg;
8015 }
8016 }
8017
8018 *p = c;
8019 return NULL;
8020 }
8021
8022 static int
8023 vfp_psr_required_here (str)
8024 char **str;
8025 {
8026 char *start = *str;
8027 const struct vfp_reg *vreg;
8028
8029 vreg = vfp_psr_parse (str);
8030
8031 if (vreg)
8032 {
8033 inst.instruction |= vreg->regno;
8034 return SUCCESS;
8035 }
8036
8037 inst.error = _("VFP system register expected");
8038
8039 *str = start;
8040 return FAIL;
8041 }
8042
8043 static void
8044 do_vfp_reg_from_ctrl (str)
8045 char *str;
8046 {
8047 skip_whitespace (str);
8048
8049 if (reg_required_here (&str, 12) == FAIL)
8050 return;
8051
8052 if (skip_past_comma (&str) == FAIL
8053 || vfp_psr_required_here (&str) == FAIL)
8054 {
8055 if (! inst.error)
8056 inst.error = BAD_ARGS;
8057 return;
8058 }
8059
8060 end_of_line (str);
8061 return;
8062 }
8063
8064 static void
8065 do_vfp_ctrl_from_reg (str)
8066 char *str;
8067 {
8068 skip_whitespace (str);
8069
8070 if (vfp_psr_required_here (&str) == FAIL)
8071 return;
8072
8073 if (skip_past_comma (&str) == FAIL
8074 || reg_required_here (&str, 12) == FAIL)
8075 {
8076 if (! inst.error)
8077 inst.error = BAD_ARGS;
8078 return;
8079 }
8080
8081 end_of_line (str);
8082 return;
8083 }
8084
8085 static void
8086 do_vfp_sp_ldst (str)
8087 char *str;
8088 {
8089 skip_whitespace (str);
8090
8091 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8092 {
8093 if (!inst.error)
8094 inst.error = BAD_ARGS;
8095 return;
8096 }
8097
8098 if (skip_past_comma (&str) == FAIL
8099 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
8100 {
8101 if (!inst.error)
8102 inst.error = BAD_ARGS;
8103 return;
8104 }
8105
8106 end_of_line (str);
8107 return;
8108 }
8109
8110 static void
8111 do_vfp_dp_ldst (str)
8112 char *str;
8113 {
8114 skip_whitespace (str);
8115
8116 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8117 {
8118 if (!inst.error)
8119 inst.error = BAD_ARGS;
8120 return;
8121 }
8122
8123 if (skip_past_comma (&str) == FAIL
8124 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
8125 {
8126 if (!inst.error)
8127 inst.error = BAD_ARGS;
8128 return;
8129 }
8130
8131 end_of_line (str);
8132 return;
8133 }
8134
8135 /* Parse and encode a VFP SP register list, storing the initial
8136 register in position POS and returning the range as the result. If
8137 the string is invalid return FAIL (an invalid range). */
8138 static long
8139 vfp_sp_reg_list (str, pos)
8140 char **str;
8141 enum vfp_sp_reg_pos pos;
8142 {
8143 long range = 0;
8144 int base_reg = 0;
8145 int new_base;
8146 long base_bits = 0;
8147 int count = 0;
8148 long tempinst;
8149 unsigned long mask = 0;
8150 int warned = 0;
8151
8152 if (**str != '{')
8153 return FAIL;
8154
8155 (*str)++;
8156 skip_whitespace (*str);
8157
8158 tempinst = inst.instruction;
8159
8160 do
8161 {
8162 inst.instruction = 0;
8163
8164 if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
8165 return FAIL;
8166
8167 if (count == 0 || base_reg > new_base)
8168 {
8169 base_reg = new_base;
8170 base_bits = inst.instruction;
8171 }
8172
8173 if (mask & (1 << new_base))
8174 {
8175 inst.error = _("invalid register list");
8176 return FAIL;
8177 }
8178
8179 if ((mask >> new_base) != 0 && ! warned)
8180 {
8181 as_tsktsk (_("register list not in ascending order"));
8182 warned = 1;
8183 }
8184
8185 mask |= 1 << new_base;
8186 count++;
8187
8188 skip_whitespace (*str);
8189
8190 if (**str == '-') /* We have the start of a range expression */
8191 {
8192 int high_range;
8193
8194 (*str)++;
8195
8196 if ((high_range
8197 = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
8198 == FAIL)
8199 {
8200 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8201 return FAIL;
8202 }
8203
8204 if (high_range <= new_base)
8205 {
8206 inst.error = _("register range not in ascending order");
8207 return FAIL;
8208 }
8209
8210 for (new_base++; new_base <= high_range; new_base++)
8211 {
8212 if (mask & (1 << new_base))
8213 {
8214 inst.error = _("invalid register list");
8215 return FAIL;
8216 }
8217
8218 mask |= 1 << new_base;
8219 count++;
8220 }
8221 }
8222 }
8223 while (skip_past_comma (str) != FAIL);
8224
8225 if (**str != '}')
8226 {
8227 inst.error = _("invalid register list");
8228 return FAIL;
8229 }
8230
8231 (*str)++;
8232
8233 range = count;
8234
8235 /* Sanity check -- should have raised a parse error above. */
8236 if (count == 0 || count > 32)
8237 abort ();
8238
8239 /* Final test -- the registers must be consecutive. */
8240 while (count--)
8241 {
8242 if ((mask & (1 << base_reg++)) == 0)
8243 {
8244 inst.error = _("non-contiguous register range");
8245 return FAIL;
8246 }
8247 }
8248
8249 inst.instruction = tempinst | base_bits;
8250 return range;
8251 }
8252
8253 static long
8254 vfp_dp_reg_list (str)
8255 char **str;
8256 {
8257 long range = 0;
8258 int base_reg = 0;
8259 int new_base;
8260 int count = 0;
8261 long tempinst;
8262 unsigned long mask = 0;
8263 int warned = 0;
8264
8265 if (**str != '{')
8266 return FAIL;
8267
8268 (*str)++;
8269 skip_whitespace (*str);
8270
8271 tempinst = inst.instruction;
8272
8273 do
8274 {
8275 inst.instruction = 0;
8276
8277 if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
8278 return FAIL;
8279
8280 if (count == 0 || base_reg > new_base)
8281 {
8282 base_reg = new_base;
8283 range = inst.instruction;
8284 }
8285
8286 if (mask & (1 << new_base))
8287 {
8288 inst.error = _("invalid register list");
8289 return FAIL;
8290 }
8291
8292 if ((mask >> new_base) != 0 && ! warned)
8293 {
8294 as_tsktsk (_("register list not in ascending order"));
8295 warned = 1;
8296 }
8297
8298 mask |= 1 << new_base;
8299 count++;
8300
8301 skip_whitespace (*str);
8302
8303 if (**str == '-') /* We have the start of a range expression */
8304 {
8305 int high_range;
8306
8307 (*str)++;
8308
8309 if ((high_range
8310 = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
8311 == FAIL)
8312 {
8313 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8314 return FAIL;
8315 }
8316
8317 if (high_range <= new_base)
8318 {
8319 inst.error = _("register range not in ascending order");
8320 return FAIL;
8321 }
8322
8323 for (new_base++; new_base <= high_range; new_base++)
8324 {
8325 if (mask & (1 << new_base))
8326 {
8327 inst.error = _("invalid register list");
8328 return FAIL;
8329 }
8330
8331 mask |= 1 << new_base;
8332 count++;
8333 }
8334 }
8335 }
8336 while (skip_past_comma (str) != FAIL);
8337
8338 if (**str != '}')
8339 {
8340 inst.error = _("invalid register list");
8341 return FAIL;
8342 }
8343
8344 (*str)++;
8345
8346 range |= 2 * count;
8347
8348 /* Sanity check -- should have raised a parse error above. */
8349 if (count == 0 || count > 16)
8350 abort ();
8351
8352 /* Final test -- the registers must be consecutive. */
8353 while (count--)
8354 {
8355 if ((mask & (1 << base_reg++)) == 0)
8356 {
8357 inst.error = _("non-contiguous register range");
8358 return FAIL;
8359 }
8360 }
8361
8362 inst.instruction = tempinst;
8363 return range;
8364 }
8365
8366 static void
8367 vfp_sp_ldstm (str, ldstm_type)
8368 char *str;
8369 enum vfp_ldstm_type ldstm_type;
8370 {
8371 long range;
8372
8373 skip_whitespace (str);
8374
8375 if (reg_required_here (&str, 16) == FAIL)
8376 return;
8377
8378 skip_whitespace (str);
8379
8380 if (*str == '!')
8381 {
8382 inst.instruction |= WRITE_BACK;
8383 str++;
8384 }
8385 else if (ldstm_type != VFP_LDSTMIA)
8386 {
8387 inst.error = _("this addressing mode requires base-register writeback");
8388 return;
8389 }
8390
8391 if (skip_past_comma (&str) == FAIL
8392 || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
8393 {
8394 if (!inst.error)
8395 inst.error = BAD_ARGS;
8396 return;
8397 }
8398
8399 inst.instruction |= range;
8400 end_of_line (str);
8401 }
8402
8403 static void
8404 vfp_dp_ldstm (str, ldstm_type)
8405 char *str;
8406 enum vfp_ldstm_type ldstm_type;
8407 {
8408 long range;
8409
8410 skip_whitespace (str);
8411
8412 if (reg_required_here (&str, 16) == FAIL)
8413 return;
8414
8415 skip_whitespace (str);
8416
8417 if (*str == '!')
8418 {
8419 inst.instruction |= WRITE_BACK;
8420 str++;
8421 }
8422 else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
8423 {
8424 inst.error = _("this addressing mode requires base-register writeback");
8425 return;
8426 }
8427
8428 if (skip_past_comma (&str) == FAIL
8429 || (range = vfp_dp_reg_list (&str)) == FAIL)
8430 {
8431 if (!inst.error)
8432 inst.error = BAD_ARGS;
8433 return;
8434 }
8435
8436 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
8437 range += 1;
8438
8439 inst.instruction |= range;
8440 end_of_line (str);
8441 }
8442
8443 static void
8444 do_vfp_sp_ldstmia (str)
8445 char *str;
8446 {
8447 vfp_sp_ldstm (str, VFP_LDSTMIA);
8448 }
8449
8450 static void
8451 do_vfp_sp_ldstmdb (str)
8452 char *str;
8453 {
8454 vfp_sp_ldstm (str, VFP_LDSTMDB);
8455 }
8456
8457 static void
8458 do_vfp_dp_ldstmia (str)
8459 char *str;
8460 {
8461 vfp_dp_ldstm (str, VFP_LDSTMIA);
8462 }
8463
8464 static void
8465 do_vfp_dp_ldstmdb (str)
8466 char *str;
8467 {
8468 vfp_dp_ldstm (str, VFP_LDSTMDB);
8469 }
8470
8471 static void
8472 do_vfp_xp_ldstmia (str)
8473 char *str;
8474 {
8475 vfp_dp_ldstm (str, VFP_LDSTMIAX);
8476 }
8477
8478 static void
8479 do_vfp_xp_ldstmdb (str)
8480 char *str;
8481 {
8482 vfp_dp_ldstm (str, VFP_LDSTMDBX);
8483 }
8484
8485 static void
8486 do_vfp_sp_compare_z (str)
8487 char *str;
8488 {
8489 skip_whitespace (str);
8490
8491 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8492 {
8493 if (!inst.error)
8494 inst.error = BAD_ARGS;
8495 return;
8496 }
8497
8498 end_of_line (str);
8499 return;
8500 }
8501
8502 static void
8503 do_vfp_dp_compare_z (str)
8504 char *str;
8505 {
8506 skip_whitespace (str);
8507
8508 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8509 {
8510 if (!inst.error)
8511 inst.error = BAD_ARGS;
8512 return;
8513 }
8514
8515 end_of_line (str);
8516 return;
8517 }
8518
8519 static void
8520 do_vfp_dp_sp_cvt (str)
8521 char *str;
8522 {
8523 skip_whitespace (str);
8524
8525 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8526 return;
8527
8528 if (skip_past_comma (&str) == FAIL
8529 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8530 {
8531 if (! inst.error)
8532 inst.error = BAD_ARGS;
8533 return;
8534 }
8535
8536 end_of_line (str);
8537 return;
8538 }
8539
8540 static void
8541 do_vfp_sp_dp_cvt (str)
8542 char *str;
8543 {
8544 skip_whitespace (str);
8545
8546 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8547 return;
8548
8549 if (skip_past_comma (&str) == FAIL
8550 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8551 {
8552 if (! inst.error)
8553 inst.error = BAD_ARGS;
8554 return;
8555 }
8556
8557 end_of_line (str);
8558 return;
8559 }
8560
8561 /* Thumb specific routines. */
8562
8563 /* Parse and validate that a register is of the right form, this saves
8564 repeated checking of this information in many similar cases.
8565 Unlike the 32-bit case we do not insert the register into the opcode
8566 here, since the position is often unknown until the full instruction
8567 has been parsed. */
8568
8569 static int
8570 thumb_reg (strp, hi_lo)
8571 char ** strp;
8572 int hi_lo;
8573 {
8574 int reg;
8575
8576 if ((reg = reg_required_here (strp, -1)) == FAIL)
8577 return FAIL;
8578
8579 switch (hi_lo)
8580 {
8581 case THUMB_REG_LO:
8582 if (reg > 7)
8583 {
8584 inst.error = _("lo register required");
8585 return FAIL;
8586 }
8587 break;
8588
8589 case THUMB_REG_HI:
8590 if (reg < 8)
8591 {
8592 inst.error = _("hi register required");
8593 return FAIL;
8594 }
8595 break;
8596
8597 default:
8598 break;
8599 }
8600
8601 return reg;
8602 }
8603
8604 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8605 was SUB. */
8606
8607 static void
8608 thumb_add_sub (str, subtract)
8609 char * str;
8610 int subtract;
8611 {
8612 int Rd, Rs, Rn = FAIL;
8613
8614 skip_whitespace (str);
8615
8616 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8617 || skip_past_comma (&str) == FAIL)
8618 {
8619 if (! inst.error)
8620 inst.error = BAD_ARGS;
8621 return;
8622 }
8623
8624 if (is_immediate_prefix (*str))
8625 {
8626 Rs = Rd;
8627 str++;
8628 if (my_get_expression (&inst.reloc.exp, &str))
8629 return;
8630 }
8631 else
8632 {
8633 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8634 return;
8635
8636 if (skip_past_comma (&str) == FAIL)
8637 {
8638 /* Two operand format, shuffle the registers
8639 and pretend there are 3. */
8640 Rn = Rs;
8641 Rs = Rd;
8642 }
8643 else if (is_immediate_prefix (*str))
8644 {
8645 str++;
8646 if (my_get_expression (&inst.reloc.exp, &str))
8647 return;
8648 }
8649 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8650 return;
8651 }
8652
8653 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8654 for the latter case, EXPR contains the immediate that was found. */
8655 if (Rn != FAIL)
8656 {
8657 /* All register format. */
8658 if (Rd > 7 || Rs > 7 || Rn > 7)
8659 {
8660 if (Rs != Rd)
8661 {
8662 inst.error = _("dest and source1 must be the same register");
8663 return;
8664 }
8665
8666 /* Can't do this for SUB. */
8667 if (subtract)
8668 {
8669 inst.error = _("subtract valid only on lo regs");
8670 return;
8671 }
8672
8673 inst.instruction = (T_OPCODE_ADD_HI
8674 | (Rd > 7 ? THUMB_H1 : 0)
8675 | (Rn > 7 ? THUMB_H2 : 0));
8676 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8677 }
8678 else
8679 {
8680 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8681 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8682 }
8683 }
8684 else
8685 {
8686 /* Immediate expression, now things start to get nasty. */
8687
8688 /* First deal with HI regs, only very restricted cases allowed:
8689 Adjusting SP, and using PC or SP to get an address. */
8690 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8691 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8692 {
8693 inst.error = _("invalid Hi register with immediate");
8694 return;
8695 }
8696
8697 if (inst.reloc.exp.X_op != O_constant)
8698 {
8699 /* Value isn't known yet, all we can do is store all the fragments
8700 we know about in the instruction and let the reloc hacking
8701 work it all out. */
8702 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8703 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8704 }
8705 else
8706 {
8707 int offset = inst.reloc.exp.X_add_number;
8708
8709 if (subtract)
8710 offset = - offset;
8711
8712 if (offset < 0)
8713 {
8714 offset = - offset;
8715 subtract = 1;
8716
8717 /* Quick check, in case offset is MIN_INT. */
8718 if (offset < 0)
8719 {
8720 inst.error = _("immediate value out of range");
8721 return;
8722 }
8723 }
8724 /* Note - you cannot convert a subtract of 0 into an
8725 add of 0 because the carry flag is set differently. */
8726 else if (offset > 0)
8727 subtract = 0;
8728
8729 if (Rd == REG_SP)
8730 {
8731 if (offset & ~0x1fc)
8732 {
8733 inst.error = _("invalid immediate value for stack adjust");
8734 return;
8735 }
8736 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8737 inst.instruction |= offset >> 2;
8738 }
8739 else if (Rs == REG_PC || Rs == REG_SP)
8740 {
8741 if (subtract
8742 || (offset & ~0x3fc))
8743 {
8744 inst.error = _("invalid immediate for address calculation");
8745 return;
8746 }
8747 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8748 : T_OPCODE_ADD_SP);
8749 inst.instruction |= (Rd << 8) | (offset >> 2);
8750 }
8751 else if (Rs == Rd)
8752 {
8753 if (offset & ~0xff)
8754 {
8755 inst.error = _("immediate value out of range");
8756 return;
8757 }
8758 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8759 inst.instruction |= (Rd << 8) | offset;
8760 }
8761 else
8762 {
8763 if (offset & ~0x7)
8764 {
8765 inst.error = _("immediate value out of range");
8766 return;
8767 }
8768 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8769 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8770 }
8771 }
8772 }
8773
8774 end_of_line (str);
8775 }
8776
8777 static void
8778 thumb_shift (str, shift)
8779 char * str;
8780 int shift;
8781 {
8782 int Rd, Rs, Rn = FAIL;
8783
8784 skip_whitespace (str);
8785
8786 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8787 || skip_past_comma (&str) == FAIL)
8788 {
8789 if (! inst.error)
8790 inst.error = BAD_ARGS;
8791 return;
8792 }
8793
8794 if (is_immediate_prefix (*str))
8795 {
8796 /* Two operand immediate format, set Rs to Rd. */
8797 Rs = Rd;
8798 str ++;
8799 if (my_get_expression (&inst.reloc.exp, &str))
8800 return;
8801 }
8802 else
8803 {
8804 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8805 return;
8806
8807 if (skip_past_comma (&str) == FAIL)
8808 {
8809 /* Two operand format, shuffle the registers
8810 and pretend there are 3. */
8811 Rn = Rs;
8812 Rs = Rd;
8813 }
8814 else if (is_immediate_prefix (*str))
8815 {
8816 str++;
8817 if (my_get_expression (&inst.reloc.exp, &str))
8818 return;
8819 }
8820 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8821 return;
8822 }
8823
8824 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8825 for the latter case, EXPR contains the immediate that was found. */
8826
8827 if (Rn != FAIL)
8828 {
8829 if (Rs != Rd)
8830 {
8831 inst.error = _("source1 and dest must be same register");
8832 return;
8833 }
8834
8835 switch (shift)
8836 {
8837 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8838 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8839 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8840 }
8841
8842 inst.instruction |= Rd | (Rn << 3);
8843 }
8844 else
8845 {
8846 switch (shift)
8847 {
8848 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8849 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8850 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8851 }
8852
8853 if (inst.reloc.exp.X_op != O_constant)
8854 {
8855 /* Value isn't known yet, create a dummy reloc and let reloc
8856 hacking fix it up. */
8857 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8858 }
8859 else
8860 {
8861 unsigned shift_value = inst.reloc.exp.X_add_number;
8862
8863 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8864 {
8865 inst.error = _("invalid immediate for shift");
8866 return;
8867 }
8868
8869 /* Shifts of zero are handled by converting to LSL. */
8870 if (shift_value == 0)
8871 inst.instruction = T_OPCODE_LSL_I;
8872
8873 /* Shifts of 32 are encoded as a shift of zero. */
8874 if (shift_value == 32)
8875 shift_value = 0;
8876
8877 inst.instruction |= shift_value << 6;
8878 }
8879
8880 inst.instruction |= Rd | (Rs << 3);
8881 }
8882
8883 end_of_line (str);
8884 }
8885
8886 static void
8887 thumb_mov_compare (str, move)
8888 char * str;
8889 int move;
8890 {
8891 int Rd, Rs = FAIL;
8892
8893 skip_whitespace (str);
8894
8895 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8896 || skip_past_comma (&str) == FAIL)
8897 {
8898 if (! inst.error)
8899 inst.error = BAD_ARGS;
8900 return;
8901 }
8902
8903 if (is_immediate_prefix (*str))
8904 {
8905 str++;
8906 if (my_get_expression (&inst.reloc.exp, &str))
8907 return;
8908 }
8909 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8910 return;
8911
8912 if (Rs != FAIL)
8913 {
8914 if (Rs < 8 && Rd < 8)
8915 {
8916 if (move == THUMB_MOVE)
8917 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
8918 since a MOV instruction produces unpredictable results. */
8919 inst.instruction = T_OPCODE_ADD_I3;
8920 else
8921 inst.instruction = T_OPCODE_CMP_LR;
8922 inst.instruction |= Rd | (Rs << 3);
8923 }
8924 else
8925 {
8926 if (move == THUMB_MOVE)
8927 inst.instruction = T_OPCODE_MOV_HR;
8928 else
8929 inst.instruction = T_OPCODE_CMP_HR;
8930
8931 if (Rd > 7)
8932 inst.instruction |= THUMB_H1;
8933
8934 if (Rs > 7)
8935 inst.instruction |= THUMB_H2;
8936
8937 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
8938 }
8939 }
8940 else
8941 {
8942 if (Rd > 7)
8943 {
8944 inst.error = _("only lo regs allowed with immediate");
8945 return;
8946 }
8947
8948 if (move == THUMB_MOVE)
8949 inst.instruction = T_OPCODE_MOV_I8;
8950 else
8951 inst.instruction = T_OPCODE_CMP_I8;
8952
8953 inst.instruction |= Rd << 8;
8954
8955 if (inst.reloc.exp.X_op != O_constant)
8956 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
8957 else
8958 {
8959 unsigned value = inst.reloc.exp.X_add_number;
8960
8961 if (value > 255)
8962 {
8963 inst.error = _("invalid immediate");
8964 return;
8965 }
8966
8967 inst.instruction |= value;
8968 }
8969 }
8970
8971 end_of_line (str);
8972 }
8973
8974 static void
8975 thumb_load_store (str, load_store, size)
8976 char * str;
8977 int load_store;
8978 int size;
8979 {
8980 int Rd, Rb, Ro = FAIL;
8981
8982 skip_whitespace (str);
8983
8984 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8985 || skip_past_comma (&str) == FAIL)
8986 {
8987 if (! inst.error)
8988 inst.error = BAD_ARGS;
8989 return;
8990 }
8991
8992 if (*str == '[')
8993 {
8994 str++;
8995 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8996 return;
8997
8998 if (skip_past_comma (&str) != FAIL)
8999 {
9000 if (is_immediate_prefix (*str))
9001 {
9002 str++;
9003 if (my_get_expression (&inst.reloc.exp, &str))
9004 return;
9005 }
9006 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9007 return;
9008 }
9009 else
9010 {
9011 inst.reloc.exp.X_op = O_constant;
9012 inst.reloc.exp.X_add_number = 0;
9013 }
9014
9015 if (*str != ']')
9016 {
9017 inst.error = _("expected ']'");
9018 return;
9019 }
9020 str++;
9021 }
9022 else if (*str == '=')
9023 {
9024 if (load_store != THUMB_LOAD)
9025 {
9026 inst.error = _("invalid pseudo operation");
9027 return;
9028 }
9029
9030 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
9031 str++;
9032
9033 skip_whitespace (str);
9034
9035 if (my_get_expression (& inst.reloc.exp, & str))
9036 return;
9037
9038 end_of_line (str);
9039
9040 if ( inst.reloc.exp.X_op != O_constant
9041 && inst.reloc.exp.X_op != O_symbol)
9042 {
9043 inst.error = "Constant expression expected";
9044 return;
9045 }
9046
9047 if (inst.reloc.exp.X_op == O_constant
9048 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
9049 {
9050 /* This can be done with a mov instruction. */
9051
9052 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
9053 inst.instruction |= inst.reloc.exp.X_add_number;
9054 return;
9055 }
9056
9057 /* Insert into literal pool. */
9058 if (add_to_lit_pool () == FAIL)
9059 {
9060 if (!inst.error)
9061 inst.error = "literal pool insertion failed";
9062 return;
9063 }
9064
9065 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
9066 inst.reloc.pc_rel = 1;
9067 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
9068 /* Adjust ARM pipeline offset to Thumb. */
9069 inst.reloc.exp.X_add_number += 4;
9070
9071 return;
9072 }
9073 else
9074 {
9075 if (my_get_expression (&inst.reloc.exp, &str))
9076 return;
9077
9078 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
9079 inst.reloc.pc_rel = 1;
9080 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
9081 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
9082 end_of_line (str);
9083 return;
9084 }
9085
9086 if (Rb == REG_PC || Rb == REG_SP)
9087 {
9088 if (size != THUMB_WORD)
9089 {
9090 inst.error = _("byte or halfword not valid for base register");
9091 return;
9092 }
9093 else if (Rb == REG_PC && load_store != THUMB_LOAD)
9094 {
9095 inst.error = _("r15 based store not allowed");
9096 return;
9097 }
9098 else if (Ro != FAIL)
9099 {
9100 inst.error = _("invalid base register for register offset");
9101 return;
9102 }
9103
9104 if (Rb == REG_PC)
9105 inst.instruction = T_OPCODE_LDR_PC;
9106 else if (load_store == THUMB_LOAD)
9107 inst.instruction = T_OPCODE_LDR_SP;
9108 else
9109 inst.instruction = T_OPCODE_STR_SP;
9110
9111 inst.instruction |= Rd << 8;
9112 if (inst.reloc.exp.X_op == O_constant)
9113 {
9114 unsigned offset = inst.reloc.exp.X_add_number;
9115
9116 if (offset & ~0x3fc)
9117 {
9118 inst.error = _("invalid offset");
9119 return;
9120 }
9121
9122 inst.instruction |= offset >> 2;
9123 }
9124 else
9125 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
9126 }
9127 else if (Rb > 7)
9128 {
9129 inst.error = _("invalid base register in load/store");
9130 return;
9131 }
9132 else if (Ro == FAIL)
9133 {
9134 /* Immediate offset. */
9135 if (size == THUMB_WORD)
9136 inst.instruction = (load_store == THUMB_LOAD
9137 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
9138 else if (size == THUMB_HALFWORD)
9139 inst.instruction = (load_store == THUMB_LOAD
9140 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
9141 else
9142 inst.instruction = (load_store == THUMB_LOAD
9143 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
9144
9145 inst.instruction |= Rd | (Rb << 3);
9146
9147 if (inst.reloc.exp.X_op == O_constant)
9148 {
9149 unsigned offset = inst.reloc.exp.X_add_number;
9150
9151 if (offset & ~(0x1f << size))
9152 {
9153 inst.error = _("invalid offset");
9154 return;
9155 }
9156 inst.instruction |= (offset >> size) << 6;
9157 }
9158 else
9159 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
9160 }
9161 else
9162 {
9163 /* Register offset. */
9164 if (size == THUMB_WORD)
9165 inst.instruction = (load_store == THUMB_LOAD
9166 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
9167 else if (size == THUMB_HALFWORD)
9168 inst.instruction = (load_store == THUMB_LOAD
9169 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
9170 else
9171 inst.instruction = (load_store == THUMB_LOAD
9172 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
9173
9174 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9175 }
9176
9177 end_of_line (str);
9178 }
9179
9180 /* A register must be given at this point.
9181
9182 Shift is the place to put it in inst.instruction.
9183
9184 Restores input start point on err.
9185 Returns the reg#, or FAIL. */
9186
9187 static int
9188 mav_reg_required_here (str, shift, regtype)
9189 char ** str;
9190 int shift;
9191 enum arm_reg_type regtype;
9192 {
9193 int reg;
9194 char *start = *str;
9195
9196 if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
9197 {
9198 if (shift >= 0)
9199 inst.instruction |= reg << shift;
9200
9201 return reg;
9202 }
9203
9204 /* Restore the start point. */
9205 *str = start;
9206
9207 /* In the few cases where we might be able to accept something else
9208 this error can be overridden. */
9209 inst.error = _(all_reg_maps[regtype].expected);
9210
9211 return FAIL;
9212 }
9213
9214 /* Cirrus Maverick Instructions. */
9215
9216 /* Wrapper functions. */
9217
9218 static void
9219 do_mav_binops_1a (str)
9220 char * str;
9221 {
9222 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
9223 }
9224
9225 static void
9226 do_mav_binops_1b (str)
9227 char * str;
9228 {
9229 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
9230 }
9231
9232 static void
9233 do_mav_binops_1c (str)
9234 char * str;
9235 {
9236 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
9237 }
9238
9239 static void
9240 do_mav_binops_1d (str)
9241 char * str;
9242 {
9243 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
9244 }
9245
9246 static void
9247 do_mav_binops_1e (str)
9248 char * str;
9249 {
9250 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
9251 }
9252
9253 static void
9254 do_mav_binops_1f (str)
9255 char * str;
9256 {
9257 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
9258 }
9259
9260 static void
9261 do_mav_binops_1g (str)
9262 char * str;
9263 {
9264 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
9265 }
9266
9267 static void
9268 do_mav_binops_1h (str)
9269 char * str;
9270 {
9271 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
9272 }
9273
9274 static void
9275 do_mav_binops_1i (str)
9276 char * str;
9277 {
9278 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
9279 }
9280
9281 static void
9282 do_mav_binops_1j (str)
9283 char * str;
9284 {
9285 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
9286 }
9287
9288 static void
9289 do_mav_binops_1k (str)
9290 char * str;
9291 {
9292 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
9293 }
9294
9295 static void
9296 do_mav_binops_1l (str)
9297 char * str;
9298 {
9299 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
9300 }
9301
9302 static void
9303 do_mav_binops_1m (str)
9304 char * str;
9305 {
9306 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
9307 }
9308
9309 static void
9310 do_mav_binops_1n (str)
9311 char * str;
9312 {
9313 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
9314 }
9315
9316 static void
9317 do_mav_binops_1o (str)
9318 char * str;
9319 {
9320 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
9321 }
9322
9323 static void
9324 do_mav_binops_2a (str)
9325 char * str;
9326 {
9327 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
9328 }
9329
9330 static void
9331 do_mav_binops_2b (str)
9332 char * str;
9333 {
9334 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
9335 }
9336
9337 static void
9338 do_mav_binops_2c (str)
9339 char * str;
9340 {
9341 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
9342 }
9343
9344 static void
9345 do_mav_binops_3a (str)
9346 char * str;
9347 {
9348 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
9349 }
9350
9351 static void
9352 do_mav_binops_3b (str)
9353 char * str;
9354 {
9355 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
9356 }
9357
9358 static void
9359 do_mav_binops_3c (str)
9360 char * str;
9361 {
9362 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
9363 }
9364
9365 static void
9366 do_mav_binops_3d (str)
9367 char * str;
9368 {
9369 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
9370 }
9371
9372 static void
9373 do_mav_triple_4a (str)
9374 char * str;
9375 {
9376 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
9377 }
9378
9379 static void
9380 do_mav_triple_4b (str)
9381 char * str;
9382 {
9383 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
9384 }
9385
9386 static void
9387 do_mav_triple_5a (str)
9388 char * str;
9389 {
9390 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
9391 }
9392
9393 static void
9394 do_mav_triple_5b (str)
9395 char * str;
9396 {
9397 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
9398 }
9399
9400 static void
9401 do_mav_triple_5c (str)
9402 char * str;
9403 {
9404 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
9405 }
9406
9407 static void
9408 do_mav_triple_5d (str)
9409 char * str;
9410 {
9411 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
9412 }
9413
9414 static void
9415 do_mav_triple_5e (str)
9416 char * str;
9417 {
9418 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
9419 }
9420
9421 static void
9422 do_mav_triple_5f (str)
9423 char * str;
9424 {
9425 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
9426 }
9427
9428 static void
9429 do_mav_triple_5g (str)
9430 char * str;
9431 {
9432 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
9433 }
9434
9435 static void
9436 do_mav_triple_5h (str)
9437 char * str;
9438 {
9439 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
9440 }
9441
9442 static void
9443 do_mav_quad_6a (str)
9444 char * str;
9445 {
9446 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
9447 REG_TYPE_MVFX);
9448 }
9449
9450 static void
9451 do_mav_quad_6b (str)
9452 char * str;
9453 {
9454 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
9455 REG_TYPE_MVFX);
9456 }
9457
9458 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
9459 static void
9460 do_mav_dspsc_1 (str)
9461 char * str;
9462 {
9463 skip_whitespace (str);
9464
9465 /* cfmvsc32. */
9466 if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
9467 || skip_past_comma (&str) == FAIL
9468 || mav_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
9469 {
9470 if (!inst.error)
9471 inst.error = BAD_ARGS;
9472
9473 return;
9474 }
9475
9476 end_of_line (str);
9477 }
9478
9479 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
9480 static void
9481 do_mav_dspsc_2 (str)
9482 char * str;
9483 {
9484 skip_whitespace (str);
9485
9486 /* cfmv32sc. */
9487 if (mav_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
9488 || skip_past_comma (&str) == FAIL
9489 || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
9490 {
9491 if (!inst.error)
9492 inst.error = BAD_ARGS;
9493
9494 return;
9495 }
9496
9497 end_of_line (str);
9498 }
9499
9500 static void
9501 do_mav_shift_1 (str)
9502 char * str;
9503 {
9504 do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9505 }
9506
9507 static void
9508 do_mav_shift_2 (str)
9509 char * str;
9510 {
9511 do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9512 }
9513
9514 static void
9515 do_mav_ldst_1 (str)
9516 char * str;
9517 {
9518 do_mav_ldst (str, REG_TYPE_MVF);
9519 }
9520
9521 static void
9522 do_mav_ldst_2 (str)
9523 char * str;
9524 {
9525 do_mav_ldst (str, REG_TYPE_MVD);
9526 }
9527
9528 static void
9529 do_mav_ldst_3 (str)
9530 char * str;
9531 {
9532 do_mav_ldst (str, REG_TYPE_MVFX);
9533 }
9534
9535 static void
9536 do_mav_ldst_4 (str)
9537 char * str;
9538 {
9539 do_mav_ldst (str, REG_TYPE_MVDX);
9540 }
9541
9542 /* Isnsn like "foo X,Y". */
9543
9544 static void
9545 do_mav_binops (str, mode, reg0, reg1)
9546 char * str;
9547 int mode;
9548 enum arm_reg_type reg0;
9549 enum arm_reg_type reg1;
9550 {
9551 int shift0, shift1;
9552
9553 shift0 = mode & 0xff;
9554 shift1 = (mode >> 8) & 0xff;
9555
9556 skip_whitespace (str);
9557
9558 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9559 || skip_past_comma (&str) == FAIL
9560 || mav_reg_required_here (&str, shift1, reg1) == FAIL)
9561 {
9562 if (!inst.error)
9563 inst.error = BAD_ARGS;
9564 }
9565 else
9566 end_of_line (str);
9567 }
9568
9569 /* Isnsn like "foo X,Y,Z". */
9570
9571 static void
9572 do_mav_triple (str, mode, reg0, reg1, reg2)
9573 char * str;
9574 int mode;
9575 enum arm_reg_type reg0;
9576 enum arm_reg_type reg1;
9577 enum arm_reg_type reg2;
9578 {
9579 int shift0, shift1, shift2;
9580
9581 shift0 = mode & 0xff;
9582 shift1 = (mode >> 8) & 0xff;
9583 shift2 = (mode >> 16) & 0xff;
9584
9585 skip_whitespace (str);
9586
9587 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9588 || skip_past_comma (&str) == FAIL
9589 || mav_reg_required_here (&str, shift1, reg1) == FAIL
9590 || skip_past_comma (&str) == FAIL
9591 || mav_reg_required_here (&str, shift2, reg2) == FAIL)
9592 {
9593 if (!inst.error)
9594 inst.error = BAD_ARGS;
9595 }
9596 else
9597 end_of_line (str);
9598 }
9599
9600 /* Isnsn like "foo W,X,Y,Z".
9601 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
9602
9603 static void
9604 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
9605 char * str;
9606 int mode;
9607 enum arm_reg_type reg0;
9608 enum arm_reg_type reg1;
9609 enum arm_reg_type reg2;
9610 enum arm_reg_type reg3;
9611 {
9612 int shift0, shift1, shift2, shift3;
9613
9614 shift0= mode & 0xff;
9615 shift1 = (mode >> 8) & 0xff;
9616 shift2 = (mode >> 16) & 0xff;
9617 shift3 = (mode >> 24) & 0xff;
9618
9619 skip_whitespace (str);
9620
9621 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9622 || skip_past_comma (&str) == FAIL
9623 || mav_reg_required_here (&str, shift1, reg1) == FAIL
9624 || skip_past_comma (&str) == FAIL
9625 || mav_reg_required_here (&str, shift2, reg2) == FAIL
9626 || skip_past_comma (&str) == FAIL
9627 || mav_reg_required_here (&str, shift3, reg3) == FAIL)
9628 {
9629 if (!inst.error)
9630 inst.error = BAD_ARGS;
9631 }
9632 else
9633 end_of_line (str);
9634 }
9635
9636 /* Maverick shift immediate instructions.
9637 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
9638 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
9639
9640 static void
9641 do_mav_shift (str, reg0, reg1)
9642 char * str;
9643 enum arm_reg_type reg0;
9644 enum arm_reg_type reg1;
9645 {
9646 int error;
9647 int imm, neg = 0;
9648
9649 skip_whitespace (str);
9650
9651 error = 0;
9652
9653 if (mav_reg_required_here (&str, 12, reg0) == FAIL
9654 || skip_past_comma (&str) == FAIL
9655 || mav_reg_required_here (&str, 16, reg1) == FAIL
9656 || skip_past_comma (&str) == FAIL)
9657 {
9658 if (!inst.error)
9659 inst.error = BAD_ARGS;
9660 return;
9661 }
9662
9663 /* Calculate the immediate operand.
9664 The operand is a 7bit signed number. */
9665 skip_whitespace (str);
9666
9667 if (*str == '#')
9668 ++str;
9669
9670 if (!ISDIGIT (*str) && *str != '-')
9671 {
9672 inst.error = _("expecting immediate, 7bit operand");
9673 return;
9674 }
9675
9676 if (*str == '-')
9677 {
9678 neg = 1;
9679 ++str;
9680 }
9681
9682 for (imm = 0; *str && ISDIGIT (*str); ++str)
9683 imm = imm * 10 + *str - '0';
9684
9685 if (imm > 64)
9686 {
9687 inst.error = _("immediate out of range");
9688 return;
9689 }
9690
9691 /* Make negative imm's into 7bit signed numbers. */
9692 if (neg)
9693 {
9694 imm = -imm;
9695 imm &= 0x0000007f;
9696 }
9697
9698 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9699 Bits 5-7 of the insn should have bits 4-6 of the immediate.
9700 Bit 4 should be 0. */
9701 imm = (imm & 0xf) | ((imm & 0x70) << 1);
9702
9703 inst.instruction |= imm;
9704 end_of_line (str);
9705 }
9706
9707 static int
9708 mav_parse_offset (str, negative)
9709 char ** str;
9710 int *negative;
9711 {
9712 char * p = *str;
9713 int offset;
9714
9715 *negative = 0;
9716
9717 skip_whitespace (p);
9718
9719 if (*p == '#')
9720 ++p;
9721
9722 if (*p == '-')
9723 {
9724 *negative = 1;
9725 ++p;
9726 }
9727
9728 if (!ISDIGIT (*p))
9729 {
9730 inst.error = _("offset expected");
9731 return 0;
9732 }
9733
9734 for (offset = 0; *p && ISDIGIT (*p); ++p)
9735 offset = offset * 10 + *p - '0';
9736
9737 if (offset > 0xff)
9738 {
9739 inst.error = _("offset out of range");
9740 return 0;
9741 }
9742
9743 *str = p;
9744
9745 return *negative ? -offset : offset;
9746 }
9747
9748 /* Maverick load/store instructions.
9749 <insn><cond> CRd,[Rn,<offset>]{!}.
9750 <insn><cond> CRd,[Rn],<offset>. */
9751
9752 static void
9753 do_mav_ldst (str, reg0)
9754 char * str;
9755 enum arm_reg_type reg0;
9756 {
9757 int offset, negative;
9758
9759 skip_whitespace (str);
9760
9761 if (mav_reg_required_here (&str, 12, reg0) == FAIL
9762 || skip_past_comma (&str) == FAIL
9763 || *str++ != '['
9764 || reg_required_here (&str, 16) == FAIL)
9765 goto fail_ldst;
9766
9767 if (skip_past_comma (&str) == SUCCESS)
9768 {
9769 /* You are here: "<offset>]{!}". */
9770 inst.instruction |= PRE_INDEX;
9771
9772 offset = mav_parse_offset (&str, &negative);
9773
9774 if (inst.error)
9775 return;
9776
9777 if (*str++ != ']')
9778 {
9779 inst.error = _("missing ]");
9780 return;
9781 }
9782
9783 if (*str == '!')
9784 {
9785 inst.instruction |= WRITE_BACK;
9786 ++str;
9787 }
9788 }
9789 else
9790 {
9791 /* You are here: "], <offset>". */
9792 if (*str++ != ']')
9793 {
9794 inst.error = _("missing ]");
9795 return;
9796 }
9797
9798 if (skip_past_comma (&str) == FAIL
9799 || (offset = mav_parse_offset (&str, &negative), inst.error))
9800 goto fail_ldst;
9801
9802 inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
9803 }
9804
9805 if (negative)
9806 offset = -offset;
9807 else
9808 inst.instruction |= CP_T_UD; /* Positive, so set bit U. */
9809
9810 inst.instruction |= offset >> 2;
9811 end_of_line (str);
9812 return;
9813
9814 fail_ldst:
9815 if (!inst.error)
9816 inst.error = BAD_ARGS;
9817 return;
9818 }
9819
9820 static void
9821 do_t_nop (str)
9822 char * str;
9823 {
9824 /* Do nothing. */
9825 end_of_line (str);
9826 return;
9827 }
9828
9829 /* Handle the Format 4 instructions that do not have equivalents in other
9830 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9831 BIC and MVN. */
9832
9833 static void
9834 do_t_arit (str)
9835 char * str;
9836 {
9837 int Rd, Rs, Rn;
9838
9839 skip_whitespace (str);
9840
9841 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9842 || skip_past_comma (&str) == FAIL
9843 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9844 {
9845 inst.error = BAD_ARGS;
9846 return;
9847 }
9848
9849 if (skip_past_comma (&str) != FAIL)
9850 {
9851 /* Three operand format not allowed for TST, CMN, NEG and MVN.
9852 (It isn't allowed for CMP either, but that isn't handled by this
9853 function.) */
9854 if (inst.instruction == T_OPCODE_TST
9855 || inst.instruction == T_OPCODE_CMN
9856 || inst.instruction == T_OPCODE_NEG
9857 || inst.instruction == T_OPCODE_MVN)
9858 {
9859 inst.error = BAD_ARGS;
9860 return;
9861 }
9862
9863 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9864 return;
9865
9866 if (Rs != Rd)
9867 {
9868 inst.error = _("dest and source1 must be the same register");
9869 return;
9870 }
9871 Rs = Rn;
9872 }
9873
9874 if (inst.instruction == T_OPCODE_MUL
9875 && Rs == Rd)
9876 as_tsktsk (_("Rs and Rd must be different in MUL"));
9877
9878 inst.instruction |= Rd | (Rs << 3);
9879 end_of_line (str);
9880 }
9881
9882 static void
9883 do_t_add (str)
9884 char * str;
9885 {
9886 thumb_add_sub (str, 0);
9887 }
9888
9889 static void
9890 do_t_asr (str)
9891 char * str;
9892 {
9893 thumb_shift (str, THUMB_ASR);
9894 }
9895
9896 static void
9897 do_t_branch9 (str)
9898 char * str;
9899 {
9900 if (my_get_expression (&inst.reloc.exp, &str))
9901 return;
9902 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9903 inst.reloc.pc_rel = 1;
9904 end_of_line (str);
9905 }
9906
9907 static void
9908 do_t_branch12 (str)
9909 char * str;
9910 {
9911 if (my_get_expression (&inst.reloc.exp, &str))
9912 return;
9913 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9914 inst.reloc.pc_rel = 1;
9915 end_of_line (str);
9916 }
9917
9918 /* Find the real, Thumb encoded start of a Thumb function. */
9919
9920 static symbolS *
9921 find_real_start (symbolP)
9922 symbolS * symbolP;
9923 {
9924 char * real_start;
9925 const char * name = S_GET_NAME (symbolP);
9926 symbolS * new_target;
9927
9928 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
9929 #define STUB_NAME ".real_start_of"
9930
9931 if (name == NULL)
9932 abort ();
9933
9934 /* Names that start with '.' are local labels, not function entry points.
9935 The compiler may generate BL instructions to these labels because it
9936 needs to perform a branch to a far away location. */
9937 if (name[0] == '.')
9938 return symbolP;
9939
9940 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9941 sprintf (real_start, "%s%s", STUB_NAME, name);
9942
9943 new_target = symbol_find (real_start);
9944
9945 if (new_target == NULL)
9946 {
9947 as_warn ("Failed to find real start of function: %s\n", name);
9948 new_target = symbolP;
9949 }
9950
9951 free (real_start);
9952
9953 return new_target;
9954 }
9955
9956 static void
9957 do_t_branch23 (str)
9958 char * str;
9959 {
9960 if (my_get_expression (& inst.reloc.exp, & str))
9961 return;
9962
9963 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
9964 inst.reloc.pc_rel = 1;
9965 end_of_line (str);
9966
9967 /* If the destination of the branch is a defined symbol which does not have
9968 the THUMB_FUNC attribute, then we must be calling a function which has
9969 the (interfacearm) attribute. We look for the Thumb entry point to that
9970 function and change the branch to refer to that function instead. */
9971 if ( inst.reloc.exp.X_op == O_symbol
9972 && inst.reloc.exp.X_add_symbol != NULL
9973 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9974 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9975 inst.reloc.exp.X_add_symbol =
9976 find_real_start (inst.reloc.exp.X_add_symbol);
9977 }
9978
9979 static void
9980 do_t_bx (str)
9981 char * str;
9982 {
9983 int reg;
9984
9985 skip_whitespace (str);
9986
9987 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9988 return;
9989
9990 /* This sets THUMB_H2 from the top bit of reg. */
9991 inst.instruction |= reg << 3;
9992
9993 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
9994 should cause the alignment to be checked once it is known. This is
9995 because BX PC only works if the instruction is word aligned. */
9996
9997 end_of_line (str);
9998 }
9999
10000 static void
10001 do_t_compare (str)
10002 char * str;
10003 {
10004 thumb_mov_compare (str, THUMB_COMPARE);
10005 }
10006
10007 static void
10008 do_t_ldmstm (str)
10009 char * str;
10010 {
10011 int Rb;
10012 long range;
10013
10014 skip_whitespace (str);
10015
10016 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10017 return;
10018
10019 if (*str != '!')
10020 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
10021 else
10022 str++;
10023
10024 if (skip_past_comma (&str) == FAIL
10025 || (range = reg_list (&str)) == FAIL)
10026 {
10027 if (! inst.error)
10028 inst.error = BAD_ARGS;
10029 return;
10030 }
10031
10032 if (inst.reloc.type != BFD_RELOC_NONE)
10033 {
10034 /* This really doesn't seem worth it. */
10035 inst.reloc.type = BFD_RELOC_NONE;
10036 inst.error = _("expression too complex");
10037 return;
10038 }
10039
10040 if (range & ~0xff)
10041 {
10042 inst.error = _("only lo-regs valid in load/store multiple");
10043 return;
10044 }
10045
10046 inst.instruction |= (Rb << 8) | range;
10047 end_of_line (str);
10048 }
10049
10050 static void
10051 do_t_ldr (str)
10052 char * str;
10053 {
10054 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
10055 }
10056
10057 static void
10058 do_t_ldrb (str)
10059 char * str;
10060 {
10061 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
10062 }
10063
10064 static void
10065 do_t_ldrh (str)
10066 char * str;
10067 {
10068 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
10069 }
10070
10071 static void
10072 do_t_lds (str)
10073 char * str;
10074 {
10075 int Rd, Rb, Ro;
10076
10077 skip_whitespace (str);
10078
10079 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10080 || skip_past_comma (&str) == FAIL
10081 || *str++ != '['
10082 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10083 || skip_past_comma (&str) == FAIL
10084 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10085 || *str++ != ']')
10086 {
10087 if (! inst.error)
10088 inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
10089 return;
10090 }
10091
10092 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10093 end_of_line (str);
10094 }
10095
10096 static void
10097 do_t_lsl (str)
10098 char * str;
10099 {
10100 thumb_shift (str, THUMB_LSL);
10101 }
10102
10103 static void
10104 do_t_lsr (str)
10105 char * str;
10106 {
10107 thumb_shift (str, THUMB_LSR);
10108 }
10109
10110 static void
10111 do_t_mov (str)
10112 char * str;
10113 {
10114 thumb_mov_compare (str, THUMB_MOVE);
10115 }
10116
10117 static void
10118 do_t_push_pop (str)
10119 char * str;
10120 {
10121 long range;
10122
10123 skip_whitespace (str);
10124
10125 if ((range = reg_list (&str)) == FAIL)
10126 {
10127 if (! inst.error)
10128 inst.error = BAD_ARGS;
10129 return;
10130 }
10131
10132 if (inst.reloc.type != BFD_RELOC_NONE)
10133 {
10134 /* This really doesn't seem worth it. */
10135 inst.reloc.type = BFD_RELOC_NONE;
10136 inst.error = _("expression too complex");
10137 return;
10138 }
10139
10140 if (range & ~0xff)
10141 {
10142 if ((inst.instruction == T_OPCODE_PUSH
10143 && (range & ~0xff) == 1 << REG_LR)
10144 || (inst.instruction == T_OPCODE_POP
10145 && (range & ~0xff) == 1 << REG_PC))
10146 {
10147 inst.instruction |= THUMB_PP_PC_LR;
10148 range &= 0xff;
10149 }
10150 else
10151 {
10152 inst.error = _("invalid register list to push/pop instruction");
10153 return;
10154 }
10155 }
10156
10157 inst.instruction |= range;
10158 end_of_line (str);
10159 }
10160
10161 static void
10162 do_t_str (str)
10163 char * str;
10164 {
10165 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
10166 }
10167
10168 static void
10169 do_t_strb (str)
10170 char * str;
10171 {
10172 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
10173 }
10174
10175 static void
10176 do_t_strh (str)
10177 char * str;
10178 {
10179 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
10180 }
10181
10182 static void
10183 do_t_sub (str)
10184 char * str;
10185 {
10186 thumb_add_sub (str, 1);
10187 }
10188
10189 static void
10190 do_t_swi (str)
10191 char * str;
10192 {
10193 skip_whitespace (str);
10194
10195 if (my_get_expression (&inst.reloc.exp, &str))
10196 return;
10197
10198 inst.reloc.type = BFD_RELOC_ARM_SWI;
10199 end_of_line (str);
10200 return;
10201 }
10202
10203 static void
10204 do_t_adr (str)
10205 char * str;
10206 {
10207 int reg;
10208
10209 /* This is a pseudo-op of the form "adr rd, label" to be converted
10210 into a relative address of the form "add rd, pc, #label-.-4". */
10211 skip_whitespace (str);
10212
10213 /* Store Rd in temporary location inside instruction. */
10214 if ((reg = reg_required_here (&str, 4)) == FAIL
10215 || (reg > 7) /* For Thumb reg must be r0..r7. */
10216 || skip_past_comma (&str) == FAIL
10217 || my_get_expression (&inst.reloc.exp, &str))
10218 {
10219 if (!inst.error)
10220 inst.error = BAD_ARGS;
10221 return;
10222 }
10223
10224 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
10225 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
10226 inst.reloc.pc_rel = 1;
10227 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
10228
10229 end_of_line (str);
10230 }
10231
10232 static void
10233 insert_reg (r, htab)
10234 const struct reg_entry *r;
10235 struct hash_control *htab;
10236 {
10237 int len = strlen (r->name) + 2;
10238 char * buf = (char *) xmalloc (len);
10239 char * buf2 = (char *) xmalloc (len);
10240 int i = 0;
10241
10242 #ifdef REGISTER_PREFIX
10243 buf[i++] = REGISTER_PREFIX;
10244 #endif
10245
10246 strcpy (buf + i, r->name);
10247
10248 for (i = 0; buf[i]; i++)
10249 buf2[i] = TOUPPER (buf[i]);
10250
10251 buf2[i] = '\0';
10252
10253 hash_insert (htab, buf, (PTR) r);
10254 hash_insert (htab, buf2, (PTR) r);
10255 }
10256
10257 static void
10258 build_reg_hsh (map)
10259 struct reg_map *map;
10260 {
10261 const struct reg_entry *r;
10262
10263 if ((map->htab = hash_new ()) == NULL)
10264 as_fatal (_("virtual memory exhausted"));
10265
10266 for (r = map->names; r->name != NULL; r++)
10267 insert_reg (r, map->htab);
10268 }
10269
10270 static void
10271 insert_reg_alias (str, regnum, htab)
10272 char *str;
10273 int regnum;
10274 struct hash_control *htab;
10275 {
10276 const char *error;
10277 struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
10278 const char *name = xmalloc (strlen (str) + 1);
10279
10280 strcpy ((char *) name, str);
10281
10282 new->name = name;
10283 new->number = regnum;
10284 new->builtin = FALSE;
10285
10286 error = hash_insert (htab, name, (PTR) new);
10287 if (error)
10288 {
10289 as_bad (_("failed to create an alias for %s, reason: %s"),
10290 str, error);
10291 free ((char *) name);
10292 free (new);
10293 }
10294 }
10295
10296 /* Look for the .req directive. This is of the form:
10297
10298 new_register_name .req existing_register_name
10299
10300 If we find one, or if it looks sufficiently like one that we want to
10301 handle any error here, return non-zero. Otherwise return zero. */
10302 static int
10303 create_register_alias (newname, p)
10304 char *newname;
10305 char *p;
10306 {
10307 char *q;
10308 char c;
10309
10310 q = p;
10311 skip_whitespace (q);
10312
10313 c = *p;
10314 *p = '\0';
10315
10316 if (*q && !strncmp (q, ".req ", 5))
10317 {
10318 char *copy_of_str;
10319 char *r;
10320
10321 #ifdef IGNORE_OPCODE_CASE
10322 newname = original_case_string;
10323 #endif
10324 copy_of_str = newname;
10325
10326 q += 4;
10327 skip_whitespace (q);
10328
10329 for (r = q; *r != '\0'; r++)
10330 if (*r == ' ')
10331 break;
10332
10333 if (r != q)
10334 {
10335 enum arm_reg_type new_type, old_type;
10336 int old_regno;
10337 char d = *r;
10338
10339 *r = '\0';
10340 old_type = arm_reg_parse_any (q);
10341 *r = d;
10342
10343 new_type = arm_reg_parse_any (newname);
10344
10345 if (new_type == REG_TYPE_MAX)
10346 {
10347 if (old_type != REG_TYPE_MAX)
10348 {
10349 old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
10350 insert_reg_alias (newname, old_regno,
10351 all_reg_maps[old_type].htab);
10352 }
10353 else
10354 as_warn (_("register '%s' does not exist\n"), q);
10355 }
10356 else if (old_type == REG_TYPE_MAX)
10357 {
10358 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
10359 copy_of_str, q);
10360 }
10361 else
10362 {
10363 /* Do not warn about redefinitions to the same alias. */
10364 if (new_type != old_type
10365 || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
10366 != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
10367 as_warn (_("ignoring redefinition of register alias '%s'"),
10368 copy_of_str);
10369
10370 }
10371 }
10372 else
10373 as_warn (_("ignoring incomplete .req pseuso op"));
10374
10375 *p = c;
10376 return 1;
10377 }
10378
10379 *p = c;
10380 return 0;
10381 }
10382
10383 static void
10384 set_constant_flonums ()
10385 {
10386 int i;
10387
10388 for (i = 0; i < NUM_FLOAT_VALS; i++)
10389 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
10390 abort ();
10391 }
10392
10393 /* Iterate over the base tables to create the instruction patterns. */
10394 static void
10395 build_arm_ops_hsh ()
10396 {
10397 unsigned int i;
10398 unsigned int j;
10399 static struct obstack insn_obstack;
10400
10401 obstack_begin (&insn_obstack, 4000);
10402
10403 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
10404 {
10405 const struct asm_opcode *insn = insns + i;
10406
10407 if (insn->cond_offset != 0)
10408 {
10409 /* Insn supports conditional execution. Build the varaints
10410 and insert them in the hash table. */
10411 for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
10412 {
10413 unsigned len = strlen (insn->template);
10414 struct asm_opcode *new;
10415 char *template;
10416
10417 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
10418 /* All condition codes are two characters. */
10419 template = obstack_alloc (&insn_obstack, len + 3);
10420
10421 strncpy (template, insn->template, insn->cond_offset);
10422 strcpy (template + insn->cond_offset, conds[j].template);
10423 if (len > insn->cond_offset)
10424 strcpy (template + insn->cond_offset + 2,
10425 insn->template + insn->cond_offset);
10426 new->template = template;
10427 new->cond_offset = 0;
10428 new->variant = insn->variant;
10429 new->parms = insn->parms;
10430 new->value = (insn->value & ~COND_MASK) | conds[j].value;
10431
10432 hash_insert (arm_ops_hsh, new->template, (PTR) new);
10433 }
10434 }
10435 /* Finally, insert the unconditional insn in the table directly;
10436 no need to build a copy. */
10437 hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
10438 }
10439 }
10440
10441 #if 0 /* Suppressed - for now. */
10442 #if defined OBJ_ELF || defined OBJ_COFF
10443
10444 #ifdef OBJ_ELF
10445 #define arm_Note Elf_External_Note
10446 #else
10447 typedef struct
10448 {
10449 unsigned char namesz[4]; /* Size of entry's owner string. */
10450 unsigned char descsz[4]; /* Size of the note descriptor. */
10451 unsigned char type[4]; /* Interpretation of the descriptor. */
10452 char name[1]; /* Start of the name+desc data. */
10453 } arm_Note;
10454 #endif
10455
10456 /* The description is kept to a fix sized in order to make updating
10457 it and merging it easier. */
10458 #define ARM_NOTE_DESCRIPTION_LENGTH 8
10459
10460 static void
10461 arm_add_note (name, description, type)
10462 const char * name;
10463 const char * description;
10464 unsigned int type;
10465 {
10466 arm_Note note ATTRIBUTE_UNUSED;
10467 char * p;
10468 unsigned int name_len;
10469
10470 name_len = (strlen (name) + 1 + 3) & ~3;
10471
10472 p = frag_more (sizeof (note.namesz));
10473 md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
10474
10475 p = frag_more (sizeof (note.descsz));
10476 md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
10477
10478 p = frag_more (sizeof (note.type));
10479 md_number_to_chars (p, (valueT) type, sizeof (note.type));
10480
10481 p = frag_more (name_len);
10482 strcpy (p, name);
10483
10484 p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
10485 strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
10486 frag_align (2, 0, 0);
10487 }
10488 #endif
10489 #endif
10490
10491 void
10492 md_begin ()
10493 {
10494 unsigned mach;
10495 unsigned int i;
10496
10497 if ( (arm_ops_hsh = hash_new ()) == NULL
10498 || (arm_tops_hsh = hash_new ()) == NULL
10499 || (arm_cond_hsh = hash_new ()) == NULL
10500 || (arm_shift_hsh = hash_new ()) == NULL
10501 || (arm_psr_hsh = hash_new ()) == NULL)
10502 as_fatal (_("virtual memory exhausted"));
10503
10504 build_arm_ops_hsh ();
10505 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
10506 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
10507 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
10508 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
10509 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
10510 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
10511 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
10512 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
10513
10514 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10515 build_reg_hsh (all_reg_maps + i);
10516
10517 set_constant_flonums ();
10518
10519 /* Set the cpu variant based on the command-line options. We prefer
10520 -mcpu= over -march= if both are set (as for GCC); and we prefer
10521 -mfpu= over any other way of setting the floating point unit.
10522 Use of legacy options with new options are faulted. */
10523 if (legacy_cpu != -1)
10524 {
10525 if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
10526 as_bad (_("use of old and new-style options to set CPU type"));
10527
10528 mcpu_cpu_opt = legacy_cpu;
10529 }
10530 else if (mcpu_cpu_opt == -1)
10531 mcpu_cpu_opt = march_cpu_opt;
10532
10533 if (legacy_fpu != -1)
10534 {
10535 if (mfpu_opt != -1)
10536 as_bad (_("use of old and new-style options to set FPU type"));
10537
10538 mfpu_opt = legacy_fpu;
10539 }
10540 else if (mfpu_opt == -1)
10541 {
10542 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
10543 /* Some environments specify a default FPU. If they don't, infer it
10544 from the processor. */
10545 if (mcpu_fpu_opt != -1)
10546 mfpu_opt = mcpu_fpu_opt;
10547 else
10548 mfpu_opt = march_fpu_opt;
10549 #else
10550 mfpu_opt = FPU_DEFAULT;
10551 #endif
10552 }
10553
10554 if (mfpu_opt == -1)
10555 {
10556 if (mcpu_cpu_opt == -1)
10557 mfpu_opt = FPU_DEFAULT;
10558 else if (mcpu_cpu_opt & ARM_EXT_V5)
10559 mfpu_opt = FPU_ARCH_VFP_V2;
10560 else
10561 mfpu_opt = FPU_ARCH_FPA;
10562 }
10563
10564 if (mcpu_cpu_opt == -1)
10565 mcpu_cpu_opt = CPU_DEFAULT;
10566
10567 cpu_variant = mcpu_cpu_opt | mfpu_opt;
10568
10569 #if defined OBJ_COFF || defined OBJ_ELF
10570 {
10571 unsigned int flags = 0;
10572
10573 /* Set the flags in the private structure. */
10574 if (uses_apcs_26) flags |= F_APCS26;
10575 if (support_interwork) flags |= F_INTERWORK;
10576 if (uses_apcs_float) flags |= F_APCS_FLOAT;
10577 if (pic_code) flags |= F_PIC;
10578 if ((cpu_variant & FPU_ANY) == FPU_NONE
10579 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
10580 flags |= F_SOFT_FLOAT;
10581 /* Using VFP conventions (even if soft-float). */
10582 if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
10583
10584 #if defined OBJ_ELF
10585 if (cpu_variant & ARM_CEXT_MAVERICK)
10586 {
10587 flags &= ~ F_SOFT_FLOAT;
10588 flags |= EF_ARM_MAVERICK_FLOAT;
10589 }
10590 #endif
10591
10592 bfd_set_private_flags (stdoutput, flags);
10593
10594 /* We have run out flags in the COFF header to encode the
10595 status of ATPCS support, so instead we create a dummy,
10596 empty, debug section called .arm.atpcs. */
10597 if (atpcs)
10598 {
10599 asection * sec;
10600
10601 sec = bfd_make_section (stdoutput, ".arm.atpcs");
10602
10603 if (sec != NULL)
10604 {
10605 bfd_set_section_flags
10606 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
10607 bfd_set_section_size (stdoutput, sec, 0);
10608 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
10609 }
10610 }
10611 }
10612 #endif
10613
10614 /* Record the CPU type as well. */
10615 switch (cpu_variant & ARM_CPU_MASK)
10616 {
10617 case ARM_2:
10618 mach = bfd_mach_arm_2;
10619 break;
10620
10621 case ARM_3: /* Also ARM_250. */
10622 mach = bfd_mach_arm_2a;
10623 break;
10624
10625 case ARM_6: /* Also ARM_7. */
10626 mach = bfd_mach_arm_3;
10627 break;
10628
10629 default:
10630 mach = bfd_mach_arm_unknown;
10631 break;
10632 }
10633
10634 /* Catch special cases. */
10635 if (cpu_variant & ARM_CEXT_IWMMXT)
10636 mach = bfd_mach_arm_iWMMXt;
10637 else if (cpu_variant & ARM_CEXT_XSCALE)
10638 mach = bfd_mach_arm_XScale;
10639 else if (cpu_variant & ARM_CEXT_MAVERICK)
10640 mach = bfd_mach_arm_ep9312;
10641 else if (cpu_variant & ARM_EXT_V5E)
10642 mach = bfd_mach_arm_5TE;
10643 else if (cpu_variant & ARM_EXT_V5)
10644 {
10645 if (cpu_variant & ARM_EXT_V4T)
10646 mach = bfd_mach_arm_5T;
10647 else
10648 mach = bfd_mach_arm_5;
10649 }
10650 else if (cpu_variant & ARM_EXT_V4)
10651 {
10652 if (cpu_variant & ARM_EXT_V4T)
10653 mach = bfd_mach_arm_4T;
10654 else
10655 mach = bfd_mach_arm_4;
10656 }
10657 else if (cpu_variant & ARM_EXT_V3M)
10658 mach = bfd_mach_arm_3M;
10659
10660 #if 0 /* Suppressed - for now. */
10661 #if defined (OBJ_ELF) || defined (OBJ_COFF)
10662
10663 /* Create a .note section to fully identify this arm binary. */
10664
10665 #define NOTE_ARCH_STRING "arch: "
10666
10667 #if defined OBJ_COFF && ! defined NT_VERSION
10668 #define NT_VERSION 1
10669 #define NT_ARCH 2
10670 #endif
10671
10672 {
10673 segT current_seg = now_seg;
10674 subsegT current_subseg = now_subseg;
10675 asection * arm_arch;
10676 const char * arch_string;
10677
10678 arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
10679
10680 #ifdef OBJ_COFF
10681 bfd_set_section_flags (stdoutput, arm_arch,
10682 SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
10683 | SEC_HAS_CONTENTS);
10684 #endif
10685 arm_arch->output_section = arm_arch;
10686 subseg_set (arm_arch, 0);
10687
10688 switch (mach)
10689 {
10690 default:
10691 case bfd_mach_arm_unknown: arch_string = "unknown"; break;
10692 case bfd_mach_arm_2: arch_string = "armv2"; break;
10693 case bfd_mach_arm_2a: arch_string = "armv2a"; break;
10694 case bfd_mach_arm_3: arch_string = "armv3"; break;
10695 case bfd_mach_arm_3M: arch_string = "armv3M"; break;
10696 case bfd_mach_arm_4: arch_string = "armv4"; break;
10697 case bfd_mach_arm_4T: arch_string = "armv4t"; break;
10698 case bfd_mach_arm_5: arch_string = "armv5"; break;
10699 case bfd_mach_arm_5T: arch_string = "armv5t"; break;
10700 case bfd_mach_arm_5TE: arch_string = "armv5te"; break;
10701 case bfd_mach_arm_XScale: arch_string = "XScale"; break;
10702 case bfd_mach_arm_ep9312: arch_string = "ep9312"; break;
10703 case bfd_mach_arm_iWMMXt: arch_string = "iWMMXt"; break;
10704 }
10705
10706 arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
10707
10708 subseg_set (current_seg, current_subseg);
10709 }
10710 #endif
10711 #endif /* Suppressed code. */
10712
10713 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
10714 }
10715
10716 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
10717 for use in the a.out file, and stores them in the array pointed to by buf.
10718 This knows about the endian-ness of the target machine and does
10719 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
10720 2 (short) and 4 (long) Floating numbers are put out as a series of
10721 LITTLENUMS (shorts, here at least). */
10722
10723 void
10724 md_number_to_chars (buf, val, n)
10725 char * buf;
10726 valueT val;
10727 int n;
10728 {
10729 if (target_big_endian)
10730 number_to_chars_bigendian (buf, val, n);
10731 else
10732 number_to_chars_littleendian (buf, val, n);
10733 }
10734
10735 static valueT
10736 md_chars_to_number (buf, n)
10737 char * buf;
10738 int n;
10739 {
10740 valueT result = 0;
10741 unsigned char * where = (unsigned char *) buf;
10742
10743 if (target_big_endian)
10744 {
10745 while (n--)
10746 {
10747 result <<= 8;
10748 result |= (*where++ & 255);
10749 }
10750 }
10751 else
10752 {
10753 while (n--)
10754 {
10755 result <<= 8;
10756 result |= (where[n] & 255);
10757 }
10758 }
10759
10760 return result;
10761 }
10762
10763 /* Turn a string in input_line_pointer into a floating point constant
10764 of type TYPE, and store the appropriate bytes in *LITP. The number
10765 of LITTLENUMS emitted is stored in *SIZEP. An error message is
10766 returned, or NULL on OK.
10767
10768 Note that fp constants aren't represent in the normal way on the ARM.
10769 In big endian mode, things are as expected. However, in little endian
10770 mode fp constants are big-endian word-wise, and little-endian byte-wise
10771 within the words. For example, (double) 1.1 in big endian mode is
10772 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
10773 the byte sequence 99 99 f1 3f 9a 99 99 99.
10774
10775 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
10776
10777 char *
10778 md_atof (type, litP, sizeP)
10779 char type;
10780 char * litP;
10781 int * sizeP;
10782 {
10783 int prec;
10784 LITTLENUM_TYPE words[MAX_LITTLENUMS];
10785 char *t;
10786 int i;
10787
10788 switch (type)
10789 {
10790 case 'f':
10791 case 'F':
10792 case 's':
10793 case 'S':
10794 prec = 2;
10795 break;
10796
10797 case 'd':
10798 case 'D':
10799 case 'r':
10800 case 'R':
10801 prec = 4;
10802 break;
10803
10804 case 'x':
10805 case 'X':
10806 prec = 6;
10807 break;
10808
10809 case 'p':
10810 case 'P':
10811 prec = 6;
10812 break;
10813
10814 default:
10815 *sizeP = 0;
10816 return _("bad call to MD_ATOF()");
10817 }
10818
10819 t = atof_ieee (input_line_pointer, type, words);
10820 if (t)
10821 input_line_pointer = t;
10822 *sizeP = prec * 2;
10823
10824 if (target_big_endian)
10825 {
10826 for (i = 0; i < prec; i++)
10827 {
10828 md_number_to_chars (litP, (valueT) words[i], 2);
10829 litP += 2;
10830 }
10831 }
10832 else
10833 {
10834 if (cpu_variant & FPU_ARCH_VFP)
10835 for (i = prec - 1; i >= 0; i--)
10836 {
10837 md_number_to_chars (litP, (valueT) words[i], 2);
10838 litP += 2;
10839 }
10840 else
10841 /* For a 4 byte float the order of elements in `words' is 1 0.
10842 For an 8 byte float the order is 1 0 3 2. */
10843 for (i = 0; i < prec; i += 2)
10844 {
10845 md_number_to_chars (litP, (valueT) words[i + 1], 2);
10846 md_number_to_chars (litP + 2, (valueT) words[i], 2);
10847 litP += 4;
10848 }
10849 }
10850
10851 return 0;
10852 }
10853
10854 /* The knowledge of the PC's pipeline offset is built into the insns
10855 themselves. */
10856
10857 long
10858 md_pcrel_from (fixP)
10859 fixS * fixP;
10860 {
10861 if (fixP->fx_addsy
10862 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
10863 && fixP->fx_subsy == NULL)
10864 return 0;
10865
10866 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
10867 {
10868 /* PC relative addressing on the Thumb is slightly odd
10869 as the bottom two bits of the PC are forced to zero
10870 for the calculation. */
10871 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
10872 }
10873
10874 #ifdef TE_WINCE
10875 /* The pattern was adjusted to accommodate CE's off-by-one fixups,
10876 so we un-adjust here to compensate for the accommodation. */
10877 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
10878 #else
10879 return fixP->fx_where + fixP->fx_frag->fr_address;
10880 #endif
10881 }
10882
10883 /* Round up a section size to the appropriate boundary. */
10884
10885 valueT
10886 md_section_align (segment, size)
10887 segT segment ATTRIBUTE_UNUSED;
10888 valueT size;
10889 {
10890 #ifdef OBJ_ELF
10891 return size;
10892 #else
10893 /* Round all sects to multiple of 4. */
10894 return (size + 3) & ~3;
10895 #endif
10896 }
10897
10898 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
10899 Otherwise we have no need to default values of symbols. */
10900
10901 symbolS *
10902 md_undefined_symbol (name)
10903 char * name ATTRIBUTE_UNUSED;
10904 {
10905 #ifdef OBJ_ELF
10906 if (name[0] == '_' && name[1] == 'G'
10907 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
10908 {
10909 if (!GOT_symbol)
10910 {
10911 if (symbol_find (name))
10912 as_bad ("GOT already in the symbol table");
10913
10914 GOT_symbol = symbol_new (name, undefined_section,
10915 (valueT) 0, & zero_address_frag);
10916 }
10917
10918 return GOT_symbol;
10919 }
10920 #endif
10921
10922 return 0;
10923 }
10924
10925 /* arm_reg_parse () := if it looks like a register, return its token and
10926 advance the pointer. */
10927
10928 static int
10929 arm_reg_parse (ccp, htab)
10930 register char ** ccp;
10931 struct hash_control *htab;
10932 {
10933 char * start = * ccp;
10934 char c;
10935 char * p;
10936 struct reg_entry * reg;
10937
10938 #ifdef REGISTER_PREFIX
10939 if (*start != REGISTER_PREFIX)
10940 return FAIL;
10941 p = start + 1;
10942 #else
10943 p = start;
10944 #ifdef OPTIONAL_REGISTER_PREFIX
10945 if (*p == OPTIONAL_REGISTER_PREFIX)
10946 p++, start++;
10947 #endif
10948 #endif
10949 if (!ISALPHA (*p) || !is_name_beginner (*p))
10950 return FAIL;
10951
10952 c = *p++;
10953 while (ISALPHA (c) || ISDIGIT (c) || c == '_')
10954 c = *p++;
10955
10956 *--p = 0;
10957 reg = (struct reg_entry *) hash_find (htab, start);
10958 *p = c;
10959
10960 if (reg)
10961 {
10962 *ccp = p;
10963 return reg->number;
10964 }
10965
10966 return FAIL;
10967 }
10968
10969 /* Search for the following register name in each of the possible reg name
10970 tables. Return the classification if found, or REG_TYPE_MAX if not
10971 present. */
10972 static enum arm_reg_type
10973 arm_reg_parse_any (cp)
10974 char *cp;
10975 {
10976 int i;
10977
10978 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10979 if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
10980 return (enum arm_reg_type) i;
10981
10982 return REG_TYPE_MAX;
10983 }
10984
10985 void
10986 md_apply_fix3 (fixP, valP, seg)
10987 fixS * fixP;
10988 valueT * valP;
10989 segT seg;
10990 {
10991 offsetT value = * valP;
10992 offsetT newval;
10993 unsigned int newimm;
10994 unsigned long temp;
10995 int sign;
10996 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
10997 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
10998
10999 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
11000
11001 /* Note whether this will delete the relocation. */
11002 #if 0
11003 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
11004 doesn't work fully.) */
11005 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
11006 && !fixP->fx_pcrel)
11007 #else
11008 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
11009 #endif
11010 fixP->fx_done = 1;
11011
11012 /* If this symbol is in a different section then we need to leave it for
11013 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
11014 so we have to undo it's effects here. */
11015 if (fixP->fx_pcrel)
11016 {
11017 if (fixP->fx_addsy != NULL
11018 && S_IS_DEFINED (fixP->fx_addsy)
11019 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
11020 {
11021 if (target_oabi
11022 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
11023 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
11024 ))
11025 value = 0;
11026 else
11027 value += md_pcrel_from (fixP);
11028 }
11029 }
11030
11031 /* Remember value for emit_reloc. */
11032 fixP->fx_addnumber = value;
11033
11034 switch (fixP->fx_r_type)
11035 {
11036 case BFD_RELOC_ARM_IMMEDIATE:
11037 newimm = validate_immediate (value);
11038 temp = md_chars_to_number (buf, INSN_SIZE);
11039
11040 /* If the instruction will fail, see if we can fix things up by
11041 changing the opcode. */
11042 if (newimm == (unsigned int) FAIL
11043 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
11044 {
11045 as_bad_where (fixP->fx_file, fixP->fx_line,
11046 _("invalid constant (%lx) after fixup"),
11047 (unsigned long) value);
11048 break;
11049 }
11050
11051 newimm |= (temp & 0xfffff000);
11052 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11053 fixP->fx_done = 1;
11054 break;
11055
11056 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11057 {
11058 unsigned int highpart = 0;
11059 unsigned int newinsn = 0xe1a00000; /* nop. */
11060
11061 newimm = validate_immediate (value);
11062 temp = md_chars_to_number (buf, INSN_SIZE);
11063
11064 /* If the instruction will fail, see if we can fix things up by
11065 changing the opcode. */
11066 if (newimm == (unsigned int) FAIL
11067 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
11068 {
11069 /* No ? OK - try using two ADD instructions to generate
11070 the value. */
11071 newimm = validate_immediate_twopart (value, & highpart);
11072
11073 /* Yes - then make sure that the second instruction is
11074 also an add. */
11075 if (newimm != (unsigned int) FAIL)
11076 newinsn = temp;
11077 /* Still No ? Try using a negated value. */
11078 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
11079 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
11080 /* Otherwise - give up. */
11081 else
11082 {
11083 as_bad_where (fixP->fx_file, fixP->fx_line,
11084 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
11085 (long) value);
11086 break;
11087 }
11088
11089 /* Replace the first operand in the 2nd instruction (which
11090 is the PC) with the destination register. We have
11091 already added in the PC in the first instruction and we
11092 do not want to do it again. */
11093 newinsn &= ~ 0xf0000;
11094 newinsn |= ((newinsn & 0x0f000) << 4);
11095 }
11096
11097 newimm |= (temp & 0xfffff000);
11098 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11099
11100 highpart |= (newinsn & 0xfffff000);
11101 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
11102 }
11103 break;
11104
11105 case BFD_RELOC_ARM_OFFSET_IMM:
11106 sign = value >= 0;
11107
11108 if (value < 0)
11109 value = - value;
11110
11111 if (validate_offset_imm (value, 0) == FAIL)
11112 {
11113 as_bad_where (fixP->fx_file, fixP->fx_line,
11114 _("bad immediate value for offset (%ld)"),
11115 (long) value);
11116 break;
11117 }
11118
11119 newval = md_chars_to_number (buf, INSN_SIZE);
11120 newval &= 0xff7ff000;
11121 newval |= value | (sign ? INDEX_UP : 0);
11122 md_number_to_chars (buf, newval, INSN_SIZE);
11123 break;
11124
11125 case BFD_RELOC_ARM_OFFSET_IMM8:
11126 case BFD_RELOC_ARM_HWLITERAL:
11127 sign = value >= 0;
11128
11129 if (value < 0)
11130 value = - value;
11131
11132 if (validate_offset_imm (value, 1) == FAIL)
11133 {
11134 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
11135 as_bad_where (fixP->fx_file, fixP->fx_line,
11136 _("invalid literal constant: pool needs to be closer"));
11137 else
11138 as_bad (_("bad immediate value for half-word offset (%ld)"),
11139 (long) value);
11140 break;
11141 }
11142
11143 newval = md_chars_to_number (buf, INSN_SIZE);
11144 newval &= 0xff7ff0f0;
11145 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
11146 md_number_to_chars (buf, newval, INSN_SIZE);
11147 break;
11148
11149 case BFD_RELOC_ARM_LITERAL:
11150 sign = value >= 0;
11151
11152 if (value < 0)
11153 value = - value;
11154
11155 if (validate_offset_imm (value, 0) == FAIL)
11156 {
11157 as_bad_where (fixP->fx_file, fixP->fx_line,
11158 _("invalid literal constant: pool needs to be closer"));
11159 break;
11160 }
11161
11162 newval = md_chars_to_number (buf, INSN_SIZE);
11163 newval &= 0xff7ff000;
11164 newval |= value | (sign ? INDEX_UP : 0);
11165 md_number_to_chars (buf, newval, INSN_SIZE);
11166 break;
11167
11168 case BFD_RELOC_ARM_SHIFT_IMM:
11169 newval = md_chars_to_number (buf, INSN_SIZE);
11170 if (((unsigned long) value) > 32
11171 || (value == 32
11172 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
11173 {
11174 as_bad_where (fixP->fx_file, fixP->fx_line,
11175 _("shift expression is too large"));
11176 break;
11177 }
11178
11179 if (value == 0)
11180 /* Shifts of zero must be done as lsl. */
11181 newval &= ~0x60;
11182 else if (value == 32)
11183 value = 0;
11184 newval &= 0xfffff07f;
11185 newval |= (value & 0x1f) << 7;
11186 md_number_to_chars (buf, newval, INSN_SIZE);
11187 break;
11188
11189 case BFD_RELOC_ARM_SWI:
11190 if (arm_data->thumb_mode)
11191 {
11192 if (((unsigned long) value) > 0xff)
11193 as_bad_where (fixP->fx_file, fixP->fx_line,
11194 _("invalid swi expression"));
11195 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
11196 newval |= value;
11197 md_number_to_chars (buf, newval, THUMB_SIZE);
11198 }
11199 else
11200 {
11201 if (((unsigned long) value) > 0x00ffffff)
11202 as_bad_where (fixP->fx_file, fixP->fx_line,
11203 _("invalid swi expression"));
11204 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
11205 newval |= value;
11206 md_number_to_chars (buf, newval, INSN_SIZE);
11207 }
11208 break;
11209
11210 case BFD_RELOC_ARM_MULTI:
11211 if (((unsigned long) value) > 0xffff)
11212 as_bad_where (fixP->fx_file, fixP->fx_line,
11213 _("invalid expression in load/store multiple"));
11214 newval = value | md_chars_to_number (buf, INSN_SIZE);
11215 md_number_to_chars (buf, newval, INSN_SIZE);
11216 break;
11217
11218 case BFD_RELOC_ARM_PCREL_BRANCH:
11219 newval = md_chars_to_number (buf, INSN_SIZE);
11220
11221 /* Sign-extend a 24-bit number. */
11222 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
11223
11224 #ifdef OBJ_ELF
11225 if (! target_oabi)
11226 value = fixP->fx_offset;
11227 #endif
11228
11229 /* We are going to store value (shifted right by two) in the
11230 instruction, in a 24 bit, signed field. Thus we need to check
11231 that none of the top 8 bits of the shifted value (top 7 bits of
11232 the unshifted, unsigned value) are set, or that they are all set. */
11233 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
11234 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
11235 {
11236 #ifdef OBJ_ELF
11237 /* Normally we would be stuck at this point, since we cannot store
11238 the absolute address that is the destination of the branch in the
11239 24 bits of the branch instruction. If however, we happen to know
11240 that the destination of the branch is in the same section as the
11241 branch instruction itself, then we can compute the relocation for
11242 ourselves and not have to bother the linker with it.
11243
11244 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
11245 because I have not worked out how to do this for OBJ_COFF or
11246 target_oabi. */
11247 if (! target_oabi
11248 && fixP->fx_addsy != NULL
11249 && S_IS_DEFINED (fixP->fx_addsy)
11250 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
11251 {
11252 /* Get pc relative value to go into the branch. */
11253 value = * valP;
11254
11255 /* Permit a backward branch provided that enough bits
11256 are set. Allow a forwards branch, provided that
11257 enough bits are clear. */
11258 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
11259 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
11260 fixP->fx_done = 1;
11261 }
11262
11263 if (! fixP->fx_done)
11264 #endif
11265 as_bad_where (fixP->fx_file, fixP->fx_line,
11266 _("GAS can't handle same-section branch dest >= 0x04000000"));
11267 }
11268
11269 value >>= 2;
11270 value += SEXT24 (newval);
11271
11272 if ( (value & ~ ((offsetT) 0xffffff)) != 0
11273 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
11274 as_bad_where (fixP->fx_file, fixP->fx_line,
11275 _("out of range branch"));
11276
11277 newval = (value & 0x00ffffff) | (newval & 0xff000000);
11278 md_number_to_chars (buf, newval, INSN_SIZE);
11279 break;
11280
11281 case BFD_RELOC_ARM_PCREL_BLX:
11282 {
11283 offsetT hbit;
11284 newval = md_chars_to_number (buf, INSN_SIZE);
11285
11286 #ifdef OBJ_ELF
11287 if (! target_oabi)
11288 value = fixP->fx_offset;
11289 #endif
11290 hbit = (value >> 1) & 1;
11291 value = (value >> 2) & 0x00ffffff;
11292 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
11293 newval = value | (newval & 0xfe000000) | (hbit << 24);
11294 md_number_to_chars (buf, newval, INSN_SIZE);
11295 }
11296 break;
11297
11298 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
11299 newval = md_chars_to_number (buf, THUMB_SIZE);
11300 {
11301 addressT diff = (newval & 0xff) << 1;
11302 if (diff & 0x100)
11303 diff |= ~0xff;
11304
11305 value += diff;
11306 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
11307 as_bad_where (fixP->fx_file, fixP->fx_line,
11308 _("branch out of range"));
11309 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
11310 }
11311 md_number_to_chars (buf, newval, THUMB_SIZE);
11312 break;
11313
11314 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
11315 newval = md_chars_to_number (buf, THUMB_SIZE);
11316 {
11317 addressT diff = (newval & 0x7ff) << 1;
11318 if (diff & 0x800)
11319 diff |= ~0x7ff;
11320
11321 value += diff;
11322 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
11323 as_bad_where (fixP->fx_file, fixP->fx_line,
11324 _("branch out of range"));
11325 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
11326 }
11327 md_number_to_chars (buf, newval, THUMB_SIZE);
11328 break;
11329
11330 case BFD_RELOC_THUMB_PCREL_BLX:
11331 case BFD_RELOC_THUMB_PCREL_BRANCH23:
11332 {
11333 offsetT newval2;
11334 addressT diff;
11335
11336 newval = md_chars_to_number (buf, THUMB_SIZE);
11337 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11338 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
11339 if (diff & 0x400000)
11340 diff |= ~0x3fffff;
11341 #ifdef OBJ_ELF
11342 value = fixP->fx_offset;
11343 #endif
11344 value += diff;
11345
11346 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
11347 as_bad_where (fixP->fx_file, fixP->fx_line,
11348 _("branch with link out of range"));
11349
11350 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
11351 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
11352 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
11353 /* For a BLX instruction, make sure that the relocation is rounded up
11354 to a word boundary. This follows the semantics of the instruction
11355 which specifies that bit 1 of the target address will come from bit
11356 1 of the base address. */
11357 newval2 = (newval2 + 1) & ~ 1;
11358 md_number_to_chars (buf, newval, THUMB_SIZE);
11359 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11360 }
11361 break;
11362
11363 case BFD_RELOC_8:
11364 if (fixP->fx_done || fixP->fx_pcrel)
11365 md_number_to_chars (buf, value, 1);
11366 #ifdef OBJ_ELF
11367 else if (!target_oabi)
11368 {
11369 value = fixP->fx_offset;
11370 md_number_to_chars (buf, value, 1);
11371 }
11372 #endif
11373 break;
11374
11375 case BFD_RELOC_16:
11376 if (fixP->fx_done || fixP->fx_pcrel)
11377 md_number_to_chars (buf, value, 2);
11378 #ifdef OBJ_ELF
11379 else if (!target_oabi)
11380 {
11381 value = fixP->fx_offset;
11382 md_number_to_chars (buf, value, 2);
11383 }
11384 #endif
11385 break;
11386
11387 #ifdef OBJ_ELF
11388 case BFD_RELOC_ARM_GOT32:
11389 case BFD_RELOC_ARM_GOTOFF:
11390 md_number_to_chars (buf, 0, 4);
11391 break;
11392 #endif
11393
11394 case BFD_RELOC_RVA:
11395 case BFD_RELOC_32:
11396 if (fixP->fx_done || fixP->fx_pcrel)
11397 md_number_to_chars (buf, value, 4);
11398 #ifdef OBJ_ELF
11399 else if (!target_oabi)
11400 {
11401 value = fixP->fx_offset;
11402 md_number_to_chars (buf, value, 4);
11403 }
11404 #endif
11405 break;
11406
11407 #ifdef OBJ_ELF
11408 case BFD_RELOC_ARM_PLT32:
11409 /* It appears the instruction is fully prepared at this point. */
11410 break;
11411 #endif
11412
11413 case BFD_RELOC_ARM_CP_OFF_IMM:
11414 sign = value >= 0;
11415 if (value < -1023 || value > 1023 || (value & 3))
11416 as_bad_where (fixP->fx_file, fixP->fx_line,
11417 _("illegal value for co-processor offset"));
11418 if (value < 0)
11419 value = -value;
11420 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11421 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
11422 md_number_to_chars (buf, newval, INSN_SIZE);
11423 break;
11424
11425 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
11426 sign = value >= 0;
11427 if (value < -255 || value > 255)
11428 as_bad_where (fixP->fx_file, fixP->fx_line,
11429 _("Illegal value for co-processor offset"));
11430 if (value < 0)
11431 value = -value;
11432 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11433 newval |= value | (sign ? INDEX_UP : 0);
11434 md_number_to_chars (buf, newval , INSN_SIZE);
11435 break;
11436
11437 case BFD_RELOC_ARM_THUMB_OFFSET:
11438 newval = md_chars_to_number (buf, THUMB_SIZE);
11439 /* Exactly what ranges, and where the offset is inserted depends
11440 on the type of instruction, we can establish this from the
11441 top 4 bits. */
11442 switch (newval >> 12)
11443 {
11444 case 4: /* PC load. */
11445 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
11446 forced to zero for these loads, so we will need to round
11447 up the offset if the instruction address is not word
11448 aligned (since the final address produced must be, and
11449 we can only describe word-aligned immediate offsets). */
11450
11451 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
11452 as_bad_where (fixP->fx_file, fixP->fx_line,
11453 _("invalid offset, target not word aligned (0x%08X)"),
11454 (unsigned int) (fixP->fx_frag->fr_address
11455 + fixP->fx_where + value));
11456
11457 if ((value + 2) & ~0x3fe)
11458 as_bad_where (fixP->fx_file, fixP->fx_line,
11459 _("invalid offset, value too big (0x%08lX)"),
11460 (long) value);
11461
11462 /* Round up, since pc will be rounded down. */
11463 newval |= (value + 2) >> 2;
11464 break;
11465
11466 case 9: /* SP load/store. */
11467 if (value & ~0x3fc)
11468 as_bad_where (fixP->fx_file, fixP->fx_line,
11469 _("invalid offset, value too big (0x%08lX)"),
11470 (long) value);
11471 newval |= value >> 2;
11472 break;
11473
11474 case 6: /* Word load/store. */
11475 if (value & ~0x7c)
11476 as_bad_where (fixP->fx_file, fixP->fx_line,
11477 _("invalid offset, value too big (0x%08lX)"),
11478 (long) value);
11479 newval |= value << 4; /* 6 - 2. */
11480 break;
11481
11482 case 7: /* Byte load/store. */
11483 if (value & ~0x1f)
11484 as_bad_where (fixP->fx_file, fixP->fx_line,
11485 _("invalid offset, value too big (0x%08lX)"),
11486 (long) value);
11487 newval |= value << 6;
11488 break;
11489
11490 case 8: /* Halfword load/store. */
11491 if (value & ~0x3e)
11492 as_bad_where (fixP->fx_file, fixP->fx_line,
11493 _("invalid offset, value too big (0x%08lX)"),
11494 (long) value);
11495 newval |= value << 5; /* 6 - 1. */
11496 break;
11497
11498 default:
11499 as_bad_where (fixP->fx_file, fixP->fx_line,
11500 "Unable to process relocation for thumb opcode: %lx",
11501 (unsigned long) newval);
11502 break;
11503 }
11504 md_number_to_chars (buf, newval, THUMB_SIZE);
11505 break;
11506
11507 case BFD_RELOC_ARM_THUMB_ADD:
11508 /* This is a complicated relocation, since we use it for all of
11509 the following immediate relocations:
11510
11511 3bit ADD/SUB
11512 8bit ADD/SUB
11513 9bit ADD/SUB SP word-aligned
11514 10bit ADD PC/SP word-aligned
11515
11516 The type of instruction being processed is encoded in the
11517 instruction field:
11518
11519 0x8000 SUB
11520 0x00F0 Rd
11521 0x000F Rs
11522 */
11523 newval = md_chars_to_number (buf, THUMB_SIZE);
11524 {
11525 int rd = (newval >> 4) & 0xf;
11526 int rs = newval & 0xf;
11527 int subtract = newval & 0x8000;
11528
11529 if (rd == REG_SP)
11530 {
11531 if (value & ~0x1fc)
11532 as_bad_where (fixP->fx_file, fixP->fx_line,
11533 _("invalid immediate for stack address calculation"));
11534 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
11535 newval |= value >> 2;
11536 }
11537 else if (rs == REG_PC || rs == REG_SP)
11538 {
11539 if (subtract ||
11540 value & ~0x3fc)
11541 as_bad_where (fixP->fx_file, fixP->fx_line,
11542 _("invalid immediate for address calculation (value = 0x%08lX)"),
11543 (unsigned long) value);
11544 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
11545 newval |= rd << 8;
11546 newval |= value >> 2;
11547 }
11548 else if (rs == rd)
11549 {
11550 if (value & ~0xff)
11551 as_bad_where (fixP->fx_file, fixP->fx_line,
11552 _("invalid 8bit immediate"));
11553 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
11554 newval |= (rd << 8) | value;
11555 }
11556 else
11557 {
11558 if (value & ~0x7)
11559 as_bad_where (fixP->fx_file, fixP->fx_line,
11560 _("invalid 3bit immediate"));
11561 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
11562 newval |= rd | (rs << 3) | (value << 6);
11563 }
11564 }
11565 md_number_to_chars (buf, newval, THUMB_SIZE);
11566 break;
11567
11568 case BFD_RELOC_ARM_THUMB_IMM:
11569 newval = md_chars_to_number (buf, THUMB_SIZE);
11570 switch (newval >> 11)
11571 {
11572 case 0x04: /* 8bit immediate MOV. */
11573 case 0x05: /* 8bit immediate CMP. */
11574 if (value < 0 || value > 255)
11575 as_bad_where (fixP->fx_file, fixP->fx_line,
11576 _("invalid immediate: %ld is too large"),
11577 (long) value);
11578 newval |= value;
11579 break;
11580
11581 default:
11582 abort ();
11583 }
11584 md_number_to_chars (buf, newval, THUMB_SIZE);
11585 break;
11586
11587 case BFD_RELOC_ARM_THUMB_SHIFT:
11588 /* 5bit shift value (0..31). */
11589 if (value < 0 || value > 31)
11590 as_bad_where (fixP->fx_file, fixP->fx_line,
11591 _("illegal Thumb shift value: %ld"), (long) value);
11592 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
11593 newval |= value << 6;
11594 md_number_to_chars (buf, newval, THUMB_SIZE);
11595 break;
11596
11597 case BFD_RELOC_VTABLE_INHERIT:
11598 case BFD_RELOC_VTABLE_ENTRY:
11599 fixP->fx_done = 0;
11600 return;
11601
11602 case BFD_RELOC_NONE:
11603 default:
11604 as_bad_where (fixP->fx_file, fixP->fx_line,
11605 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
11606 }
11607 }
11608
11609 /* Translate internal representation of relocation info to BFD target
11610 format. */
11611
11612 arelent *
11613 tc_gen_reloc (section, fixp)
11614 asection * section ATTRIBUTE_UNUSED;
11615 fixS * fixp;
11616 {
11617 arelent * reloc;
11618 bfd_reloc_code_real_type code;
11619
11620 reloc = (arelent *) xmalloc (sizeof (arelent));
11621
11622 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
11623 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
11624 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
11625
11626 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
11627 #ifndef OBJ_ELF
11628 if (fixp->fx_pcrel == 0)
11629 reloc->addend = fixp->fx_offset;
11630 else
11631 reloc->addend = fixp->fx_offset = reloc->address;
11632 #else /* OBJ_ELF */
11633 reloc->addend = fixp->fx_offset;
11634 #endif
11635
11636 switch (fixp->fx_r_type)
11637 {
11638 case BFD_RELOC_8:
11639 if (fixp->fx_pcrel)
11640 {
11641 code = BFD_RELOC_8_PCREL;
11642 break;
11643 }
11644
11645 case BFD_RELOC_16:
11646 if (fixp->fx_pcrel)
11647 {
11648 code = BFD_RELOC_16_PCREL;
11649 break;
11650 }
11651
11652 case BFD_RELOC_32:
11653 if (fixp->fx_pcrel)
11654 {
11655 code = BFD_RELOC_32_PCREL;
11656 break;
11657 }
11658
11659 case BFD_RELOC_ARM_PCREL_BRANCH:
11660 case BFD_RELOC_ARM_PCREL_BLX:
11661 case BFD_RELOC_RVA:
11662 case BFD_RELOC_THUMB_PCREL_BRANCH9:
11663 case BFD_RELOC_THUMB_PCREL_BRANCH12:
11664 case BFD_RELOC_THUMB_PCREL_BRANCH23:
11665 case BFD_RELOC_THUMB_PCREL_BLX:
11666 case BFD_RELOC_VTABLE_ENTRY:
11667 case BFD_RELOC_VTABLE_INHERIT:
11668 code = fixp->fx_r_type;
11669 break;
11670
11671 case BFD_RELOC_ARM_LITERAL:
11672 case BFD_RELOC_ARM_HWLITERAL:
11673 /* If this is called then the a literal has
11674 been referenced across a section boundary. */
11675 as_bad_where (fixp->fx_file, fixp->fx_line,
11676 _("literal referenced across section boundary"));
11677 return NULL;
11678
11679 #ifdef OBJ_ELF
11680 case BFD_RELOC_ARM_GOT32:
11681 case BFD_RELOC_ARM_GOTOFF:
11682 case BFD_RELOC_ARM_PLT32:
11683 code = fixp->fx_r_type;
11684 break;
11685 #endif
11686
11687 case BFD_RELOC_ARM_IMMEDIATE:
11688 as_bad_where (fixp->fx_file, fixp->fx_line,
11689 _("internal relocation (type: IMMEDIATE) not fixed up"));
11690 return NULL;
11691
11692 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11693 as_bad_where (fixp->fx_file, fixp->fx_line,
11694 _("ADRL used for a symbol not defined in the same file"));
11695 return NULL;
11696
11697 case BFD_RELOC_ARM_OFFSET_IMM:
11698 as_bad_where (fixp->fx_file, fixp->fx_line,
11699 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
11700 return NULL;
11701
11702 default:
11703 {
11704 char * type;
11705
11706 switch (fixp->fx_r_type)
11707 {
11708 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
11709 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
11710 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
11711 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
11712 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
11713 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
11714 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
11715 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
11716 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
11717 default: type = _("<unknown>"); break;
11718 }
11719 as_bad_where (fixp->fx_file, fixp->fx_line,
11720 _("cannot represent %s relocation in this object file format"),
11721 type);
11722 return NULL;
11723 }
11724 }
11725
11726 #ifdef OBJ_ELF
11727 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
11728 && GOT_symbol
11729 && fixp->fx_addsy == GOT_symbol)
11730 {
11731 code = BFD_RELOC_ARM_GOTPC;
11732 reloc->addend = fixp->fx_offset = reloc->address;
11733 }
11734 #endif
11735
11736 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
11737
11738 if (reloc->howto == NULL)
11739 {
11740 as_bad_where (fixp->fx_file, fixp->fx_line,
11741 _("cannot represent %s relocation in this object file format"),
11742 bfd_get_reloc_code_name (code));
11743 return NULL;
11744 }
11745
11746 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
11747 vtable entry to be used in the relocation's section offset. */
11748 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
11749 reloc->address = fixp->fx_offset;
11750
11751 return reloc;
11752 }
11753
11754 int
11755 md_estimate_size_before_relax (fragP, segtype)
11756 fragS * fragP ATTRIBUTE_UNUSED;
11757 segT segtype ATTRIBUTE_UNUSED;
11758 {
11759 as_fatal (_("md_estimate_size_before_relax\n"));
11760 return 1;
11761 }
11762
11763 static void
11764 output_inst (str)
11765 const char *str;
11766 {
11767 char * to = NULL;
11768
11769 if (inst.error)
11770 {
11771 as_bad ("%s -- `%s'", inst.error, str);
11772 return;
11773 }
11774
11775 to = frag_more (inst.size);
11776
11777 if (thumb_mode && (inst.size > THUMB_SIZE))
11778 {
11779 assert (inst.size == (2 * THUMB_SIZE));
11780 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
11781 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
11782 }
11783 else if (inst.size > INSN_SIZE)
11784 {
11785 assert (inst.size == (2 * INSN_SIZE));
11786 md_number_to_chars (to, inst.instruction, INSN_SIZE);
11787 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
11788 }
11789 else
11790 md_number_to_chars (to, inst.instruction, inst.size);
11791
11792 if (inst.reloc.type != BFD_RELOC_NONE)
11793 fix_new_arm (frag_now, to - frag_now->fr_literal,
11794 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
11795 inst.reloc.type);
11796
11797 #ifdef OBJ_ELF
11798 dwarf2_emit_insn (inst.size);
11799 #endif
11800 }
11801
11802 void
11803 md_assemble (str)
11804 char * str;
11805 {
11806 char c;
11807 char *p;
11808 char *start;
11809
11810 /* Align the instruction.
11811 This may not be the right thing to do but ... */
11812 #if 0
11813 arm_align (2, 0);
11814 #endif
11815
11816 /* Align the previous label if needed. */
11817 if (last_label_seen != NULL)
11818 {
11819 symbol_set_frag (last_label_seen, frag_now);
11820 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
11821 S_SET_SEGMENT (last_label_seen, now_seg);
11822 }
11823
11824 memset (&inst, '\0', sizeof (inst));
11825 inst.reloc.type = BFD_RELOC_NONE;
11826
11827 skip_whitespace (str);
11828
11829 /* Scan up to the end of the op-code, which must end in white space or
11830 end of string. */
11831 for (start = p = str; *p != '\0'; p++)
11832 if (*p == ' ')
11833 break;
11834
11835 if (p == str)
11836 {
11837 as_bad (_("no operator -- statement `%s'\n"), str);
11838 return;
11839 }
11840
11841 if (thumb_mode)
11842 {
11843 const struct thumb_opcode * opcode;
11844
11845 c = *p;
11846 *p = '\0';
11847 opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
11848 *p = c;
11849
11850 if (opcode)
11851 {
11852 /* Check that this instruction is supported for this CPU. */
11853 if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
11854 {
11855 as_bad (_("selected processor does not support `%s'"), str);
11856 return;
11857 }
11858
11859 mapping_state (MAP_THUMB);
11860 inst.instruction = opcode->value;
11861 inst.size = opcode->size;
11862 (*opcode->parms) (p);
11863 output_inst (str);
11864 return;
11865 }
11866 }
11867 else
11868 {
11869 const struct asm_opcode * opcode;
11870
11871 c = *p;
11872 *p = '\0';
11873 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
11874 *p = c;
11875
11876 if (opcode)
11877 {
11878 /* Check that this instruction is supported for this CPU. */
11879 if ((opcode->variant & cpu_variant) == 0)
11880 {
11881 as_bad (_("selected processor does not support `%s'"), str);
11882 return;
11883 }
11884
11885 mapping_state (MAP_ARM);
11886 inst.instruction = opcode->value;
11887 inst.size = INSN_SIZE;
11888 (*opcode->parms) (p);
11889 output_inst (str);
11890 return;
11891 }
11892 }
11893
11894 /* It wasn't an instruction, but it might be a register alias of the form
11895 alias .req reg. */
11896 if (create_register_alias (str, p))
11897 return;
11898
11899 as_bad (_("bad instruction `%s'"), start);
11900 }
11901
11902 /* md_parse_option
11903 Invocation line includes a switch not recognized by the base assembler.
11904 See if it's a processor-specific option.
11905
11906 This routine is somewhat complicated by the need for backwards
11907 compatibility (since older releases of gcc can't be changed).
11908 The new options try to make the interface as compatible as
11909 possible with GCC.
11910
11911 New options (supported) are:
11912
11913 -mcpu=<cpu name> Assemble for selected processor
11914 -march=<architecture name> Assemble for selected architecture
11915 -mfpu=<fpu architecture> Assemble for selected FPU.
11916 -EB/-mbig-endian Big-endian
11917 -EL/-mlittle-endian Little-endian
11918 -k Generate PIC code
11919 -mthumb Start in Thumb mode
11920 -mthumb-interwork Code supports ARM/Thumb interworking
11921
11922 For now we will also provide support for:
11923
11924 -mapcs-32 32-bit Program counter
11925 -mapcs-26 26-bit Program counter
11926 -macps-float Floats passed in FP registers
11927 -mapcs-reentrant Reentrant code
11928 -matpcs
11929 (sometime these will probably be replaced with -mapcs=<list of options>
11930 and -matpcs=<list of options>)
11931
11932 The remaining options are only supported for back-wards compatibility.
11933 Cpu variants, the arm part is optional:
11934 -m[arm]1 Currently not supported.
11935 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
11936 -m[arm]3 Arm 3 processor
11937 -m[arm]6[xx], Arm 6 processors
11938 -m[arm]7[xx][t][[d]m] Arm 7 processors
11939 -m[arm]8[10] Arm 8 processors
11940 -m[arm]9[20][tdmi] Arm 9 processors
11941 -mstrongarm[110[0]] StrongARM processors
11942 -mxscale XScale processors
11943 -m[arm]v[2345[t[e]]] Arm architectures
11944 -mall All (except the ARM1)
11945 FP variants:
11946 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
11947 -mfpe-old (No float load/store multiples)
11948 -mvfpxd VFP Single precision
11949 -mvfp All VFP
11950 -mno-fpu Disable all floating point instructions
11951
11952 The following CPU names are recognized:
11953 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
11954 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
11955 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
11956 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
11957 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
11958 arm10t arm10e, arm1020t, arm1020e, arm10200e,
11959 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
11960
11961 */
11962
11963 const char * md_shortopts = "m:k";
11964
11965 #ifdef ARM_BI_ENDIAN
11966 #define OPTION_EB (OPTION_MD_BASE + 0)
11967 #define OPTION_EL (OPTION_MD_BASE + 1)
11968 #else
11969 #if TARGET_BYTES_BIG_ENDIAN
11970 #define OPTION_EB (OPTION_MD_BASE + 0)
11971 #else
11972 #define OPTION_EL (OPTION_MD_BASE + 1)
11973 #endif
11974 #endif
11975
11976 struct option md_longopts[] =
11977 {
11978 #ifdef OPTION_EB
11979 {"EB", no_argument, NULL, OPTION_EB},
11980 #endif
11981 #ifdef OPTION_EL
11982 {"EL", no_argument, NULL, OPTION_EL},
11983 #endif
11984 {NULL, no_argument, NULL, 0}
11985 };
11986
11987 size_t md_longopts_size = sizeof (md_longopts);
11988
11989 struct arm_option_table
11990 {
11991 char *option; /* Option name to match. */
11992 char *help; /* Help information. */
11993 int *var; /* Variable to change. */
11994 int value; /* What to change it to. */
11995 char *deprecated; /* If non-null, print this message. */
11996 };
11997
11998 struct arm_option_table arm_opts[] =
11999 {
12000 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
12001 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
12002 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
12003 &support_interwork, 1, NULL},
12004 {"moabi", N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
12005 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
12006 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
12007 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
12008 1, NULL},
12009 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
12010 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
12011 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
12012 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
12013 NULL},
12014
12015 /* These are recognized by the assembler, but have no affect on code. */
12016 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
12017 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
12018
12019 /* DON'T add any new processors to this list -- we want the whole list
12020 to go away... Add them to the processors table instead. */
12021 {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
12022 {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
12023 {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
12024 {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
12025 {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12026 {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12027 {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12028 {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12029 {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
12030 {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
12031 {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
12032 {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
12033 {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
12034 {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
12035 {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
12036 {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
12037 {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
12038 {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
12039 {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
12040 {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
12041 {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
12042 {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
12043 {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
12044 {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
12045 {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
12046 {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
12047 {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
12048 {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
12049 {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
12050 {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
12051 {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
12052 {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
12053 {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
12054 {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
12055 {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12056 {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12057 {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12058 {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12059 {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12060 {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12061 {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
12062 {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
12063 {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
12064 {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
12065 {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
12066 {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
12067 {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12068 {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12069 {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12070 {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12071 {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12072 {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12073 {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12074 {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12075 {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12076 {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12077 {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
12078 {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
12079 {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
12080 {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
12081 {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12082 {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12083 {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12084 {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12085 {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12086 {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12087 {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12088 {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12089 {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
12090 {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
12091 N_("use -mcpu=strongarm110")},
12092 {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
12093 N_("use -mcpu=strongarm1100")},
12094 {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
12095 N_("use -mcpu=strongarm1110")},
12096 {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
12097 {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
12098 {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
12099
12100 /* Architecture variants -- don't add any more to this list either. */
12101 {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
12102 {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
12103 {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12104 {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12105 {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
12106 {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
12107 {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12108 {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12109 {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
12110 {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
12111 {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12112 {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12113 {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
12114 {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
12115 {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12116 {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12117 {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12118 {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12119
12120 /* Floating point variants -- don't add any more to this list either. */
12121 {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
12122 {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
12123 {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
12124 {"mno-fpu", NULL, &legacy_fpu, 0,
12125 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
12126
12127 {NULL, NULL, NULL, 0, NULL}
12128 };
12129
12130 struct arm_cpu_option_table
12131 {
12132 char *name;
12133 int value;
12134 /* For some CPUs we assume an FPU unless the user explicitly sets
12135 -mfpu=... */
12136 int default_fpu;
12137 };
12138
12139 /* This list should, at a minimum, contain all the cpu names
12140 recognized by GCC. */
12141 static struct arm_cpu_option_table arm_cpus[] =
12142 {
12143 {"all", ARM_ANY, FPU_ARCH_FPA},
12144 {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA},
12145 {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA},
12146 {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA},
12147 {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA},
12148 {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA},
12149 {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA},
12150 {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA},
12151 {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA},
12152 {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA},
12153 {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA},
12154 {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA},
12155 {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA},
12156 {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA},
12157 {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA},
12158 {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA},
12159 {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA},
12160 {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA},
12161 {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA},
12162 {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA},
12163 {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12164 {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA},
12165 {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12166 {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12167 {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA},
12168 {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA},
12169 {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA},
12170 {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA},
12171 {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12172 {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
12173 {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA},
12174 {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA},
12175 {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA},
12176 {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA},
12177 {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA},
12178 {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA},
12179 {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA},
12180 {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA},
12181 {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA},
12182 {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12183 {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12184 {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12185 {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
12186 /* For V5 or later processors we default to using VFP; but the user
12187 should really set the FPU type explicitly. */
12188 {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12189 {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
12190 {"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
12191 {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12192 {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
12193 {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12194 {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
12195 {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
12196 {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
12197 {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
12198 {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
12199 {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
12200 /* ??? XSCALE is really an architecture. */
12201 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12202 /* ??? iwmmxt is not a processor. */
12203 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
12204 {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12205 /* Maverick */
12206 {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_NONE},
12207 {NULL, 0, 0}
12208 };
12209
12210 struct arm_arch_option_table
12211 {
12212 char *name;
12213 int value;
12214 int default_fpu;
12215 };
12216
12217 /* This list should, at a minimum, contain all the architecture names
12218 recognized by GCC. */
12219 static struct arm_arch_option_table arm_archs[] =
12220 {
12221 {"all", ARM_ANY, FPU_ARCH_FPA},
12222 {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
12223 {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
12224 {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
12225 {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
12226 {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
12227 {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
12228 {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
12229 {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
12230 {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12231 {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
12232 {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
12233 {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
12234 {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
12235 {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
12236 {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
12237 {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
12238 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
12239 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
12240 {NULL, 0, 0}
12241 };
12242
12243 /* ISA extensions in the co-processor space. */
12244 struct arm_arch_extension_table
12245 {
12246 char *name;
12247 int value;
12248 };
12249
12250 static struct arm_arch_extension_table arm_extensions[] =
12251 {
12252 {"maverick", ARM_CEXT_MAVERICK},
12253 {"xscale", ARM_CEXT_XSCALE},
12254 {"iwmmxt", ARM_CEXT_IWMMXT},
12255 {NULL, 0}
12256 };
12257
12258 struct arm_fpu_option_table
12259 {
12260 char *name;
12261 int value;
12262 };
12263
12264 /* This list should, at a minimum, contain all the fpu names
12265 recognized by GCC. */
12266 static struct arm_fpu_option_table arm_fpus[] =
12267 {
12268 {"softfpa", FPU_NONE},
12269 {"fpe", FPU_ARCH_FPE},
12270 {"fpe2", FPU_ARCH_FPE},
12271 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
12272 {"fpa", FPU_ARCH_FPA},
12273 {"fpa10", FPU_ARCH_FPA},
12274 {"fpa11", FPU_ARCH_FPA},
12275 {"arm7500fe", FPU_ARCH_FPA},
12276 {"softvfp", FPU_ARCH_VFP},
12277 {"softvfp+vfp", FPU_ARCH_VFP_V2},
12278 {"vfp", FPU_ARCH_VFP_V2},
12279 {"vfp9", FPU_ARCH_VFP_V2},
12280 {"vfp10", FPU_ARCH_VFP_V2},
12281 {"vfp10-r0", FPU_ARCH_VFP_V1},
12282 {"vfpxd", FPU_ARCH_VFP_V1xD},
12283 {"arm1020t", FPU_ARCH_VFP_V1},
12284 {"arm1020e", FPU_ARCH_VFP_V2},
12285 {NULL, 0}
12286 };
12287
12288 struct arm_long_option_table
12289 {
12290 char *option; /* Substring to match. */
12291 char *help; /* Help information. */
12292 int (*func) PARAMS ((char *subopt)); /* Function to decode sub-option. */
12293 char *deprecated; /* If non-null, print this message. */
12294 };
12295
12296 static int
12297 arm_parse_extension (str, opt_p)
12298 char *str;
12299 int *opt_p;
12300 {
12301 while (str != NULL && *str != 0)
12302 {
12303 struct arm_arch_extension_table *opt;
12304 char *ext;
12305 int optlen;
12306
12307 if (*str != '+')
12308 {
12309 as_bad (_("invalid architectural extension"));
12310 return 0;
12311 }
12312
12313 str++;
12314 ext = strchr (str, '+');
12315
12316 if (ext != NULL)
12317 optlen = ext - str;
12318 else
12319 optlen = strlen (str);
12320
12321 if (optlen == 0)
12322 {
12323 as_bad (_("missing architectural extension"));
12324 return 0;
12325 }
12326
12327 for (opt = arm_extensions; opt->name != NULL; opt++)
12328 if (strncmp (opt->name, str, optlen) == 0)
12329 {
12330 *opt_p |= opt->value;
12331 break;
12332 }
12333
12334 if (opt->name == NULL)
12335 {
12336 as_bad (_("unknown architectural extnsion `%s'"), str);
12337 return 0;
12338 }
12339
12340 str = ext;
12341 };
12342
12343 return 1;
12344 }
12345
12346 static int
12347 arm_parse_cpu (str)
12348 char *str;
12349 {
12350 struct arm_cpu_option_table *opt;
12351 char *ext = strchr (str, '+');
12352 int optlen;
12353
12354 if (ext != NULL)
12355 optlen = ext - str;
12356 else
12357 optlen = strlen (str);
12358
12359 if (optlen == 0)
12360 {
12361 as_bad (_("missing cpu name `%s'"), str);
12362 return 0;
12363 }
12364
12365 for (opt = arm_cpus; opt->name != NULL; opt++)
12366 if (strncmp (opt->name, str, optlen) == 0)
12367 {
12368 mcpu_cpu_opt = opt->value;
12369 mcpu_fpu_opt = opt->default_fpu;
12370
12371 if (ext != NULL)
12372 return arm_parse_extension (ext, &mcpu_cpu_opt);
12373
12374 return 1;
12375 }
12376
12377 as_bad (_("unknown cpu `%s'"), str);
12378 return 0;
12379 }
12380
12381 static int
12382 arm_parse_arch (str)
12383 char *str;
12384 {
12385 struct arm_arch_option_table *opt;
12386 char *ext = strchr (str, '+');
12387 int optlen;
12388
12389 if (ext != NULL)
12390 optlen = ext - str;
12391 else
12392 optlen = strlen (str);
12393
12394 if (optlen == 0)
12395 {
12396 as_bad (_("missing architecture name `%s'"), str);
12397 return 0;
12398 }
12399
12400
12401 for (opt = arm_archs; opt->name != NULL; opt++)
12402 if (strcmp (opt->name, str) == 0)
12403 {
12404 march_cpu_opt = opt->value;
12405 march_fpu_opt = opt->default_fpu;
12406
12407 if (ext != NULL)
12408 return arm_parse_extension (ext, &march_cpu_opt);
12409
12410 return 1;
12411 }
12412
12413 as_bad (_("unknown architecture `%s'\n"), str);
12414 return 0;
12415 }
12416
12417 static int
12418 arm_parse_fpu (str)
12419 char *str;
12420 {
12421 struct arm_fpu_option_table *opt;
12422
12423 for (opt = arm_fpus; opt->name != NULL; opt++)
12424 if (strcmp (opt->name, str) == 0)
12425 {
12426 mfpu_opt = opt->value;
12427 return 1;
12428 }
12429
12430 as_bad (_("unknown floating point format `%s'\n"), str);
12431 return 0;
12432 }
12433
12434 struct arm_long_option_table arm_long_opts[] =
12435 {
12436 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
12437 arm_parse_cpu, NULL},
12438 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
12439 arm_parse_arch, NULL},
12440 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
12441 arm_parse_fpu, NULL},
12442 {NULL, NULL, 0, NULL}
12443 };
12444
12445 int
12446 md_parse_option (c, arg)
12447 int c;
12448 char * arg;
12449 {
12450 struct arm_option_table *opt;
12451 struct arm_long_option_table *lopt;
12452
12453 switch (c)
12454 {
12455 #ifdef OPTION_EB
12456 case OPTION_EB:
12457 target_big_endian = 1;
12458 break;
12459 #endif
12460
12461 #ifdef OPTION_EL
12462 case OPTION_EL:
12463 target_big_endian = 0;
12464 break;
12465 #endif
12466
12467 case 'a':
12468 /* Listing option. Just ignore these, we don't support additional
12469 ones. */
12470 return 0;
12471
12472 default:
12473 for (opt = arm_opts; opt->option != NULL; opt++)
12474 {
12475 if (c == opt->option[0]
12476 && ((arg == NULL && opt->option[1] == 0)
12477 || strcmp (arg, opt->option + 1) == 0))
12478 {
12479 #if WARN_DEPRECATED
12480 /* If the option is deprecated, tell the user. */
12481 if (opt->deprecated != NULL)
12482 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
12483 arg ? arg : "", _(opt->deprecated));
12484 #endif
12485
12486 if (opt->var != NULL)
12487 *opt->var = opt->value;
12488
12489 return 1;
12490 }
12491 }
12492
12493 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
12494 {
12495 /* These options are expected to have an argument. */
12496 if (c == lopt->option[0]
12497 && arg != NULL
12498 && strncmp (arg, lopt->option + 1,
12499 strlen (lopt->option + 1)) == 0)
12500 {
12501 #if WARN_DEPRECATED
12502 /* If the option is deprecated, tell the user. */
12503 if (lopt->deprecated != NULL)
12504 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
12505 _(lopt->deprecated));
12506 #endif
12507
12508 /* Call the sup-option parser. */
12509 return (*lopt->func)(arg + strlen (lopt->option) - 1);
12510 }
12511 }
12512
12513 as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
12514 return 0;
12515 }
12516
12517 return 1;
12518 }
12519
12520 void
12521 md_show_usage (fp)
12522 FILE * fp;
12523 {
12524 struct arm_option_table *opt;
12525 struct arm_long_option_table *lopt;
12526
12527 fprintf (fp, _(" ARM-specific assembler options:\n"));
12528
12529 for (opt = arm_opts; opt->option != NULL; opt++)
12530 if (opt->help != NULL)
12531 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
12532
12533 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
12534 if (lopt->help != NULL)
12535 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
12536
12537 #ifdef OPTION_EB
12538 fprintf (fp, _("\
12539 -EB assemble code for a big-endian cpu\n"));
12540 #endif
12541
12542 #ifdef OPTION_EL
12543 fprintf (fp, _("\
12544 -EL assemble code for a little-endian cpu\n"));
12545 #endif
12546 }
12547
12548 /* We need to be able to fix up arbitrary expressions in some statements.
12549 This is so that we can handle symbols that are an arbitrary distance from
12550 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12551 which returns part of an address in a form which will be valid for
12552 a data instruction. We do this by pushing the expression into a symbol
12553 in the expr_section, and creating a fix for that. */
12554
12555 static void
12556 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
12557 fragS * frag;
12558 int where;
12559 short int size;
12560 expressionS * exp;
12561 int pc_rel;
12562 int reloc;
12563 {
12564 fixS * new_fix;
12565 arm_fix_data * arm_data;
12566
12567 switch (exp->X_op)
12568 {
12569 case O_constant:
12570 case O_symbol:
12571 case O_add:
12572 case O_subtract:
12573 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12574 break;
12575
12576 default:
12577 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12578 pc_rel, reloc);
12579 break;
12580 }
12581
12582 /* Mark whether the fix is to a THUMB instruction, or an ARM
12583 instruction. */
12584 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
12585 new_fix->tc_fix_data = (PTR) arm_data;
12586 arm_data->thumb_mode = thumb_mode;
12587
12588 return;
12589 }
12590
12591 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
12592
12593 void
12594 cons_fix_new_arm (frag, where, size, exp)
12595 fragS * frag;
12596 int where;
12597 int size;
12598 expressionS * exp;
12599 {
12600 bfd_reloc_code_real_type type;
12601 int pcrel = 0;
12602
12603 /* Pick a reloc.
12604 FIXME: @@ Should look at CPU word size. */
12605 switch (size)
12606 {
12607 case 1:
12608 type = BFD_RELOC_8;
12609 break;
12610 case 2:
12611 type = BFD_RELOC_16;
12612 break;
12613 case 4:
12614 default:
12615 type = BFD_RELOC_32;
12616 break;
12617 case 8:
12618 type = BFD_RELOC_64;
12619 break;
12620 }
12621
12622 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
12623 }
12624
12625 /* A good place to do this, although this was probably not intended
12626 for this kind of use. We need to dump the literal pool before
12627 references are made to a null symbol pointer. */
12628
12629 void
12630 arm_cleanup ()
12631 {
12632 literal_pool * pool;
12633
12634 for (pool = list_of_pools; pool; pool = pool->next)
12635 {
12636 /* Put it at the end of the relevent section. */
12637 subseg_set (pool->section, pool->sub_section);
12638 s_ltorg (0);
12639 }
12640 }
12641
12642 void
12643 arm_start_line_hook ()
12644 {
12645 last_label_seen = NULL;
12646 }
12647
12648 void
12649 arm_frob_label (sym)
12650 symbolS * sym;
12651 {
12652 last_label_seen = sym;
12653
12654 ARM_SET_THUMB (sym, thumb_mode);
12655
12656 #if defined OBJ_COFF || defined OBJ_ELF
12657 ARM_SET_INTERWORK (sym, support_interwork);
12658 #endif
12659
12660 /* Note - do not allow local symbols (.Lxxx) to be labeled
12661 as Thumb functions. This is because these labels, whilst
12662 they exist inside Thumb code, are not the entry points for
12663 possible ARM->Thumb calls. Also, these labels can be used
12664 as part of a computed goto or switch statement. eg gcc
12665 can generate code that looks like this:
12666
12667 ldr r2, [pc, .Laaa]
12668 lsl r3, r3, #2
12669 ldr r2, [r3, r2]
12670 mov pc, r2
12671
12672 .Lbbb: .word .Lxxx
12673 .Lccc: .word .Lyyy
12674 ..etc...
12675 .Laaa: .word Lbbb
12676
12677 The first instruction loads the address of the jump table.
12678 The second instruction converts a table index into a byte offset.
12679 The third instruction gets the jump address out of the table.
12680 The fourth instruction performs the jump.
12681
12682 If the address stored at .Laaa is that of a symbol which has the
12683 Thumb_Func bit set, then the linker will arrange for this address
12684 to have the bottom bit set, which in turn would mean that the
12685 address computation performed by the third instruction would end
12686 up with the bottom bit set. Since the ARM is capable of unaligned
12687 word loads, the instruction would then load the incorrect address
12688 out of the jump table, and chaos would ensue. */
12689 if (label_is_thumb_function_name
12690 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
12691 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
12692 {
12693 /* When the address of a Thumb function is taken the bottom
12694 bit of that address should be set. This will allow
12695 interworking between Arm and Thumb functions to work
12696 correctly. */
12697
12698 THUMB_SET_FUNC (sym, 1);
12699
12700 label_is_thumb_function_name = FALSE;
12701 }
12702 }
12703
12704 /* Adjust the symbol table. This marks Thumb symbols as distinct from
12705 ARM ones. */
12706
12707 void
12708 arm_adjust_symtab ()
12709 {
12710 #ifdef OBJ_COFF
12711 symbolS * sym;
12712
12713 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
12714 {
12715 if (ARM_IS_THUMB (sym))
12716 {
12717 if (THUMB_IS_FUNC (sym))
12718 {
12719 /* Mark the symbol as a Thumb function. */
12720 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
12721 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
12722 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
12723
12724 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
12725 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
12726 else
12727 as_bad (_("%s: unexpected function type: %d"),
12728 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
12729 }
12730 else switch (S_GET_STORAGE_CLASS (sym))
12731 {
12732 case C_EXT:
12733 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
12734 break;
12735 case C_STAT:
12736 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
12737 break;
12738 case C_LABEL:
12739 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
12740 break;
12741 default:
12742 /* Do nothing. */
12743 break;
12744 }
12745 }
12746
12747 if (ARM_IS_INTERWORK (sym))
12748 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
12749 }
12750 #endif
12751 #ifdef OBJ_ELF
12752 symbolS * sym;
12753 char bind;
12754
12755 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
12756 {
12757 if (ARM_IS_THUMB (sym))
12758 {
12759 elf_symbol_type * elf_sym;
12760
12761 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
12762 bind = ELF_ST_BIND (elf_sym);
12763
12764 /* If it's a .thumb_func, declare it as so,
12765 otherwise tag label as .code 16. */
12766 if (THUMB_IS_FUNC (sym))
12767 elf_sym->internal_elf_sym.st_info =
12768 ELF_ST_INFO (bind, STT_ARM_TFUNC);
12769 else
12770 elf_sym->internal_elf_sym.st_info =
12771 ELF_ST_INFO (bind, STT_ARM_16BIT);
12772 }
12773 }
12774 #endif
12775 }
12776
12777 int
12778 arm_data_in_code ()
12779 {
12780 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
12781 {
12782 *input_line_pointer = '/';
12783 input_line_pointer += 5;
12784 *input_line_pointer = 0;
12785 return 1;
12786 }
12787
12788 return 0;
12789 }
12790
12791 char *
12792 arm_canonicalize_symbol_name (name)
12793 char * name;
12794 {
12795 int len;
12796
12797 if (thumb_mode && (len = strlen (name)) > 5
12798 && streq (name + len - 5, "/data"))
12799 *(name + len - 5) = 0;
12800
12801 return name;
12802 }
12803
12804 #if defined OBJ_COFF || defined OBJ_ELF
12805 void
12806 arm_validate_fix (fixP)
12807 fixS * fixP;
12808 {
12809 /* If the destination of the branch is a defined symbol which does not have
12810 the THUMB_FUNC attribute, then we must be calling a function which has
12811 the (interfacearm) attribute. We look for the Thumb entry point to that
12812 function and change the branch to refer to that function instead. */
12813 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
12814 && fixP->fx_addsy != NULL
12815 && S_IS_DEFINED (fixP->fx_addsy)
12816 && ! THUMB_IS_FUNC (fixP->fx_addsy))
12817 {
12818 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
12819 }
12820 }
12821 #endif
12822
12823 int
12824 arm_force_relocation (fixp)
12825 struct fix * fixp;
12826 {
12827 #if defined (OBJ_COFF) && defined (TE_PE)
12828 if (fixp->fx_r_type == BFD_RELOC_RVA)
12829 return 1;
12830 #endif
12831 #ifdef OBJ_ELF
12832 if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12833 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12834 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
12835 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
12836 return 1;
12837 #endif
12838
12839 /* Resolve these relocations even if the symbol is extern or weak. */
12840 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
12841 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
12842 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
12843 return 0;
12844
12845 return generic_force_reloc (fixp);
12846 }
12847
12848 #ifdef OBJ_COFF
12849 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
12850 local labels from being added to the output symbol table when they
12851 are used with the ADRL pseudo op. The ADRL relocation should always
12852 be resolved before the binbary is emitted, so it is safe to say that
12853 it is adjustable. */
12854
12855 bfd_boolean
12856 arm_fix_adjustable (fixP)
12857 fixS * fixP;
12858 {
12859 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
12860 return 1;
12861 return 0;
12862 }
12863 #endif
12864
12865 #ifdef OBJ_ELF
12866 /* Relocations against Thumb function names must be left unadjusted,
12867 so that the linker can use this information to correctly set the
12868 bottom bit of their addresses. The MIPS version of this function
12869 also prevents relocations that are mips-16 specific, but I do not
12870 know why it does this.
12871
12872 FIXME:
12873 There is one other problem that ought to be addressed here, but
12874 which currently is not: Taking the address of a label (rather
12875 than a function) and then later jumping to that address. Such
12876 addresses also ought to have their bottom bit set (assuming that
12877 they reside in Thumb code), but at the moment they will not. */
12878
12879 bfd_boolean
12880 arm_fix_adjustable (fixP)
12881 fixS * fixP;
12882 {
12883 if (fixP->fx_addsy == NULL)
12884 return 1;
12885
12886 if (THUMB_IS_FUNC (fixP->fx_addsy)
12887 && fixP->fx_subsy == NULL)
12888 return 0;
12889
12890 /* We need the symbol name for the VTABLE entries. */
12891 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
12892 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12893 return 0;
12894
12895 /* Don't allow symbols to be discarded on GOT related relocs. */
12896 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
12897 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
12898 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
12899 return 0;
12900
12901 return 1;
12902 }
12903
12904 const char *
12905 elf32_arm_target_format ()
12906 {
12907 if (target_big_endian)
12908 {
12909 if (target_oabi)
12910 return "elf32-bigarm-oabi";
12911 else
12912 return "elf32-bigarm";
12913 }
12914 else
12915 {
12916 if (target_oabi)
12917 return "elf32-littlearm-oabi";
12918 else
12919 return "elf32-littlearm";
12920 }
12921 }
12922
12923 void
12924 armelf_frob_symbol (symp, puntp)
12925 symbolS * symp;
12926 int * puntp;
12927 {
12928 elf_frob_symbol (symp, puntp);
12929 }
12930
12931 static bfd_reloc_code_real_type
12932 arm_parse_reloc ()
12933 {
12934 char id [16];
12935 char * ip;
12936 unsigned int i;
12937 static struct
12938 {
12939 char * str;
12940 int len;
12941 bfd_reloc_code_real_type reloc;
12942 }
12943 reloc_map[] =
12944 {
12945 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
12946 MAP ("(got)", BFD_RELOC_ARM_GOT32),
12947 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
12948 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
12949 branch instructions generated by GCC for PLT relocs. */
12950 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
12951 { NULL, 0, BFD_RELOC_UNUSED }
12952 #undef MAP
12953 };
12954
12955 for (i = 0, ip = input_line_pointer;
12956 i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
12957 i++, ip++)
12958 id[i] = TOLOWER (*ip);
12959
12960 for (i = 0; reloc_map[i].str; i++)
12961 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
12962 break;
12963
12964 input_line_pointer += reloc_map[i].len;
12965
12966 return reloc_map[i].reloc;
12967 }
12968
12969 static void
12970 s_arm_elf_cons (nbytes)
12971 int nbytes;
12972 {
12973 expressionS exp;
12974
12975 #ifdef md_flush_pending_output
12976 md_flush_pending_output ();
12977 #endif
12978
12979 if (is_it_end_of_statement ())
12980 {
12981 demand_empty_rest_of_line ();
12982 return;
12983 }
12984
12985 #ifdef md_cons_align
12986 md_cons_align (nbytes);
12987 #endif
12988
12989 mapping_state (MAP_DATA);
12990 do
12991 {
12992 bfd_reloc_code_real_type reloc;
12993
12994 expression (& exp);
12995
12996 if (exp.X_op == O_symbol
12997 && * input_line_pointer == '('
12998 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
12999 {
13000 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
13001 int size = bfd_get_reloc_size (howto);
13002
13003 if (size > nbytes)
13004 as_bad ("%s relocations do not fit in %d bytes",
13005 howto->name, nbytes);
13006 else
13007 {
13008 register char *p = frag_more ((int) nbytes);
13009 int offset = nbytes - size;
13010
13011 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
13012 &exp, 0, reloc);
13013 }
13014 }
13015 else
13016 emit_expr (&exp, (unsigned int) nbytes);
13017 }
13018 while (*input_line_pointer++ == ',');
13019
13020 /* Put terminator back into stream. */
13021 input_line_pointer --;
13022 demand_empty_rest_of_line ();
13023 }
13024
13025 #endif /* OBJ_ELF */
13026
13027 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
13028 of an rs_align_code fragment. */
13029
13030 void
13031 arm_handle_align (fragP)
13032 fragS *fragP;
13033 {
13034 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
13035 static char const thumb_noop[2] = { 0xc0, 0x46 };
13036 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
13037 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
13038
13039 int bytes, fix, noop_size;
13040 char * p;
13041 const char * noop;
13042
13043 if (fragP->fr_type != rs_align_code)
13044 return;
13045
13046 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
13047 p = fragP->fr_literal + fragP->fr_fix;
13048 fix = 0;
13049
13050 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
13051 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
13052
13053 if (fragP->tc_frag_data)
13054 {
13055 if (target_big_endian)
13056 noop = thumb_bigend_noop;
13057 else
13058 noop = thumb_noop;
13059 noop_size = sizeof (thumb_noop);
13060 }
13061 else
13062 {
13063 if (target_big_endian)
13064 noop = arm_bigend_noop;
13065 else
13066 noop = arm_noop;
13067 noop_size = sizeof (arm_noop);
13068 }
13069
13070 if (bytes & (noop_size - 1))
13071 {
13072 fix = bytes & (noop_size - 1);
13073 memset (p, 0, fix);
13074 p += fix;
13075 bytes -= fix;
13076 }
13077
13078 while (bytes >= noop_size)
13079 {
13080 memcpy (p, noop, noop_size);
13081 p += noop_size;
13082 bytes -= noop_size;
13083 fix += noop_size;
13084 }
13085
13086 fragP->fr_fix += fix;
13087 fragP->fr_var = noop_size;
13088 }
13089
13090 /* Called from md_do_align. Used to create an alignment
13091 frag in a code section. */
13092
13093 void
13094 arm_frag_align_code (n, max)
13095 int n;
13096 int max;
13097 {
13098 char * p;
13099
13100 /* We assume that there will never be a requirement
13101 to support alignments greater than 32 bytes. */
13102 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
13103 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
13104
13105 p = frag_var (rs_align_code,
13106 MAX_MEM_FOR_RS_ALIGN_CODE,
13107 1,
13108 (relax_substateT) max,
13109 (symbolS *) NULL,
13110 (offsetT) n,
13111 (char *) NULL);
13112 *p = 0;
13113
13114 }
13115
13116 /* Perform target specific initialisation of a frag. */
13117
13118 void
13119 arm_init_frag (fragP)
13120 fragS *fragP;
13121 {
13122 /* Record whether this frag is in an ARM or a THUMB area. */
13123 fragP->tc_frag_data = thumb_mode;
13124 }
This page took 0.325649 seconds and 4 git commands to generate.